/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
** version 4.0.0. By combining all the individual C code files into this
** single large file, the entire code can be compiled as a single translation
** unit. This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately. Performance improvements
** of 5% or more are commonly seen when SQLite is compiled as a single
** translation unit.
**
** This file is all you need to compile SQLite. To use SQLite in other
** programs, you need this file and the "sqlite4.h" header file that defines
** the programming interface to the SQLite library. (If you do not have
** the "sqlite4.h" header file at hand, you will find a copy embedded within
** the text of this file. Search for "Begin file sqlite4.h" to find the start
** of the embedded sqlite4.h header file.) Additional code files may be needed
** if you want a wrapper to interface SQLite with your choice of programming
** language. The code for the "sqlite4" command-line shell is also in a
** separate file. This file contains only code for the core SQLite library.
*/
#define SQLITE_CORE 1
#define SQLITE_AMALGAMATION 1
#ifndef SQLITE_PRIVATE
# define SQLITE_PRIVATE static
#endif
#ifndef SQLITE_API
# define SQLITE_API
#endif
/************** Begin file sqliteInt.h ***************************************/
/*
** 2001 September 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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
#define SQLITE_OMIT_ANALYZE 1
#define SQLITE_OMIT_PROGRESS_CALLBACK 1
#define SQLITE_OMIT_VIRTUALTABLE 1
#define SQLITE_OMIT_XFER_OPT 1
/* #define SQLITE_OMIT_AUTOMATIC_INDEX 1 */
/*
** These #defines should enable >2GB file support on POSIX if the
** underlying operating system supports it. If the OS lacks
** large file support, or if the OS is windows, these should be no-ops.
**
** Ticket #2739: The _LARGEFILE_SOURCE macro must appear before any
** system #includes. Hence, this block of code must be the very first
** code in all source files.
**
** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
** on the compiler command line. This is necessary if you are compiling
** on a recent machine (ex: Red Hat 7.2) but you want your code to work
** on an older machine (ex: Red Hat 6.0). If you compile on Red Hat 7.2
** without this option, LFS is enable. But LFS does not exist in the kernel
** in Red Hat 6.0, so the code won't work. Hence, for maximum binary
** portability you should omit LFS.
**
** Similar is true for Mac OS X. LFS is only supported on Mac OS X 9 and later.
*/
#ifndef SQLITE_DISABLE_LFS
# define _LARGE_FILE 1
# ifndef _FILE_OFFSET_BITS
# define _FILE_OFFSET_BITS 64
# endif
# define _LARGEFILE_SOURCE 1
#endif
/*
** Include the configuration header output by 'configure' if we're using the
** autoconf-based build
*/
#ifdef _HAVE_SQLITE_CONFIG_H
#include "config.h"
#endif
/************** Include sqliteLimit.h in the middle of sqliteInt.h ***********/
/************** Begin file sqliteLimit.h *************************************/
/*
** 2007 May 7
**
** 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 defines various limits of what SQLite can process.
*/
/*
** The maximum length of a TEXT or BLOB in bytes. This also
** limits the size of a row in a table or index.
**
** The hard limit is the ability of a 32-bit signed integer
** to count the size: 2^31-1 or 2147483647.
*/
#ifndef SQLITE_MAX_LENGTH
# define SQLITE_MAX_LENGTH 1000000000
#endif
/*
** This is the maximum number of
**
** * Columns in a table
** * Columns in an index
** * Columns in a view
** * Terms in the SET clause of an UPDATE statement
** * Terms in the result set of a SELECT statement
** * Terms in the GROUP BY or ORDER BY clauses of a SELECT statement.
** * Terms in the VALUES clause of an INSERT statement
**
** The hard upper limit here is 32676. Most database people will
** tell you that in a well-normalized database, you usually should
** not have more than a dozen or so columns in any table. And if
** that is the case, there is no point in having more than a few
** dozen values in any of the other situations described above.
*/
#ifndef SQLITE_MAX_COLUMN
# define SQLITE_MAX_COLUMN 2000
#endif
/*
** The maximum length of a single SQL statement in bytes.
**
** It used to be the case that setting this value to zero would
** turn the limit off. That is no longer true. It is not possible
** to turn this limit off.
*/
#ifndef SQLITE_MAX_SQL_LENGTH
# define SQLITE_MAX_SQL_LENGTH 1000000000
#endif
/*
** The maximum depth of an expression tree. This is limited to
** some extent by SQLITE_MAX_SQL_LENGTH. But sometime you might
** want to place more severe limits on the complexity of an
** expression.
**
** A value of 0 used to mean that the limit was not enforced.
** But that is no longer true. The limit is now strictly enforced
** at all times.
*/
#ifndef SQLITE_MAX_EXPR_DEPTH
# define SQLITE_MAX_EXPR_DEPTH 1000
#endif
/*
** The maximum number of terms in a compound SELECT statement.
** The code generator for compound SELECT statements does one
** level of recursion for each term. A stack overflow can result
** if the number of terms is too large. In practice, most SQL
** never has more than 3 or 4 terms. Use a value of 0 to disable
** any limit on the number of terms in a compount SELECT.
*/
#ifndef SQLITE_MAX_COMPOUND_SELECT
# define SQLITE_MAX_COMPOUND_SELECT 500
#endif
/*
** The maximum number of opcodes in a VDBE program.
** Not currently enforced.
*/
#ifndef SQLITE_MAX_VDBE_OP
# define SQLITE_MAX_VDBE_OP 25000
#endif
/*
** The maximum number of arguments to an SQL function.
*/
#ifndef SQLITE_MAX_FUNCTION_ARG
# define SQLITE_MAX_FUNCTION_ARG 127
#endif
/*
** The maximum number of in-memory pages to use for the main database
** table and for temporary tables. The SQLITE_DEFAULT_CACHE_SIZE
*/
#ifndef SQLITE_DEFAULT_CACHE_SIZE
# define SQLITE_DEFAULT_CACHE_SIZE 2000
#endif
#ifndef SQLITE_DEFAULT_TEMP_CACHE_SIZE
# define SQLITE_DEFAULT_TEMP_CACHE_SIZE 500
#endif
/*
** The default number of frames to accumulate in the log file before
** checkpointing the database in WAL mode.
*/
#ifndef SQLITE_DEFAULT_WAL_AUTOCHECKPOINT
# define SQLITE_DEFAULT_WAL_AUTOCHECKPOINT 1000
#endif
/*
** The maximum number of attached databases. This must be between 0
** and 62. The upper bound on 62 is because a 64-bit integer bitmap
** is used internally to track attached databases.
*/
#ifndef SQLITE_MAX_ATTACHED
# define SQLITE_MAX_ATTACHED 10
#endif
/*
** The maximum value of a ?nnn wildcard that the parser will accept.
*/
#ifndef SQLITE_MAX_VARIABLE_NUMBER
# define SQLITE_MAX_VARIABLE_NUMBER 999
#endif
/* Maximum page size. The upper bound on this value is 65536. This a limit
** imposed by the use of 16-bit offsets within each page.
**
** Earlier versions of SQLite allowed the user to change this value at
** compile time. This is no longer permitted, on the grounds that it creates
** a library that is technically incompatible with an SQLite library
** compiled with a different limit. If a process operating on a database
** with a page-size of 65536 bytes crashes, then an instance of SQLite
** compiled with the default page-size limit will not be able to rollback
** the aborted transaction. This could lead to database corruption.
*/
#ifdef SQLITE_MAX_PAGE_SIZE
# undef SQLITE_MAX_PAGE_SIZE
#endif
#define SQLITE_MAX_PAGE_SIZE 65536
/*
** The default size of a database page.
*/
#ifndef SQLITE_DEFAULT_PAGE_SIZE
# define SQLITE_DEFAULT_PAGE_SIZE 1024
#endif
#if SQLITE_DEFAULT_PAGE_SIZE>SQLITE_MAX_PAGE_SIZE
# undef SQLITE_DEFAULT_PAGE_SIZE
# define SQLITE_DEFAULT_PAGE_SIZE SQLITE_MAX_PAGE_SIZE
#endif
/*
** Ordinarily, if no value is explicitly provided, SQLite creates databases
** with page size SQLITE_DEFAULT_PAGE_SIZE. However, based on certain
** device characteristics (sector-size and atomic write() support),
** SQLite may choose a larger value. This constant is the maximum value
** SQLite will choose on its own.
*/
#ifndef SQLITE_MAX_DEFAULT_PAGE_SIZE
# define SQLITE_MAX_DEFAULT_PAGE_SIZE 8192
#endif
#if SQLITE_MAX_DEFAULT_PAGE_SIZE>SQLITE_MAX_PAGE_SIZE
# undef SQLITE_MAX_DEFAULT_PAGE_SIZE
# define SQLITE_MAX_DEFAULT_PAGE_SIZE SQLITE_MAX_PAGE_SIZE
#endif
/*
** Maximum number of pages in one database file.
**
** This is really just the default value for the max_page_count pragma.
** This value can be lowered (or raised) at run-time using that the
** max_page_count macro.
*/
#ifndef SQLITE_MAX_PAGE_COUNT
# define SQLITE_MAX_PAGE_COUNT 1073741823
#endif
/*
** Maximum length (in bytes) of the pattern in a LIKE or GLOB
** operator.
*/
#ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH
# define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000
#endif
/*
** Maximum depth of recursion for triggers.
**
** A value of 1 means that a trigger program will not be able to itself
** fire any triggers. A value of 0 means that no trigger programs at all
** may be executed.
*/
#ifndef SQLITE_MAX_TRIGGER_DEPTH
# define SQLITE_MAX_TRIGGER_DEPTH 1000
#endif
/************** End of sqliteLimit.h *****************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
/* Disable nuisance warnings on Borland compilers */
#if defined(__BORLANDC__)
#pragma warn -rch /* unreachable code */
#pragma warn -ccc /* Condition is always true or false */
#pragma warn -aus /* Assigned value is never used */
#pragma warn -csu /* Comparing signed and unsigned */
#pragma warn -spa /* Suspicious pointer arithmetic */
#endif
/* Needed for various definitions... */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
/*
** Include standard header files as necessary
*/
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
/*
** The following macros are used to cast pointers to integers and
** integers to pointers. The way you do this varies from one compiler
** 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.
** 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.
**
** Ticket #3860: The llvm-gcc-4.2 compiler from Apple chokes on
** the ((void*)&((char*)0)[X]) construct. But MSVC chokes on ((void*)(X)).
** So we have to define the macros in different ways depending on the
** compiler.
*/
#if defined(__PTRDIFF_TYPE__) /* This case should work for GCC */
# define SQLITE_INT_TO_PTR(X) ((void*)(__PTRDIFF_TYPE__)(X))
# define SQLITE_PTR_TO_INT(X) ((int)(__PTRDIFF_TYPE__)(X))
#elif !defined(__GNUC__) /* Works for compilers other than LLVM */
# define SQLITE_INT_TO_PTR(X) ((void*)&((char*)0)[X])
# define SQLITE_PTR_TO_INT(X) ((int)(((char*)X)-(char*)0))
#elif defined(HAVE_STDINT_H) /* Use this case if we have ANSI headers */
# define SQLITE_INT_TO_PTR(X) ((void*)(intptr_t)(X))
# define SQLITE_PTR_TO_INT(X) ((int)(intptr_t)(X))
#else /* Generates a warning - but it always works */
# define SQLITE_INT_TO_PTR(X) ((void*)(X))
# define SQLITE_PTR_TO_INT(X) ((int)(X))
#endif
/*
** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2.
** 0 means mutexes are permanently disable and the library is never
** threadsafe. 1 means the library is serialized which is the highest
** level of threadsafety. 2 means the libary is multithreaded - multiple
** threads can use SQLite as long as no two threads try to use the same
** database connection at the same time.
**
** Older versions of SQLite used an optional THREADSAFE macro.
** We support that for legacy.
*/
#if !defined(SQLITE_THREADSAFE)
#if defined(THREADSAFE)
# define SQLITE_THREADSAFE THREADSAFE
#else
# define SQLITE_THREADSAFE 1 /* IMP: R-07272-22309 */
#endif
#endif
/*
** Powersafe overwrite is on by default. But can be turned off using
** the -DSQLITE_POWERSAFE_OVERWRITE=0 command-line option.
*/
#ifndef SQLITE_POWERSAFE_OVERWRITE
# define SQLITE_POWERSAFE_OVERWRITE 1
#endif
/*
** The SQLITE_DEFAULT_MEMSTATUS macro must be defined as either 0 or 1.
** It determines whether or not the features related to
** SQLITE_CONFIG_MEMSTATUS are available by default or not. This value can
** be overridden at runtime using the sqlite4_config() API.
*/
#if !defined(SQLITE_DEFAULT_MEMSTATUS)
# define SQLITE_DEFAULT_MEMSTATUS 1
#endif
/*
** Exactly one of the following macros must be defined in order to
** specify which memory allocation subsystem to use.
**
** SQLITE_SYSTEM_MALLOC // Use normal system malloc()
** SQLITE_WIN32_MALLOC // Use Win32 native heap API
** SQLITE_MEMDEBUG // Debugging version of system malloc()
**
** On Windows, if the SQLITE_WIN32_MALLOC_VALIDATE macro is defined and the
** assert() macro is enabled, each call into the Win32 native heap subsystem
** will cause HeapValidate to be called. If heap validation should fail, an
** assertion will be triggered.
**
** (Historical note: There used to be several other options, but we've
** pared it down to just these three.)
**
** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as
** the default.
*/
#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)>1
# error "At most one of the following compile-time configuration options\
is allows: SQLITE_SYSTEM_MALLOC, SQLITE_WIN32_MALLOC, SQLITE_MEMDEBUG"
#endif
#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)==0
# define SQLITE_SYSTEM_MALLOC 1
#endif
/*
** If SQLITE_MALLOC_SOFT_LIMIT is not zero, then try to keep the
** sizes of memory allocations below this value where possible.
*/
#if !defined(SQLITE_MALLOC_SOFT_LIMIT)
# define SQLITE_MALLOC_SOFT_LIMIT 1024
#endif
/*
** We need to define _XOPEN_SOURCE as follows in order to enable
** recursive mutexes on most Unix systems. But Mac OS X is different.
** The _XOPEN_SOURCE define causes problems for Mac OS X we are told,
** so it is omitted there. See ticket #2673.
**
** Later we learn that _XOPEN_SOURCE is poorly or incorrectly
** implemented on some systems. So we avoid defining it at all
** if it is already defined or if it is unneeded because we are
** not doing a threadsafe build. Ticket #2681.
**
** See also ticket #2741.
*/
#if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__) && SQLITE_THREADSAFE
# define _XOPEN_SOURCE 500 /* Needed to enable pthread recursive mutexes */
#endif
/*
** The TCL headers are only needed when compiling the TCL bindings.
*/
#if defined(SQLITE_TCL) || defined(TCLSH)
# include <tcl.h>
#endif
/*
** Many people are failing to set -DNDEBUG=1 when compiling SQLite.
** Setting NDEBUG makes the code smaller and run faster. So the following
** lines are added to automatically set NDEBUG unless the -DSQLITE_DEBUG=1
** option is set. Thus NDEBUG becomes an opt-in rather than an opt-out
** feature.
*/
#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
# define NDEBUG 1
#endif
/*
** 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
** to help ensure adequate test coverage in places where simple
** condition/decision coverage is inadequate. For example, testcase()
** can be used to make sure boundary values are tested. For
** bitmask tests, testcase() can be used to make sure each bit
** is significant and used at least once. On switch statements
** where multiple cases go to the same block of code, testcase()
** can insure that all cases are evaluated.
**
*/
#ifdef SQLITE_COVERAGE_TEST
SQLITE_PRIVATE void sqlite4Coverage(int);
# define testcase(X) if( X ){ sqlite4Coverage(__LINE__); }
#else
# define testcase(X)
#endif
/*
** The TESTONLY macro is used to enclose variable declarations or
** other bits of code that are needed to support the arguments
** within testcase() and assert() macros.
*/
#if !defined(NDEBUG) || defined(SQLITE_COVERAGE_TEST)
# define TESTONLY(X) X
#else
# define TESTONLY(X)
#endif
/*
** Sometimes we need a small amount of code such as a variable initialization
** to setup for a later assert() statement. We do not want this code to
** appear when assert() is disabled. The following macro is therefore
** used to contain that setup code. The "VVA" acronym stands for
** "Verification, Validation, and Accreditation". In other words, the
** code within VVA_ONLY() will only run during verification processes.
*/
#ifndef NDEBUG
# define VVA_ONLY(X) X
#else
# define VVA_ONLY(X)
#endif
/*
** 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
** of SQLite to unexpected behavior - to make the code "self-healing"
** or "ductile" rather than being "brittle" and crashing at the first
** hint of unplanned behavior.
**
** In other words, ALWAYS and NEVER are added for defensive code.
**
** When doing coverage testing ALWAYS and NEVER are hard-coded to
** be true and false so that the unreachable code then specify will
** not be counted as untested code.
*/
#if defined(SQLITE_COVERAGE_TEST)
# define ALWAYS(X) (1)
# define NEVER(X) (0)
#elif !defined(NDEBUG)
# define ALWAYS(X) ((X)?1:(assert(0),0))
# define NEVER(X) ((X)?(assert(0),1):0)
#else
# define ALWAYS(X) (X)
# define NEVER(X) (X)
#endif
/*
** Return true (non-zero) if the input is a integer that is too large
** to fit in 32-bits. This macro is used inside of various testcase()
** macros to verify that we have tested SQLite for large-file support.
*/
#define IS_BIG_INT(X) (((X)&~(i64)0xffffffff)!=0)
/*
** The macro unlikely() is a hint that surrounds a boolean
** expression that is usually false. Macro likely() surrounds
** a boolean expression that is usually true. GCC is able to
** use these hints to generate better code, sometimes.
*/
#if defined(__GNUC__) && 0
# define likely(X) __builtin_expect((X),1)
# define unlikely(X) __builtin_expect((X),0)
#else
# define likely(X) !!(X)
# define unlikely(X) !!(X)
#endif
/************** Include sqlite4.h in the middle of sqliteInt.h ***************/
/************** Begin file sqlite4.h *****************************************/
/*
** 2001 September 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.
**
*************************************************************************
** This header file defines the interface that the SQLite library
** presents to client programs. If a C-function, structure, datatype,
** or constant definition does not appear in this file, then it is
** not a published API of SQLite, is subject to change without
** notice, and should not be referenced by programs that use SQLite.
**
** Some of the definitions that are in this file are marked as
** "experimental". Experimental interfaces are normally new
** features recently added to SQLite. We do not anticipate changes
** to experimental interfaces but reserve the right to make minor changes
** if experience from use "in the wild" suggest such changes are prudent.
**
** The official C-language API documentation for SQLite is derived
** from comments in this file. This file is the authoritative source
** on how SQLite interfaces are suppose to operate.
**
** The name of this file under configuration management is "sqlite.h.in".
** The makefile makes some minor changes to this file (such as inserting
** the version number) and changes its name to "sqlite4.h" as
** part of the build process.
*/
#ifndef _SQLITE4_H_
#define _SQLITE4_H_
#include <stdarg.h> /* Needed for the definition of va_list */
/*
** Make sure we can call this stuff from C++.
*/
#if 0
extern "C" {
#endif
/*
** Add the ability to override 'extern'
*/
#ifndef SQLITE_EXTERN
# define SQLITE_EXTERN extern
#endif
#ifndef SQLITE_API
# define SQLITE_API
#endif
/*
** These no-op macros are used in front of interfaces to mark those
** interfaces as either deprecated or experimental. New applications
** should not use deprecated interfaces - they are support for backwards
** compatibility only. Application writers should be aware that
** experimental interfaces are subject to change in point releases.
**
** These macros used to resolve to various kinds of compiler magic that
** would generate warning messages when they were used. But that
** compiler magic ended up generating such a flurry of bug reports
** that we have taken it all out and gone back to using simple
** noop macros.
*/
#define SQLITE_DEPRECATED
#define SQLITE_EXPERIMENTAL
/*
** Ensure these symbols were not defined by some previous header file.
*/
#ifdef SQLITE_VERSION
# undef SQLITE_VERSION
#endif
#ifdef SQLITE_VERSION_NUMBER
# undef SQLITE_VERSION_NUMBER
#endif
/*
** CAPIREF: Run-time Environment Object
**
** An instance of the following object defines the run-time environment
** for an SQLite4 database connection. This object defines the interface
** to appropriate mutex routines, memory allocation routines, a
** pseudo-random number generator, real-time clock, and the key-value
** backend stores.
*/
typedef struct sqlite4_env sqlite4_env;
/*
** CAPIREF: Find the default run-time environment
**
** Return a pointer to the default run-time environment.
*/
SQLITE_API sqlite4_env *sqlite4_env_default(void);
/*
** CAPIREF: Size of an sqlite4_env object
**
** Return the number of bytes of memory needed to hold an sqlite4_env
** object. This number varies from one machine to another, and from
** one release of SQLite to another.
*/
SQLITE_API int sqlite4_env_size(void);
/*
** CAPIREF: Configure a run-time environment
*/
SQLITE_API int sqlite4_env_config(sqlite4_env*, int op, ...);
/*
** CAPIREF: Configuration options for sqlite4_env_config().
*/
#define SQLITE_ENVCONFIG_INIT 1 /* size, template */
#define SQLITE_ENVCONFIG_SINGLETHREAD 2 /* */
#define SQLITE_ENVCONFIG_MULTITHREAD 3 /* */
#define SQLITE_ENVCONFIG_SERIALIZED 4 /* */
#define SQLITE_ENVCONFIG_MUTEX 5 /* sqlite4_mutex_methods* */
#define SQLITE_ENVCONFIG_GETMUTEX 6 /* sqlite4_mutex_methods* */
#define SQLITE_ENVCONFIG_MALLOC 7 /* sqlite4_mem_methods* */
#define SQLITE_ENVCONFIG_GETMALLOC 8 /* sqlite4_mem_methods* */
#define SQLITE_ENVCONFIG_MEMSTATUS 9 /* boolean */
#define SQLITE_ENVCONFIG_LOOKASIDE 10 /* size, count */
#define SQLITE_ENVCONFIG_LOG 11 /* xLog, pArg */
#define SQLITE_ENVCONFIG_KVSTORE_PUSH 12 /* name, factory */
#define SQLITE_ENVCONFIG_KVSTORE_POP 13 /* name */
#define SQLITE_ENVCONFIG_KVSTORE_GET 14 /* name, *factor */
/*
** CAPIREF: Compile-Time Library Version Numbers
**
** ^(The [SQLITE_VERSION] C preprocessor macro in the sqlite4.h header
** evaluates to a string literal that is the SQLite version in the
** format "X.Y.Z" where X is the major version number (always 3 for
** SQLite3) and Y is the minor version number and Z is the release number.)^
** ^(The [SQLITE_VERSION_NUMBER] C preprocessor macro resolves to an integer
** with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z are the same
** numbers used in [SQLITE_VERSION].)^
** The SQLITE_VERSION_NUMBER for any given release of SQLite will also
** be larger than the release from which it is derived. Either Y will
** be held constant and Z will be incremented or else Y will be incremented
** and Z will be reset to zero.
**
** Since version 3.6.18, 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 an SHA1
** hash of the entire source tree.
**
** See also: [sqlite4_libversion()],
** [sqlite4_libversion_number()], [sqlite4_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION "4.0.0"
#define SQLITE_VERSION_NUMBER 4000000
#define SQLITE_SOURCE_ID "2012-06-26 20:17:04 f19a93d9f9d862741bc7fbb05e292d430864b2b1"
/*
** CAPIREF: Run-Time Library Version Numbers
** KEYWORDS: sqlite4_version, sqlite4_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 insure that the application is
** compiled with matching library and header files.
**
** <blockquote><pre>
** assert( sqlite4_libversion_number()==SQLITE_VERSION_NUMBER );
** assert( strcmp(sqlite4_sourceid(),SQLITE_SOURCE_ID)==0 );
** assert( strcmp(sqlite4_libversion(),SQLITE_VERSION)==0 );
** </pre></blockquote>)^
**
** ^The sqlite4_libversion() function returns a pointer to a string
** constant that contains the text of [SQLITE_VERSION]. ^The
** sqlite4_libversion_number() function returns an integer equal to
** [SQLITE_VERSION_NUMBER]. ^The sqlite4_sourceid() function returns
** a pointer to a string constant whose value is the same as the
** [SQLITE_SOURCE_ID] C preprocessor macro.
**
** See also: [sqlite_version()] and [sqlite_source_id()].
*/
SQLITE_API const char *sqlite4_libversion(void);
SQLITE_API const char *sqlite4_sourceid(void);
SQLITE_API int sqlite4_libversion_number(void);
/*
** CAPIREF: Run-Time Library Compilation Options Diagnostics
**
** ^The sqlite4_compileoption_used() function returns 0 or 1
** indicating whether the specified option was defined at
** compile time. ^The SQLITE_ prefix may be omitted from the
** option name passed to sqlite4_compileoption_used().
**
** ^The sqlite4_compileoption_get() function allows iterating
** over the list of options that were defined at compile time by
** returning the N-th compile time option string. ^If N is out of range,
** sqlite4_compileoption_get() returns a NULL pointer. ^The SQLITE_
** prefix is omitted from any strings returned by
** sqlite4_compileoption_get().
**
** ^Support for the diagnostic functions sqlite4_compileoption_used()
** and sqlite4_compileoption_get() may be omitted by specifying the
** [SQLITE_OMIT_COMPILEOPTION_DIAGS] option at compile time.
**
** See also: SQL functions [sqlite_compileoption_used()] and
** [sqlite_compileoption_get()] and the [compile_options pragma].
*/
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
SQLITE_API int sqlite4_compileoption_used(const char *zOptName);
SQLITE_API const char *sqlite4_compileoption_get(int N);
#endif
/*
** CAPIREF: Test To See If The Library Is Threadsafe
**
** ^The sqlite4_threadsafe(E) function returns zero if the [sqlite4_env]
** object is configured in such a way that it should only be used by a
** single thread at a time. In other words, this routine returns zero
** if the environment is configured as [SQLITE_ENVCONFIG_SINGLETHREAD].
**
** ^The sqlite4_threadsafe(E) function returns one if multiple
** [database connection] objects associated with E can be used at the
** same time in different threads, so long as no single [database connection]
** object is used by two or more threads at the same time. This
** corresponds to [SQLITE_ENVCONFIG_MULTITHREAD].
**
** ^The sqlite4_threadsafe(E) function returns two if the same
** [database connection] can be used at the same time from two or more
** separate threads. This setting corresponds to [SQLITE_ENVCONFIG_SERIALIZED].
**
** Note that SQLite4 is always threadsafe in this sense: Two or more
** objects each associated with different [sqlite4_env] objects can
** always be used at the same time in separate threads.
*/
SQLITE_API int sqlite4_threadsafe(sqlite4_env*);
/*
** CAPIREF: Database Connection Handle
** KEYWORDS: {database connection} {database connections}
**
** Each open SQLite database is represented by a pointer to an instance of
** the opaque structure named "sqlite4". It is useful to think of an sqlite4
** pointer as an object. The [sqlite4_open()]
** interface is its constructors, and [sqlite4_close()]
** is its destructor. There are many other interfaces (such as
** [sqlite4_prepare_v2()], [sqlite4_create_function()], and
** [sqlite4_busy_timeout()] to name but three) that are methods on an
** sqlite4 object.
*/
typedef struct sqlite4 sqlite4;
/*
** CAPIREF: 64-Bit Integer Types
** KEYWORDS: sqlite_int64 sqlite_uint64
**
** Because there is no cross-platform way to specify 64-bit integer types
** SQLite includes typedefs for 64-bit signed and unsigned integers.
**
** The sqlite4_int64 and sqlite4_uint64 are the preferred type definitions.
** The sqlite_int64 and sqlite_uint64 types are supported for backwards
** compatibility only.
**
** ^The sqlite4_int64 and sqlite_int64 types can store integer values
** between -9223372036854775808 and +9223372036854775807 inclusive. ^The
** sqlite4_uint64 and sqlite_uint64 types can store integer values
** between 0 and +18446744073709551615 inclusive.
*/
#ifdef SQLITE_INT64_TYPE
typedef SQLITE_INT64_TYPE sqlite_int64;
typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
#elif defined(_MSC_VER) || defined(__BORLANDC__)
typedef __int64 sqlite_int64;
typedef unsigned __int64 sqlite_uint64;
#else
typedef long long int sqlite_int64;
typedef unsigned long long int sqlite_uint64;
#endif
typedef sqlite_int64 sqlite4_int64;
typedef sqlite_uint64 sqlite4_uint64;
/*
** CAPIREF: String length type
**
** A type for measuring the length of the string. Like size_t but
** does not require <stddef.h>
*/
typedef int sqlite4_size_t;
/*
** If compiling for a processor that lacks floating point support,
** substitute integer for floating-point.
*/
#ifdef SQLITE_OMIT_FLOATING_POINT
# define double sqlite4_int64
#endif
/*
** CAPIREF: Closing A Database Connection
**
** ^The sqlite4_close() routine is the destructor for the [sqlite4] object.
** ^Calls to sqlite4_close() return SQLITE_OK if the [sqlite4] object is
** successfully destroyed and all associated resources are deallocated.
**
** Applications must [sqlite4_finalize | finalize] all [prepared statements]
** and [sqlite4_blob_close | close] all [BLOB handles] associated with
** the [sqlite4] object prior to attempting to close the object. ^If
** sqlite4_close() is called on a [database connection] that still has
** outstanding [prepared statements] or [BLOB handles], then it returns
** SQLITE_BUSY.
**
** ^If [sqlite4_close()] is invoked while a transaction is open,
** the transaction is automatically rolled back.
**
** The C parameter to [sqlite4_close(C)] must be either a NULL
** pointer or an [sqlite4] object pointer obtained
** from [sqlite4_open()] and not previously closed.
** ^Calling sqlite4_close() with a NULL pointer argument is a
** harmless no-op.
*/
SQLITE_API int sqlite4_close(sqlite4 *);
/*
** The type for a callback function.
** This is legacy and deprecated. It is included for historical
** compatibility and is not documented.
*/
typedef int (*sqlite4_callback)(void*,int,char**, char**);
/*
** CAPIREF: One-Step Query Execution Interface
**
** The sqlite4_exec() interface is a convenience wrapper around
** [sqlite4_prepare_v2()], [sqlite4_step()], and [sqlite4_finalize()],
** that allows an application to run multiple statements of SQL
** without having to use a lot of C code.
**
** ^The sqlite4_exec() interface runs zero or more UTF-8 encoded,
** semicolon-separate SQL statements passed into its 2nd argument,
** in the context of the [database connection] passed in as its 1st
** argument. ^If the callback function of the 3rd argument to
** sqlite4_exec() is not NULL, then it is invoked for each result row
** coming out of the evaluated SQL statements. ^The 4th argument to
** sqlite4_exec() is relayed through to the 1st argument of each
** callback invocation. ^If the callback pointer to sqlite4_exec()
** is NULL, then no callback is ever invoked and result rows are
** ignored.
**
** ^If an error occurs while evaluating the SQL statements passed into
** sqlite4_exec(), then execution of the current statement stops and
** subsequent statements are skipped. ^If the 5th parameter to sqlite4_exec()
** is not NULL then any error message is written into memory obtained
** from [sqlite4_malloc()] and passed back through the 5th parameter.
** To avoid memory leaks, the application should invoke [sqlite4_free()]
** on error message strings returned through the 5th parameter of
** of sqlite4_exec() after the error message string is no longer needed.
** ^If the 5th parameter to sqlite4_exec() is not NULL and no errors
** occur, then sqlite4_exec() sets the pointer in its 5th parameter to
** NULL before returning.
**
** ^If an sqlite4_exec() callback returns non-zero, the sqlite4_exec()
** routine returns SQLITE_ABORT without invoking the callback again and
** without running any subsequent SQL statements.
**
** ^The 2nd argument to the sqlite4_exec() callback function is the
** number of columns in the result. ^The 3rd argument to the sqlite4_exec()
** callback is an array of pointers to strings obtained as if from
** [sqlite4_column_text()], one for each column. ^If an element of a
** result row is NULL then the corresponding string pointer for the
** sqlite4_exec() callback is a NULL pointer. ^The 4th argument to the
** sqlite4_exec() callback is an array of pointers to strings where each
** entry represents the name of corresponding result column as obtained
** from [sqlite4_column_name()].
**
** ^If the 2nd parameter to sqlite4_exec() is a NULL pointer, a pointer
** to an empty string, or a pointer that contains only whitespace and/or
** SQL comments, then no SQL statements are evaluated and the database
** is not changed.
**
** Restrictions:
**
** <ul>
** <li> The application must insure that the 1st parameter to sqlite4_exec()
** is a valid and open [database connection].
** <li> The application must not close [database connection] specified by
** the 1st parameter to sqlite4_exec() while sqlite4_exec() is running.
** <li> The application must not modify the SQL statement text passed into
** the 2nd parameter of sqlite4_exec() while sqlite4_exec() is running.
** </ul>
*/
SQLITE_API int sqlite4_exec(
sqlite4*, /* An open database */
const char *sql, /* SQL to be evaluated */
int (*callback)(void*,int,char**,char**), /* Callback function */
void *, /* 1st argument to callback */
char **errmsg /* Error msg written here */
);
/*
** CAPIREF: Result Codes
** KEYWORDS: SQLITE_OK {error code} {error codes}
** KEYWORDS: {result code} {result codes}
**
** Many SQLite functions return an integer result code from the set shown
** here in order to indicate success or failure.
**
** New error codes may be added in future versions of SQLite.
**
** See also: [SQLITE_IOERR_READ | extended result codes],
** [sqlite4_vtab_on_conflict()] [SQLITE_ROLLBACK | result codes].
*/
#define SQLITE_OK 0 /* Successful result */
/* beginning-of-error-codes */
#define SQLITE_ERROR 1 /* SQL error or missing database */
#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 */
#define SQLITE_BUSY 5 /* The database file is locked */
#define SQLITE_LOCKED 6 /* A table in the database is locked */
#define SQLITE_NOMEM 7 /* A malloc() failed */
#define SQLITE_READONLY 8 /* Attempt to write a readonly database */
#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite4_interrupt()*/
#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */
#define SQLITE_CORRUPT 11 /* The database disk image is malformed */
#define SQLITE_NOTFOUND 12 /* Unknown opcode in sqlite4_file_control() */
#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 /* Database is empty */
#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 */
#define SQLITE_MISMATCH 20 /* Data type mismatch */
#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 /* Auxiliary database format error */
#define SQLITE_RANGE 25 /* 2nd parameter to sqlite4_bind out of range */
#define SQLITE_NOTADB 26 /* File opened that is not a database file */
#define SQLITE_ROW 100 /* sqlite4_step() has another row ready */
#define SQLITE_DONE 101 /* sqlite4_step() has finished executing */
#define SQLITE_INEXACT 102 /* xSeek method of storage finds nearby ans */
/* end-of-error-codes */
/*
** CAPIREF: Extended Result Codes
** KEYWORDS: {extended error code} {extended error codes}
** KEYWORDS: {extended result code} {extended result codes}
**
** In its default configuration, SQLite API routines return one of 26 integer
** [SQLITE_OK | 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 and later) include
** support for additional result codes that provide more detailed information
** about errors. The extended result codes are enabled or disabled
** on a per database connection basis using the
** [sqlite4_extended_result_codes()] API.
**
** Some of the available extended result codes are listed here.
** One may expect the number of extended result codes will be expand
** over time. Software that uses extended result codes should expect
** to see new result codes in future releases of SQLite.
**
** The SQLITE_OK result code will never be extended. It will always
** be exactly zero.
*/
#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8))
#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8))
#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8))
#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8))
#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8))
#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8))
#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8))
#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8))
#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8))
#define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8))
#define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11<<8))
#define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12<<8))
#define SQLITE_IOERR_ACCESS (SQLITE_IOERR | (13<<8))
#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8))
#define SQLITE_IOERR_LOCK (SQLITE_IOERR | (15<<8))
#define SQLITE_IOERR_CLOSE (SQLITE_IOERR | (16<<8))
#define SQLITE_IOERR_DIR_CLOSE (SQLITE_IOERR | (17<<8))
#define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8))
#define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8))
#define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8))
#define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8))
#define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8))
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
/*
** CAPIREF: Flags For File Open Operations
**
** These bit values are intended for use as options in the
** [sqlite4_open()] interface
*/
#define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite4_open() */
#define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite4_open() */
#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite4_open() */
/* NB: The above must not overlap with the SQLITE_KVOPEN_xxxxx flags
** defined below */
/*
** CAPIREF: Mutex Handle
**
** The mutex module within SQLite defines [sqlite4_mutex] to be an
** abstract type for a mutex object. The SQLite core never looks
** at the internal representation of an [sqlite4_mutex]. It only
** deals with pointers to the [sqlite4_mutex] object.
**
** Mutexes are created using [sqlite4_mutex_alloc()].
*/
typedef struct sqlite4_mutex sqlite4_mutex;
struct sqlite4_mutex {
struct sqlite4_mutex_methods *pMutexMethods;
/* Subclasses will typically add additional fields */
};
/*
** CAPIREF: Initialize The SQLite Library
**
** ^The sqlite4_initialize(A) routine initializes an sqlite4_env object A.
** ^The sqlite4_shutdown(A) routine
** deallocates any resources that were allocated by sqlite4_initialize(A).
**
** A call to sqlite4_initialize(A) is an "effective" call if it is
** the first time sqlite4_initialize(A) is invoked during the lifetime of
** A, or if it is the first time sqlite4_initialize(A) is invoked
** following a call to sqlite4_shutdown(A). ^(Only an effective call
** of sqlite4_initialize(A) does any initialization or A. All other calls
** are harmless no-ops.)^
**
** A call to sqlite4_shutdown(A) is an "effective" call if it is the first
** call to sqlite4_shutdown(A) since the last sqlite4_initialize(A). ^(Only
** an effective call to sqlite4_shutdown(A) does any deinitialization.
** All other valid calls to sqlite4_shutdown(A) are harmless no-ops.)^
**
** The sqlite4_initialize(A) interface is threadsafe, but sqlite4_shutdown(A)
** is not. The sqlite4_shutdown(A) interface must only be called from a
** single thread. All open [database connections] must be closed and all
** other SQLite resources must be deallocated prior to invoking
** sqlite4_shutdown(A).
**
** ^The sqlite4_initialize(A) routine returns [SQLITE_OK] on success.
** ^If for some reason, sqlite4_initialize(A) is unable to initialize
** the sqlite4_env object A (perhaps it is unable to allocate a needed
** resource such as a mutex) it returns an [error code] other than [SQLITE_OK].
**
** ^The sqlite4_initialize() routine is called internally by many other
** SQLite interfaces so that an application usually does not need to
** invoke sqlite4_initialize() directly. For example, [sqlite4_open()]
** calls sqlite4_initialize() so the SQLite library will be automatically
** initialized when [sqlite4_open()] is called if it has not be initialized
** already. ^However, if SQLite is compiled with the [SQLITE_OMIT_AUTOINIT]
** compile-time option, then the automatic calls to sqlite4_initialize()
** are omitted and the application must call sqlite4_initialize() directly
** prior to using any other SQLite interface. For maximum portability,
** it is recommended that applications always invoke sqlite4_initialize()
** directly prior to using any other SQLite interface. Future releases
** of SQLite may require this. In other words, the behavior exhibited
** when SQLite is compiled with [SQLITE_OMIT_AUTOINIT] might become the
** default behavior in some future release of SQLite.
*/
SQLITE_API int sqlite4_initialize(sqlite4_env*);
SQLITE_API int sqlite4_shutdown(sqlite4_env*);
/*
** CAPIREF: Configure database connections
**
** The sqlite4_db_config() interface is used to make configuration
** changes to a [database connection]. The interface is similar to
** [sqlite4_env_config()] except that the changes apply to a single
** [database connection] (specified in the first argument).
**
** The second argument to sqlite4_db_config(D,V,...) is the
** [SQLITE_DBCONFIG_LOOKASIDE | configuration verb] - an integer code
** that indicates what aspect of the [database connection] is being configured.
** Subsequent arguments vary depending on the configuration verb.
**
** ^Calls to sqlite4_db_config() return SQLITE_OK if and only if
** the call is considered successful.
*/
SQLITE_API int sqlite4_db_config(sqlite4*, int op, ...);
/*
** CAPIREF: Run-time environment of a database connection
**
** Return the sqlite4_env object to which the database connection
** belongs.
*/
SQLITE_API sqlite4_env *sqlite4_db_env(sqlite4*);
/*
** CAPIREF: Memory Allocation Routines
**
** An instance of this object defines the interface between SQLite
** and low-level memory allocation routines.
**
** This object is used in only one place in the SQLite interface.
** A pointer to an instance of this object is the argument to
** [sqlite4_env_config()] when the configuration option is
** [SQLITE_ENVCONFIG_MALLOC] or [SQLITE_ENVCONFIG_GETMALLOC].
** By creating an instance of this object
** and passing it to [sqlite4_env_config]([SQLITE_ENVCONFIG_MALLOC])
** during configuration, an application can specify an alternative
** memory allocation subsystem for SQLite to use for all of its
** dynamic memory needs.
**
** Note that SQLite comes with several [built-in memory allocators]
** that are perfectly adequate for the overwhelming majority of applications
** and that this object is only useful to a tiny minority of applications
** with specialized memory allocation requirements. This object is
** also used during testing of SQLite in order to specify an alternative
** memory allocator that simulates memory out-of-memory conditions in
** order to verify that SQLite recovers gracefully from such
** conditions.
**
** The xMalloc, xRealloc, and xFree methods must work like the
** malloc(), realloc() and free() functions from the standard C library.
** ^SQLite guarantees that the second argument to
** xRealloc is always a value returned by a prior call to xRoundup.
**
** xSize should return the allocated size of a memory allocation
** previously obtained from xMalloc or xRealloc. The allocated size
** is always at least as big as the requested size but may be larger.
**
** The xRoundup method returns what would be the allocated size of
** a memory allocation given a particular requested size. Most memory
** allocators round up memory allocations at least to the next multiple
** of 8. Some allocators round up to a larger multiple or to a power of 2.
** Every memory allocation request coming in through [sqlite4_malloc()]
** or [sqlite4_realloc()] first calls xRoundup. If xRoundup returns 0,
** that causes the corresponding memory allocation to fail.
**
** The xInit method initializes the memory allocator. (For example,
** it might allocate any require mutexes or initialize internal data
** structures. The xShutdown method is invoked (indirectly) by
** [sqlite4_shutdown()] and should deallocate any resources acquired
** by xInit. The pMemEnv pointer is used as the only parameter to
** xInit and xShutdown.
**
** SQLite holds the [SQLITE_MUTEX_STATIC_MASTER] mutex when it invokes
** the xInit method, so the xInit method need not be threadsafe. The
** xShutdown method is only called from [sqlite4_shutdown()] so it does
** not need to be threadsafe either. For all other methods, SQLite
** holds the [SQLITE_MUTEX_STATIC_MEM] mutex as long as the
** [SQLITE_CONFIG_MEMSTATUS] configuration option is turned on (which
** it is by default) and so the methods are automatically serialized.
** However, if [SQLITE_CONFIG_MEMSTATUS] is disabled, then the other
** methods must be threadsafe or else make their own arrangements for
** serialization.
**
** SQLite will never invoke xInit() more than once without an intervening
** call to xShutdown().
*/
typedef struct sqlite4_mem_methods sqlite4_mem_methods;
struct sqlite4_mem_methods {
void *(*xMalloc)(void*,sqlite4_size_t); /* Memory allocation function */
void (*xFree)(void*,void*); /* Free a prior allocation */
void *(*xRealloc)(void*,void*,int); /* Resize an allocation */
sqlite4_size_t (*xSize)(void*,void*); /* Return the size of an allocation */
int (*xInit)(void*); /* Initialize the memory allocator */
void (*xShutdown)(void*); /* Deinitialize the allocator */
void (*xBeginBenign)(void*); /* Enter a benign malloc region */
void (*xEndBenign)(void*); /* Leave a benign malloc region */
void *pMemEnv; /* 1st argument to all routines */
};
/*
** CAPIREF: Database Connection Configuration Options
**
** These constants are the available integer configuration options that
** can be passed as the second argument to the [sqlite4_db_config()] interface.
**
** New configuration options may be added in future releases of SQLite.
** Existing configuration options might be discontinued. Applications
** should check the return code from [sqlite4_db_config()] to make sure that
** the call worked. ^The [sqlite4_db_config()] interface will return a
** non-zero [error code] if a discontinued or unsupported configuration option
** is invoked.
**
** <dl>
** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
** <dd> ^This option takes three additional arguments that determine the
** [lookaside memory allocator] configuration for the [database connection].
** ^The first argument (the third parameter to [sqlite4_db_config()] is a
** pointer to a memory buffer to use for lookaside memory.
** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb
** may be NULL in which case SQLite will allocate the
** lookaside buffer itself using [sqlite4_malloc()]. ^The second argument is the
** size of each lookaside buffer slot. ^The third argument is the number of
** slots. The size of the buffer in the first argument must be greater than
** or equal to the product of the second and third arguments. The buffer
** must be aligned to an 8-byte boundary. ^If the second argument to
** SQLITE_DBCONFIG_LOOKASIDE is not a multiple of 8, it is internally
** rounded down to the next smaller multiple of 8. ^(The lookaside memory
** configuration for a database connection can only be changed when that
** connection is not currently using lookaside memory, or in other words
** when the "current value" returned by
** [sqlite4_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero.
** Any attempt to change the lookaside memory configuration when lookaside
** memory is in use leaves the configuration unchanged and returns
** [SQLITE_BUSY].)^</dd>
**
** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt>
** <dd> ^This option is used to enable or disable the enforcement of
** [foreign key constraints]. There should be two additional arguments.
** The first argument is an integer which is 0 to disable FK enforcement,
** positive to enable FK enforcement or negative to leave FK enforcement
** unchanged. The second parameter is a pointer to an integer into which
** is written 0 or 1 to indicate whether FK enforcement is off or on
** following this call. The second parameter may be a NULL pointer, in
** which case the FK enforcement setting is not reported back. </dd>
**
** <dt>SQLITE_DBCONFIG_ENABLE_TRIGGER</dt>
** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers].
** There should be two additional arguments.
** The first argument is an integer which is 0 to disable triggers,
** positive to enable triggers 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 triggers are disabled or enabled
** following this call. The second parameter may be a NULL pointer, in
** which case the trigger setting is not reported back. </dd>
**
** </dl>
*/
#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */
/*
** CAPIREF: Last Insert Rowid
**
** ^Each entry in an SQLite table has a unique 64-bit signed
** integer key called the [ROWID | "rowid"]. ^The rowid is always available
** as an undeclared column named ROWID, OID, or _ROWID_ as long as those
** names are not also used by explicitly declared columns. ^If
** the table has a column of type [INTEGER PRIMARY KEY] then that column
** is another alias for the rowid.
**
** ^This routine returns the [rowid] of the most recent
** successful [INSERT] into the database from the [database connection]
** in the first argument. ^As of SQLite version 3.7.7, this routines
** records the last insert rowid of both ordinary tables and [virtual tables].
** ^If no successful [INSERT]s
** have ever occurred on that database connection, zero is returned.
**
** ^(If an [INSERT] occurs within a trigger or within a [virtual table]
** method, then this routine will return the [rowid] of the inserted
** row as long as the trigger or virtual table method is running.
** But once the trigger or virtual table method ends, the value returned
** by this routine reverts to what it was before the trigger or virtual
** table method began.)^
**
** ^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,
** and INSERT OR ABORT make no changes to the return value of this
** routine when their insertion fails. ^(When INSERT OR REPLACE
** encounters a constraint violation, it does not fail. The
** INSERT continues to completion after deleting rows that caused
** the constraint problem so INSERT OR REPLACE will always change
** the return value of this interface.)^
**
** ^For the purposes of this routine, an [INSERT] is considered to
** be successful even if it is subsequently rolled back.
**
** This function is accessible to SQL statements via the
** [last_insert_rowid() SQL function].
**
** If a separate thread performs a new [INSERT] on the same
** database connection while the [sqlite4_last_insert_rowid()]
** function is running and thus changes the last insert [rowid],
** then the value returned by [sqlite4_last_insert_rowid()] is
** unpredictable and might not equal either the old or the new
** last insert [rowid].
*/
SQLITE_API sqlite4_int64 sqlite4_last_insert_rowid(sqlite4*);
/*
** CAPIREF: Count The Number Of Rows Modified
**
** ^This function returns the number of database rows that were changed
** or inserted or deleted by the most recently completed SQL statement
** on the [database connection] specified by the first parameter.
** ^(Only changes that are directly specified by the [INSERT], [UPDATE],
** or [DELETE] statement are counted. Auxiliary changes caused by
** triggers or [foreign key actions] are not counted.)^ Use the
** [sqlite4_total_changes()] function to find the total number of changes
** including changes caused by triggers and foreign key actions.
**
** ^Changes to a view that are simulated by an [INSTEAD OF trigger]
** are not counted. Only real table changes are counted.
**
** ^(A "row change" is a change to a single row of a single table
** caused by an INSERT, DELETE, or UPDATE statement. Rows that
** are changed as side effects of [REPLACE] constraint resolution,
** rollback, ABORT processing, [DROP TABLE], or by any other
** mechanisms do not count as direct row changes.)^
**
** A "trigger context" is a scope of execution that begins and
** ends with the script of a [CREATE TRIGGER | trigger].
** Most SQL statements are
** evaluated outside of any trigger. This is the "top level"
** trigger context. If a trigger fires from the top level, a
** new trigger context is entered for the duration of that one
** trigger. Subtriggers create subcontexts for their duration.
**
** ^Calling [sqlite4_exec()] or [sqlite4_step()] recursively does
** not create a new trigger context.
**
** ^This function returns the number of direct row changes in the
** most recent INSERT, UPDATE, or DELETE statement within the same
** trigger context.
**
** ^Thus, when called from the top level, this function returns the
** number of changes in the most recent INSERT, UPDATE, or DELETE
** that also occurred at the top level. ^(Within the body of a trigger,
** the sqlite4_changes() interface can be called to find the number of
** changes in the most recently completed INSERT, UPDATE, or DELETE
** statement within the body of the same trigger.
** However, the number returned does not include changes
** caused by subtriggers since those have their own context.)^
**
** See also the [sqlite4_total_changes()] interface, the
** [count_changes pragma], and the [changes() SQL function].
**
** If a separate thread makes changes on the same database connection
** while [sqlite4_changes()] is running then the value returned
** is unpredictable and not meaningful.
*/
SQLITE_API int sqlite4_changes(sqlite4*);
/*
** CAPIREF: Total Number Of Rows Modified
**
** ^This function returns the number of row changes caused by [INSERT],
** [UPDATE] or [DELETE] statements since the [database connection] was opened.
** ^(The count returned by sqlite4_total_changes() includes all changes
** from all [CREATE TRIGGER | trigger] contexts and changes made by
** [foreign key actions]. However,
** the count does not include changes used to implement [REPLACE] constraints,
** do rollbacks or ABORT processing, or [DROP TABLE] processing. The
** count does not include rows of views that fire an [INSTEAD OF trigger],
** though if the INSTEAD OF trigger makes changes of its own, those changes
** are counted.)^
** ^The sqlite4_total_changes() function counts the changes as soon as
** the statement that makes them is completed (when the statement handle
** is passed to [sqlite4_reset()] or [sqlite4_finalize()]).
**
** See also the [sqlite4_changes()] interface, the
** [count_changes pragma], and the [total_changes() SQL function].
**
** If a separate thread makes changes on the same database connection
** while [sqlite4_total_changes()] is running then the value
** returned is unpredictable and not meaningful.
*/
SQLITE_API int sqlite4_total_changes(sqlite4*);
/*
** CAPIREF: Interrupt A Long-Running Query
**
** ^This function causes any pending database operation to abort and
** return at its earliest opportunity. This routine is typically
** called in response to a user action such as pressing "Cancel"
** or Ctrl-C where the user wants a long query operation to halt
** immediately.
**
** ^It is safe to call this routine from a thread different from the
** thread that is currently running the database operation. But it
** is not safe to call this routine with a [database connection] that
** is closed or might close before sqlite4_interrupt() returns.
**
** ^If an SQL operation is very nearly finished at the time when
** sqlite4_interrupt() is called, then it might not have an opportunity
** to be interrupted and might continue to completion.
**
** ^An SQL operation that is interrupted will return [SQLITE_INTERRUPT].
** ^If the interrupted SQL operation is an INSERT, UPDATE, or DELETE
** that is inside an explicit transaction, then the entire transaction
** will be rolled back automatically.
**
** ^The sqlite4_interrupt(D) call is in effect until all currently running
** SQL statements on [database connection] D complete. ^Any new SQL statements
** that are started after the sqlite4_interrupt() call and before the
** running statements reaches zero are interrupted as if they had been
** running prior to the sqlite4_interrupt() call. ^New SQL statements
** that are started after the running statement count reaches zero are
** not effected by the sqlite4_interrupt().
** ^A call to sqlite4_interrupt(D) that occurs when there are no running
** SQL statements is a no-op and has no effect on SQL statements
** that are started after the sqlite4_interrupt() call returns.
**
** If the database connection closes while [sqlite4_interrupt()]
** is running then bad things will likely happen.
*/
SQLITE_API void sqlite4_interrupt(sqlite4*);
/*
** CAPIREF: Determine If An SQL Statement Is Complete
**
** These routines are useful during command-line input to determine if the
** currently entered text seems to form a complete SQL statement or
** if additional input is needed before sending the text into
** SQLite for parsing. ^These routines return 1 if the input string
** appears to be a complete SQL statement. ^A statement is judged to be
** complete if it ends with a semicolon token and is not a prefix of a
** well-formed CREATE TRIGGER statement. ^Semicolons that are embedded within
** string literals or quoted identifier names or comments are not
** independent tokens (they are part of the token in which they are
** embedded) and thus do not count as a statement terminator. ^Whitespace
** and comments that follow the final semicolon are ignored.
**
** ^These routines return 0 if the statement is incomplete. ^If a
** memory allocation fails, then SQLITE_NOMEM is returned.
**
** ^These routines do not parse the SQL statements thus
** will not detect syntactically incorrect SQL.
**
** ^(If SQLite has not been initialized using [sqlite4_initialize()] prior
** to invoking sqlite4_complete16() then sqlite4_initialize() is invoked
** automatically by sqlite4_complete16(). If that initialization fails,
** then the return value from sqlite4_complete16() will be non-zero
** regardless of whether or not the input SQL is complete.)^
**
** The input to [sqlite4_complete()] must be a zero-terminated
** UTF-8 string.
**
** The input to [sqlite4_complete16()] must be a zero-terminated
** UTF-16 string in native byte order.
*/
SQLITE_API int sqlite4_complete(const char *sql);
SQLITE_API int sqlite4_complete16(const void *sql);
/*
** CAPIREF: Formatted String Printing Functions
**
** These routines are work-alikes of the "printf()" family of functions
** from the standard C library.
**
** ^The sqlite4_mprintf() and sqlite4_vmprintf() routines write their
** results into memory obtained from [sqlite4_malloc()].
** The strings returned by these two routines should be
** released by [sqlite4_free()]. ^Both routines return a
** NULL pointer if [sqlite4_malloc()] is unable to allocate enough
** memory to hold the resulting string.
**
** ^(The sqlite4_snprintf() routine is similar to "snprintf()" from
** the standard C library. The result is written into the
** buffer supplied as the first parameter whose size is given by
** the second parameter.)^ The return value from sqltie4_snprintf()
** is the number of bytes actually written into the buffer, not
** counting the zero terminator. The buffer is always zero-terminated
** as long as it it at least one byte in length.
**
** The sqlite4_snprintf() differs from the standard library snprintf()
** routine in two ways: (1) sqlite4_snprintf() returns the number of
** bytes actually written, not the number of bytes that would have been
** written if the buffer had been infinitely long. (2) If the buffer is
** at least one byte long, sqlite4_snprintf() always zero-terminates its
** result.
**
** ^As long as the buffer size is greater than zero, sqlite4_snprintf()
** guarantees that the buffer is always zero-terminated. ^The second
** parameter "n" is the total size of the buffer, including space for
** the zero terminator. So the longest string that can be completely
** written will be n-1 characters.
**
** ^The sqlite4_vsnprintf() routine is a varargs version of sqlite4_snprintf().
**
** These routines all implement some additional formatting
** options that are useful for constructing SQL statements.
** All of the usual printf() formatting options apply. In addition, there
** is are "%q", "%Q", and "%z" options.
**
** ^(The %q option works like %s in that it substitutes a nul-terminated
** string from the argument list. But %q also doubles every '\'' character.
** %q is designed for use inside a string literal.)^ By doubling each '\''
** character it escapes that character and allows it to be inserted into
** the string.
**
** For example, assume the string variable zText contains text as follows:
**
** <blockquote><pre>
** char *zText = "It's a happy day!";
** </pre></blockquote>
**
** One can use this text in an SQL statement as follows:
**
** <blockquote><pre>
** char *zSQL = sqlite4_mprintf("INSERT INTO table VALUES('%q')", zText);
** sqlite4_exec(db, zSQL, 0, 0, 0);
** sqlite4_free(zSQL);
** </pre></blockquote>
**
** Because the %q format string is used, the '\'' character in zText
** is escaped and the SQL generated is as follows:
**
** <blockquote><pre>
** INSERT INTO table1 VALUES('It''s a happy day!')
** </pre></blockquote>
**
** This is correct. Had we used %s instead of %q, the generated SQL
** would have looked like this:
**
** <blockquote><pre>
** INSERT INTO table1 VALUES('It's a happy day!');
** </pre></blockquote>
**
** This second example is an SQL syntax error. As a general rule you should
** always use %q instead of %s when inserting text into a string literal.
**
** ^(The %Q option works like %q except it also adds single quotes around
** the outside of the total string. Additionally, if the parameter in the
** argument list is a NULL pointer, %Q substitutes the text "NULL" (without
** single quotes).)^ So, for example, one could say:
**
** <blockquote><pre>
** char *zSQL = sqlite4_mprintf("INSERT INTO table VALUES(%Q)", zText);
** sqlite4_exec(db, zSQL, 0, 0, 0);
** sqlite4_free(zSQL);
** </pre></blockquote>
**
** The code above will render a correct SQL statement in the zSQL
** variable even if the zText variable is a NULL pointer.
**
** ^(The "%z" formatting option works like "%s" but with the
** addition that after the string has been read and copied into
** the result, [sqlite4_free()] is called on the input string.)^
*/
SQLITE_API char *sqlite4_mprintf(sqlite4_env*, const char*,...);
SQLITE_API char *sqlite4_vmprintf(sqlite4_env*, const char*, va_list);
SQLITE_API sqlite4_size_t sqlite4_snprintf(char*,sqlite4_size_t,const char*, ...);
SQLITE_API sqlite4_size_t sqlite4_vsnprintf(char*,sqlite4_size_t,const char*, va_list);
/*
** CAPIREF: Memory Allocation Subsystem
**
** The SQLite core uses these three routines for all of its own
** internal memory allocation needs.
**
** ^The sqlite4_malloc() routine returns a pointer to a block
** of memory at least N bytes in length, where N is the parameter.
** ^If sqlite4_malloc() is unable to obtain sufficient free
** memory, it returns a NULL pointer. ^If the parameter N to
** sqlite4_malloc() is zero or negative then sqlite4_malloc() returns
** a NULL pointer.
**
** ^Calling sqlite4_free() with a pointer previously returned
** by sqlite4_malloc() or sqlite4_realloc() releases that memory so
** that it might be reused. ^The sqlite4_free() routine is
** a no-op if is called with a NULL pointer. Passing a NULL pointer
** to sqlite4_free() is harmless. After being freed, memory
** should neither be read nor written. Even reading previously freed
** memory might result in a segmentation fault or other severe error.
** Memory corruption, a segmentation fault, or other severe error
** might result if sqlite4_free() is called with a non-NULL pointer that
** was not obtained from sqlite4_malloc() or sqlite4_realloc().
**
** ^(The sqlite4_realloc() interface attempts to resize a
** prior memory allocation to be at least N bytes, where N is the
** second parameter. The memory allocation to be resized is the first
** parameter.)^ ^ If the first parameter to sqlite4_realloc()
** is a NULL pointer then its behavior is identical to calling
** sqlite4_malloc(N) where N is the second parameter to sqlite4_realloc().
** ^If the second parameter to sqlite4_realloc() is zero or
** negative then the behavior is exactly the same as calling
** sqlite4_free(P) where P is the first parameter to sqlite4_realloc().
** ^sqlite4_realloc() returns a pointer to a memory allocation
** of at least N bytes in size or NULL if sufficient memory is unavailable.
** ^If M is the size of the prior allocation, then min(N,M) bytes
** of the prior allocation are copied into the beginning of buffer returned
** by sqlite4_realloc() and the prior allocation is freed.
** ^If sqlite4_realloc() returns NULL, then the prior allocation
** is not freed.
**
** ^The memory returned by sqlite4_malloc() and sqlite4_realloc()
** is always aligned to at least an 8 byte boundary, or to a
** 4 byte boundary if the [SQLITE_4_BYTE_ALIGNED_MALLOC] compile-time
** option is used.
**
** The pointer arguments to [sqlite4_free()] and [sqlite4_realloc()]
** must be either NULL or else pointers obtained from a prior
** invocation of [sqlite4_malloc()] or [sqlite4_realloc()] that have
** not yet been released.
**
** The application must not read or write any part of
** a block of memory after it has been released using
** [sqlite4_free()] or [sqlite4_realloc()].
*/
SQLITE_API void *sqlite4_malloc(sqlite4_env*, sqlite4_size_t);
SQLITE_API void *sqlite4_realloc(sqlite4_env*, void*, sqlite4_size_t);
SQLITE_API void sqlite4_free(sqlite4_env*, void*);
/*
** CAPIREF: Memory Allocator Statistics
**
** SQLite provides these two interfaces for reporting on the status
** of the [sqlite4_malloc()], [sqlite4_free()], and [sqlite4_realloc()]
** routines, which form the built-in memory allocation subsystem.
**
** ^The [sqlite4_memory_used(E)] routine returns the number of bytes
** of memory currently outstanding (malloced but not freed) for
** sqlite4_env environment E.
** ^The [sqlite4_memory_highwater(E)] routine returns the maximum
** value of [sqlite4_memory_used(E)] since the high-water mark
** was last reset. ^The values returned by [sqlite4_memory_used()] and
** [sqlite4_memory_highwater()] include any overhead
** added by SQLite in its implementation of [sqlite4_malloc()],
** but not overhead added by the any underlying system library
** routines that [sqlite4_malloc()] may call.
**
** ^The memory high-water mark is reset to the current value of
** [sqlite4_memory_used(E)] if and only if the R parameter to
** [sqlite4_memory_highwater(E,R)] is true. ^The value returned
** by [sqlite4_memory_highwater(E,1)] is the high-water mark
** prior to the reset.
*/
SQLITE_API sqlite4_uint64 sqlite4_memory_used(sqlite4_env*);
SQLITE_API sqlite4_uint64 sqlite4_memory_highwater(sqlite4_env*, int resetFlag);
/*
** CAPIREF: Pseudo-Random Number Generator
**
** ^A call to this routine stores N bytes of pseudo-randomness into buffer P.
*/
SQLITE_API void sqlite4_randomness(sqlite4_env*, int N, void *P);
/*
** CAPIREF: Compile-Time Authorization Callbacks
**
** ^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 [sqlite4_prepare()] or its variants [sqlite4_prepare_v2()],
** [sqlite4_prepare16()] and [sqlite4_prepare16_v2()]. ^At various
** points during the compilation process, as logic is being created
** to perform various actions, the authorizer callback is invoked to
** see if those actions are allowed. ^The authorizer callback should
** return [SQLITE_OK] to allow the action, [SQLITE_IGNORE] to disallow the
** specific action but allow the SQL statement to continue to be
** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be
** rejected with an error. ^If the authorizer callback returns
** any value other than [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY]
** then the [sqlite4_prepare_v2()] or equivalent call that triggered
** the authorizer will fail with an error message.
**
** When the callback returns [SQLITE_OK], that means the operation
** requested is ok. ^When the callback returns [SQLITE_DENY], the
** [sqlite4_prepare_v2()] or equivalent call that triggered the
** authorizer will fail with an error message explaining that
** access is denied.
**
** ^The first parameter to the authorizer callback is a copy of the third
** parameter to the sqlite4_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 zero-terminated strings that contain additional
** details about the action to be authorized.
**
** ^If the action code is [SQLITE_READ]
** and the callback returns [SQLITE_IGNORE] then the
** [prepared statement] statement is constructed to substitute
** a NULL value in place of the table column that would have
** been read if [SQLITE_OK] had been returned. The [SQLITE_IGNORE]
** return can be used to deny an untrusted user access to individual
** columns of a table.
** ^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.
**
** An authorizer is used when [sqlite4_prepare | preparing]
** SQL statements from an untrusted source, to ensure that the SQL statements
** do not try to access data they are not allowed to see, or that they do not
** try to execute malicious statements that damage the database. For
** example, an application may allow a user to enter arbitrary
** SQL queries for evaluation by a database. But the application does
** not want the user to be able to make arbitrary changes to the
** database. An authorizer could then be put in place while the
** user-entered SQL is being [sqlite4_prepare | prepared] that
** disallows everything except [SELECT] statements.
**
** Applications that need to process SQL from untrusted sources
** might also consider lowering resource limits using [sqlite4_limit()]
** and limiting database size using the [max_page_count] [PRAGMA]
** in addition to using an authorizer.
**
** ^(Only a single authorizer can be in place on a database connection
** at a time. Each call to sqlite4_set_authorizer overrides the
** previous call.)^ ^Disable the authorizer by installing a NULL callback.
** The authorizer is disabled by default.
**
** The authorizer callback must not do anything that will modify
** the database connection that invoked the authorizer callback.
** Note that [sqlite4_prepare_v2()] and [sqlite4_step()] both modify their
** database connections for the meaning of "modify" in this paragraph.
**
** ^When [sqlite4_prepare_v2()] is used to prepare a statement, the
** statement might be re-prepared during [sqlite4_step()] due to a
** schema change. Hence, the application should ensure that the
** correct authorizer callback remains in place during the [sqlite4_step()].
**
** ^Note that the authorizer callback is invoked only during
** [sqlite4_prepare()] or its variants. Authorization is not
** performed during statement evaluation in [sqlite4_step()], unless
** as stated in the previous paragraph, sqlite4_step() invokes
** sqlite4_prepare_v2() to reprepare a statement after a schema change.
*/
SQLITE_API int sqlite4_set_authorizer(
sqlite4*,
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
void *pUserData
);
/*
** CAPIREF: Authorizer Return Codes
**
** The [sqlite4_set_authorizer | authorizer callback function] must
** return either [SQLITE_OK] or one of these two constants in order
** to signal SQLite whether or not the action is permitted. See the
** [sqlite4_set_authorizer | authorizer documentation] for additional
** information.
**
** Note that SQLITE_IGNORE is also used as a [SQLITE_ROLLBACK | return code]
** from the [sqlite4_vtab_on_conflict()] interface.
*/
#define SQLITE_DENY 1 /* Abort the SQL statement with an error */
#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */
/*
** CAPIREF: Authorizer Action Codes
**
** The [sqlite4_set_authorizer()] interface registers a callback function
** that is invoked to authorize certain SQL statement actions. The
** second parameter to the callback is an integer code that specifies
** what action is being authorized. These are the integer action codes that
** the authorizer callback may be passed.
**
** These action code values signify what kind of operation is to be
** authorized. The 3rd and 4th parameters to the authorization
** callback function will be parameters or NULL depending on which of these
** codes is used as the second parameter. ^(The 5th parameter to the
** authorizer callback is the name of the database ("main", "temp",
** etc.) if applicable.)^ ^The 6th parameter to the authorizer callback
** is the name of the inner-most trigger or view that is responsible for
** the access attempt or NULL if this access attempt is directly from
** top-level SQL code.
*/
/******************************************* 3rd ************ 4th ***********/
#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */
#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */
#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */
#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */
#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */
#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */
#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */
#define SQLITE_CREATE_VIEW 8 /* View Name NULL */
#define SQLITE_DELETE 9 /* Table Name NULL */
#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */
#define SQLITE_DROP_TABLE 11 /* Table Name NULL */
#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */
#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */
#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */
#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */
#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */
#define SQLITE_DROP_VIEW 17 /* View Name NULL */
#define SQLITE_INSERT 18 /* Table Name NULL */
#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */
#define SQLITE_READ 20 /* Table Name Column Name */
#define SQLITE_SELECT 21 /* NULL NULL */
#define SQLITE_TRANSACTION 22 /* Operation NULL */
#define SQLITE_UPDATE 23 /* Table Name Column Name */
#define SQLITE_ATTACH 24 /* Filename NULL */
#define SQLITE_DETACH 25 /* Database Name NULL */
#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */
#define SQLITE_REINDEX 27 /* Index Name NULL */
#define SQLITE_ANALYZE 28 /* Table Name NULL */
#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */
#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */
#define SQLITE_FUNCTION 31 /* NULL Function Name */
#define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */
#define SQLITE_COPY 0 /* No longer used */
/*
** CAPIREF: Tracing And Profiling Functions
**
** These routines register callback functions that can be used for
** tracing and profiling the execution of SQL statements.
**
** ^The callback function registered by sqlite4_trace() is invoked at
** various times when an SQL statement is being run by [sqlite4_step()].
** ^The sqlite4_trace() callback is invoked with a UTF-8 rendering of the
** SQL statement text as the statement first begins executing.
** ^(Additional sqlite4_trace() callbacks might occur
** as each triggered subprogram is entered. The callbacks for triggers
** contain a UTF-8 SQL comment that identifies the trigger.)^
**
** ^The callback function registered by sqlite4_profile() is invoked
** as each SQL statement finishes. ^The profile callback contains
** the original statement text and an estimate of wall-clock time
** of how long that statement took to run. ^The profile callback
** time is in units of nanoseconds, however the current implementation
** is only capable of millisecond resolution so the six least significant
** digits in the time are meaningless. Future versions of SQLite
** might provide greater resolution on the profiler callback. The
** sqlite4_profile() function is considered experimental and is
** subject to change in future versions of SQLite.
*/
SQLITE_API void *sqlite4_trace(sqlite4*, void(*xTrace)(void*,const char*), void*);
SQLITE_API SQLITE_EXPERIMENTAL void *sqlite4_profile(sqlite4*,
void(*xProfile)(void*,const char*,sqlite4_uint64), void*);
/*
** CAPIREF: Query Progress Callbacks
**
** ^The sqlite4_progress_handler(D,N,X,P) interface causes the callback
** function X to be invoked periodically during long running calls to
** [sqlite4_exec()] and [sqlite4_step()] for
** database connection D. An example use for this
** interface is to keep a GUI updated during a large query.
**
** ^The parameter P is passed through as the only parameter to the
** callback function X. ^The parameter N is the number of
** [virtual machine instructions] that are evaluated between successive
** invocations of the callback X.
**
** ^Only a single progress handler may be defined at one time per
** [database connection]; setting a new progress handler cancels the
** old one. ^Setting parameter X to NULL disables the progress handler.
** ^The progress handler is also disabled by setting N to a value less
** than 1.
**
** ^If the progress callback returns non-zero, the operation is
** interrupted. This feature can be used to implement a
** "Cancel" button on a GUI progress dialog box.
**
** The progress handler callback must not do anything that will modify
** the database connection that invoked the progress handler.
** Note that [sqlite4_prepare_v2()] and [sqlite4_step()] both modify their
** database connections for the meaning of "modify" in this paragraph.
**
*/
SQLITE_API void sqlite4_progress_handler(sqlite4*, int, int(*)(void*), void*);
/*
** CAPIREF: Opening A New Database Connection
**
** ^These routines open an SQLite4 database file as specified by the
** URI argument.
** ^(A [database connection] handle is usually
** returned in *ppDb, even if an error occurs. The only exception is that
** if SQLite is unable to allocate memory to hold the [sqlite4] object,
** a NULL will be written into *ppDb instead of a pointer to the [sqlite4]
** object.)^ ^(If the database is opened (and/or created) successfully, then
** [SQLITE_OK] is returned. Otherwise an [error code] is returned.)^ ^The
** [sqlite4_errmsg()] routine can be used to obtain
** an English language description of the error following a failure of any
** of the sqlite4_open() routines.
**
** Whether or not an error occurs when it is opened, resources
** associated with the [database connection] handle should be released by
** passing it to [sqlite4_close()] when it is no longer required.
**
*/
SQLITE_API int sqlite4_open(
sqlite4_env *pEnv, /* Run-time environment. NULL means use the default */
const char *filename, /* Database filename (UTF-8) */
sqlite4 **ppDb, /* OUT: SQLite db handle */
... /* Optional parameters. Zero terminates options */
);
/*
** CAPIREF: Obtain Values For URI Parameters
**
** These are utility routines, useful to VFS implementations, that check
** to see if a database file was a URI that contained a specific query
** parameter, and if so obtains the value of that query parameter.
**
** If F is the database filename pointer passed into the xOpen() method of
** a VFS implementation when the flags parameter to xOpen() has one or
** more of the [SQLITE_OPEN_URI] or [SQLITE_OPEN_MAIN_DB] bits set and
** P is the name of the query parameter, then
** sqlite4_uri_parameter(F,P) returns the value of the P
** parameter if it exists or a NULL pointer if P does not appear as a
** query parameter on F. If P is a query parameter of F
** has no explicit value, then sqlite4_uri_parameter(F,P) returns
** a pointer to an empty string.
**
** The sqlite4_uri_boolean(F,P,B) routine assumes that P is a boolean
** parameter and returns true (1) or false (0) according to the value
** of P. The value of P is true if it is "yes" or "true" or "on" or
** a non-zero number and is false otherwise. If P is not a query parameter
** on F then sqlite4_uri_boolean(F,P,B) returns (B!=0).
**
** The sqlite4_uri_int64(F,P,D) routine converts the value of P into a
** 64-bit signed integer and returns that integer, or D if P does not
** exist. If the value of P is something other than an integer, then
** zero is returned.
**
** If F is a NULL pointer, then sqlite4_uri_parameter(F,P) returns NULL and
** sqlite4_uri_boolean(F,P,B) returns B. If F is not a NULL pointer and
** is not a database file pathname pointer that SQLite passed into the xOpen
** VFS method, then the behavior of this routine is undefined and probably
** undesirable.
*/
SQLITE_API const char *sqlite4_uri_parameter(const char *zFilename, const char *zParam);
SQLITE_API int sqlite4_uri_boolean(const char *zFile, const char *zParam, int bDefault);
SQLITE_API sqlite4_int64 sqlite4_uri_int64(const char*, const char*, sqlite4_int64);
/*
** CAPIREF: Error Codes And Messages
**
** ^The sqlite4_errcode() interface returns the numeric
** [extended result code] for the most recent failed sqlite4_* API call
** associated with a [database connection]. If a prior API call failed
** but the most recent API call succeeded, the return value from
** sqlite4_errcode() is undefined.
**
** ^The sqlite4_errmsg() and sqlite4_errmsg16() return English-language
** text that describes the error, as either UTF-8 or UTF-16 respectively.
** ^(Memory to hold the error message string is managed internally.
** The application does not need to worry about freeing the result.
** However, the error string might be overwritten or deallocated by
** subsequent calls to other SQLite interface functions.)^
**
** When the serialized [threading mode] is in use, it might be the
** case that a second error occurs on a separate thread in between
** the time of the first error and the call to these interfaces.
** When that happens, the second error will be reported since these
** interfaces always report the most recent result. To avoid
** this, each thread can obtain exclusive use of the [database connection] D
** by invoking [sqlite4_mutex_enter]([sqlite4_db_mutex](D)) before beginning
** to use D and invoking [sqlite4_mutex_leave]([sqlite4_db_mutex](D)) after
** all calls to the interfaces listed here are completed.
**
** If an interface fails with SQLITE_MISUSE, that means the interface
** was invoked incorrectly by the application. In that case, the
** error code and message may or may not be set.
*/
SQLITE_API int sqlite4_errcode(sqlite4 *db);
SQLITE_API const char *sqlite4_errmsg(sqlite4*);
SQLITE_API const void *sqlite4_errmsg16(sqlite4*);
/*
** CAPIREF: SQL Statement Object
** KEYWORDS: {prepared statement} {prepared statements}
**
** An instance of this object represents a single SQL statement.
** This object is variously known as a "prepared statement" or a
** "compiled SQL statement" or simply as a "statement".
**
** The life of a statement object goes something like this:
**
** <ol>
** <li> Create the object using [sqlite4_prepare_v2()] or a related
** function.
** <li> Bind values to [host parameters] using the sqlite4_bind_*()
** interfaces.
** <li> Run the SQL by calling [sqlite4_step()] one or more times.
** <li> Reset the statement using [sqlite4_reset()] then go back
** to step 2. Do this zero or more times.
** <li> Destroy the object using [sqlite4_finalize()].
** </ol>
**
** Refer to documentation on individual methods above for additional
** information.
*/
typedef struct sqlite4_stmt sqlite4_stmt;
/*
** CAPIREF: Run-time Limits
**
** ^(This interface allows the size of various constructs to be limited
** on a connection by connection basis. The first parameter is the
** [database connection] whose limit is to be set or queried. The
** second parameter is one of the [limit categories] that define a
** class of constructs to be size limited. The third parameter is the
** new limit for that construct.)^
**
** ^If the new limit is a negative number, the limit is unchanged.
** ^(For each limit category SQLITE_LIMIT_<i>NAME</i> there is a
** [limits | hard upper bound]
** set at compile-time by a C preprocessor macro called
** [limits | SQLITE_MAX_<i>NAME</i>].
** (The "_LIMIT_" in the name is changed to "_MAX_".))^
** ^Attempts to increase a limit above its hard upper bound are
** silently truncated to the hard upper bound.
**
** ^Regardless of whether or not the limit was changed, the
** [sqlite4_limit()] interface returns the prior value of the limit.
** ^Hence, to find the current value of a limit without changing it,
** simply invoke this interface with the third parameter set to -1.
**
** Run-time limits are intended for use in applications that manage
** both their own internal database and also databases that are controlled
** by untrusted external sources. An example application might be a
** web browser that has its own databases for storing history and
** separate databases controlled by JavaScript applications downloaded
** off the Internet. The internal databases can be given the
** large, default limits. Databases managed by external sources can
** be given much smaller limits designed to prevent a denial of service
** attack. Developers might also want to use the [sqlite4_set_authorizer()]
** interface to further control untrusted SQL. The size of the database
** created by an untrusted script can be contained using the
** [max_page_count] [PRAGMA].
**
** New run-time limit categories may be added in future releases.
*/
SQLITE_API int sqlite4_limit(sqlite4*, int id, int newVal);
/*
** CAPIREF: Run-Time Limit Categories
** KEYWORDS: {limit category} {*limit categories}
**
** These constants define various performance limits
** that can be lowered at run-time using [sqlite4_limit()].
** The synopsis of the meanings of the various limits is shown below.
** Additional information is available at [limits | Limits in SQLite].
**
** <dl>
** [[SQLITE_LIMIT_LENGTH]] ^(<dt>SQLITE_LIMIT_LENGTH</dt>
** <dd>The maximum size of any string or BLOB or table row, in bytes.<dd>)^
**
** [[SQLITE_LIMIT_SQL_LENGTH]] ^(<dt>SQLITE_LIMIT_SQL_LENGTH</dt>
** <dd>The maximum length of an SQL statement, in bytes.</dd>)^
**
** [[SQLITE_LIMIT_COLUMN]] ^(<dt>SQLITE_LIMIT_COLUMN</dt>
** <dd>The maximum number of columns in a table definition or in the
** result set of a [SELECT] or the maximum number of columns in an index
** or in an ORDER BY or GROUP BY clause.</dd>)^
**
** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt>
** <dd>The maximum depth of the parse tree on any expression.</dd>)^
**
** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt>
** <dd>The maximum number of terms in a compound SELECT statement.</dd>)^
**
** [[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. This limit is not currently
** enforced, though that might be added in some future release of
** SQLite.</dd>)^
**
** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(<dt>SQLITE_LIMIT_FUNCTION_ARG</dt>
** <dd>The maximum number of arguments on a function.</dd>)^
**
** [[SQLITE_LIMIT_ATTACHED]] ^(<dt>SQLITE_LIMIT_ATTACHED</dt>
** <dd>The maximum number of [ATTACH | attached databases].)^</dd>
**
** [[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]]
** ^(<dt>SQLITE_LIMIT_LIKE_PATTERN_LENGTH</dt>
** <dd>The maximum length of the pattern argument to the [LIKE] or
** [GLOB] operators.</dd>)^
**
** [[SQLITE_LIMIT_VARIABLE_NUMBER]]
** ^(<dt>SQLITE_LIMIT_VARIABLE_NUMBER</dt>
** <dd>The maximum index number of any [parameter] in an SQL statement.)^
**
** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt>
** <dd>The maximum depth of recursion for triggers.</dd>)^
** </dl>
*/
#define SQLITE_LIMIT_LENGTH 0
#define SQLITE_LIMIT_SQL_LENGTH 1
#define SQLITE_LIMIT_COLUMN 2
#define SQLITE_LIMIT_EXPR_DEPTH 3
#define SQLITE_LIMIT_COMPOUND_SELECT 4
#define SQLITE_LIMIT_VDBE_OP 5
#define SQLITE_LIMIT_FUNCTION_ARG 6
#define SQLITE_LIMIT_ATTACHED 7
#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8
#define SQLITE_LIMIT_VARIABLE_NUMBER 9
#define SQLITE_LIMIT_TRIGGER_DEPTH 10
/*
** CAPIREF: Compiling An SQL Statement
** KEYWORDS: {SQL statement compiler}
**
** To execute an SQL query, it must first be compiled into a byte-code
** program using one of these routines.
**
** The first argument, "db", is a [database connection] obtained from a
** prior successful call to [sqlite4_open()].
** 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 sqlite4_prepare() and sqlite4_prepare_v2()
** interfaces use UTF-8, and sqlite4_prepare16() and sqlite4_prepare16_v2()
** use UTF-16.
**
** ^If the nByte argument is less than zero, then zSql is read up to the
** first zero terminator. ^If nByte is non-negative, then it is the maximum
** number of bytes read from zSql. ^When nByte is non-negative, the
** zSql string ends at either the first '\000' or '\u0000' character or
** the nByte-th byte, whichever comes first. If the caller knows
** that the supplied string is nul-terminated, then there is a small
** performance advantage to be gained by passing an nByte parameter that
** is equal to the number of bytes in the input string <i>including</i>
** the nul-terminator bytes as this saves SQLite from having to
** make a copy of the input string.
**
** ^If pzTail is not NULL then *pzTail is made to point to the first byte
** past the end of the first SQL statement in zSql. These routines only
** compile the first statement in zSql, so *pzTail is left pointing to
** what remains uncompiled.
**
** ^*ppStmt is left pointing to a compiled [prepared statement] that can be
** executed using [sqlite4_step()]. ^If there is an error, *ppStmt is set
** to NULL. ^If the input text contains no SQL (if the input is an empty
** string or a comment) then *ppStmt is set to NULL.
** The calling procedure is responsible for deleting the compiled
** SQL statement using [sqlite4_finalize()] after it has finished with it.
** ppStmt may not be NULL.
**
** ^On success, the sqlite4_prepare() family of routines return [SQLITE_OK];
** otherwise an [error code] is returned.
*/
SQLITE_API int sqlite4_prepare(
sqlite4 *db, /* Database handle */
const char *zSql, /* SQL statement, UTF-8 encoded */
int nByte, /* Maximum length of zSql in bytes. */
sqlite4_stmt **ppStmt, /* OUT: Statement handle */
const char **pzTail /* OUT: Pointer to unused portion of zSql */
);
/*
** CAPIREF: Retrieving Statement SQL
**
** ^This interface can be used to retrieve a saved copy of the original
** SQL text used to create a [prepared statement] if that statement was
** compiled using either [sqlite4_prepare_v2()] or [sqlite4_prepare16_v2()].
*/
SQLITE_API const char *sqlite4_sql(sqlite4_stmt *pStmt);
/*
** CAPIREF: Determine If An SQL Statement Writes The Database
**
** ^The sqlite4_stmt_readonly(X) interface returns true (non-zero) if
** and only if the [prepared statement] X makes no direct changes to
** the content of the database file.
**
** Note that [application-defined SQL functions] or
** [virtual tables] might change the database indirectly as a side effect.
** ^(For example, if an application defines a function "eval()" that
** calls [sqlite4_exec()], then the following SQL statement would
** change the database file through side-effects:
**
** <blockquote><pre>
** SELECT eval('DELETE FROM t1') FROM t2;
** </pre></blockquote>
**
** But because the [SELECT] statement does not change the database file
** directly, sqlite4_stmt_readonly() would still return true.)^
**
** ^Transaction control statements such as [BEGIN], [COMMIT], [ROLLBACK],
** [SAVEPOINT], and [RELEASE] cause sqlite4_stmt_readonly() to return true,
** since the statements themselves do not actually modify the database but
** rather they control the timing of when other statements modify the
** database. ^The [ATTACH] and [DETACH] statements also cause
** sqlite4_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.
*/
SQLITE_API int sqlite4_stmt_readonly(sqlite4_stmt *pStmt);
/*
** CAPIREF: Determine If A Prepared Statement Has Been Reset
**
** ^The sqlite4_stmt_busy(S) interface returns true (non-zero) if the
** [prepared statement] S has been stepped at least once using
** [sqlite4_step(S)] but has not run to completion and/or has not
** been reset using [sqlite4_reset(S)]. ^The sqlite4_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]
** object, then the behavior is undefined and probably undesirable.
**
** This interface can be used in combination [sqlite4_next_stmt()]
** to locate all prepared statements associated with a database
** connection that are in need of being reset. This can be used,
** for example, in diagnostic routines to search for prepared
** statements that are holding a transaction open.
*/
SQLITE_API int sqlite4_stmt_busy(sqlite4_stmt*);
/*
** CAPIREF: Dynamically Typed Value Object
** KEYWORDS: {protected sqlite4_value} {unprotected sqlite4_value}
**
** SQLite uses the sqlite4_value object to represent all values
** that can be stored in a database table. SQLite uses dynamic typing
** for the values it stores. ^Values stored in sqlite4_value objects
** can be integers, floating point values, strings, BLOBs, or NULL.
**
** An sqlite4_value object may be either "protected" or "unprotected".
** Some interfaces require a protected sqlite4_value. Other interfaces
** will accept either a protected or an unprotected sqlite4_value.
** Every interface that accepts sqlite4_value arguments specifies
** whether or not it requires a protected sqlite4_value.
**
** The terms "protected" and "unprotected" refer to whether or not
** a mutex is held. An internal mutex is held for a protected
** sqlite4_value object but no mutex is held for an unprotected
** sqlite4_value object. If SQLite is compiled to be single-threaded
** (with [SQLITE_THREADSAFE=0] and with [sqlite4_threadsafe()] returning 0)
** or if SQLite is run in one of reduced mutex modes
** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD]
** then there is no distinction between protected and unprotected
** sqlite4_value objects and they can be used interchangeably. However,
** for maximum code portability it is recommended that applications
** still make the distinction between protected and unprotected
** sqlite4_value objects even when not strictly required.
**
** ^The sqlite4_value objects that are passed as parameters into the
** implementation of [application-defined SQL functions] are protected.
** ^The sqlite4_value object returned by
** [sqlite4_column_value()] is unprotected.
** Unprotected sqlite4_value objects may only be used with
** [sqlite4_result_value()] and [sqlite4_bind_value()].
** The [sqlite4_value_blob | sqlite4_value_type()] family of
** interfaces require protected sqlite4_value objects.
*/
typedef struct Mem sqlite4_value;
/*
** CAPIREF: SQL Function Context Object
**
** The context in which an SQL function executes is stored in an
** sqlite4_context object. ^A pointer to an sqlite4_context object
** is always first parameter to [application-defined SQL functions].
** The application-defined SQL function implementation will pass this
** pointer through into calls to [sqlite4_result_int | sqlite4_result()],
** [sqlite4_aggregate_context()], [sqlite4_user_data()],
** [sqlite4_context_db_handle()], [sqlite4_get_auxdata()],
** and/or [sqlite4_set_auxdata()].
*/
typedef struct sqlite4_context sqlite4_context;
/*
** CAPIREF: Binding Values To Prepared Statements
** KEYWORDS: {host parameter} {host parameters} {host parameter name}
** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
**
** ^(In the SQL statement text input to [sqlite4_prepare_v2()] and its variants,
** literals may be replaced by a [parameter] that matches one of following
** templates:
**
** <ul>
** <li> ?
** <li> ?NNN
** <li> :VVV
** <li> @VVV
** <li> $VVV
** </ul>
**
** In the templates above, NNN represents an integer literal,
** and VVV represents an alphanumeric identifier.)^ ^The values of these
** parameters (also called "host parameter names" or "SQL parameters")
** can be set using the sqlite4_bind_*() routines defined here.
**
** ^The first argument to the sqlite4_bind_*() routines is always
** a pointer to the [sqlite4_stmt] object returned from
** [sqlite4_prepare_v2()] or its variants.
**
** ^The second argument is the index of the SQL parameter to be set.
** ^The leftmost SQL parameter has an index of 1. ^When the same named
** SQL parameter is used more than once, second and subsequent
** occurrences have the same index as the first occurrence.
** ^The index for named parameters can be looked up using the
** [sqlite4_bind_parameter_index()] API if desired. ^The index
** for "?NNN" parameters is the value of NNN.
** ^The NNN value must be between 1 and the [sqlite4_limit()]
** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 999).
**
** ^The third argument is the value to bind to the parameter.
**
** ^(In those routines that have a fourth argument, its value is the
** number of bytes in the parameter. To be clear: the value is the
** number of <u>bytes</u> in the value, not the number of characters.)^
** ^If the fourth parameter is negative, the length of the string is
** the number of bytes up to the first zero terminator.
** If a non-negative fourth parameter is provided to sqlite4_bind_text()
** or sqlite4_bind_text16() then that parameter must be the byte offset
** where the NUL terminator would occur assuming the string were NUL
** terminated. If any NUL characters occur at byte offsets less than
** the value of the fourth parameter then the resulting string value will
** contain embedded NULs. The result of expressions involving strings
** with embedded NULs is undefined.
**
** ^The fifth argument to sqlite4_bind_blob(), sqlite4_bind_text(), and
** sqlite4_bind_text16() is a destructor used to dispose of the BLOB or
** string after SQLite has finished with it. ^The destructor is called
** to dispose of the BLOB or string even if the call to sqlite4_bind_blob(),
** sqlite4_bind_text(), or sqlite4_bind_text16() fails.
** ^If the fifth argument is
** the special value [SQLITE_STATIC], then SQLite assumes that the
** information is in static, unmanaged space and does not need to be freed.
** ^If the fifth argument has the value [SQLITE_TRANSIENT], then
** SQLite makes its own private copy of the data immediately, before
** the sqlite4_bind_*() routine returns.
**
** ^The sqlite4_bind_zeroblob() routine binds a BLOB of length N that
** is filled with zeroes. ^A zeroblob uses a fixed amount of memory
** (just an integer to hold its size) while it is being processed.
** Zeroblobs are intended to serve as placeholders for BLOBs whose
** content is later written using
** [sqlite4_blob_open | incremental BLOB I/O] routines.
** ^A negative value for the zeroblob results in a zero-length BLOB.
**
** ^If any of the sqlite4_bind_*() routines are called with a NULL pointer
** for the [prepared statement] or with a prepared statement for which
** [sqlite4_step()] has been called more recently than [sqlite4_reset()],
** then the call will return [SQLITE_MISUSE]. If any sqlite4_bind_()
** routine is passed a [prepared statement] that has been finalized, the
** result is undefined and probably harmful.
**
** ^Bindings are not cleared by the [sqlite4_reset()] routine.
** ^Unbound parameters are interpreted as NULL.
**
** ^The sqlite4_bind_* routines return [SQLITE_OK] on success or an
** [error code] if anything goes wrong.
** ^[SQLITE_RANGE] is returned if the parameter
** index is out of range. ^[SQLITE_NOMEM] is returned if malloc() fails.
**
** See also: [sqlite4_bind_parameter_count()],
** [sqlite4_bind_parameter_name()], and [sqlite4_bind_parameter_index()].
*/
SQLITE_API int sqlite4_bind_blob(sqlite4_stmt*, int, const void*, int n, void(*)(void*));
SQLITE_API int sqlite4_bind_double(sqlite4_stmt*, int, double);
SQLITE_API int sqlite4_bind_int(sqlite4_stmt*, int, int);
SQLITE_API int sqlite4_bind_int64(sqlite4_stmt*, int, sqlite4_int64);
SQLITE_API int sqlite4_bind_null(sqlite4_stmt*, int);
SQLITE_API int sqlite4_bind_text(sqlite4_stmt*, int, const char*, int n, void(*)(void*));
SQLITE_API int sqlite4_bind_text16(sqlite4_stmt*, int, const void*, int, void(*)(void*));
SQLITE_API int sqlite4_bind_value(sqlite4_stmt*, int, const sqlite4_value*);
SQLITE_API int sqlite4_bind_zeroblob(sqlite4_stmt*, int, int n);
/*
** CAPIREF: Number Of SQL Parameters
**
** ^This routine can be used to find the number of [SQL parameters]
** in a [prepared statement]. SQL parameters are tokens of the
** form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as
** placeholders for values that are [sqlite4_bind_blob | bound]
** to the parameters at a later time.
**
** ^(This routine actually returns the index of the largest (rightmost)
** parameter. For all forms except ?NNN, this will correspond to the
** number of unique parameters. If parameters of the ?NNN form are used,
** there may be gaps in the list.)^
**
** See also: [sqlite4_bind_blob|sqlite4_bind()],
** [sqlite4_bind_parameter_name()], and
** [sqlite4_bind_parameter_index()].
*/
SQLITE_API int sqlite4_bind_parameter_count(sqlite4_stmt*);
/*
** CAPIREF: Name Of A Host Parameter
**
** ^The sqlite4_bind_parameter_name(P,N) interface returns
** the name of the N-th [SQL parameter] in the [prepared statement] P.
** ^(SQL parameters of the form "?NNN" or ":AAA" or "@AAA" or "$AAA"
** have a name which is the string "?NNN" or ":AAA" or "@AAA" or "$AAA"
** respectively.
** In other words, the initial ":" or "$" or "@" or "?"
** is included as part of the name.)^
** ^Parameters of the form "?" without a following integer have no name
** and are referred to as "nameless" or "anonymous parameters".
**
** ^The first host parameter has an index of 1, not 0.
**
** ^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 [sqlite4_prepare16()] or
** [sqlite4_prepare16_v2()].
**
** See also: [sqlite4_bind_blob|sqlite4_bind()],
** [sqlite4_bind_parameter_count()], and
** [sqlite4_bind_parameter_index()].
*/
SQLITE_API const char *sqlite4_bind_parameter_name(sqlite4_stmt*, int);
/*
** CAPIREF: Index Of A Parameter With A Given Name
**
** ^Return the index of an SQL parameter given its name. ^The
** index value returned is suitable for use as the second
** parameter to [sqlite4_bind_blob|sqlite4_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 [sqlite4_prepare16_v2()].
**
** See also: [sqlite4_bind_blob|sqlite4_bind()],
** [sqlite4_bind_parameter_count()], and
** [sqlite4_bind_parameter_index()].
*/
SQLITE_API int sqlite4_bind_parameter_index(sqlite4_stmt*, const char *zName);
/*
** CAPIREF: Reset All Bindings On A Prepared Statement
**
** ^Contrary to the intuition of many, [sqlite4_reset()] does not reset
** the [sqlite4_bind_blob | bindings] on a [prepared statement].
** ^Use this routine to reset all host parameters to NULL.
*/
SQLITE_API int sqlite4_clear_bindings(sqlite4_stmt*);
/*
** CAPIREF: Number Of Columns In A Result Set
**
** ^Return the number of columns in the result set returned by the
** [prepared statement]. ^This routine returns 0 if pStmt is an SQL
** statement that does not return data (for example an [UPDATE]).
**
** See also: [sqlite4_data_count()]
*/
SQLITE_API int sqlite4_column_count(sqlite4_stmt *pStmt);
/*
** CAPIREF: Column Names In A Result Set
**
** ^These routines return the name assigned to a particular column
** in the result set of a [SELECT] statement. ^The sqlite4_column_name()
** interface returns a pointer to a zero-terminated UTF-8 string
** and sqlite4_column_name16() returns a pointer to a zero-terminated
** UTF-16 string. ^The first parameter is the [prepared statement]
** that implements the [SELECT] statement. ^The second parameter is the
** column number. ^The leftmost column is number 0.
**
** ^The returned string pointer is valid until either the [prepared statement]
** is destroyed by [sqlite4_finalize()] or until the statement is automatically
** reprepared by the first call to [sqlite4_step()] for a particular run
** or until the next call to
** sqlite4_column_name() or sqlite4_column_name16() on the same column.
**
** ^If sqlite4_malloc() fails during the processing of either routine
** (for example during a conversion from UTF-8 to UTF-16) then a
** NULL pointer is returned.
**
** ^The name of a result column is the value of the "AS" clause for
** that column, if there is an AS clause. If there is no AS clause
** then the name of the column is unspecified and may change from
** one release of SQLite to the next.
*/
SQLITE_API const char *sqlite4_column_name(sqlite4_stmt*, int N);
SQLITE_API const void *sqlite4_column_name16(sqlite4_stmt*, int N);
/*
** CAPIREF: Source Of Data In A Query Result
**
** ^These routines provide a means to determine the database, table, and
** table column that is the origin of a particular result column in
** [SELECT] statement.
** ^The name of the database or table or column can be returned as
** either a UTF-8 or UTF-16 string. ^The _database_ routines return
** the database name, the _table_ routines return the table name, and
** the origin_ routines return the column name.
** ^The returned string is valid until the [prepared statement] is destroyed
** using [sqlite4_finalize()] or until the statement is automatically
** reprepared by the first call to [sqlite4_step()] for a particular run
** or until the same information is requested
** again in a different encoding.
**
** ^The names returned are the original un-aliased names of the
** database, table, and column.
**
** ^The first argument to these interfaces is a [prepared statement].
** ^These functions return information about the Nth result column returned by
** the statement, where N is the second function argument.
** ^The left-most column is column 0 for these routines.
**
** ^If the Nth column returned by the statement is an expression or
** subquery and is not a column value, then all of these functions return
** NULL. ^These routine might also return NULL if a memory allocation error
** occurs. ^Otherwise, they return the name of the attached database, table,
** or column that query result column was extracted from.
**
** ^As with all other SQLite APIs, those whose names end with "16" return
** UTF-16 encoded strings and the other functions return UTF-8.
**
** ^These APIs are only available if the library was compiled with the
** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol.
**
** If two or more threads call one or more of these routines against the same
** prepared statement and column at the same time then the results are
** undefined.
**
** If two or more threads call one or more
** [sqlite4_column_database_name | column metadata interfaces]
** for the same [prepared statement] and result column
** at the same time then the results are undefined.
*/
SQLITE_API const char *sqlite4_column_database_name(sqlite4_stmt*,int);
SQLITE_API const void *sqlite4_column_database_name16(sqlite4_stmt*,int);
SQLITE_API const char *sqlite4_column_table_name(sqlite4_stmt*,int);
SQLITE_API const void *sqlite4_column_table_name16(sqlite4_stmt*,int);
SQLITE_API const char *sqlite4_column_origin_name(sqlite4_stmt*,int);
SQLITE_API const void *sqlite4_column_origin_name16(sqlite4_stmt*,int);
/*
** CAPIREF: Declared Datatype Of A Query Result
**
** ^(The first parameter is a [prepared statement].
** If this statement is a [SELECT] statement and the Nth column of the
** returned result set of that [SELECT] is a table column (not an
** expression or subquery) then the declared type of the table
** column is returned.)^ ^If the Nth column of the result set is an
** expression or subquery, then a NULL pointer is returned.
** ^The returned string is always UTF-8 encoded.
**
** ^(For example, given the database schema:
**
** CREATE TABLE t1(c1 VARIANT);
**
** and the following statement to be compiled:
**
** SELECT c1 + 1, c1 FROM t1;
**
** this routine would return the string "VARIANT" for the second result
** column (i==1), and a NULL pointer for the first result column (i==0).)^
**
** ^SQLite uses dynamic run-time typing. ^So just because a column
** is declared to contain a particular type does not mean that the
** data stored in that column is of the declared type. SQLite is
** strongly typed, but the typing is dynamic not static. ^Type
** is associated with individual values, not with the containers
** used to hold those values.
*/
SQLITE_API const char *sqlite4_column_decltype(sqlite4_stmt*,int);
SQLITE_API const void *sqlite4_column_decltype16(sqlite4_stmt*,int);
/*
** CAPIREF: Evaluate An SQL Statement
**
** After a [prepared statement] has been prepared using either
** [sqlite4_prepare_v2()] or [sqlite4_prepare16_v2()] or one of the legacy
** interfaces [sqlite4_prepare()] or [sqlite4_prepare16()], this function
** must be called one or more times to evaluate the statement.
**
** The details of the behavior of the sqlite4_step() interface depend
** on whether the statement was prepared using the newer "v2" interface
** [sqlite4_prepare_v2()] and [sqlite4_prepare16_v2()] or the older legacy
** interface [sqlite4_prepare()] and [sqlite4_prepare16()]. The use of the
** new "v2" 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],
** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE].
** ^With the "v2" interface, any of the other [result codes] or
** [extended result codes] might be returned as well.
**
** ^[SQLITE_BUSY] means that the database engine was unable to acquire the
** database locks it needs to do its job. ^If the statement is a [COMMIT]
** or occurs outside of an explicit transaction, then you can retry the
** statement. If the statement is not a [COMMIT] and occurs within an
** explicit transaction then you should rollback the transaction before
** continuing.
**
** ^[SQLITE_DONE] means that the statement has finished executing
** successfully. sqlite4_step() should not be called again on this virtual
** machine without first calling [sqlite4_reset()] to reset the virtual
** machine back to its initial state.
**
** ^If the SQL statement being executed returns any data, then [SQLITE_ROW]
** is returned each time a new row of data is ready for processing by the
** caller. The values may be accessed using the [column access functions].
** sqlite4_step() is called again to retrieve the next row of data.
**
** ^[SQLITE_ERROR] means that a run-time error (such as a constraint
** violation) has occurred. sqlite4_step() should not be called again on
** the VM. More information may be found by calling [sqlite4_errmsg()].
** ^With the legacy interface, a more specific error code (for example,
** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth)
** can be obtained by calling [sqlite4_reset()] on the
** [prepared statement]. ^In the "v2" interface,
** the more specific error code is returned directly by sqlite4_step().
**
** [SQLITE_MISUSE] means that the this routine was called inappropriately.
** Perhaps it was called on a [prepared statement] that has
** already been [sqlite4_finalize | finalized] or on one that had
** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could
** be the case that the same database connection is being used by two or
** more threads at the same moment in time.
**
** For all versions of SQLite up to and including 3.6.23.1, a call to
** [sqlite4_reset()] was required after sqlite4_step() returned anything
** other than [SQLITE_ROW] before any subsequent invocation of
** sqlite4_step(). Failure to reset the prepared statement using
** [sqlite4_reset()] would result in an [SQLITE_MISUSE] return from
** sqlite4_step(). But after version 3.6.23.1, sqlite4_step() began
** calling [sqlite4_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
** is broken by definition. The [SQLITE_OMIT_AUTORESET] compile-time option
** can be used to restore the legacy behavior.
**
** <b>Goofy Interface Alert:</b> In the legacy interface, the sqlite4_step()
** API always returns a generic error code, [SQLITE_ERROR], following any
** error other than [SQLITE_BUSY] and [SQLITE_MISUSE]. You must call
** [sqlite4_reset()] or [sqlite4_finalize()] in order to find one of the
** 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 either [sqlite4_prepare_v2()] or [sqlite4_prepare16_v2()] instead
** of the legacy [sqlite4_prepare()] and [sqlite4_prepare16()] interfaces,
** then the more specific [error codes] are returned directly
** by sqlite4_step(). The use of the "v2" interface is recommended.
*/
SQLITE_API int sqlite4_step(sqlite4_stmt*);
/*
** CAPIREF: Number of columns in a result set
**
** ^The sqlite4_data_count(P) interface returns the number of columns in the
** current row of the result set of [prepared statement] P.
** ^If prepared statement P does not have results ready to return
** (via calls to the [sqlite4_column_int | sqlite4_column_*()] of
** interfaces) then sqlite4_data_count(P) returns 0.
** ^The sqlite4_data_count(P) routine also returns 0 if P is a NULL pointer.
** ^The sqlite4_data_count(P) routine returns 0 if the previous call to
** [sqlite4_step](P) returned [SQLITE_DONE]. ^The sqlite4_data_count(P)
** will return non-zero if previous call to [sqlite4_step](P) returned
** [SQLITE_ROW], except in the case of the [PRAGMA incremental_vacuum]
** where it always returns zero since each step of that multi-step
** pragma returns 0 columns of data.
**
** See also: [sqlite4_column_count()]
*/
SQLITE_API int sqlite4_data_count(sqlite4_stmt *pStmt);
/*
** CAPIREF: Fundamental Datatypes
** KEYWORDS: SQLITE_TEXT
**
** ^(Every value in SQLite has one of five fundamental datatypes:
**
** <ul>
** <li> 64-bit signed integer
** <li> 64-bit IEEE floating point number
** <li> string
** <li> BLOB
** <li> NULL
** </ul>)^
**
** These constants are codes for each of those types.
*/
#define SQLITE_INTEGER 1
#define SQLITE_FLOAT 2
#define SQLITE_TEXT 3
#define SQLITE_BLOB 4
#define SQLITE_NULL 5
/*
** CAPIREF: Result Values From A Query
** KEYWORDS: {column access functions}
**
** These routines form the "result set" interface.
**
** ^These routines return information about a single column of the current
** result row of a query. ^In every case the first argument is a pointer
** to the [prepared statement] that is being evaluated (the [sqlite4_stmt*]
** that was returned from [sqlite4_prepare_v2()] or one of its variants)
** and the second argument is the index of the column for which information
** should be returned. ^The leftmost column of the result set has the index 0.
** ^The number of columns in the result can be determined using
** [sqlite4_column_count()].
**
** If the SQL statement does not currently point to a valid row, or if the
** column index is out of range, the result is undefined.
** These routines may only be called when the most recent call to
** [sqlite4_step()] has returned [SQLITE_ROW] and neither
** [sqlite4_reset()] nor [sqlite4_finalize()] have been called subsequently.
** If any of these routines are called after [sqlite4_reset()] or
** [sqlite4_finalize()] or after [sqlite4_step()] has returned
** something other than [SQLITE_ROW], the results are undefined.
** If [sqlite4_step()] or [sqlite4_reset()] or [sqlite4_finalize()]
** are called from a different thread while any of these routines
** are pending, then the results are undefined.
**
** ^The sqlite4_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 value
** returned by sqlite4_column_type() is only meaningful if no type
** conversions have occurred as described below. After a type conversion,
** the value returned by sqlite4_column_type() is undefined. Future
** versions of SQLite may change the behavior of sqlite4_column_type()
** following a type conversion.
**
** ^If the result is a BLOB or UTF-8 string then the sqlite4_column_bytes()
** routine returns the number of bytes in that BLOB or string.
** ^If the result is a UTF-16 string, then sqlite4_column_bytes() converts
** the string to UTF-8 and then returns the number of bytes.
** ^If the result is a numeric value then sqlite4_column_bytes() uses
** [sqlite4_snprintf()] to convert that value to a UTF-8 string and returns
** the number of bytes in that string.
** ^If the result is NULL, then sqlite4_column_bytes() returns zero.
**
** ^If the result is a BLOB or UTF-16 string then the sqlite4_column_bytes16()
** routine returns the number of bytes in that BLOB or string.
** ^If the result is a UTF-8 string, then sqlite4_column_bytes16() converts
** the string to UTF-16 and then returns the number of bytes.
** ^If the result is a numeric value then sqlite4_column_bytes16() uses
** [sqlite4_snprintf()] to convert that value to a UTF-16 string and returns
** the number of bytes in that string.
** ^If the result is NULL, then sqlite4_column_bytes16() returns zero.
**
** ^The values returned by [sqlite4_column_bytes()] and
** [sqlite4_column_bytes16()] do not include the zero terminators at the end
** of the string. ^For clarity: the values returned by
** [sqlite4_column_bytes()] and [sqlite4_column_bytes16()] are the number of
** bytes in the string, not the number of characters.
**
** ^Strings returned by sqlite4_column_text() and sqlite4_column_text16(),
** even empty strings, are always zero-terminated. ^The return
** value from sqlite4_column_blob() for a zero-length BLOB is a NULL pointer.
**
** ^The object returned by [sqlite4_column_value()] is an
** [unprotected sqlite4_value] object. An unprotected sqlite4_value object
** may only be used with [sqlite4_bind_value()] and [sqlite4_result_value()].
** If the [unprotected sqlite4_value] object returned by
** [sqlite4_column_value()] is used in any other way, including calls
** to routines like [sqlite4_value_int()], [sqlite4_value_text()],
** or [sqlite4_value_bytes()], then the behavior is undefined.
**
** These routines attempt to convert the value where appropriate. ^For
** example, if the internal representation is FLOAT and a text result
** is requested, [sqlite4_snprintf()] is used internally to perform the
** conversion automatically. ^(The following table details the conversions
** that are applied:
**
** <blockquote>
** <table border="1">
** <tr><th> Internal<br>Type <th> Requested<br>Type <th> Conversion
**
** <tr><td> NULL <td> INTEGER <td> Result is 0
** <tr><td> NULL <td> FLOAT <td> Result is 0.0
** <tr><td> NULL <td> TEXT <td> Result is NULL pointer
** <tr><td> NULL <td> BLOB <td> Result is NULL pointer
** <tr><td> INTEGER <td> FLOAT <td> Convert from integer to float
** <tr><td> INTEGER <td> TEXT <td> ASCII rendering of the integer
** <tr><td> INTEGER <td> BLOB <td> Same as INTEGER->TEXT
** <tr><td> FLOAT <td> INTEGER <td> Convert from float to integer
** <tr><td> FLOAT <td> TEXT <td> ASCII rendering of the float
** <tr><td> FLOAT <td> BLOB <td> Same as FLOAT->TEXT
** <tr><td> TEXT <td> INTEGER <td> Use atoi()
** <tr><td> TEXT <td> FLOAT <td> Use atof()
** <tr><td> TEXT <td> BLOB <td> No change
** <tr><td> BLOB <td> INTEGER <td> Convert to TEXT then use atoi()
** <tr><td> BLOB <td> FLOAT <td> Convert to TEXT then use atof()
** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed
** </table>
** </blockquote>)^
**
** The table above makes reference to standard C library functions atoi()
** and atof(). SQLite does not really use these functions. It has its
** own equivalent internal routines. The atoi() and atof() names are
** used in the table for brevity and because they are familiar to most
** C programmers.
**
** Note that when type conversions occur, pointers returned by prior
** calls to sqlite4_column_blob(), sqlite4_column_text(), and/or
** sqlite4_column_text16() may be invalidated.
** Type conversions and pointer invalidations might occur
** in the following cases:
**
** <ul>
** <li> The initial content is a BLOB and sqlite4_column_text() or
** sqlite4_column_text16() is called. A zero-terminator might
** need to be added to the string.</li>
** <li> The initial content is UTF-8 text and sqlite4_column_bytes16() or
** sqlite4_column_text16() is called. The content must be converted
** to UTF-16.</li>
** <li> The initial content is UTF-16 text and sqlite4_column_bytes() or
** sqlite4_column_text() is called. The content must be converted
** to UTF-8.</li>
** </ul>
**
** ^Conversions between UTF-16be and UTF-16le are always done in place and do
** not invalidate a prior pointer, though of course the content of the buffer
** that the prior pointer references will have been modified. Other kinds
** of conversion are done in place when it is possible, but sometimes they
** are not possible and in those cases prior pointers are invalidated.
**
** The safest and easiest to remember policy is to invoke these routines
** in one of the following ways:
**
** <ul>
** <li>sqlite4_column_text() followed by sqlite4_column_bytes()</li>
** <li>sqlite4_column_blob() followed by sqlite4_column_bytes()</li>
** <li>sqlite4_column_text16() followed by sqlite4_column_bytes16()</li>
** </ul>
**
** In other words, you should call sqlite4_column_text(),
** sqlite4_column_blob(), or sqlite4_column_text16() first to force the result
** into the desired format, then invoke sqlite4_column_bytes() or
** sqlite4_column_bytes16() to find the size of the result. Do not mix calls
** to sqlite4_column_text() or sqlite4_column_blob() with calls to
** sqlite4_column_bytes16(), and do not mix calls to sqlite4_column_text16()
** with calls to sqlite4_column_bytes().
**
** ^The pointers returned are valid until a type conversion occurs as
** described above, or until [sqlite4_step()] or [sqlite4_reset()] or
** [sqlite4_finalize()] is called. ^The memory space used to hold strings
** and BLOBs is freed automatically. Do <b>not</b> pass the pointers returned
** [sqlite4_column_blob()], [sqlite4_column_text()], etc. into
** [sqlite4_free()].
**
** ^(If a memory allocation error occurs during the evaluation of any
** of these routines, a default value is returned. The default value
** is either the integer 0, the floating point number 0.0, or a NULL
** pointer. Subsequent calls to [sqlite4_errcode()] will return
** [SQLITE_NOMEM].)^
*/
SQLITE_API const void *sqlite4_column_blob(sqlite4_stmt*, int iCol);
SQLITE_API int sqlite4_column_bytes(sqlite4_stmt*, int iCol);
SQLITE_API int sqlite4_column_bytes16(sqlite4_stmt*, int iCol);
SQLITE_API double sqlite4_column_double(sqlite4_stmt*, int iCol);
SQLITE_API int sqlite4_column_int(sqlite4_stmt*, int iCol);
SQLITE_API sqlite4_int64 sqlite4_column_int64(sqlite4_stmt*, int iCol);
SQLITE_API const unsigned char *sqlite4_column_text(sqlite4_stmt*, int iCol);
SQLITE_API const void *sqlite4_column_text16(sqlite4_stmt*, int iCol);
SQLITE_API int sqlite4_column_type(sqlite4_stmt*, int iCol);
SQLITE_API sqlite4_value *sqlite4_column_value(sqlite4_stmt*, int iCol);
/*
** CAPIREF: Destroy A Prepared Statement Object
**
** ^The sqlite4_finalize() function is called to delete a [prepared statement].
** ^If the most recent evaluation of the statement encountered no errors
** or if the statement is never been evaluated, then sqlite4_finalize() returns
** SQLITE_OK. ^If the most recent evaluation of statement S failed, then
** sqlite4_finalize(S) returns the appropriate [error code] or
** [extended error code].
**
** ^The sqlite4_finalize(S) routine can be called at any point during
** the life cycle of [prepared statement] S:
** before statement S is ever evaluated, after
** one or more calls to [sqlite4_reset()], or after any call
** to [sqlite4_step()] regardless of whether or not the statement has
** completed execution.
**
** ^Invoking sqlite4_finalize() on a NULL pointer is a harmless no-op.
**
** The application must finalize every [prepared statement] in order to avoid
** resource leaks. It is a grievous error for the application to try to use
** a prepared statement after it has been finalized. Any use of a prepared
** statement after it has been finalized can result in undefined and
** undesirable behavior such as segfaults and heap corruption.
*/
SQLITE_API int sqlite4_finalize(sqlite4_stmt *pStmt);
/*
** CAPIREF: Reset A Prepared Statement Object
**
** The sqlite4_reset() function is called to reset a [prepared statement]
** object back to its initial state, ready to be re-executed.
** ^Any SQL statement variables that had values bound to them using
** the [sqlite4_bind_blob | sqlite4_bind_*() API] retain their values.
** Use [sqlite4_clear_bindings()] to reset the bindings.
**
** ^The [sqlite4_reset(S)] interface resets the [prepared statement] S
** back to the beginning of its program.
**
** ^If the most recent call to [sqlite4_step(S)] for the
** [prepared statement] S returned [SQLITE_ROW] or [SQLITE_DONE],
** or if [sqlite4_step(S)] has never before been called on S,
** then [sqlite4_reset(S)] returns [SQLITE_OK].
**
** ^If the most recent call to [sqlite4_step(S)] for the
** [prepared statement] S indicated an error, then
** [sqlite4_reset(S)] returns an appropriate [error code].
**
** ^The [sqlite4_reset(S)] interface does not change the values
** of any [sqlite4_bind_blob|bindings] on the [prepared statement] S.
*/
SQLITE_API int sqlite4_reset(sqlite4_stmt *pStmt);
/*
** CAPIREF: Create Or Redefine SQL Functions
** KEYWORDS: {function creation routines}
** KEYWORDS: {application-defined SQL function}
** KEYWORDS: {application-defined SQL functions}
**
** ^These functions (collectively known as "function creation routines")
** are used to add SQL functions or aggregates or to redefine the behavior
** of existing SQL functions or aggregates. The only differences between
** these routines are the text encoding expected for
** the second parameter (the name of the function being created)
** and the presence or absence of a destructor callback for
** the application data pointer.
**
** ^The first parameter is the [database connection] to which the SQL
** function is to be added. ^If an application uses more than one database
** connection then application-defined SQL functions must be added
** to each database connection separately.
**
** ^The second parameter is the name of the SQL function to be created or
** redefined. ^The length of the name is limited to 255 bytes in a UTF-8
** representation, exclusive of the zero-terminator. ^Note that the name
** length limit is in UTF-8 bytes, not characters nor UTF-16 bytes.
** ^Any attempt to create a function with a longer name
** will result in [SQLITE_MISUSE] being returned.
**
** ^The third parameter (nArg)
** is the number of arguments that the SQL function or
** aggregate takes. ^If this parameter is -1, then the SQL function or
** aggregate may take any number of arguments between 0 and the limit
** set by [sqlite4_limit]([SQLITE_LIMIT_FUNCTION_ARG]). If the third
** parameter is less than -1 or greater than 127 then the behavior is
** undefined.
**
** ^The fourth parameter, eTextRep, specifies what
** [SQLITE_UTF8 | text encoding] this SQL function prefers for
** its parameters. Every SQL function implementation must be able to work
** with UTF-8, UTF-16le, or UTF-16be. But some implementations may be
** more efficient with one encoding than another. ^An application may
** invoke sqlite4_create_function() or sqlite4_create_function16() multiple
** times with the same function but with different values of eTextRep.
** ^When multiple implementations of the same function are available, SQLite
** will pick the one that involves the least amount of data conversion.
** If there is only a single implementation which does not care what text
** encoding is used, then the fourth argument should be [SQLITE_ANY].
**
** ^(The fifth parameter is an arbitrary pointer. The implementation of the
** function can gain access to this pointer using [sqlite4_user_data()].)^
**
** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are
** pointers to C-language functions that implement the SQL function or
** aggregate. ^A scalar SQL function requires an implementation of the xFunc
** callback only; NULL pointers must be passed as the xStep and xFinal
** parameters. ^An aggregate SQL function requires an implementation of xStep
** and xFinal and NULL pointer must be passed for xFunc. ^To delete an existing
** SQL function or aggregate, pass NULL pointers for all three function
** callbacks.
**
** ^(If the ninth parameter to sqlite4_create_function_v2() is not NULL,
** then it is destructor for the application data pointer.
** The destructor is invoked when the function is deleted, either by being
** overloaded or when the database connection closes.)^
** ^The destructor is also invoked if the call to
** sqlite4_create_function_v2() fails.
** ^When the destructor callback of the tenth parameter is invoked, it
** is passed a single argument which is a copy of the application data
** pointer which was the fifth parameter to sqlite4_create_function_v2().
**
** ^It is permitted to register multiple implementations of the same
** functions with the same name but with either differing numbers of
** arguments or differing preferred text encodings. ^SQLite will use
** the implementation that most closely matches the way in which the
** SQL function is used. ^A function implementation with a non-negative
** nArg parameter is a better match than a function implementation with
** a negative nArg. ^A function where the preferred text encoding
** matches the database encoding is a better
** match than a function where the encoding is different.
** ^A function where the encoding difference is between UTF16le and UTF16be
** is a closer match than a function where the encoding difference is
** between UTF8 and UTF16.
**
** ^Built-in functions may be overloaded by new application-defined functions.
**
** ^An application-defined function is permitted to call other
** SQLite interfaces. However, such calls must not
** close the database connection nor finalize or reset the prepared
** statement in which the function is running.
*/
SQLITE_API int sqlite4_create_function(
sqlite4 *db,
const char *zFunctionName,
int nArg,
int eTextRep,
void *pApp,
void (*xFunc)(sqlite4_context*,int,sqlite4_value**),
void (*xStep)(sqlite4_context*,int,sqlite4_value**),
void (*xFinal)(sqlite4_context*)
);
SQLITE_API int sqlite4_create_function16(
sqlite4 *db,
const void *zFunctionName,
int nArg,
int eTextRep,
void *pApp,
void (*xFunc)(sqlite4_context*,int,sqlite4_value**),
void (*xStep)(sqlite4_context*,int,sqlite4_value**),
void (*xFinal)(sqlite4_context*)
);
SQLITE_API int sqlite4_create_function_v2(
sqlite4 *db,
const char *zFunctionName,
int nArg,
int eTextRep,
void *pApp,
void (*xFunc)(sqlite4_context*,int,sqlite4_value**),
void (*xStep)(sqlite4_context*,int,sqlite4_value**),
void (*xFinal)(sqlite4_context*),
void(*xDestroy)(void*)
);
/*
** CAPIREF: Text Encodings
**
** These constant define integer codes that represent the various
** text encodings supported by SQLite.
*/
#define SQLITE_UTF8 1
#define SQLITE_UTF16LE 2
#define SQLITE_UTF16BE 3
#define SQLITE_UTF16 4 /* Use native byte order */
#define SQLITE_ANY 5 /* sqlite4_create_function only */
#define SQLITE_UTF16_ALIGNED 8 /* sqlite4_create_collation only */
/*
** CAPIREF: Deprecated Functions
** DEPRECATED
**
** These functions are [deprecated]. In order to maintain
** backwards compatibility with older code, these functions continue
** to be supported. However, new applications should avoid
** the use of these functions. To help encourage people to avoid
** using these functions, we are not going to tell you what they do.
*/
#ifndef SQLITE_OMIT_DEPRECATED
SQLITE_API SQLITE_DEPRECATED int sqlite4_aggregate_count(sqlite4_context*);
SQLITE_API SQLITE_DEPRECATED int sqlite4_expired(sqlite4_stmt*);
SQLITE_API SQLITE_DEPRECATED int sqlite4_transfer_bindings(sqlite4_stmt*, sqlite4_stmt*);
SQLITE_API SQLITE_DEPRECATED int sqlite4_global_recover(void);
#endif
/*
** CAPIREF: Obtaining SQL Function Parameter Values
**
** The C-language implementation of SQL functions and aggregates uses
** this set of interface routines to access the parameter values on
** the function or aggregate.
**
** The xFunc (for scalar functions) or xStep (for aggregates) parameters
** to [sqlite4_create_function()] and [sqlite4_create_function16()]
** define callbacks that implement the SQL functions and aggregates.
** The 3rd parameter to these callbacks is an array of pointers to
** [protected sqlite4_value] objects. There is one [sqlite4_value] object for
** each parameter to the SQL function. These routines are used to
** extract values from the [sqlite4_value] objects.
**
** These routines work only with [protected sqlite4_value] objects.
** Any attempt to use these routines on an [unprotected sqlite4_value]
** object results in undefined behavior.
**
** ^These routines work just like the corresponding [column access functions]
** except that these routines take a single [protected sqlite4_value] object
** pointer instead of a [sqlite4_stmt*] pointer and an integer column number.
**
** ^The sqlite4_value_text16() interface extracts a UTF-16 string
** in the native byte-order of the host machine. ^The
** sqlite4_value_text16be() and sqlite4_value_text16le() interfaces
** extract UTF-16 strings as big-endian and little-endian respectively.
**
** ^(The sqlite4_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
** such a conversion is possible without loss of information (in other
** words, if the value is a string that looks like a number)
** then the conversion is performed. Otherwise no conversion occurs.
** The [SQLITE_INTEGER | datatype] after conversion is returned.)^
**
** Please pay particular attention to the fact that the pointer returned
** from [sqlite4_value_blob()], [sqlite4_value_text()], or
** [sqlite4_value_text16()] can be invalidated by a subsequent call to
** [sqlite4_value_bytes()], [sqlite4_value_bytes16()], [sqlite4_value_text()],
** or [sqlite4_value_text16()].
**
** These routines must be called from the same thread as
** the SQL function that supplied the [sqlite4_value*] parameters.
*/
SQLITE_API const void *sqlite4_value_blob(sqlite4_value*);
SQLITE_API int sqlite4_value_bytes(sqlite4_value*);
SQLITE_API int sqlite4_value_bytes16(sqlite4_value*);
SQLITE_API double sqlite4_value_double(sqlite4_value*);
SQLITE_API int sqlite4_value_int(sqlite4_value*);
SQLITE_API sqlite4_int64 sqlite4_value_int64(sqlite4_value*);
SQLITE_API const unsigned char *sqlite4_value_text(sqlite4_value*);
SQLITE_API const void *sqlite4_value_text16(sqlite4_value*);
SQLITE_API const void *sqlite4_value_text16le(sqlite4_value*);
SQLITE_API const void *sqlite4_value_text16be(sqlite4_value*);
SQLITE_API int sqlite4_value_type(sqlite4_value*);
SQLITE_API int sqlite4_value_numeric_type(sqlite4_value*);
/*
** CAPIREF: Obtain Aggregate Function Context
**
** Implementations of aggregate SQL functions use this
** routine to allocate memory for storing their state.
**
** ^The first time the sqlite4_aggregate_context(C,N) routine is called
** for a particular aggregate function, SQLite
** allocates N of memory, zeroes out that memory, and returns a pointer
** to the new memory. ^On second and subsequent calls to
** sqlite4_aggregate_context() for the same aggregate function instance,
** the same buffer is returned. Sqlite3_aggregate_context() is normally
** called once for each invocation of the xStep callback and then one
** last time when the xFinal callback is invoked. ^(When no rows match
** an aggregate query, the xStep() callback of the aggregate function
** implementation is never called and xFinal() is called exactly once.
** In those cases, sqlite4_aggregate_context() might be called for the
** first time from within xFinal().)^
**
** ^The sqlite4_aggregate_context(C,N) routine returns a NULL pointer if N is
** less than or equal to zero or if a memory allocate error occurs.
**
** ^(The amount of space allocated by sqlite4_aggregate_context(C,N) is
** determined by the N parameter on first successful call. Changing the
** value of N in subsequent call to sqlite4_aggregate_context() within
** the same aggregate function instance will not resize the memory
** allocation.)^
**
** ^SQLite automatically frees the memory allocated by
** sqlite4_aggregate_context() when the aggregate query concludes.
**
** The first parameter must be a copy of the
** [sqlite4_context | SQL function context] that is the first parameter
** to the xStep or xFinal callback routine that implements the aggregate
** function.
**
** This routine must be called from the same thread in which
** the aggregate SQL function is running.
*/
SQLITE_API void *sqlite4_aggregate_context(sqlite4_context*, int nBytes);
/*
** CAPIREF: User Data For Functions
**
** ^The sqlite4_user_data() interface returns a copy of
** the pointer that was the pUserData parameter (the 5th parameter)
** of the [sqlite4_create_function()]
** and [sqlite4_create_function16()] routines that originally
** registered the application defined function.
**
** This routine must be called from the same thread in which
** the application-defined function is running.
*/
SQLITE_API void *sqlite4_user_data(sqlite4_context*);
/*
** CAPIREF: Database Connection For Functions
**
** ^The sqlite4_context_db_handle() interface returns a copy of
** the pointer to the [database connection] (the 1st parameter)
** of the [sqlite4_create_function()]
** and [sqlite4_create_function16()] routines that originally
** registered the application defined function.
*/
SQLITE_API sqlite4 *sqlite4_context_db_handle(sqlite4_context*);
SQLITE_API sqlite4_env *sqlite4_context_env(sqlite4_context*);
/*
** CAPIREF: Function Auxiliary Data
**
** The following two functions may be used by scalar SQL functions to
** associate metadata with argument values. If the same value is passed to
** multiple invocations of the same SQL function during query execution, under
** some circumstances the associated metadata may be preserved. This may
** be used, for example, to add a regular-expression matching scalar
** function. The compiled version of the regular expression is stored as
** metadata associated with the SQL value passed as the regular expression
** pattern. The compiled regular expression can be reused on multiple
** invocations of the same function so that the original pattern string
** does not need to be recompiled on each invocation.
**
** ^The sqlite4_get_auxdata() interface returns a pointer to the metadata
** associated by the sqlite4_set_auxdata() function with the Nth argument
** value to the application-defined function. ^If no metadata has been ever
** been set for the Nth argument of the function, or if the corresponding
** function parameter has changed since the meta-data was set,
** then sqlite4_get_auxdata() returns a NULL pointer.
**
** ^The sqlite4_set_auxdata() interface saves the metadata
** pointed to by its 3rd parameter as the metadata for the N-th
** argument of the application-defined function. Subsequent
** calls to sqlite4_get_auxdata() might return this data, if it has
** not been destroyed.
** ^If it is not NULL, SQLite will invoke the destructor
** function given by the 4th parameter to sqlite4_set_auxdata() on
** the metadata when the corresponding function parameter changes
** or when the SQL statement completes, whichever comes first.
**
** SQLite is free to call the destructor and drop metadata on any
** parameter of any function at any time. ^The only guarantee is that
** the destructor will be called before the metadata is dropped.
**
** ^(In practice, metadata is preserved between function calls for
** expressions that are constant at compile time. This includes literal
** values and [parameters].)^
**
** These routines must be called from the same thread in which
** the SQL function is running.
*/
SQLITE_API void *sqlite4_get_auxdata(sqlite4_context*, int N);
SQLITE_API void sqlite4_set_auxdata(sqlite4_context*, int N, void*, void (*)(void*));
/*
** CAPIREF: Constants Defining Special Destructor Behavior
**
** These are special values for the destructor that is passed in as the
** final argument to routines like [sqlite4_result_blob()]. ^If the destructor
** argument is SQLITE_STATIC, it means that the content pointer is constant
** and will never change. It does not need to be destroyed. ^The
** SQLITE_TRANSIENT value means that the content will likely change in
** the near future and that SQLite should make its own private copy of
** the content before returning.
**
** The typedef is necessary to work around problems in certain
** C++ compilers. See ticket #2191.
*/
typedef void (*sqlite4_destructor_type)(void*);
SQLITE_API void sqlite4_dynamic(void*);
#define SQLITE_STATIC ((sqlite4_destructor_type)0)
#define SQLITE_TRANSIENT ((sqlite4_destructor_type)-1)
#define SQLITE_DYNAMIC (sqlite4_dynamic)
/*
** CAPIREF: Setting The Result Of An SQL Function
**
** These routines are used by the xFunc or xFinal callbacks that
** implement SQL functions and aggregates. See
** [sqlite4_create_function()] and [sqlite4_create_function16()]
** for additional information.
**
** These functions work very much like the [parameter binding] family of
** functions used to bind values to host parameters in prepared statements.
** Refer to the [SQL parameter] documentation for additional information.
**
** ^The sqlite4_result_blob() interface sets the result from
** an application-defined function to be the BLOB whose content is pointed
** to by the second parameter and which is N bytes long where N is the
** third parameter.
**
** ^The sqlite4_result_zeroblob() interfaces set the result of
** the application-defined function to be a BLOB containing all zero
** bytes and N bytes in size, where N is the value of the 2nd parameter.
**
** ^The sqlite4_result_double() interface sets the result from
** an application-defined function to be a floating point value specified
** by its 2nd argument.
**
** ^The sqlite4_result_error() and sqlite4_result_error16() functions
** cause the implemented SQL function to throw an exception.
** ^SQLite uses the string pointed to by the
** 2nd parameter of sqlite4_result_error() or sqlite4_result_error16()
** as the text of an error message. ^SQLite interprets the error
** message string from sqlite4_result_error() as UTF-8. ^SQLite
** interprets the string from sqlite4_result_error16() as UTF-16 in native
** byte order. ^If the third parameter to sqlite4_result_error()
** or sqlite4_result_error16() is negative then SQLite takes as the error
** message all text up through the first zero character.
** ^If the third parameter to sqlite4_result_error() or
** sqlite4_result_error16() is non-negative then SQLite takes that many
** bytes (not characters) from the 2nd parameter as the error message.
** ^The sqlite4_result_error() and sqlite4_result_error16()
** routines make a private copy of the error message text before
** they return. Hence, the calling function can deallocate or
** modify the text after they return without harm.
** ^The sqlite4_result_error_code() function changes the error code
** returned by SQLite as a result of an error in a function. ^By default,
** the error code is SQLITE_ERROR. ^A subsequent call to sqlite4_result_error()
** or sqlite4_result_error16() resets the error code to SQLITE_ERROR.
**
** ^The sqlite4_result_toobig() interface causes SQLite to throw an error
** indicating that a string or BLOB is too long to represent.
**
** ^The sqlite4_result_nomem() interface causes SQLite to throw an error
** indicating that a memory allocation failed.
**
** ^The sqlite4_result_int() interface sets the return value
** of the application-defined function to be the 32-bit signed integer
** value given in the 2nd argument.
** ^The sqlite4_result_int64() interface sets the return value
** of the application-defined function to be the 64-bit signed integer
** value given in the 2nd argument.
**
** ^The sqlite4_result_null() interface sets the return value
** of the application-defined function to be NULL.
**
** ^The sqlite4_result_text(), sqlite4_result_text16(),
** sqlite4_result_text16le(), and sqlite4_result_text16be() interfaces
** set the return value of the application-defined function to be
** a text string which is represented as UTF-8, UTF-16 native byte order,
** UTF-16 little endian, or UTF-16 big endian, respectively.
** ^SQLite takes the text result from the application from
** the 2nd parameter of the sqlite4_result_text* interfaces.
** ^If the 3rd parameter to the sqlite4_result_text* interfaces
** is negative, then SQLite takes result text from the 2nd parameter
** through the first zero character.
** ^If the 3rd parameter to the sqlite4_result_text* interfaces
** is non-negative, then as many bytes (not characters) of the text
** pointed to by the 2nd parameter are taken as the application-defined
** function result. If the 3rd parameter is non-negative, then it
** must be the byte offset into the string where the NUL terminator would
** appear if the string where NUL terminated. If any NUL characters occur
** in the string at a byte offset that is less than the value of the 3rd
** parameter, then the resulting string will contain embedded NULs and the
** result of expressions operating on strings with embedded NULs is undefined.
** ^If the 4th parameter to the sqlite4_result_text* interfaces
** or sqlite4_result_blob is a non-NULL pointer, then SQLite calls that
** function as the destructor on the text or BLOB result when it has
** finished using that result.
** ^If the 4th parameter to the sqlite4_result_text* interfaces or to
** sqlite4_result_blob is the special constant SQLITE_STATIC, then SQLite
** assumes that the text or BLOB result is in constant space and does not
** copy the content of the parameter nor call a destructor on the content
** when it has finished using that result.
** ^If the 4th parameter to the sqlite4_result_text* interfaces
** or sqlite4_result_blob is the special constant SQLITE_TRANSIENT
** then SQLite makes a copy of the result into space obtained from
** from [sqlite4_malloc()] before it returns.
**
** ^The sqlite4_result_value() interface sets the result of
** the application-defined function to be a copy the
** [unprotected sqlite4_value] object specified by the 2nd parameter. ^The
** sqlite4_result_value() interface makes a copy of the [sqlite4_value]
** so that the [sqlite4_value] specified in the parameter may change or
** be deallocated after sqlite4_result_value() returns without harm.
** ^A [protected sqlite4_value] object may always be used where an
** [unprotected sqlite4_value] object is required, so either
** kind of [sqlite4_value] object can be used with this interface.
**
** If these routines are called from within the different thread
** than the one containing the application-defined function that received
** the [sqlite4_context] pointer, the results are undefined.
*/
SQLITE_API void sqlite4_result_blob(sqlite4_context*, const void*, int, void(*)(void*));
SQLITE_API void sqlite4_result_double(sqlite4_context*, double);
SQLITE_API void sqlite4_result_error(sqlite4_context*, const char*, int);
SQLITE_API void sqlite4_result_error16(sqlite4_context*, const void*, int);
SQLITE_API void sqlite4_result_error_toobig(sqlite4_context*);
SQLITE_API void sqlite4_result_error_nomem(sqlite4_context*);
SQLITE_API void sqlite4_result_error_code(sqlite4_context*, int);
SQLITE_API void sqlite4_result_int(sqlite4_context*, int);
SQLITE_API void sqlite4_result_int64(sqlite4_context*, sqlite4_int64);
SQLITE_API void sqlite4_result_null(sqlite4_context*);
SQLITE_API void sqlite4_result_text(sqlite4_context*, const char*, int, void(*)(void*));
SQLITE_API void sqlite4_result_text16(sqlite4_context*, const void*, int, void(*)(void*));
SQLITE_API void sqlite4_result_text16le(sqlite4_context*, const void*, int,void(*)(void*));
SQLITE_API void sqlite4_result_text16be(sqlite4_context*, const void*, int,void(*)(void*));
SQLITE_API void sqlite4_result_value(sqlite4_context*, sqlite4_value*);
SQLITE_API void sqlite4_result_zeroblob(sqlite4_context*, int n);
/*
** CAPIREF: Define New Collating Sequences
**
** ^This function adds, removes, or modifies a [collation] associated
** with the [database connection] specified as the first argument.
**
** ^The name of the collation is a UTF-8 string.
** ^Collation names that compare equal according to [sqlite4_strnicmp()] are
** considered to be the same name.
**
** ^(The third argument (eTextRep) must be one of the constants:
** <ul>
** <li> [SQLITE_UTF8],
** <li> [SQLITE_UTF16LE],
** <li> [SQLITE_UTF16BE],
** <li> [SQLITE_UTF16], or
** <li> [SQLITE_UTF16_ALIGNED].
** </ul>)^
** ^The eTextRep argument determines the encoding of strings passed
** to the collating function callback, xCallback.
** ^The [SQLITE_UTF16] and [SQLITE_UTF16_ALIGNED] values for eTextRep
** force strings to be UTF16 with native byte order.
** ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin
** on an even byte address.
**
** ^The fourth argument, pArg, is an application data pointer that is passed
** through as the first argument to the collating function callback.
**
** ^The fifth argument, xCallback, is a pointer to the comparision function.
** ^The sixth argument, xMakeKey, is a pointer to a function that generates
** a sort key.
** ^Multiple functions can be registered using the same name but
** with different eTextRep parameters and SQLite will use whichever
** function requires the least amount of data transformation.
** ^If the xCallback argument is NULL then the collating function is
** deleted. ^When all collating functions having the same name are deleted,
** that collation is no longer usable.
**
** ^The collating function callback is invoked with a copy of the pArg
** application data pointer and with two strings in the encoding specified
** by the eTextRep argument. The collating function must return an
** integer that is negative, zero, or positive
** if the first string is less than, equal to, or greater than the second,
** respectively. A collating function must always return the same answer
** given the same inputs. If two or more collating functions are registered
** to the same collation name (using different eTextRep values) then all
** must give an equivalent answer when invoked with equivalent strings.
** The collating function must obey the following properties for all
** strings A, B, and C:
**
** <ol>
** <li> If A==B then B==A.
** <li> If A==B and B==C then A==C.
** <li> If A<B THEN B>A.
** <li> If A<B and B<C then A<C.
** </ol>
**
** If a collating function fails any of the above constraints and that
** collating function is registered and used, then the behavior of SQLite
** is undefined.
**
** ^Collating functions are deleted when they are overridden by later
** calls to the collation creation functions or when the
** [database connection] is closed using [sqlite4_close()].
**
** ^The xDestroy callback is <u>not</u> called if the
** sqlite4_create_collation() function fails. Applications that invoke
** sqlite4_create_collation() with a non-NULL xDestroy argument should
** check the return code and dispose of the application data pointer
** themselves rather than expecting SQLite to deal with it for them.
** This is different from every other SQLite interface. The inconsistency
** is unfortunate but cannot be changed without breaking backwards
** compatibility.
**
** See also: [sqlite4_collation_needed()] and [sqlite4_collation_needed16()].
*/
SQLITE_API int sqlite4_create_collation(
sqlite4*,
const char *zName,
int eTextRep,
void *pArg,
int(*xCompare)(void*,int,const void*,int,const void*),
int(*xMakeKey)(void*,int,const void*,int,void*),
void(*xDestroy)(void*)
);
/*
** CAPIREF: Collation Needed Callbacks
**
** ^To avoid having to register all collation sequences before a database
** can be used, a single callback function may be registered with the
** [database connection] to be invoked whenever an undefined collation
** sequence is required.
**
** ^If the function is registered using the sqlite4_collation_needed() API,
** then it is passed the names of undefined collation sequences as strings
** encoded in UTF-8. ^If sqlite4_collation_needed16() is used,
** the names are passed as UTF-16 in machine native byte order.
** ^A call to either function replaces the existing collation-needed callback.
**
** ^(When the callback is invoked, the first argument passed is a copy
** of the second argument to sqlite4_collation_needed() or
** sqlite4_collation_needed16(). The second argument is the database
** connection. The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE],
** or [SQLITE_UTF16LE], indicating the most desirable form of the collation
** sequence function required. The fourth parameter is the name of the
** required collation sequence.)^
**
** The callback function should register the desired collation using
** [sqlite4_create_collation()], [sqlite4_create_collation16()], or
** [sqlite4_create_collation_v2()].
*/
SQLITE_API int sqlite4_collation_needed(
sqlite4*,
void*,
void(*)(void*,sqlite4*,int eTextRep,const char*)
);
SQLITE_API int sqlite4_collation_needed16(
sqlite4*,
void*,
void(*)(void*,sqlite4*,int eTextRep,const void*)
);
/*
** CAPIREF: Suspend Execution For A Short Time
**
** The sqlite4_sleep() function causes the current thread to suspend execution
** for at least a number of milliseconds specified in its parameter.
**
** If the operating system does not support sleep requests with
** millisecond time resolution, then the time will be rounded up to
** the nearest second. The number of milliseconds of sleep actually
** requested from the operating system is returned.
**
** ^SQLite implements this interface by calling the xSleep()
** method of the default [sqlite4_vfs] object. If the xSleep() method
** of the default VFS is not implemented correctly, or not implemented at
** all, then the behavior of sqlite4_sleep() may deviate from the description
** in the previous paragraphs.
*/
SQLITE_API int sqlite4_sleep(int);
/*
** CAPIREF: Test For Auto-Commit Mode
** KEYWORDS: {autocommit mode}
**
** ^The sqlite4_get_autocommit() interface returns non-zero or
** zero if the given database connection is or is not in autocommit mode,
** respectively. ^Autocommit mode is on by default.
** ^Autocommit mode is disabled by a [BEGIN] statement.
** ^Autocommit mode is re-enabled by a [COMMIT] or [ROLLBACK].
**
** If certain kinds of errors occur on a statement within a multi-statement
** transaction (errors including [SQLITE_FULL], [SQLITE_IOERR],
** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the
** transaction might be rolled back automatically. The only way to
** find out whether SQLite automatically rolled back the transaction after
** an error is to use this function.
**
** If another thread changes the autocommit status of the database
** connection while this routine is running, then the return value
** is undefined.
*/
SQLITE_API int sqlite4_get_autocommit(sqlite4*);
/*
** CAPIREF: Find The Database Handle Of A Prepared Statement
**
** ^The sqlite4_db_handle interface returns the [database connection] handle
** to which a [prepared statement] belongs. ^The [database connection]
** returned by sqlite4_db_handle is the same [database connection]
** that was the first argument
** to the [sqlite4_prepare_v2()] call (or its variants) that was used to
** create the statement in the first place.
*/
SQLITE_API sqlite4 *sqlite4_db_handle(sqlite4_stmt*);
/*
** CAPIREF: Return The Filename For A Database Connection
**
** ^The sqlite4_db_filename(D,N) interface returns a pointer to a filename
** associated with database N of connection D. ^The main database file
** has the name "main". If there is no attached database N on the database
** connection D, or if database N is a temporary or in-memory database, then
** a NULL pointer is returned.
**
** ^The filename returned by this function is the output of the
** xFullPathname method of the [VFS]. ^In other words, the filename
** will be an absolute pathname, even if the filename used
** to open the database originally was a URI or relative pathname.
*/
SQLITE_API const char *sqlite4_db_filename(sqlite4 *db, const char *zDbName);
/*
** CAPIREF: Find the next prepared statement
**
** ^This interface returns a pointer to the next [prepared statement] after
** pStmt associated with the [database connection] pDb. ^If pStmt is NULL
** then this interface returns a pointer to the first prepared statement
** associated with the database connection pDb. ^If no prepared statement
** satisfies the conditions of this routine, it returns NULL.
**
** The [database connection] pointer D in a call to
** [sqlite4_next_stmt(D,S)] must refer to an open database
** connection and in particular must not be a NULL pointer.
*/
SQLITE_API sqlite4_stmt *sqlite4_next_stmt(sqlite4 *pDb, sqlite4_stmt *pStmt);
/*
** CAPIREF: Free Memory Used By A Database Connection
**
** ^The sqlite4_db_release_memory(D) interface attempts to free as much heap
** memory as possible from database connection D.
*/
SQLITE_API int sqlite4_db_release_memory(sqlite4*);
/*
** CAPIREF: Extract Metadata About A Column Of A Table
**
** ^This routine returns metadata about a specific column of a specific
** database table accessible using the [database connection] handle
** passed as the first function argument.
**
** ^The column is identified by the second, third and fourth parameters to
** this function. ^The second parameter is either the name of the database
** (i.e. "main", "temp", or an attached database) containing the specified
** table or NULL. ^If it is NULL, then all attached databases are searched
** for the table using the same algorithm used by the database engine to
** resolve unqualified table references.
**
** ^The third and fourth parameters to this function are the table and column
** name of the desired column, respectively. Neither of these parameters
** may be NULL.
**
** ^Metadata is returned by writing to the memory locations passed as the 5th
** and subsequent parameters to this function. ^Any of these arguments may be
** NULL, in which case the corresponding element of metadata is omitted.
**
** ^(<blockquote>
** <table border="1">
** <tr><th> Parameter <th> Output<br>Type <th> Description
**
** <tr><td> 5th <td> const char* <td> Data type
** <tr><td> 6th <td> const char* <td> Name of default collation sequence
** <tr><td> 7th <td> int <td> True if column has a NOT NULL constraint
** <tr><td> 8th <td> int <td> True if column is part of the PRIMARY KEY
** <tr><td> 9th <td> int <td> True if column is [AUTOINCREMENT]
** </table>
** </blockquote>)^
**
** ^The memory pointed to by the character pointers returned for the
** declaration type and collation sequence is valid only until the next
** call to any SQLite API function.
**
** ^If the specified table is actually a view, an [error code] is returned.
**
** ^If the specified column is "rowid", "oid" or "_rowid_" and an
** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output
** parameters are set for the explicitly declared column. ^(If there is no
** explicitly declared [INTEGER PRIMARY KEY] column, then the output
** parameters are set as follows:
**
** <pre>
** data type: "INTEGER"
** collation sequence: "BINARY"
** not null: 0
** primary key: 1
** auto increment: 0
** </pre>)^
**
** ^(This function may load one or more schemas from database files. If an
** error occurs during this process, or if the requested table or column
** cannot be found, an [error code] is returned and an error message left
** in the [database connection] (to be retrieved using sqlite4_errmsg()).)^
**
** ^This API is only available if the library was compiled with the
** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined.
*/
SQLITE_API int sqlite4_table_column_metadata(
sqlite4 *db, /* Connection handle */
const char *zDbName, /* Database name or NULL */
const char *zTableName, /* Table name */
const char *zColumnName, /* Column name */
char const **pzDataType, /* OUTPUT: Declared data type */
char const **pzCollSeq, /* OUTPUT: Collation sequence name */
int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */
int *pPrimaryKey, /* OUTPUT: True if column part of PK */
int *pAutoinc /* OUTPUT: True if column is auto-increment */
);
/*
** CAPIREF: Load An Extension
**
** ^This interface loads an SQLite extension library from the named file.
**
** ^The sqlite4_load_extension() interface attempts to load an
** SQLite extension library contained in the file zFile.
**
** ^The entry point is zProc.
** ^zProc may be 0, in which case the name of the entry point
** defaults to "sqlite4_extension_init".
** ^The sqlite4_load_extension() interface returns
** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong.
** ^If an error occurs and pzErrMsg is not 0, then the
** [sqlite4_load_extension()] interface shall attempt to
** fill *pzErrMsg with error message text stored in memory
** obtained from [sqlite4_malloc()]. The calling function
** should free this memory by calling [sqlite4_free()].
**
** ^Extension loading must be enabled using
** [sqlite4_enable_load_extension()] prior to calling this API,
** otherwise an error will be returned.
**
** See also the [load_extension() SQL function].
*/
SQLITE_API int sqlite4_load_extension(
sqlite4 *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 */
char **pzErrMsg /* Put error message here if not 0 */
);
/*
** CAPIREF: Enable Or Disable Extension Loading
**
** ^So as not to open security holes in older applications that are
** unprepared to deal with extension loading, and as a means of disabling
** extension loading while evaluating user-entered SQL, the following API
** is provided to turn the [sqlite4_load_extension()] mechanism on and off.
**
** ^Extension loading is off by default. See ticket #1863.
** ^Call the sqlite4_enable_load_extension() routine with onoff==1
** to turn extension loading on and call it with onoff==0 to turn
** it back off again.
*/
SQLITE_API int sqlite4_enable_load_extension(sqlite4 *db, int onoff);
/*
** The interface to the virtual-table mechanism is currently considered
** to be experimental. The interface might change in incompatible ways.
** If this is a problem for you, do not use the interface at this time.
**
** When the virtual-table mechanism stabilizes, we will declare the
** interface fixed, support it indefinitely, and remove this comment.
*/
/*
** Structures used by the virtual table interface
*/
typedef struct sqlite4_vtab sqlite4_vtab;
typedef struct sqlite4_index_info sqlite4_index_info;
typedef struct sqlite4_vtab_cursor sqlite4_vtab_cursor;
typedef struct sqlite4_module sqlite4_module;
/*
** CAPIREF: Virtual Table Object
** KEYWORDS: sqlite4_module {virtual table module}
**
** This structure, sometimes called a "virtual table module",
** defines the implementation of a [virtual tables].
** This structure consists mostly of methods for the module.
**
** ^A virtual table module is created by filling in a persistent
** instance of this structure and passing a pointer to that instance
** to [sqlite4_create_module()] or [sqlite4_create_module_v2()].
** ^The registration remains valid until it is replaced by a different
** module or until the [database connection] closes. The content
** of this structure must not change while it is registered with
** any database connection.
*/
struct sqlite4_module {
int iVersion;
int (*xCreate)(sqlite4*, void *pAux,
int argc, const char *const*argv,
sqlite4_vtab **ppVTab, char**);
int (*xConnect)(sqlite4*, void *pAux,
int argc, const char *const*argv,
sqlite4_vtab **ppVTab, char**);
int (*xBestIndex)(sqlite4_vtab *pVTab, sqlite4_index_info*);
int (*xDisconnect)(sqlite4_vtab *pVTab);
int (*xDestroy)(sqlite4_vtab *pVTab);
int (*xOpen)(sqlite4_vtab *pVTab, sqlite4_vtab_cursor **ppCursor);
int (*xClose)(sqlite4_vtab_cursor*);
int (*xFilter)(sqlite4_vtab_cursor*, int idxNum, const char *idxStr,
int argc, sqlite4_value **argv);
int (*xNext)(sqlite4_vtab_cursor*);
int (*xEof)(sqlite4_vtab_cursor*);
int (*xColumn)(sqlite4_vtab_cursor*, sqlite4_context*, int);
int (*xRowid)(sqlite4_vtab_cursor*, sqlite4_int64 *pRowid);
int (*xUpdate)(sqlite4_vtab *, int, sqlite4_value **, sqlite4_int64 *);
int (*xBegin)(sqlite4_vtab *pVTab);
int (*xSync)(sqlite4_vtab *pVTab);
int (*xCommit)(sqlite4_vtab *pVTab);
int (*xRollback)(sqlite4_vtab *pVTab);
int (*xFindFunction)(sqlite4_vtab *pVtab, int nArg, const char *zName,
void (**pxFunc)(sqlite4_context*,int,sqlite4_value**),
void **ppArg);
int (*xRename)(sqlite4_vtab *pVtab, const char *zNew);
/* The methods above are in version 1 of the sqlite_module object. Those
** below are for version 2 and greater. */
int (*xSavepoint)(sqlite4_vtab *pVTab, int);
int (*xRelease)(sqlite4_vtab *pVTab, int);
int (*xRollbackTo)(sqlite4_vtab *pVTab, int);
};
/*
** CAPIREF: Virtual Table Indexing Information
** KEYWORDS: sqlite4_index_info
**
** The sqlite4_index_info structure and its substructures is used as part
** of the [virtual table] interface to
** pass information into and receive the reply from the [xBestIndex]
** method of a [virtual table module]. The fields under **Inputs** are the
** inputs to xBestIndex and are read-only. xBestIndex inserts its
** results into the **Outputs** fields.
**
** ^(The aConstraint[] array records WHERE clause constraints of the form:
**
** <blockquote>column OP expr</blockquote>
**
** where OP is =, <, <=, >, or >=.)^ ^(The particular operator is
** stored in aConstraint[].op using one of the
** [SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_ values].)^
** ^(The index of the column is stored in
** aConstraint[].iColumn.)^ ^(aConstraint[].usable is TRUE if the
** expr on the right-hand side can be evaluated (and thus the constraint
** is usable) and false if it cannot.)^
**
** ^The optimizer automatically inverts terms of the form "expr OP column"
** and makes other simplifications to the WHERE clause in an attempt to
** get as many WHERE clause terms into the form shown above as possible.
** ^The aConstraint[] array only reports WHERE clause terms that are
** relevant to the particular virtual table being queried.
**
** ^Information about the ORDER BY clause is stored in aOrderBy[].
** ^Each term of aOrderBy records a column of the ORDER BY clause.
**
** 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
** and becomes the argvIndex-th entry in argv. ^(If aConstraintUsage[].omit
** is true, then the constraint is assumed to be fully handled by the
** virtual table and is not checked again by SQLite.)^
**
** ^The idxNum and idxPtr values are recorded and passed into the
** [xFilter] method.
** ^[sqlite4_free()] is used to free idxPtr if and only if
** needToFreeIdxPtr is true.
**
** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in
** the correct order to satisfy the ORDER BY clause so that no separate
** sorting step is required.
**
** ^The estimatedCost value is an estimate of the cost of doing the
** particular lookup. A full scan of a table with N entries should have
** a cost of N. A binary search of a table of N entries should have a
** cost of approximately log(N).
*/
struct sqlite4_index_info {
/* Inputs */
int nConstraint; /* Number of entries in aConstraint */
struct sqlite4_index_constraint {
int iColumn; /* Column on left-hand side of constraint */
unsigned char op; /* Constraint operator */
unsigned char usable; /* True if this constraint is usable */
int iTermOffset; /* Used internally - xBestIndex should ignore */
} *aConstraint; /* Table of WHERE clause constraints */
int nOrderBy; /* Number of terms in the ORDER BY clause */
struct sqlite4_index_orderby {
int iColumn; /* Column number */
unsigned char desc; /* True for DESC. False for ASC. */
} *aOrderBy; /* The ORDER BY clause */
/* Outputs */
struct sqlite4_index_constraint_usage {
int argvIndex; /* if >0, constraint is part of argv to xFilter */
unsigned char omit; /* Do not code a test for this constraint */
} *aConstraintUsage;
int idxNum; /* Number used to identify the index */
char *idxStr; /* String, possibly obtained from sqlite4_malloc */
int needToFreeIdxStr; /* Free idxStr using sqlite4_free() if true */
int orderByConsumed; /* True if output is already ordered */
double estimatedCost; /* Estimated cost of using this index */
};
/*
** CAPIREF: Virtual Table Constraint Operator Codes
**
** These macros defined the allowed values for the
** [sqlite4_index_info].aConstraint[].op field. Each value represents
** 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
/*
** CAPIREF: Register A Virtual Table Implementation
**
** ^These routines are used to register a new [virtual table module] name.
** ^Module names must be registered before
** creating a new [virtual table] using the module and before using a
** preexisting [virtual table] for the module.
**
** ^The module name is registered on the [database connection] specified
** by the first parameter. ^The name of the module is given by the
** second parameter. ^The third parameter is a pointer to
** the implementation of the [virtual table module]. ^The fourth
** parameter is an arbitrary client data pointer that is passed through
** into the [xCreate] and [xConnect] methods of the virtual table module
** when a new virtual table is be being created or reinitialized.
**
** ^The sqlite4_create_module_v2() interface has a fifth parameter which
** is a pointer to a destructor for the pClientData. ^SQLite will
** invoke the destructor function (if it is not NULL) when SQLite
** no longer needs the pClientData pointer. ^The destructor will also
** be invoked if the call to sqlite4_create_module_v2() fails.
** ^The sqlite4_create_module()
** interface is equivalent to sqlite4_create_module_v2() with a NULL
** destructor.
*/
SQLITE_API int sqlite4_create_module(
sqlite4 *db, /* SQLite connection to register module with */
const char *zName, /* Name of the module */
const sqlite4_module *p, /* Methods for the module */
void *pClientData /* Client data for xCreate/xConnect */
);
SQLITE_API int sqlite4_create_module_v2(
sqlite4 *db, /* SQLite connection to register module with */
const char *zName, /* Name of the module */
const sqlite4_module *p, /* Methods for the module */
void *pClientData, /* Client data for xCreate/xConnect */
void(*xDestroy)(void*) /* Module destructor function */
);
/*
** CAPIREF: Virtual Table Instance Object
** KEYWORDS: sqlite4_vtab
**
** Every [virtual table module] implementation uses a subclass
** of this object to describe a particular instance
** of the [virtual table]. Each subclass will
** be tailored to the specific needs of the module implementation.
** The purpose of this superclass is to define certain fields that are
** common to all module implementations.
**
** ^Virtual tables methods can set an error message by assigning a
** string obtained from [sqlite4_mprintf()] to zErrMsg. The method should
** take care that any prior string is freed by a call to [sqlite4_free()]
** prior to assigning a new string to zErrMsg. ^After the error message
** is delivered up to the client application, the string will be automatically
** freed by sqlite4_free() and the zErrMsg field will be zeroed.
*/
struct sqlite4_vtab {
const sqlite4_module *pModule; /* The module for this virtual table */
int nRef; /* NO LONGER USED */
char *zErrMsg; /* Error message from sqlite4_mprintf() */
/* Virtual table implementations will typically add additional fields */
};
/*
** CAPIREF: Virtual Table Cursor Object
** KEYWORDS: sqlite4_vtab_cursor {virtual table cursor}
**
** Every [virtual table module] implementation uses a subclass of the
** following structure to describe cursors that point into the
** [virtual table] and are used
** to loop through the virtual table. Cursors are created using the
** [sqlite4_module.xOpen | xOpen] method of the module and are destroyed
** by the [sqlite4_module.xClose | xClose] method. Cursors are used
** by the [xFilter], [xNext], [xEof], [xColumn], and [xRowid] methods
** of the module. Each module implementation will define
** the content of a cursor structure to suit its own needs.
**
** This superclass exists in order to define fields of the cursor that
** are common to all implementations.
*/
struct sqlite4_vtab_cursor {
sqlite4_vtab *pVtab; /* Virtual table of this cursor */
/* Virtual table implementations will typically add additional fields */
};
/*
** CAPIREF: Declare The Schema Of A Virtual Table
**
** ^The [xCreate] and [xConnect] methods of a
** [virtual table module] call this interface
** to declare the format (the names and datatypes of the columns) of
** the virtual tables they implement.
*/
SQLITE_API int sqlite4_declare_vtab(sqlite4*, const char *zSQL);
/*
** CAPIREF: Overload A Function For A Virtual Table
**
** ^(Virtual tables can provide alternative implementations of functions
** using the [xFindFunction] method of the [virtual table module].
** But global versions of those functions
** must exist in order to be overloaded.)^
**
** ^(This API makes sure a global version of a function with a particular
** name and number of parameters exists. If no such function exists
** before this API is called, a new function is created.)^ ^The implementation
** of the new function always causes an exception to be thrown. So
** the new function is not good for anything by itself. Its only
** purpose is to be a placeholder function that can be overloaded
** by a [virtual table].
*/
SQLITE_API int sqlite4_overload_function(sqlite4*, const char *zFuncName, int nArg);
/*
**
/*
** CAPIREF: Mutexes
**
** The SQLite core uses these routines for thread
** synchronization. Though they are intended for internal
** use by SQLite, code that links against SQLite is
** permitted to use any of these routines.
**
** The SQLite source code contains multiple implementations
** of these mutex routines. An appropriate implementation
** is selected automatically at compile-time. ^(The following
** implementations are available in the SQLite core:
**
** <ul>
** <li> SQLITE_MUTEX_PTHREADS
** <li> SQLITE_MUTEX_W32
** <li> SQLITE_MUTEX_NOOP
** </ul>)^
**
** ^The SQLITE_MUTEX_NOOP implementation is a set of routines
** that does no real locking and is appropriate for use in
** a single-threaded application. ^The SQLITE_MUTEX_PTHREADS
** and SQLITE_MUTEX_W32 implementations
** are appropriate for use on Unix and Windows.
**
** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex
** implementation is included with the library. In this case the
** application must supply a custom mutex implementation using the
** [SQLITE_CONFIG_MUTEX] option of the sqlite4_env_config() function
** before calling sqlite4_initialize() or any other public sqlite4_
** function that calls sqlite4_initialize().)^
**
** ^The sqlite4_mutex_alloc() routine allocates a new
** mutex and returns a pointer to it. ^If it returns NULL
** that means that a mutex could not be allocated. ^SQLite
** will unwind its stack and return an error. ^(The argument
** to sqlite4_mutex_alloc() is one of these integer constants:
**
** <ul>
** <li> SQLITE_MUTEX_FAST
** <li> SQLITE_MUTEX_RECURSIVE
** </ul>)^
**
** ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
** The mutex implementation does not need to make a distinction
** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
** not want to. ^SQLite will only request a recursive mutex in
** cases where it really needs one. ^If a faster non-recursive mutex
** implementation is available on the host platform, the mutex subsystem
** might return such a mutex in response to SQLITE_MUTEX_FAST.
**
** ^The sqlite4_mutex_free() routine deallocates a previously
** allocated mutex.
**
** ^The sqlite4_mutex_enter() and sqlite4_mutex_try() routines attempt
** to enter a mutex. ^If another thread is already within the mutex,
** sqlite4_mutex_enter() will block and sqlite4_mutex_try() will return
** SQLITE_BUSY. ^The sqlite4_mutex_try() interface returns [SQLITE_OK]
** upon successful entry. ^(Mutexes created using
** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread.
** In such cases the,
** mutex must be exited an equal number of times before another thread
** can enter.)^ ^(If the same thread tries to enter any other
** kind of mutex more than once, the behavior is undefined.
** SQLite will never exhibit
** such behavior in its own use of mutexes.)^
**
** ^(Some systems (for example, Windows 95) do not support the operation
** implemented by sqlite4_mutex_try(). On those systems, sqlite4_mutex_try()
** will always return SQLITE_BUSY. The SQLite core only ever uses
** sqlite4_mutex_try() as an optimization so this is acceptable behavior.)^
**
** ^The sqlite4_mutex_leave() routine exits a mutex that was
** previously entered by the same thread. ^(The behavior
** is undefined if the mutex is not currently entered by the
** calling thread or is not currently allocated. SQLite will
** never do either.)^
**
** ^If the argument to sqlite4_mutex_enter(), sqlite4_mutex_try(), or
** sqlite4_mutex_leave() is a NULL pointer, then all three routines
** behave as no-ops.
**
** See also: [sqlite4_mutex_held()] and [sqlite4_mutex_notheld()].
*/
SQLITE_API sqlite4_mutex *sqlite4_mutex_alloc(sqlite4_env*, int);
SQLITE_API void sqlite4_mutex_free(sqlite4_mutex*);
SQLITE_API void sqlite4_mutex_enter(sqlite4_mutex*);
SQLITE_API int sqlite4_mutex_try(sqlite4_mutex*);
SQLITE_API void sqlite4_mutex_leave(sqlite4_mutex*);
/*
** CAPIREF: Mutex Methods Object
**
** An instance of this structure defines the low-level routines
** used to allocate and use mutexes.
**
** Usually, the default mutex implementations provided by SQLite are
** sufficient, however the user has the option of substituting a custom
** implementation for specialized deployments or systems for which SQLite
** does not provide a suitable implementation. In this case, the user
** creates and populates an instance of this structure to pass
** to sqlite4_env_config() along with the [SQLITE_CONFIG_MUTEX] option.
** Additionally, an instance of this structure can be used as an
** output variable when querying the system for the current mutex
** implementation, using the [SQLITE_CONFIG_GETMUTEX] option.
**
** ^The xMutexInit method defined by this structure is invoked as
** part of system initialization by the sqlite4_initialize() function.
** ^The xMutexInit routine is called by SQLite exactly once for each
** effective call to [sqlite4_initialize()].
**
** ^The xMutexEnd method defined by this structure is invoked as
** part of system shutdown by the sqlite4_shutdown() function. The
** implementation of this method is expected to release all outstanding
** resources obtained by the mutex methods implementation, especially
** those obtained by the xMutexInit method. ^The xMutexEnd()
** interface is invoked exactly once for each call to [sqlite4_shutdown()].
**
** ^(The remaining seven methods defined by this structure (xMutexAlloc,
** xMutexFree, xMutexEnter, xMutexTry, xMutexLeave, xMutexHeld and
** xMutexNotheld) implement the following interfaces (respectively):
**
** <ul>
** <li> [sqlite4_mutex_alloc()] </li>
** <li> [sqlite4_mutex_free()] </li>
** <li> [sqlite4_mutex_enter()] </li>
** <li> [sqlite4_mutex_try()] </li>
** <li> [sqlite4_mutex_leave()] </li>
** <li> [sqlite4_mutex_held()] </li>
** <li> [sqlite4_mutex_notheld()] </li>
** </ul>)^
**
** The only difference is that the public sqlite4_XXX functions enumerated
** above silently ignore any invocations that pass a NULL pointer instead
** of a valid mutex handle. The implementations of the methods defined
** by this structure are not required to handle this case, the results
** of passing a NULL pointer instead of a valid mutex handle are undefined
** (i.e. it is acceptable to provide an implementation that segfaults if
** it is passed a NULL pointer).
**
** The xMutexInit() method must be threadsafe. ^It must be harmless to
** invoke xMutexInit() multiple times within the same process and without
** intervening calls to xMutexEnd(). Second and subsequent calls to
** xMutexInit() must be no-ops.
**
** ^xMutexInit() must not use SQLite memory allocation ([sqlite4_malloc()]
** and its associates). ^Similarly, xMutexAlloc() must not use SQLite memory
** allocation for a static mutex. ^However xMutexAlloc() may use SQLite
** memory allocation for a fast or recursive mutex.
**
** ^SQLite will invoke the xMutexEnd() method when [sqlite4_shutdown()] is
** called, but only if the prior call to xMutexInit returned SQLITE_OK.
** If xMutexInit fails in any way, it is expected to clean up after itself
** prior to returning.
*/
typedef struct sqlite4_mutex_methods sqlite4_mutex_methods;
struct sqlite4_mutex_methods {
int (*xMutexInit)(void*);
int (*xMutexEnd)(void*);
sqlite4_mutex *(*xMutexAlloc)(void*,int);
void (*xMutexFree)(sqlite4_mutex *);
void (*xMutexEnter)(sqlite4_mutex *);
int (*xMutexTry)(sqlite4_mutex *);
void (*xMutexLeave)(sqlite4_mutex *);
int (*xMutexHeld)(sqlite4_mutex *);
int (*xMutexNotheld)(sqlite4_mutex *);
void *pMutexEnv;
};
/*
** CAPIREF: Mutex Verification Routines
**
** The sqlite4_mutex_held() and sqlite4_mutex_notheld() routines
** are intended for use inside assert() statements. ^The SQLite core
** never uses these routines except inside an assert() and applications
** are advised to follow the lead of the core. ^The SQLite core only
** provides implementations for these routines when it is compiled
** with the SQLITE_DEBUG flag. ^External mutex implementations
** are only required to provide these routines if SQLITE_DEBUG is
** defined and if NDEBUG is not defined.
**
** ^These routines should return true if the mutex in their argument
** is held or not held, respectively, by the calling thread.
**
** ^The implementation is not required to provide versions of these
** routines that actually work. If the implementation does not provide working
** versions of these routines, it should at least provide stubs that always
** return true so that one does not get spurious assertion failures.
**
** ^If the argument to sqlite4_mutex_held() is a NULL pointer then
** the routine should return 1. This seems counter-intuitive since
** clearly the mutex cannot be held if it does not exist. But
** the reason the mutex does not exist is because the build is not
** using mutexes. And we do not want the assert() containing the
** call to sqlite4_mutex_held() to fail, so a non-zero return is
** the appropriate thing to do. ^The sqlite4_mutex_notheld()
** interface should also return 1 when given a NULL pointer.
*/
#ifndef NDEBUG
SQLITE_API int sqlite4_mutex_held(sqlite4_mutex*);
SQLITE_API int sqlite4_mutex_notheld(sqlite4_mutex*);
#endif
/*
** CAPIREF: Mutex Types
**
** The [sqlite4_mutex_alloc()] interface takes a single argument
** which is one of these integer constants.
**
** The set of static mutexes may change from one SQLite release to the
** next. Applications that override the built-in mutex logic must be
** prepared to accommodate additional static mutexes.
*/
#define SQLITE_MUTEX_FAST 0
#define SQLITE_MUTEX_RECURSIVE 1
/*
** CAPIREF: Retrieve the mutex for a database connection
**
** ^This interface returns a pointer the [sqlite4_mutex] object that
** serializes access to the [database connection] given in the argument
** when the [threading mode] is Serialized.
** ^If the [threading mode] is Single-thread or Multi-thread then this
** routine returns a NULL pointer.
*/
SQLITE_API sqlite4_mutex *sqlite4_db_mutex(sqlite4*);
/*
** CAPIREF: Low-Level Control Of Database Backends
**
** ^The [sqlite4_kvstore_control()] interface makes a direct call to the
** xControl method of the key-value store associated with the particular
** database identified by the second argument. ^The name of the database
** is "main" for the main database or "temp" for the TEMP database, or the
** name that appears after the AS keyword for databases that were added
** using the [ATTACH] SQL command. ^A NULL pointer can be used in place
** of "main" to refer to the main database file.
**
** ^The third and fourth parameters to this routine are passed directly
** through to the second and third parameters of the
** sqlite4_kv_methods.xControl method. ^The return value of the xControl
** call becomes the return value of this routine.
**
** ^If the second parameter (zDbName) does not match the name of any
** open database file, then SQLITE_ERROR is returned. ^This error
** code is not remembered and will not be recalled by [sqlite4_errcode()]
** or [sqlite4_errmsg()]. The underlying xControl method might also return
** SQLITE_ERROR. There is no way to distinguish between an incorrect zDbName
** and an SQLITE_ERROR return from the underlying xControl method.
*/
SQLITE_API int sqlite4_kvstore_control(sqlite4*, const char *zDbName, int op, void*);
/*
** <dl>
** <dt>SQLITE_KVCTRL_LSM_HANDLE</dt><dd>
**
** <dt>SQLITE_KVCTRL_SYNCHRONOUS</dt><dd>
** This op is used to configure or query the synchronous level of the
** database backend (either OFF, NORMAL or FULL). The fourth parameter passed
** to kvstore_control should be of type (int *). Call the value that the
** parameter points to N. If N is initially 0, 1 or 2, then the database
** backend should attempt to change the synchronous level to OFF, NORMAL
** or FULL, respectively. Regardless of its initial value, N is set to
** the current (possibly updated) synchronous level before returning (
** 0, 1 or 2).
*/
#define SQLITE_KVCTRL_LSM_HANDLE 1
#define SQLITE_KVCTRL_SYNCHRONOUS 2
/*
** CAPIREF: Testing Interface
**
** ^The sqlite4_test_control() interface is used to read out internal
** state of SQLite and to inject faults into SQLite for testing
** purposes. ^The first parameter is an operation code that determines
** the number, meaning, and operation of all subsequent parameters.
**
** This interface is not for use by applications. It exists solely
** for verifying the correct operation of the SQLite library. Depending
** on how the SQLite library is compiled, this interface might not exist.
**
** The details of the operation codes, their meanings, the parameters
** they take, and what they do are all subject to change without notice.
** Unlike most of the SQLite API, this function is not guaranteed to
** operate consistently from one release to the next.
*/
SQLITE_API int sqlite4_test_control(int op, ...);
/*
** CAPIREF: Testing Interface Operation Codes
**
** These constants are the valid operation code parameters used
** as the first argument to [sqlite4_test_control()].
**
** These parameters and their meanings are subject to change
** without notice. These values are for testing purposes only.
** Applications should not use any of these parameters or the
** [sqlite4_test_control()] interface.
*/
#define SQLITE_TESTCTRL_FIRST 1
#define SQLITE_TESTCTRL_FAULT_INSTALL 2
#define SQLITE_TESTCTRL_ASSERT 3
#define SQLITE_TESTCTRL_ALWAYS 4
#define SQLITE_TESTCTRL_RESERVE 5
#define SQLITE_TESTCTRL_OPTIMIZATIONS 6
#define SQLITE_TESTCTRL_ISKEYWORD 7
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 8
#define SQLITE_TESTCTRL_EXPLAIN_STMT 9
#define SQLITE_TESTCTRL_LAST 9
/*
** CAPIREF: SQLite Runtime Status
**
** ^This interface is used to retrieve runtime status information
** about the performance of SQLite, and optionally to reset various
** highwater marks. ^The first argument is an integer code for
** the specific parameter to measure. ^(Recognized integer codes
** are of the form [status parameters | SQLITE_STATUS_...].)^
** ^The current value of the parameter is returned into *pCurrent.
** ^The highest recorded value is returned in *pHighwater. ^If the
** resetFlag is true, then the highest record value is reset after
** *pHighwater is written. ^(Some parameters do not record the highest
** value. For those parameters
** nothing is written into *pHighwater and the resetFlag is ignored.)^
** ^(Other parameters record only the highwater mark and not the current
** value. For these latter parameters nothing is written into *pCurrent.)^
**
** ^The sqlite4_status() routine returns SQLITE_OK on success and a
** non-zero [error code] on failure.
**
** This routine is threadsafe but is not atomic. This routine can be
** called while other threads are running the same or different SQLite
** interfaces. However the values returned in *pCurrent and
** *pHighwater reflect the status of SQLite at different points in time
** and it is possible that another thread might change the parameter
** in between the times when *pCurrent and *pHighwater are written.
**
** See also: [sqlite4_db_status()]
*/
SQLITE_API int sqlite4_env_status(
sqlite4_env *pEnv,
int op,
sqlite4_uint64 *pCurrent,
sqlite4_uint64 *pHighwater,
int resetFlag
);
/*
** CAPIREF: Status Parameters
** KEYWORDS: {status parameters}
**
** These integer constants designate various run-time status parameters
** that can be returned by [sqlite4_status()].
**
** <dl>
** [[SQLITE_STATUS_MEMORY_USED]] ^(<dt>SQLITE_STATUS_MEMORY_USED</dt>
** <dd>This parameter is the current amount of memory checked out
** using [sqlite4_malloc()], either directly or indirectly. The
** figure includes calls made to [sqlite4_malloc()] by the application
** and internal memory usage by the SQLite library. Scratch memory
** controlled by [SQLITE_CONFIG_SCRATCH] and 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 [sqlite4_mem_methods].</dd>)^
**
** [[SQLITE_STATUS_MALLOC_SIZE]] ^(<dt>SQLITE_STATUS_MALLOC_SIZE</dt>
** <dd>This parameter records the largest memory allocation request
** handed to [sqlite4_malloc()] or [sqlite4_realloc()] (or their
** internal equivalents). Only the value returned in the
** *pHighwater parameter to [sqlite4_status()] is of interest.
** The value written into the *pCurrent parameter is undefined.</dd>)^
**
** [[SQLITE_STATUS_MALLOC_COUNT]] ^(<dt>SQLITE_STATUS_MALLOC_COUNT</dt>
** <dd>This parameter records the number of separate memory allocations
** currently checked out.</dd>)^
**
** [[SQLITE_STATUS_PARSER_STACK]] ^(<dt>SQLITE_STATUS_PARSER_STACK</dt>
** <dd>This parameter records the deepest parser stack. It is only
** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].</dd>)^
** </dl>
**
** New status parameters may be added from time to time.
*/
#define SQLITE_ENVSTATUS_MEMORY_USED 0
#define SQLITE_ENVSTATUS_MALLOC_SIZE 1
#define SQLITE_ENVSTATUS_MALLOC_COUNT 2
#define SQLITE_ENVSTATUS_PARSER_STACK 3
/*
** CAPIREF: Database Connection Status
**
** ^This interface is used to retrieve runtime status information
** about a single [database connection]. ^The first argument is the
** database connection object to be interrogated. ^The second argument
** is an integer constant, taken from the set of
** [SQLITE_DBSTATUS options], that
** determines the parameter to interrogate. The set of
** [SQLITE_DBSTATUS options] is likely
** to grow in future releases of SQLite.
**
** ^The current value of the requested parameter is written into *pCur
** and the highest instantaneous value is written into *pHiwtr. ^If
** the resetFlg is true, then the highest instantaneous value is
** reset back down to the current value.
**
** ^The sqlite4_db_status() routine returns SQLITE_OK on success and a
** non-zero [error code] on failure.
**
** See also: [sqlite4_status()] and [sqlite4_stmt_status()].
*/
SQLITE_API int sqlite4_db_status(sqlite4*, int op, int *pCur, int *pHiwtr, int resetFlg);
/*
** CAPIREF: Status Parameters for database connections
** KEYWORDS: {SQLITE_DBSTATUS options}
**
** These constants are the available integer "verbs" that can be passed as
** the second argument to the [sqlite4_db_status()] interface.
**
** New verbs may be added in future releases of SQLite. Existing verbs
** might be discontinued. Applications should check the return code from
** [sqlite4_db_status()] to make sure that the call worked.
** The [sqlite4_db_status()] interface will return a non-zero error code
** if a discontinued or unsupported verb is invoked.
**
** <dl>
** [[SQLITE_DBSTATUS_LOOKASIDE_USED]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_USED</dt>
** <dd>This parameter returns the number of lookaside memory slots currently
** checked out.</dd>)^
**
** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_HIT</dt>
** <dd>This parameter returns the number malloc attempts that were
** satisfied using lookaside memory. Only the high-water value is meaningful;
** the current value is always zero.)^
**
** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]]
** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE</dt>
** <dd>This parameter returns the number malloc attempts that might have
** been satisfied using lookaside memory but failed due to the amount of
** memory requested being larger than the lookaside slot size.
** Only the high-water value is meaningful;
** the current value is always zero.)^
**
** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]]
** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL</dt>
** <dd>This parameter returns the number malloc attempts that might have
** been satisfied using lookaside memory but failed due to all lookaside
** memory already being in use.
** Only the high-water value is meaningful;
** the current value is always zero.)^
**
** [[SQLITE_DBSTATUS_CACHE_USED]] ^(<dt>SQLITE_DBSTATUS_CACHE_USED</dt>
** <dd>This parameter returns the approximate number of of bytes of heap
** memory used by all pager caches associated with the database connection.)^
** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0.
**
** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(<dt>SQLITE_DBSTATUS_SCHEMA_USED</dt>
** <dd>This parameter returns the approximate number of of bytes of heap
** memory used to store the schema for all databases associated
** with the connection - main, temp, and any [ATTACH]-ed databases.)^
** ^The full amount of memory used by the schemas is reported, even if the
** schema memory is shared with other database connections due to
** [shared cache mode] being enabled.
** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0.
**
** [[SQLITE_DBSTATUS_STMT_USED]] ^(<dt>SQLITE_DBSTATUS_STMT_USED</dt>
** <dd>This parameter returns the approximate number of of bytes of heap
** and lookaside memory used by all prepared statements associated with
** the database connection.)^
** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0.
** </dd>
**
** [[SQLITE_DBSTATUS_CACHE_HIT]] ^(<dt>SQLITE_DBSTATUS_CACHE_HIT</dt>
** <dd>This parameter returns the number of pager cache hits that have
** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT
** is always 0.
** </dd>
**
** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(<dt>SQLITE_DBSTATUS_CACHE_MISS</dt>
** <dd>This parameter returns the number of pager cache misses that have
** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS
** is always 0.
** </dd>
** </dl>
*/
#define SQLITE_DBSTATUS_LOOKASIDE_USED 0
#define SQLITE_DBSTATUS_CACHE_USED 1
#define SQLITE_DBSTATUS_SCHEMA_USED 2
#define SQLITE_DBSTATUS_STMT_USED 3
#define SQLITE_DBSTATUS_LOOKASIDE_HIT 4
#define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5
#define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6
#define SQLITE_DBSTATUS_CACHE_HIT 7
#define SQLITE_DBSTATUS_CACHE_MISS 8
#define SQLITE_DBSTATUS_MAX 8 /* Largest defined DBSTATUS */
/*
** CAPIREF: Prepared Statement Status
**
** ^(Each prepared statement maintains various
** [SQLITE_STMTSTATUS counters] that measure the number
** of times it has performed specific operations.)^ These counters can
** be used to monitor the performance characteristics of the prepared
** statements. For example, if the number of table steps greatly exceeds
** the number of table searches or result rows, that would tend to indicate
** that the prepared statement is using a full table scan rather than
** an index.
**
** ^(This interface is used to retrieve and reset counter values from
** a [prepared statement]. The first argument is the prepared statement
** object to be interrogated. The second argument
** is an integer code for a specific [SQLITE_STMTSTATUS counter]
** to be interrogated.)^
** ^The current value of the requested counter is returned.
** ^If the resetFlg is true, then the counter is reset to zero after this
** interface call returns.
**
** See also: [sqlite4_status()] and [sqlite4_db_status()].
*/
SQLITE_API int sqlite4_stmt_status(sqlite4_stmt*, int op,int resetFlg);
/*
** CAPIREF: Status Parameters for prepared statements
** KEYWORDS: {SQLITE_STMTSTATUS counter} {SQLITE_STMTSTATUS counters}
**
** These preprocessor macros define integer codes that name counter
** values associated with the [sqlite4_stmt_status()] interface.
** The meanings of the various counters are as follows:
**
** <dl>
** [[SQLITE_STMTSTATUS_FULLSCAN_STEP]] <dt>SQLITE_STMTSTATUS_FULLSCAN_STEP</dt>
** <dd>^This is the number of times that SQLite has stepped forward in
** a table as part of a full table scan. Large numbers for this counter
** may indicate opportunities for performance improvement through
** careful use of indices.</dd>
**
** [[SQLITE_STMTSTATUS_SORT]] <dt>SQLITE_STMTSTATUS_SORT</dt>
** <dd>^This is the number of sort operations that have occurred.
** A non-zero value in this counter may indicate an opportunity to
** improvement performance through careful use of indices.</dd>
**
** [[SQLITE_STMTSTATUS_AUTOINDEX]] <dt>SQLITE_STMTSTATUS_AUTOINDEX</dt>
** <dd>^This is the number of rows inserted into transient indices that
** were created automatically in order to help joins run faster.
** A non-zero value in this counter may indicate an opportunity to
** improvement performance by adding permanent indices that do not
** need to be reinitialized each time the statement is run.</dd>
** </dl>
*/
#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1
#define SQLITE_STMTSTATUS_SORT 2
#define SQLITE_STMTSTATUS_AUTOINDEX 3
/*
** CAPIREF: Unlock Notification
**
** ^When running in shared-cache mode, a database operation may fail with
** an [SQLITE_LOCKED] error if the required locks on the shared-cache or
** individual tables within the shared-cache cannot be obtained. See
** [SQLite Shared-Cache Mode] for a description of shared-cache locking.
** ^This API may be used to register a callback that SQLite will invoke
** when the connection currently holding the required lock relinquishes it.
** ^This API is only available if the library was compiled with the
** [SQLITE_ENABLE_UNLOCK_NOTIFY] C-preprocessor symbol defined.
**
** See Also: [Using the SQLite Unlock Notification Feature].
**
** ^Shared-cache locks are released when a database connection concludes
** its current transaction, either by committing it or rolling it back.
**
** ^When a connection (known as the blocked connection) fails to obtain a
** shared-cache lock and SQLITE_LOCKED is returned to the caller, the
** identity of the database connection (the blocking connection) that
** has locked the required resource is stored internally. ^After an
** application receives an SQLITE_LOCKED error, it may call the
** sqlite4_unlock_notify() method with the blocked connection handle as
** the first argument to register for a callback that will be invoked
** when the blocking connections current transaction is concluded. ^The
** callback is invoked from within the [sqlite4_step] or [sqlite4_close]
** call that concludes the blocking connections transaction.
**
** ^(If sqlite4_unlock_notify() is called in a multi-threaded application,
** there is a chance that the blocking connection will have already
** concluded its transaction by the time sqlite4_unlock_notify() is invoked.
** If this happens, then the specified callback is invoked immediately,
** from within the call to sqlite4_unlock_notify().)^
**
** ^If the blocked connection is attempting to obtain a write-lock on a
** shared-cache table, and more than one other connection currently holds
** a read-lock on the same table, then SQLite arbitrarily selects one of
** the other connections to use as the blocking connection.
**
** ^(There may be at most one unlock-notify callback registered by a
** blocked connection. If sqlite4_unlock_notify() is called when the
** blocked connection already has a registered unlock-notify callback,
** then the new callback replaces the old.)^ ^If sqlite4_unlock_notify() is
** called with a NULL pointer as its second argument, then any existing
** unlock-notify callback is canceled. ^The blocked connections
** unlock-notify callback may also be canceled by closing the blocked
** connection using [sqlite4_close()].
**
** The unlock-notify callback is not reentrant. If an application invokes
** any sqlite4_xxx API functions from within an unlock-notify callback, a
** crash or deadlock may be the result.
**
** ^Unless deadlock is detected (see below), sqlite4_unlock_notify() always
** returns SQLITE_OK.
**
** <b>Callback Invocation Details</b>
**
** When an unlock-notify callback is registered, the application provides a
** single void* pointer that is passed to the callback when it is invoked.
** However, the signature of the callback function allows SQLite to pass
** it an array of void* context pointers. The first argument passed to
** an unlock-notify callback is a pointer to an array of void* pointers,
** and the second is the number of entries in the array.
**
** When a blocking connections transaction is concluded, there may be
** more than one blocked connection that has registered for an unlock-notify
** callback. ^If two or more such blocked connections have specified the
** same callback function, then instead of invoking the callback function
** multiple times, it is invoked once with the set of void* context pointers
** specified by the blocked connections bundled together into an array.
** This gives the application an opportunity to prioritize any actions
** related to the set of unblocked database connections.
**
** <b>Deadlock Detection</b>
**
** Assuming that after registering for an unlock-notify callback a
** database waits for the callback to be issued before taking any further
** action (a reasonable assumption), then using this API may cause the
** application to deadlock. For example, if connection X is waiting for
** connection Y's transaction to be concluded, and similarly connection
** Y is waiting on connection X's transaction, then neither connection
** will proceed and the system may remain deadlocked indefinitely.
**
** To avoid this scenario, the sqlite4_unlock_notify() performs deadlock
** detection. ^If a given call to sqlite4_unlock_notify() would put the
** system in a deadlocked state, then SQLITE_LOCKED is returned and no
** unlock-notify callback is registered. The system is said to be in
** a deadlocked state if connection A has registered for an unlock-notify
** callback on the conclusion of connection B's transaction, and connection
** B has itself registered for an unlock-notify callback when connection
** A's transaction is concluded. ^Indirect deadlock is also detected, so
** the system is also considered to be deadlocked if connection B has
** registered for an unlock-notify callback on the conclusion of connection
** C's transaction, where connection C is waiting on connection A. ^Any
** number of levels of indirection are allowed.
**
** <b>The "DROP TABLE" Exception</b>
**
** When a call to [sqlite4_step()] returns SQLITE_LOCKED, it is almost
** always appropriate to call sqlite4_unlock_notify(). There is however,
** one exception. When executing a "DROP TABLE" or "DROP INDEX" statement,
** SQLite checks if there are any currently executing SELECT statements
** that belong to the same connection. If there are, SQLITE_LOCKED is
** returned. In this case there is no "blocking connection", so invoking
** sqlite4_unlock_notify() results in the unlock-notify callback being
** invoked immediately. If the application then re-attempts the "DROP TABLE"
** or "DROP INDEX" query, an infinite loop might be the result.
**
** One way around this problem is to check the extended error code returned
** by an sqlite4_step() call. ^(If there is a blocking connection, then the
** extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in
** the special "DROP TABLE/INDEX" case, the extended error code is just
** SQLITE_LOCKED.)^
*/
SQLITE_API int sqlite4_unlock_notify(
sqlite4 *pBlocked, /* Waiting connection */
void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */
void *pNotifyArg /* Argument to pass to xNotify */
);
/*
** CAPIREF: String Comparison
**
** ^The [sqlite4_strnicmp()] API allows applications and extensions to
** compare the contents of two buffers containing UTF-8 strings in a
** case-independent fashion, using the same definition of case independence
** that SQLite uses internally when comparing identifiers.
*/
SQLITE_API int sqlite4_strnicmp(const char *, const char *, int);
/*
** CAPIREF: Error Logging Interface
**
** ^The [sqlite4_log()] interface writes a message into the error log
** established by the [SQLITE_CONFIG_LOG] option to [sqlite4_env_config()].
** ^If logging is enabled, the zFormat string and subsequent arguments are
** used with [sqlite4_snprintf()] to generate the final output string.
**
** The sqlite4_log() interface is intended for use by extensions such as
** virtual tables, collating functions, and SQL functions. While there is
** nothing to prevent an application from calling sqlite4_log(), doing so
** is considered bad form.
**
** The zFormat string must not be NULL.
**
** To avoid deadlocks and other threading problems, the sqlite4_log() routine
** will not use dynamically allocated memory. The log message is stored in
** a fixed-length buffer on the stack. If the log message is longer than
** a few hundred characters, it will be truncated to the length of the
** buffer.
*/
SQLITE_API void sqlite4_log(sqlite4_env*, int iErrCode, const char *zFormat, ...);
/*
** CAPIREF: Virtual Table Interface Configuration
**
** This function may be called by either the [xConnect] or [xCreate] method
** of a [virtual table] implementation to configure
** various facets of the virtual table interface.
**
** If this interface is invoked outside the context of an xConnect or
** xCreate virtual table method then the behavior is undefined.
**
** At present, there is only one option that may be configured using
** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].) Further options
** may be added in the future.
*/
SQLITE_API int sqlite4_vtab_config(sqlite4*, int op, ...);
/*
** CAPIREF: Virtual Table Configuration Options
**
** These macros define the various options to the
** [sqlite4_vtab_config()] interface that [virtual table] implementations
** can use to customize and optimize their behavior.
**
** <dl>
** <dt>SQLITE_VTAB_CONSTRAINT_SUPPORT
** <dd>Calls of the form
** [sqlite4_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported,
** where X is an integer. If X is zero, then the [virtual table] whose
** [xCreate] or [xConnect] method invoked [sqlite4_vtab_config()] does not
** support constraints. In this configuration (which is the default) if
** a call to the [xUpdate] method returns [SQLITE_CONSTRAINT], then the entire
** statement is rolled back as if [ON CONFLICT | OR ABORT] had been
** specified as part of the users SQL statement, regardless of the actual
** ON CONFLICT mode specified.
**
** If X is non-zero, then the virtual table implementation guarantees
** that if [xUpdate] returns [SQLITE_CONSTRAINT], it will do so before
** any modifications to internal or persistent data structures have been made.
** If the [ON CONFLICT] mode is ABORT, FAIL, IGNORE or ROLLBACK, SQLite
** is able to roll back a statement or database transaction, and abandon
** or continue processing the current SQL statement as appropriate.
** If the ON CONFLICT mode is REPLACE and the [xUpdate] method returns
** [SQLITE_CONSTRAINT], SQLite handles this as if the ON CONFLICT mode
** had been ABORT.
**
** Virtual table implementations that are required to handle OR REPLACE
** must do so within the [xUpdate] method. If a call to the
** [sqlite4_vtab_on_conflict()] function indicates that the current ON
** CONFLICT policy is REPLACE, the virtual table implementation should
** silently replace the appropriate rows within the xUpdate callback and
** return SQLITE_OK. Or, if this is not possible, it may return
** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT
** constraint handling.
** </dl>
*/
#define SQLITE_VTAB_CONSTRAINT_SUPPORT 1
/*
** CAPIREF: Determine The Virtual Table Conflict Policy
**
** This function may only be called from within a call to the [xUpdate] method
** of a [virtual table] implementation for an INSERT or UPDATE operation. ^The
** value returned is one of [SQLITE_ROLLBACK], [SQLITE_IGNORE], [SQLITE_FAIL],
** [SQLITE_ABORT], or [SQLITE_REPLACE], according to the [ON CONFLICT] mode
** of the SQL statement that triggered the call to the [xUpdate] method of the
** [virtual table].
*/
SQLITE_API int sqlite4_vtab_on_conflict(sqlite4 *);
/*
** CAPIREF: Conflict resolution modes
**
** These constants are returned by [sqlite4_vtab_on_conflict()] to
** inform a [virtual table] implementation what the [ON CONFLICT] mode
** is for the SQL statement being evaluated.
**
** Note that the [SQLITE_IGNORE] constant is also used as a potential
** return value from the [sqlite4_set_authorizer()] callback and that
** [SQLITE_ABORT] is also a [result code].
*/
#define SQLITE_ROLLBACK 1
/* #define SQLITE_IGNORE 2 // Also used by sqlite4_authorizer() callback */
#define SQLITE_FAIL 3
/* #define SQLITE_ABORT 4 // Also an error code */
#define SQLITE_REPLACE 5
/*
** CAPI4REF: Length of a key-value storage key or data field
**
** The length of the key or data for a key-value storage entry is
** stored in a variable of this type.
*/
typedef int sqlite4_kvsize;
/*
** CAPI4REF: Key-Value Storage Engine Object
**
** An instance of a subclass of the following object defines a
** connection to a storage engine.
*/
typedef struct sqlite4_kvstore sqlite4_kvstore;
struct sqlite4_kvstore {
const struct sqlite4_kv_methods *pStoreVfunc; /* Methods */
sqlite4_env *pEnv; /* Runtime environment for kvstore */
int iTransLevel; /* Current transaction level */
unsigned kvId; /* Unique ID used for tracing */
unsigned fTrace; /* True to enable tracing */
char zKVName[12]; /* Used for debugging */
/* Subclasses will typically append additional fields */
};
/*
** CAPI4REF: Key-Value Storage Engine Cursor Object
**
** An instance of a subclass of the following object defines a cursor
** used to scan through a key-value storage engine.
*/
typedef struct sqlite4_kvcursor sqlite4_kvcursor;
struct sqlite4_kvcursor {
sqlite4_kvstore *pStore; /* The owner of this cursor */
const struct sqlite4_kv_methods *pStoreVfunc; /* Methods */
sqlite4_env *pEnv; /* Runtime environment */
int iTransLevel; /* Current transaction level */
unsigned curId; /* Unique ID for tracing */
unsigned fTrace; /* True to enable tracing */
/* Subclasses will typically add additional fields */
};
/*
** CAPI4REF: Key-value storage engine virtual method table
**
** A Key-Value storage engine is defined by an instance of the following
** object.
*/
struct sqlite4_kv_methods {
int iVersion;
int szSelf;
int (*xReplace)(
sqlite4_kvstore*,
const unsigned char *pKey, sqlite4_kvsize nKey,
const unsigned char *pData, sqlite4_kvsize nData);
int (*xOpenCursor)(sqlite4_kvstore*, sqlite4_kvcursor**);
int (*xSeek)(sqlite4_kvcursor*,
const unsigned char *pKey, sqlite4_kvsize nKey, int dir);
int (*xNext)(sqlite4_kvcursor*);
int (*xPrev)(sqlite4_kvcursor*);
int (*xDelete)(sqlite4_kvcursor*);
int (*xKey)(sqlite4_kvcursor*,
const unsigned char **ppKey, sqlite4_kvsize *pnKey);
int (*xData)(sqlite4_kvcursor*, sqlite4_kvsize ofst, sqlite4_kvsize n,
const unsigned char **ppData, sqlite4_kvsize *pnData);
int (*xReset)(sqlite4_kvcursor*);
int (*xCloseCursor)(sqlite4_kvcursor*);
int (*xBegin)(sqlite4_kvstore*, int);
int (*xCommitPhaseOne)(sqlite4_kvstore*, int);
int (*xCommitPhaseTwo)(sqlite4_kvstore*, int);
int (*xRollback)(sqlite4_kvstore*, int);
int (*xRevert)(sqlite4_kvstore*, int);
int (*xClose)(sqlite4_kvstore*);
int (*xControl)(sqlite4_kvstore*, int, void*);
};
typedef struct sqlite4_kv_methods sqlite4_kv_methods;
/*
** CAPI4REF: Key-value storage engine open flags
**
** Allowed values to the flags parameter of an sqlite4_kvstore object
** factory.
**
** The flags parameter to the sqlite4_kvstore factory (the fourth parameter)
** is an OR-ed combination of these values and the
** [SQLITE_OPEN_READONLY | SQLITE_OPEN_xxxxx] flags that appear as
** arguments to [sqlite4_open()].
*/
#define SQLITE_KVOPEN_TEMPORARY 0x00010000 /* A temporary database */
#define SQLITE_KVOPEN_NO_TRANSACTIONS 0x00020000 /* No transactions needed */
/*
** CAPI4REF: Representation Of Numbers
**
** Every number in SQLite is represented in memory by an instance of
** the following object.
*/
typedef struct sqlite4_num sqlite4_num;
struct sqlite4_num {
unsigned char sign; /* Sign of the overall value */
unsigned char approx; /* True if the value is approximate */
unsigned short e; /* The exponent. */
sqlite4_uint64 m; /* The significant */
};
/*
** CAPI4REF: Operations On SQLite Number Objects
*/
SQLITE_API sqlite4_num sqlite4_num_add(sqlite4_num, sqlite4_num);
SQLITE_API sqlite4_num sqlite4_num_sub(sqlite4_num, sqlite4_num);
SQLITE_API sqlite4_num sqlite4_num_mul(sqlite4_num, sqlite4_num);
SQLITE_API sqlite4_num sqlite4_num_div(sqlite4_num, sqlite4_num);
SQLITE_API int sqlite4_num_isinf(sqlite4_num);
SQLITE_API int sqlite4_num_isnan(sqlite4_num);
SQLITE_API sqlite4_num sqlite4_num_round(sqlite4_num, int iDigit);
SQLITE_API int sqlite4_num_compare(sqlite4_num, sqlite4_num);
SQLITE_API sqlite4_num sqlite4_num_from_text(const char*, int n, unsigned flags);
SQLITE_API sqlite4_num sqlite4_num_from_int64(sqlite4_int64);
SQLITE_API sqlite4_num sqlite4_num_from_double(double);
SQLITE_API int sqlite4_num_to_int32(sqlite4_num, int*);
SQLITE_API int sqlite4_num_to_int64(sqlite4_num, sqlite4_int64*);
SQLITE_API double sqlite4_num_to_double(sqlite4_num);
SQLITE_API int sqlite4_num_to_text(sqlite4_num, char*);
/*
** CAPI4REF: Flags For Text-To-Numeric Conversion
*/
#define SQLITE_PREFIX_ONLY 0x10
#define SQLITE_IGNORE_WHITESPACE 0x20
/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/
#ifdef SQLITE_OMIT_FLOATING_POINT
# undef double
#endif
#if 0
} /* End of the 'extern "C"' block */
#endif
#endif
/*
** 2010 August 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.
**
*************************************************************************
*/
#ifndef _SQLITE3RTREE_H_
#define _SQLITE3RTREE_H_
#if 0
extern "C" {
#endif
typedef struct sqlite4_rtree_geometry sqlite4_rtree_geometry;
/*
** Register a geometry callback named zGeom that can be used as part of an
** R-Tree geometry query as follows:
**
** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...)
*/
SQLITE_API int sqlite4_rtree_geometry_callback(
sqlite4 *db,
const char *zGeom,
int (*xGeom)(sqlite4_rtree_geometry *, int nCoord, double *aCoord, int *pRes),
void *pContext
);
/*
** A pointer to a structure of the following type is passed as the first
** argument to callbacks registered using rtree_geometry_callback().
*/
struct sqlite4_rtree_geometry {
void *pContext; /* Copy of pContext passed to s_r_g_c() */
int nParam; /* Size of array aParam[] */
double *aParam; /* Parameters passed to SQL geom function */
void *pUser; /* Callback implementation user data */
void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */
};
#if 0
} /* end of the 'extern "C"' block */
#endif
#endif /* ifndef _SQLITE3RTREE_H_ */
/************** End of sqlite4.h *********************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
/************** Include hash.h in the middle of sqliteInt.h ******************/
/************** Begin file hash.h ********************************************/
/*
** 2001 September 22
**
** 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 the header file for the generic hash-table implemenation
** used in SQLite.
*/
#ifndef _SQLITE_HASH_H_
#define _SQLITE_HASH_H_
/* Forward declarations of structures. */
typedef struct Hash Hash;
typedef struct HashElem HashElem;
/* A complete hash table is an instance of the following structure.
** The internals of this structure are intended to be opaque -- client
** code should not attempt to access or modify the fields of this structure
** directly. Change this structure only by using the routines below.
** However, some of the "procedures" and "functions" for modifying and
** accessing this structure are really macros, so we can't really make
** this structure opaque.
**
** All elements of the hash table are on a single doubly-linked list.
** Hash.first points to the head of this list.
**
** There are Hash.htsize buckets. Each bucket points to a spot in
** the global doubly-linked list. The contents of the bucket are the
** element pointed to plus the next _ht.count-1 elements in the list.
**
** Hash.htsize and Hash.ht may be zero. In that case lookup is done
** by a linear search of the global list. For small tables, the
** Hash.ht table is never allocated because if there are few elements
** in the table, it is faster to do a linear search than to manage
** the hash table.
*/
struct Hash {
struct sqlite4_env *pEnv; /* Memory allocation environment */
unsigned int htsize; /* Number of buckets in the hash table */
unsigned int count; /* Number of entries in this table */
HashElem *first; /* The first element of the array */
struct _ht { /* the hash table */
int count; /* Number of entries with this hash */
HashElem *chain; /* Pointer to first entry with this hash */
} *ht;
};
/* Each element in the hash table is an instance of the following
** structure. All elements are stored on a single doubly-linked list.
**
** Again, this structure is intended to be opaque, but it can't really
** be opaque because it is used by macros.
*/
struct HashElem {
HashElem *next, *prev; /* Next and previous elements in the table */
void *data; /* Data associated with this element */
const char *pKey; int nKey; /* Key associated with this element */
};
/*
** Access routines. To delete, insert a NULL pointer.
*/
SQLITE_PRIVATE void sqlite4HashInit(struct sqlite4_env *pEnv, Hash*);
SQLITE_PRIVATE void *sqlite4HashInsert(Hash*, const char *pKey, int nKey, void *pData);
SQLITE_PRIVATE void *sqlite4HashFind(const Hash*, const char *pKey, int nKey);
SQLITE_PRIVATE void sqlite4HashClear(Hash*);
/*
** Macros for looping over all elements of a hash table. The idiom is
** like this:
**
** Hash h;
** HashElem *p;
** ...
** for(p=sqliteHashFirst(&h); p; p=sqliteHashNext(p)){
** SomeStructure *pData = sqliteHashData(p);
** // do something with pData
** }
*/
#define sqliteHashFirst(H) ((H)->first)
#define sqliteHashNext(E) ((E)->next)
#define sqliteHashData(E) ((E)->data)
/* #define sqliteHashKey(E) ((E)->pKey) // NOT USED */
/* #define sqliteHashKeysize(E) ((E)->nKey) // NOT USED */
/*
** Number of entries in a hash table
*/
/* #define sqliteHashCount(H) ((H)->count) // NOT USED */
#endif /* _SQLITE_HASH_H_ */
/************** End of hash.h ************************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
/************** Include parse.h in the middle of sqliteInt.h *****************/
/************** Begin file parse.h *******************************************/
#define TK_SEMI 1
#define TK_EXPLAIN 2
#define TK_QUERY 3
#define TK_PLAN 4
#define TK_BEGIN 5
#define TK_TRANSACTION 6
#define TK_DEFERRED 7
#define TK_IMMEDIATE 8
#define TK_EXCLUSIVE 9
#define TK_COMMIT 10
#define TK_END 11
#define TK_ROLLBACK 12
#define TK_SAVEPOINT 13
#define TK_RELEASE 14
#define TK_TO 15
#define TK_TABLE 16
#define TK_CREATE 17
#define TK_IF 18
#define TK_NOT 19
#define TK_EXISTS 20
#define TK_TEMP 21
#define TK_LP 22
#define TK_RP 23
#define TK_AS 24
#define TK_COMMA 25
#define TK_ID 26
#define TK_INDEXED 27
#define TK_ABORT 28
#define TK_ACTION 29
#define TK_AFTER 30
#define TK_ANALYZE 31
#define TK_ASC 32
#define TK_ATTACH 33
#define TK_BEFORE 34
#define TK_BY 35
#define TK_CASCADE 36
#define TK_CAST 37
#define TK_COLUMNKW 38
#define TK_CONFLICT 39
#define TK_DATABASE 40
#define TK_DESC 41
#define TK_DETACH 42
#define TK_EACH 43
#define TK_FAIL 44
#define TK_FOR 45
#define TK_IGNORE 46
#define TK_INITIALLY 47
#define TK_INSTEAD 48
#define TK_LIKE_KW 49
#define TK_MATCH 50
#define TK_NO 51
#define TK_KEY 52
#define TK_OF 53
#define TK_OFFSET 54
#define TK_PRAGMA 55
#define TK_RAISE 56
#define TK_REPLACE 57
#define TK_RESTRICT 58
#define TK_ROW 59
#define TK_TRIGGER 60
#define TK_VIEW 61
#define TK_VIRTUAL 62
#define TK_REINDEX 63
#define TK_RENAME 64
#define TK_CTIME_KW 65
#define TK_ANY 66
#define TK_OR 67
#define TK_AND 68
#define TK_IS 69
#define TK_BETWEEN 70
#define TK_IN 71
#define TK_ISNULL 72
#define TK_NOTNULL 73
#define TK_NE 74
#define TK_EQ 75
#define TK_GT 76
#define TK_LE 77
#define TK_LT 78
#define TK_GE 79
#define TK_ESCAPE 80
#define TK_BITAND 81
#define TK_BITOR 82
#define TK_LSHIFT 83
#define TK_RSHIFT 84
#define TK_PLUS 85
#define TK_MINUS 86
#define TK_STAR 87
#define TK_SLASH 88
#define TK_REM 89
#define TK_CONCAT 90
#define TK_COLLATE 91
#define TK_BITNOT 92
#define TK_STRING 93
#define TK_JOIN_KW 94
#define TK_CONSTRAINT 95
#define TK_DEFAULT 96
#define TK_NULL 97
#define TK_PRIMARY 98
#define TK_UNIQUE 99
#define TK_CHECK 100
#define TK_REFERENCES 101
#define TK_AUTOINCR 102
#define TK_ON 103
#define TK_INSERT 104
#define TK_DELETE 105
#define TK_UPDATE 106
#define TK_SET 107
#define TK_DEFERRABLE 108
#define TK_FOREIGN 109
#define TK_DROP 110
#define TK_UNION 111
#define TK_ALL 112
#define TK_EXCEPT 113
#define TK_INTERSECT 114
#define TK_SELECT 115
#define TK_DISTINCT 116
#define TK_DOT 117
#define TK_FROM 118
#define TK_JOIN 119
#define TK_USING 120
#define TK_ORDER 121
#define TK_GROUP 122
#define TK_HAVING 123
#define TK_LIMIT 124
#define TK_WHERE 125
#define TK_INTO 126
#define TK_VALUES 127
#define TK_INTEGER 128
#define TK_FLOAT 129
#define TK_BLOB 130
#define TK_REGISTER 131
#define TK_VARIABLE 132
#define TK_CASE 133
#define TK_WHEN 134
#define TK_THEN 135
#define TK_ELSE 136
#define TK_INDEX 137
#define TK_ALTER 138
#define TK_ADD 139
#define TK_TO_TEXT 140
#define TK_TO_BLOB 141
#define TK_TO_NUMERIC 142
#define TK_TO_INT 143
#define TK_TO_REAL 144
#define TK_ISNOT 145
#define TK_END_OF_FILE 146
#define TK_ILLEGAL 147
#define TK_SPACE 148
#define TK_UNCLOSED_STRING 149
#define TK_FUNCTION 150
#define TK_COLUMN 151
#define TK_AGG_FUNCTION 152
#define TK_AGG_COLUMN 153
#define TK_CONST_FUNC 154
#define TK_UMINUS 155
#define TK_UPLUS 156
/************** End of parse.h ***********************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stddef.h>
/*
** If compiling for a processor that lacks floating point support,
** substitute integer for floating-point
*/
#ifdef SQLITE_OMIT_FLOATING_POINT
# define double sqlite_int64
# define float sqlite_int64
# define LONGDOUBLE_TYPE sqlite_int64
# ifndef SQLITE_BIG_DBL
# define SQLITE_BIG_DBL (((sqlite4_int64)1)<<50)
# endif
# define SQLITE_OMIT_DATETIME_FUNCS 1
# define SQLITE_OMIT_TRACE 1
# undef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
# undef SQLITE_HAVE_ISNAN
#endif
#ifndef SQLITE_BIG_DBL
# define SQLITE_BIG_DBL (1e99)
#endif
/*
** 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
** to omit code used by TEMP tables without messy #ifndef statements.
*/
#ifdef SQLITE_OMIT_TEMPDB
#define OMIT_TEMPDB 1
#else
#define OMIT_TEMPDB 0
#endif
/*
** The "file format" number is an integer that is incremented whenever
** the VDBE-level file format changes. The following macros define the
** the default file format for new databases and the maximum file format
** that the library can read.
*/
#define SQLITE_MAX_FILE_FORMAT 4
#ifndef SQLITE_DEFAULT_FILE_FORMAT
# define SQLITE_DEFAULT_FILE_FORMAT 4
#endif
/*
** Determine whether triggers are recursive by default. This can be
** changed at run-time using a pragma.
*/
#ifndef SQLITE_DEFAULT_RECURSIVE_TRIGGERS
# define SQLITE_DEFAULT_RECURSIVE_TRIGGERS 0
#endif
/*
** Provide a default value for SQLITE_TEMP_STORE in case it is not specified
** on the command-line
*/
#ifndef SQLITE_TEMP_STORE
# define SQLITE_TEMP_STORE 1
#endif
/*
** GCC does not define the offsetof() macro so we'll have to do it
** ourselves.
*/
#ifndef offsetof
#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD))
#endif
/*
** Check to see if this machine uses EBCDIC. (Yes, believe it or
** not, there are still machines out there that use EBCDIC.)
*/
#if 'A' == '\301'
# define SQLITE_EBCDIC 1
#else
# define SQLITE_ASCII 1
#endif
/*
** Integers of known sizes. These typedefs might change for architectures
** where the sizes very. Preprocessor macros are available so that the
** types can be conveniently redefined at compile-type. Like this:
**
** cc '-DUINTPTR_TYPE=long long int' ...
*/
#ifndef UINT32_TYPE
# ifdef HAVE_UINT32_T
# define UINT32_TYPE uint32_t
# else
# define UINT32_TYPE unsigned int
# endif
#endif
#ifndef UINT16_TYPE
# ifdef HAVE_UINT16_T
# define UINT16_TYPE uint16_t
# else
# define UINT16_TYPE unsigned short int
# endif
#endif
#ifndef INT16_TYPE
# ifdef HAVE_INT16_T
# define INT16_TYPE int16_t
# else
# define INT16_TYPE short int
# endif
#endif
#ifndef UINT8_TYPE
# ifdef HAVE_UINT8_T
# define UINT8_TYPE uint8_t
# else
# define UINT8_TYPE unsigned char
# endif
#endif
#ifndef INT8_TYPE
# ifdef HAVE_INT8_T
# define INT8_TYPE int8_t
# else
# define INT8_TYPE signed char
# endif
#endif
#ifndef LONGDOUBLE_TYPE
# define LONGDOUBLE_TYPE long double
#endif
typedef sqlite_int64 i64; /* 8-byte signed integer */
typedef sqlite_uint64 u64; /* 8-byte unsigned integer */
typedef UINT32_TYPE u32; /* 4-byte unsigned integer */
typedef UINT16_TYPE u16; /* 2-byte unsigned integer */
typedef INT16_TYPE i16; /* 2-byte signed integer */
typedef UINT8_TYPE u8; /* 1-byte unsigned integer */
typedef INT8_TYPE i8; /* 1-byte signed integer */
/*
** SQLITE_MAX_U32 is a u64 constant that is the maximum u64 value
** that can be stored in a u32 without loss of data. The value
** is 0x00000000ffffffff. But because of quirks of some compilers, we
** have to specify the value in the less intuitive manner shown:
*/
#define SQLITE_MAX_U32 ((((u64)1)<<32)-1)
/*
** In the sqlite4_num object, the maximum exponent value. Values
** larger than this are +Inf, or -Inf, or NaN.
*/
#define SQLITE_MX_EXP 999 /* Maximum exponent */
#define SQLITE_NAN_EXP 2000 /* Exponent to use for NaN */
/*
** The datatype used to store estimates of the number of rows in a
** table or index. This is an unsigned integer type. For 99.9% of
** the world, a 32-bit integer is sufficient. But a 64-bit integer
** can be used at compile-time if desired.
*/
#ifdef SQLITE_64BIT_STATS
typedef u64 tRowcnt; /* 64-bit only if requested at compile-time */
#else
typedef u32 tRowcnt; /* 32-bit is the default */
#endif
/*
** Macros to determine whether the machine is big or little endian,
** evaluated at runtime.
*/
#ifdef SQLITE_AMALGAMATION
SQLITE_PRIVATE const int sqlite4one = 1;
#else
SQLITE_PRIVATE const int sqlite4one;
#endif
#if defined(i386) || defined(__i386__) || defined(_M_IX86)\
|| defined(__x86_64) || defined(__x86_64__)
# define SQLITE_BIGENDIAN 0
# define SQLITE_LITTLEENDIAN 1
# define SQLITE_UTF16NATIVE SQLITE_UTF16LE
#else
# define SQLITE_BIGENDIAN (*(char *)(&sqlite4one)==0)
# define SQLITE_LITTLEENDIAN (*(char *)(&sqlite4one)==1)
# define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE)
#endif
/*
** Constants for the largest and smallest possible 64-bit signed integers.
** These macros are designed to work correctly on both 32-bit and 64-bit
** compilers.
*/
#define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32))
#define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)
#define LARGEST_UINT64 (0xffffffff|(((i64)0xffffffff)<<32))
/*
** Round up a number to the next larger multiple of 8. This is used
** to force 8-byte alignment on 64-bit architectures.
*/
#define ROUND8(x) (((x)+7)&~7)
#define SQLITE_MIN(a,b) (((a)<(b)) ? (a) : (b))
#define SQLITE_MAX(a,b) (((a)>(b)) ? (a) : (b))
/*
** Round down to the nearest multiple of 8
*/
#define ROUNDDOWN8(x) ((x)&~7)
/*
** Assert that the pointer X is aligned to an 8-byte boundary. This
** macro is used only within assert() to verify that the code gets
** all alignment restrictions correct.
**
** Except, if SQLITE_4_BYTE_ALIGNED_MALLOC is defined, then the
** underlying malloc() implemention might return us 4-byte aligned
** pointers. In that case, only verify 4-byte alignment.
*/
#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC
# define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&3)==0)
#else
# define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&7)==0)
#endif
/*
** Name of the master database table. The master database table
** is a special table that holds the names and attributes of all
** user tables and indices.
*/
#define MASTER_NAME "sqlite_master"
#define TEMP_MASTER_NAME "sqlite_temp_master"
/*
** The root-page of the master database table.
*/
#define MASTER_ROOT 1
/*
** The name of the schema table.
*/
#define SCHEMA_TABLE(x) ((!OMIT_TEMPDB)&&(x==1)?TEMP_MASTER_NAME:MASTER_NAME)
/*
** A convenience macro that returns the number of elements in
** an array.
*/
#define ArraySize(X) ((int)(sizeof(X)/sizeof(X[0])))
/*
** The following macros are used to suppress compiler warnings and to
** 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
** 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.
**
** When a function parameter is not used at all within the body of a function,
** it is generally named "NotUsed" or "NotUsed2" to make things even clearer.
** However, these macros may also be used to suppress warnings related to
** parameters that may or may not be used depending on compilation options.
** For example those parameters only used in assert() statements. In these
** cases the parameters are named as per the usual conventions.
*/
#define UNUSED_PARAMETER(x) (void)(x)
#define UNUSED_PARAMETER2(x,y) UNUSED_PARAMETER(x),UNUSED_PARAMETER(y)
/*
** Forward references to structures
*/
typedef struct AggInfo AggInfo;
typedef struct AuthContext AuthContext;
typedef struct AutoincInfo AutoincInfo;
typedef struct CollSeq CollSeq;
typedef struct Column Column;
typedef struct Db Db;
typedef struct Schema Schema;
typedef struct Expr Expr;
typedef struct ExprList ExprList;
typedef struct ExprSpan ExprSpan;
typedef struct FKey FKey;
typedef struct FuncDestructor FuncDestructor;
typedef struct FuncDef FuncDef;
typedef struct FuncDefTable FuncDefTable;
typedef struct IdList IdList;
typedef struct Index Index;
typedef struct IndexSample IndexSample;
typedef struct KeyClass KeyClass;
typedef struct KeyInfo KeyInfo;
typedef struct Lookaside Lookaside;
typedef struct LookasideSlot LookasideSlot;
typedef struct Module Module;
typedef struct NameContext NameContext;
typedef struct Parse Parse;
typedef struct RowSet RowSet;
typedef struct Savepoint Savepoint;
typedef struct Select Select;
typedef struct SrcList SrcList;
typedef struct StrAccum StrAccum;
typedef struct Table Table;
typedef struct Token Token;
typedef struct Trigger Trigger;
typedef struct TriggerPrg TriggerPrg;
typedef struct TriggerStep TriggerStep;
typedef struct UnpackedRecord UnpackedRecord;
typedef struct VTable VTable;
typedef struct VtabCtx VtabCtx;
typedef struct Walker Walker;
typedef struct WherePlan WherePlan;
typedef struct WhereInfo WhereInfo;
typedef struct WhereLevel WhereLevel;
/************** Include vdbe.h in the middle of sqliteInt.h ******************/
/************** Begin file vdbe.h ********************************************/
/*
** 2001 September 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.
**
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE. The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
/* #include <stdio.h> */
/*
** A single VDBE is an opaque structure named "Vdbe". Only routines
** in the source file sqliteVdbe.c are allowed to see the insides
** of this structure.
*/
typedef struct Vdbe Vdbe;
/*
** The names of the following types declared in vdbeInt.h are required
** for the VdbeOp definition.
*/
typedef struct VdbeFunc VdbeFunc;
typedef struct Mem Mem;
typedef struct SubProgram SubProgram;
typedef struct VdbeCursor VdbeCursor;
/*
** A single instruction of the virtual machine has an opcode
** and as many as three operands. The instruction is recorded
** as an instance of the following structure:
*/
struct VdbeOp {
u8 opcode; /* What operation to perform */
signed char p4type; /* One of the P4_xxx constants for p4 */
u8 opflags; /* Mask of the OPFLG_* flags in opcodes.h */
u8 p5; /* Fifth parameter is an unsigned character */
int p1; /* First operand */
int p2; /* Second parameter (often the jump destination) */
int p3; /* The third parameter */
union { /* fourth parameter */
int i; /* Integer value if p4type==P4_INT32 */
void *p; /* Generic pointer */
char *z; /* Pointer to data for string (char array) types */
i64 *pI64; /* Used when p4type is P4_INT64 */
double *pReal; /* Used when p4type is P4_REAL */
FuncDef *pFunc; /* Used when p4type is P4_FUNCDEF */
VdbeFunc *pVdbeFunc; /* Used when p4type is P4_VDBEFUNC */
CollSeq *pColl; /* Used when p4type is P4_COLLSEQ */
Mem *pMem; /* Used when p4type is P4_MEM */
VTable *pVtab; /* Used when p4type is P4_VTAB */
KeyInfo *pKeyInfo; /* Used when p4type is P4_KEYINFO */
int *ai; /* Used when p4type is P4_INTARRAY */
SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */
int (*xAdvance)(VdbeCursor*);
} p4;
#ifdef SQLITE_DEBUG
char *zComment; /* Comment to improve readability */
#endif
#ifdef VDBE_PROFILE
int cnt; /* Number of times this instruction was executed */
u64 cycles; /* Total time spent executing this instruction */
#endif
};
typedef struct VdbeOp VdbeOp;
/*
** A sub-routine used to implement a trigger program.
*/
struct SubProgram {
VdbeOp *aOp; /* Array of opcodes for sub-program */
int nOp; /* Elements in aOp[] */
int nMem; /* Number of memory cells required */
int nCsr; /* Number of cursors required */
int nOnce; /* Number of OP_Once instructions */
void *token; /* id that may be used to recursive triggers */
SubProgram *pNext; /* Next sub-program already visited */
};
/*
** A smaller version of VdbeOp used for the VdbeAddOpList() function because
** it takes up less space.
*/
struct VdbeOpList {
u8 opcode; /* What operation to perform */
signed char p1; /* First operand */
signed char p2; /* Second parameter (often the jump destination) */
signed char p3; /* Third parameter */
};
typedef struct VdbeOpList VdbeOpList;
/*
** Allowed values of VdbeOp.p4type
*/
#define P4_NOTUSED 0 /* The P4 parameter is not used */
#define P4_DYNAMIC (-1) /* Pointer to a string obtained from sqliteMalloc() */
#define P4_STATIC (-2) /* Pointer to a static string */
#define P4_COLLSEQ (-4) /* P4 is a pointer to a CollSeq structure */
#define P4_FUNCDEF (-5) /* P4 is a pointer to a FuncDef structure */
#define P4_KEYINFO (-6) /* P4 is a pointer to a KeyInfo structure */
#define P4_VDBEFUNC (-7) /* P4 is a pointer to a VdbeFunc structure */
#define P4_MEM (-8) /* P4 is a pointer to a Mem* structure */
#define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */
#define P4_VTAB (-10) /* P4 is a pointer to an sqlite4_vtab structure */
#define P4_MPRINTF (-11) /* P4 is a string obtained from sqlite4_mprintf() */
#define P4_REAL (-12) /* P4 is a 64-bit floating point value */
#define P4_INT64 (-13) /* P4 is a 64-bit signed integer */
#define P4_INT32 (-14) /* P4 is a 32-bit signed integer */
#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */
#define P4_SUBPROGRAM (-18) /* P4 is a pointer to a SubProgram structure */
#define P4_ADVANCE (-19) /* P4 is a pointer to BtreeNext() or BtreePrev() */
/* When adding a P4 argument using P4_KEYINFO, a copy of the KeyInfo structure
** is made. That copy is freed when the Vdbe is finalized. But if the
** argument is P4_KEYINFO_HANDOFF, the passed in pointer is used. It still
** gets freed when the Vdbe is finalized so it still should be obtained
** from a single sqliteMalloc(). But no copy is made and the calling
** function should *not* try to free the KeyInfo.
*/
#define P4_KEYINFO_HANDOFF (-16)
#define P4_KEYINFO_STATIC (-17)
/*
** The Vdbe.aColName array contains 5n Mem structures, where n is the
** number of columns of data returned by the statement.
*/
#define COLNAME_NAME 0
#define COLNAME_DECLTYPE 1
#define COLNAME_DATABASE 2
#define COLNAME_TABLE 3
#define COLNAME_COLUMN 4
#ifdef SQLITE_ENABLE_COLUMN_METADATA
# define COLNAME_N 5 /* Number of COLNAME_xxx symbols */
#else
# ifdef SQLITE_OMIT_DECLTYPE
# define COLNAME_N 1 /* Store only the name */
# else
# define COLNAME_N 2 /* Store the name and decltype */
# endif
#endif
/*
** The following macro converts a relative address in the p2 field
** of a VdbeOp structure into a negative number so that
** sqlite4VdbeAddOpList() knows that the address is relative. Calling
** the macro again restores the address.
*/
#define ADDR(X) (-1-(X))
/*
** The makefile scans the vdbe.c source file and creates the "opcodes.h"
** header file that defines a number for each opcode used by the VDBE.
*/
/************** Include opcodes.h in the middle of vdbe.h ********************/
/************** Begin file opcodes.h *****************************************/
/* Automatically generated. Do not edit */
/* See the mkopcodeh.awk script for details */
#define OP_Goto 1
#define OP_Gosub 2
#define OP_Return 3
#define OP_Yield 4
#define OP_HaltIfNull 5
#define OP_Halt 6
#define OP_Integer 7
#define OP_Int64 8
#define OP_Real 129 /* same as TK_FLOAT */
#define OP_String8 93 /* same as TK_STRING */
#define OP_String 9
#define OP_Null 10
#define OP_Blob 11
#define OP_Variable 12
#define OP_Move 13
#define OP_Copy 14
#define OP_SCopy 15
#define OP_ResultRow 16
#define OP_Concat 90 /* same as TK_CONCAT */
#define OP_Add 85 /* same as TK_PLUS */
#define OP_Subtract 86 /* same as TK_MINUS */
#define OP_Multiply 87 /* same as TK_STAR */
#define OP_Divide 88 /* same as TK_SLASH */
#define OP_Remainder 89 /* same as TK_REM */
#define OP_CollSeq 17
#define OP_Function 18
#define OP_BitAnd 81 /* same as TK_BITAND */
#define OP_BitOr 82 /* same as TK_BITOR */
#define OP_ShiftLeft 83 /* same as TK_LSHIFT */
#define OP_ShiftRight 84 /* same as TK_RSHIFT */
#define OP_AddImm 20
#define OP_MustBeInt 21
#define OP_RealAffinity 22
#define OP_ToText 140 /* same as TK_TO_TEXT */
#define OP_ToBlob 141 /* same as TK_TO_BLOB */
#define OP_ToNumeric 142 /* same as TK_TO_NUMERIC*/
#define OP_ToInt 143 /* same as TK_TO_INT */
#define OP_ToReal 144 /* same as TK_TO_REAL */
#define OP_Eq 75 /* same as TK_EQ */
#define OP_Ne 74 /* same as TK_NE */
#define OP_Lt 78 /* same as TK_LT */
#define OP_Le 77 /* same as TK_LE */
#define OP_Gt 76 /* same as TK_GT */
#define OP_Ge 79 /* same as TK_GE */
#define OP_Permutation 23
#define OP_Compare 24
#define OP_Jump 25
#define OP_And 68 /* same as TK_AND */
#define OP_Or 67 /* same as TK_OR */
#define OP_Not 19 /* same as TK_NOT */
#define OP_BitNot 92 /* same as TK_BITNOT */
#define OP_Once 26
#define OP_If 27
#define OP_IfNot 28
#define OP_IsNull 72 /* same as TK_ISNULL */
#define OP_NotNull 73 /* same as TK_NOTNULL */
#define OP_Column 29
#define OP_Affinity 30
#define OP_MakeIdxKey 31
#define OP_MakeKey 32
#define OP_MakeRecord 33
#define OP_Count 34
#define OP_Savepoint 35
#define OP_Transaction 36
#define OP_SetCookie 37
#define OP_VerifyCookie 38
#define OP_OpenRead 39
#define OP_OpenWrite 40
#define OP_OpenAutoindex 41
#define OP_OpenEphemeral 42
#define OP_SorterOpen 43
#define OP_OpenPseudo 44
#define OP_Close 45
#define OP_SeekPk 46
#define OP_SeekLt 47
#define OP_SeekLe 48
#define OP_SeekGe 49
#define OP_SeekGt 50
#define OP_Seek 51
#define OP_NotExists 52
#define OP_NotFound 53
#define OP_Found 54
#define OP_IsUnique 55
#define OP_Sequence 56
#define OP_NewRowid 57
#define OP_NewIdxid 58
#define OP_Insert 59
#define OP_InsertInt 60
#define OP_Delete 61
#define OP_ResetCount 62
#define OP_GrpCompare 63
#define OP_SorterData 64
#define OP_RowKey 65
#define OP_RowData 66
#define OP_Rowid 69
#define OP_NullRow 70
#define OP_Last 71
#define OP_SorterSort 80
#define OP_Sort 91
#define OP_Rewind 94
#define OP_SorterNext 95
#define OP_Prev 96
#define OP_Next 97
#define OP_SorterInsert 98
#define OP_IdxInsert 99
#define OP_IdxDelete 100
#define OP_IdxRowid 101
#define OP_IdxLT 102
#define OP_IdxLE 103
#define OP_IdxGE 104
#define OP_IdxGT 105
#define OP_Clear 106
#define OP_ParseSchema 107
#define OP_LoadAnalysis 108
#define OP_DropTable 109
#define OP_DropIndex 110
#define OP_DropTrigger 111
#define OP_RowSetTest 112
#define OP_RowSetAdd 113
#define OP_RowSetRead 114
#define OP_Program 115
#define OP_Param 116
#define OP_FkCounter 117
#define OP_FkIfZero 118
#define OP_MemMax 119
#define OP_IfPos 120
#define OP_IfNeg 121
#define OP_IfZero 122
#define OP_AggStep 123
#define OP_AggFinal 124
#define OP_JournalMode 125
#define OP_Expire 126
#define OP_VBegin 127
#define OP_VCreate 128
#define OP_VDestroy 130
#define OP_VOpen 131
#define OP_VFilter 132
#define OP_VColumn 133
#define OP_VNext 134
#define OP_VRename 135
#define OP_VUpdate 136
#define OP_Trace 137
#define OP_Noop 138
#define OP_Explain 139
/* Properties such as "out2" or "jump" that are specified in
** comments following the "case" for each opcode in the vdbe.c
** are encoded into bitvectors as follows:
*/
#define OPFLG_JUMP 0x0001 /* jump: P2 holds jmp target */
#define OPFLG_OUT2_PRERELEASE 0x0002 /* out2-prerelease: */
#define OPFLG_IN1 0x0004 /* in1: P1 is an input */
#define OPFLG_IN2 0x0008 /* in2: P2 is an input */
#define OPFLG_IN3 0x0010 /* in3: P3 is an input */
#define OPFLG_OUT2 0x0020 /* out2: P2 is an output */
#define OPFLG_OUT3 0x0040 /* out3: P3 is an output */
#define OPFLG_INITIALIZER {\
/* 0 */ 0x00, 0x01, 0x01, 0x04, 0x04, 0x10, 0x00, 0x02,\
/* 8 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x24, 0x24,\
/* 16 */ 0x00, 0x00, 0x00, 0x24, 0x04, 0x05, 0x04, 0x00,\
/* 24 */ 0x00, 0x01, 0x01, 0x05, 0x05, 0x00, 0x00, 0x00,\
/* 32 */ 0x00, 0x00, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00,\
/* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,\
/* 48 */ 0x11, 0x11, 0x11, 0x08, 0x11, 0x11, 0x11, 0x11,\
/* 56 */ 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,\
/* 64 */ 0x00, 0x00, 0x00, 0x4c, 0x4c, 0x02, 0x00, 0x01,\
/* 72 */ 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,\
/* 80 */ 0x01, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,\
/* 88 */ 0x4c, 0x4c, 0x4c, 0x01, 0x24, 0x02, 0x01, 0x01,\
/* 96 */ 0x01, 0x01, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01,\
/* 104 */ 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
/* 112 */ 0x15, 0x14, 0x04, 0x01, 0x02, 0x00, 0x01, 0x08,\
/* 120 */ 0x05, 0x05, 0x05, 0x00, 0x00, 0x02, 0x00, 0x00,\
/* 128 */ 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,\
/* 136 */ 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04,\
/* 144 */ 0x04,}
/************** End of opcodes.h *********************************************/
/************** Continuing where we left off in vdbe.h ***********************/
/*
** Prototypes for the VDBE interface. See comments on the implementation
** for a description of what each of these routines does.
*/
SQLITE_PRIVATE Vdbe *sqlite4VdbeCreate(sqlite4*);
SQLITE_PRIVATE int sqlite4VdbeAddOp0(Vdbe*,int);
SQLITE_PRIVATE int sqlite4VdbeAddOp1(Vdbe*,int,int);
SQLITE_PRIVATE int sqlite4VdbeAddOp2(Vdbe*,int,int,int);
SQLITE_PRIVATE int sqlite4VdbeAddOp3(Vdbe*,int,int,int,int);
SQLITE_PRIVATE int sqlite4VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int);
SQLITE_PRIVATE int sqlite4VdbeAddOp4Int(Vdbe*,int,int,int,int,int);
SQLITE_PRIVATE int sqlite4VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp);
SQLITE_PRIVATE void sqlite4VdbeAddParseSchemaOp(Vdbe*,int,char*);
SQLITE_PRIVATE void sqlite4VdbeChangeP1(Vdbe*, u32 addr, int P1);
SQLITE_PRIVATE void sqlite4VdbeChangeP2(Vdbe*, u32 addr, int P2);
SQLITE_PRIVATE void sqlite4VdbeChangeP3(Vdbe*, u32 addr, int P3);
SQLITE_PRIVATE void sqlite4VdbeChangeP5(Vdbe*, u8 P5);
SQLITE_PRIVATE void sqlite4VdbeJumpHere(Vdbe*, int addr);
SQLITE_PRIVATE void sqlite4VdbeChangeToNoop(Vdbe*, int addr);
SQLITE_PRIVATE void sqlite4VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
SQLITE_PRIVATE void sqlite4VdbeUsesStorage(Vdbe*, int);
SQLITE_PRIVATE VdbeOp *sqlite4VdbeGetOp(Vdbe*, int);
SQLITE_PRIVATE int sqlite4VdbeMakeLabel(Vdbe*);
SQLITE_PRIVATE void sqlite4VdbeRunOnlyOnce(Vdbe*);
SQLITE_PRIVATE void sqlite4VdbeDelete(Vdbe*);
SQLITE_PRIVATE void sqlite4VdbeDeleteObject(sqlite4*,Vdbe*);
SQLITE_PRIVATE void sqlite4VdbeMakeReady(Vdbe*,Parse*);
SQLITE_PRIVATE int sqlite4VdbeFinalize(Vdbe*);
SQLITE_PRIVATE void sqlite4VdbeResolveLabel(Vdbe*, int);
SQLITE_PRIVATE int sqlite4VdbeCurrentAddr(Vdbe*);
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE int sqlite4VdbeAssertMayAbort(Vdbe *, int);
SQLITE_PRIVATE void sqlite4VdbeTrace(Vdbe*,FILE*);
#endif
SQLITE_PRIVATE void sqlite4VdbeResetStepResult(Vdbe*);
SQLITE_PRIVATE void sqlite4VdbeRewind(Vdbe*);
SQLITE_PRIVATE int sqlite4VdbeReset(Vdbe*);
SQLITE_PRIVATE void sqlite4VdbeSetNumCols(Vdbe*,int);
SQLITE_PRIVATE int sqlite4VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*));
SQLITE_PRIVATE void sqlite4VdbeCountChanges(Vdbe*);
SQLITE_PRIVATE sqlite4 *sqlite4VdbeDb(Vdbe*);
SQLITE_PRIVATE void sqlite4VdbeSetSql(Vdbe*, const char *z, int n);
SQLITE_PRIVATE void sqlite4VdbeSwap(Vdbe*,Vdbe*);
SQLITE_PRIVATE VdbeOp *sqlite4VdbeTakeOpArray(Vdbe*, int*, int*);
SQLITE_PRIVATE sqlite4_value *sqlite4VdbeGetValue(Vdbe*, int, u8);
SQLITE_PRIVATE void sqlite4VdbeSetVarmask(Vdbe*, int);
#ifndef SQLITE_OMIT_TRACE
SQLITE_PRIVATE char *sqlite4VdbeExpandSql(Vdbe*, const char*);
#endif
SQLITE_PRIVATE void sqlite4VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
SQLITE_PRIVATE int sqlite4VdbeRecordCompare(int,const void*,UnpackedRecord*);
SQLITE_PRIVATE UnpackedRecord *sqlite4VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **);
#ifndef SQLITE_OMIT_TRIGGER
SQLITE_PRIVATE void sqlite4VdbeLinkSubProgram(Vdbe *, SubProgram *);
#endif
#ifndef NDEBUG
SQLITE_PRIVATE void sqlite4VdbeComment(Vdbe*, const char*, ...);
# define VdbeComment(X) sqlite4VdbeComment X
SQLITE_PRIVATE void sqlite4VdbeNoopComment(Vdbe*, const char*, ...);
# define VdbeNoopComment(X) sqlite4VdbeNoopComment X
#else
# define VdbeComment(X)
# define VdbeNoopComment(X)
#endif
#endif
/************** End of vdbe.h ************************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
/************** Include storage.h in the middle of sqliteInt.h ***************/
/************** Begin file storage.h *****************************************/
/*
** 2012 January 20
**
** 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 header file defines the interface to the KV storage engine(s).
**
** Notes on the storage subsystem interface:
**
** The storage subsystem is a key/value database. All keys and values are
** binary with arbitrary content. Keys are unique. Keys compare in
** memcmp() order. Shorter keys appear first.
**
** The xBegin, xCommit, and xRollback methods change the transaction level
** of the store. The transaction level is a non-negative integer that is
** initialized to zero. The transaction level must be at least 1 in order
** for content to be read. The transaction level must be at least 2 for
** content to be modified.
**
** The xBegin method increases transaction level. The increase may be no
** more than 1 unless the transaction level is initially 0 in which case
** it can be increased immediately to 2. Increasing the transaction level
** to 1 or more makes a "snapshot" of the database file such that changes
** made by other connections are not visible. An xBegin call may fail
** with SQLITE_BUSY if the initial transaction level is 0 or 1.
**
** A read-only database will fail an attempt to increase xBegin above 1. An
** implementation that does not support nested transactions will fail any
** attempt to increase the transaction level above 2.
**
** The xCommitPhaseOne and xCommitPhaseTwo methods implement a 2-phase
** commit that lowers the transaction level to the value given in the
** second argument, making all the changes made at higher transaction levels
** permanent. A rollback is still possible following phase one. If
** possible, errors should be reported during phase one so that a
** multiple-database transaction can still be rolled back if the
** phase one fails on a different database. Implementations that do not
** support two-phase commit can implement xCommitPhaseOne as a no-op function
** returning SQLITE_OK.
**
** The xRollback method lowers the transaction level to the value given in
** its argument and reverts or undoes all changes made at higher transaction
** levels. An xRollback to level N causes the database to revert to the state
** it was in on the most recent xBegin to level N+1.
**
** The xRevert(N) method causes the state of the database file to go back
** to what it was immediately after the most recent xCommit(N). Higher-level
** subtransactions are cancelled. This call is equivalent to xRollback(N-1)
** followed by xBegin(N) but is atomic and might be more efficient.
**
** The xReplace method replaces the value for an existing entry with the
** given key, or creates a new entry with the given key and value if no
** prior entry exists with the given key. The key and value pointers passed
** into xReplace belong to the caller will likely be destroyed when the
** call to xReplace returns so the xReplace routine must make its own
** copy of that information.
**
** A cursor is at all times pointing to ether an entry in the database or
** to EOF. EOF means "no entry". Cursor operations other than xCloseCursor
** will fail if the transaction level is less than 1.
**
** The xSeek method moves a cursor to an entry in the database that matches
** the supplied key as closely as possible. If the dir argument is 0, then
** the match must be exact or else the seek fails and the cursor is left
** pointing to EOF. If dir is negative, then an exact match is
** found if it is available, otherwise the cursor is positioned at the largest
** entry that is less than the search key or to EOF if the store contains no
** entry less than the search key. If dir is positive, then an exist match
** is found if it is available, otherwise the cursor is left pointing the
** the smallest entry that is larger than the search key, or to EOF if there
** are no entries larger than the search key.
**
** The return code from xSeek might be one of the following:
**
** SQLITE_OK The cursor is left pointing to any entry that
** exactly matchings the probe key.
**
** SQLITE_INEXACT The cursor is left pointing to the nearest entry
** to the probe it could find, either before or after
** the probe, according to the dir argument.
**
** SQLITE_NOTFOUND No suitable entry could be found. Either dir==0 and
** there was no exact match, or dir<0 and the probe is
** smaller than every entry in the database, or dir>0 and
** the probe is larger than every entry in the database.
**
** xSeek might also return some error code like SQLITE_IOERR or
** SQLITE_NOMEM.
**
** The xNext method will only be called following an xSeek with a positive dir,
** or another xNext. The xPrev method will only be called following an xSeek
** with a negative dir or another xPrev. Both xNext and xPrev will return
** SQLITE_OK on success and SQLITE_NOTFOUND if they run off the end of the
** database. Both routines might also return error codes such as
** SQLITE_IOERR, SQLITE_CORRUPT, or SQLITE_NOMEM.
**
** Values returned by xKey and xData are guaranteed to remain stable until
** the next xSeek, xNext, xPrev, xReset, xDelete, or xCloseCursor on the same
** cursor. This is true even if the transaction level is reduced to zero,
** or if the content of the entry is changed by xInsert, xDelete on a different
** cursor, or xRollback. The content returned by repeated calls to xKey and
** xData is allowed (but is not required) to change if xInsert, xDelete, or
** xRollback are invoked in between the calls, but the content returned by
** every call must be stable until the cursor moves, or is reset or closed.
** The cursor owns the values returned by xKey and xData and will take
** responsiblity for freeing memory used to hold those values when appropriate.
**
** The xDelete method deletes the entry that the cursor is currently
** pointing at. However, subsequent xNext or xPrev calls behave as if the
** entries is not actually deleted until the cursor moves. In other words
** it is acceptable to xDelete an entry out from under a cursor. Subsequent
** xNext or xPrev calls on that cursor will work the same as if the entry
** had not been deleted. Two cursors can be pointing to the same entry and
** one cursor can xDelete and the other cursor is expected to continue
** functioning normally, including responding correctly to subsequent
** xNext and xPrev calls.
*/
/* Typedefs of datatypes */
typedef struct sqlite4_kvstore KVStore;
typedef struct sqlite4_kv_methods KVStoreMethods;
typedef struct sqlite4_kvcursor KVCursor;
typedef unsigned char KVByteArray;
typedef sqlite4_kvsize KVSize;
SQLITE_PRIVATE int sqlite4KVStoreOpenMem(sqlite4_env*, KVStore**, const char *, unsigned);
SQLITE_PRIVATE int sqlite4KVStoreOpenLsm(sqlite4_env*, KVStore**, const char *, unsigned);
SQLITE_PRIVATE int sqlite4KVStoreOpen(
sqlite4*,
const char *zLabel,
const char *zUri,
KVStore**,
unsigned flags
);
SQLITE_PRIVATE int sqlite4KVStoreReplace(
KVStore*,
const KVByteArray *pKey, KVSize nKey,
const KVByteArray *pData, KVSize nData
);
SQLITE_PRIVATE int sqlite4KVStoreOpenCursor(KVStore *p, KVCursor **ppKVCursor);
SQLITE_PRIVATE int sqlite4KVCursorSeek(
KVCursor *p,
const KVByteArray *pKey, KVSize nKey,
int dir
);
SQLITE_PRIVATE int sqlite4KVCursorNext(KVCursor *p);
SQLITE_PRIVATE int sqlite4KVCursorPrev(KVCursor *p);
SQLITE_PRIVATE int sqlite4KVCursorDelete(KVCursor *p);
SQLITE_PRIVATE int sqlite4KVCursorReset(KVCursor *p);
SQLITE_PRIVATE int sqlite4KVCursorKey(KVCursor *p, const KVByteArray **ppKey, KVSize *pnKey);
SQLITE_PRIVATE int sqlite4KVCursorData(
KVCursor *p,
KVSize ofst,
KVSize n,
const KVByteArray **ppData,
KVSize *pnData
);
SQLITE_PRIVATE int sqlite4KVCursorClose(KVCursor *p);
SQLITE_PRIVATE int sqlite4KVStoreBegin(KVStore *p, int iLevel);
SQLITE_PRIVATE int sqlite4KVStoreCommitPhaseOne(KVStore *p, int iLevel);
SQLITE_PRIVATE int sqlite4KVStoreCommitPhaseTwo(KVStore *p, int iLevel);
SQLITE_PRIVATE int sqlite4KVStoreCommit(KVStore *p, int iLevel);
SQLITE_PRIVATE int sqlite4KVStoreRollback(KVStore *p, int iLevel);
SQLITE_PRIVATE int sqlite4KVStoreRevert(KVStore *p, int iLevel);
SQLITE_PRIVATE int sqlite4KVStoreClose(KVStore *p);
SQLITE_PRIVATE int sqlite4KVStoreGetMeta(KVStore *p, int, int, unsigned int*);
SQLITE_PRIVATE int sqlite4KVStorePutMeta(sqlite4*, KVStore *p, int, int, unsigned int*);
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE void sqlite4KVStoreDump(KVStore *p);
#endif
/************** End of storage.h *********************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
/************** Include os.h in the middle of sqliteInt.h ********************/
/************** Begin file os.h **********************************************/
/*
** 2001 September 16
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
******************************************************************************
**
** This header file (together with is companion C source-code file
** "os.c") attempt to abstract the underlying operating system so that
** the SQLite library will work on both POSIX and windows systems.
**
** This header file is #include-ed by sqliteInt.h and thus ends up
** being included by every source file.
*/
#ifndef _SQLITE_OS_H_
#define _SQLITE_OS_H_
/*
** Figure out if we are dealing with Unix, Windows, or some other
** operating system. After the following block of preprocess macros,
** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, SQLITE_OS_WINRT, and SQLITE_OS_OTHER
** will defined to either 1 or 0. One of the four will be 1. The other
** three will be 0.
*/
#if defined(SQLITE_OS_OTHER)
# if SQLITE_OS_OTHER==1
# undef SQLITE_OS_UNIX
# define SQLITE_OS_UNIX 0
# undef SQLITE_OS_WIN
# define SQLITE_OS_WIN 0
# undef SQLITE_OS_WINRT
# define SQLITE_OS_WINRT 0
# else
# undef SQLITE_OS_OTHER
# endif
#endif
#if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER)
# define SQLITE_OS_OTHER 0
# ifndef SQLITE_OS_WIN
# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) \
|| defined(__MINGW32__) || defined(__BORLANDC__)
# define SQLITE_OS_WIN 1
# define SQLITE_OS_UNIX 0
# define SQLITE_OS_WINRT 0
# else
# define SQLITE_OS_WIN 0
# define SQLITE_OS_UNIX 1
# define SQLITE_OS_WINRT 0
# endif
# else
# define SQLITE_OS_UNIX 0
# define SQLITE_OS_WINRT 0
# endif
#else
# ifndef SQLITE_OS_WIN
# define SQLITE_OS_WIN 0
# endif
#endif
/*
** Define the maximum size of a temporary filename
*/
#if SQLITE_OS_WIN
# include <windows.h>
# define SQLITE_TEMPNAME_SIZE (MAX_PATH+50)
#else
# define SQLITE_TEMPNAME_SIZE 200
#endif
/*
** OS Interface functions.
*/
SQLITE_PRIVATE int sqlite4OsInit(sqlite4_env*);
SQLITE_PRIVATE int sqlite4OsRandomness(sqlite4_env*, int, unsigned char*);
SQLITE_PRIVATE int sqlite4OsCurrentTime(sqlite4_env*, sqlite4_uint64*);
#endif /* _SQLITE_OS_H_ */
/************** End of os.h **************************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
/************** Include mutex.h in the middle of sqliteInt.h *****************/
/************** Begin file mutex.h *******************************************/
/*
** 2007 August 28
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains the common header for all mutex implementations.
** The sqliteInt.h header #includes this file so that it is available
** to all source files. We break it out in an effort to keep the code
** better organized.
**
** NOTE: source files should *not* #include this header file directly.
** Source files should #include the sqliteInt.h file and let that file
** include this one indirectly.
*/
/*
** Figure out what version of the code to use. The choices are
**
** SQLITE_MUTEX_OMIT No mutex logic. Not even stubs. The
** mutexes implemention cannot be overridden
** at start-time.
**
** SQLITE_MUTEX_NOOP For single-threaded applications. No
** mutual exclusion is provided. But this
** implementation can be overridden at
** start-time.
**
** SQLITE_MUTEX_PTHREADS For multi-threaded applications on Unix.
**
** SQLITE_MUTEX_W32 For multi-threaded applications on Win32.
*/
#if !SQLITE_THREADSAFE
# define SQLITE_MUTEX_OMIT
#endif
#if SQLITE_THREADSAFE && !defined(SQLITE_MUTEX_NOOP)
# if SQLITE_OS_UNIX
# define SQLITE_MUTEX_PTHREADS
# elif SQLITE_OS_WIN
# define SQLITE_MUTEX_W32
# else
# define SQLITE_MUTEX_NOOP
# endif
#endif
#ifdef SQLITE_MUTEX_OMIT
/*
** If this is a no-op implementation, implement everything as macros.
*/
#define sqlite4_mutex_alloc(X,Y) ((sqlite4_mutex*)8)
#define sqlite4_mutex_free(X)
#define sqlite4_mutex_enter(X)
#define sqlite4_mutex_try(X) SQLITE_OK
#define sqlite4_mutex_leave(X)
#define sqlite4_mutex_held(X) ((void)(X),1)
#define sqlite4_mutex_notheld(X) ((void)(X),1)
#define sqlite4MutexAlloc(X,Y) ((sqlite4_mutex*)8)
#define sqlite4MutexInit(E) SQLITE_OK
#define sqlite4MutexEnd(E)
#define MUTEX_LOGIC(X)
#else
#define MUTEX_LOGIC(X) X
#endif /* defined(SQLITE_MUTEX_OMIT) */
/************** End of mutex.h ***********************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
/*
** Each database file to be accessed by the system is an instance
** of the following structure. There are normally two of these structures
** in the sqlite.aDb[] array. aDb[0] is the main database file and
** aDb[1] is the database file used to hold temporary tables. Additional
** databases may be attached.
*/
struct Db {
char *zName; /* Name of this database */
KVStore *pKV; /* KV store for the database file */
u8 inTrans; /* 0: not writable. 1: Transaction. 2: Checkpoint */
u8 chngFlag; /* True if modified */
Schema *pSchema; /* Pointer to database schema (possibly shared) */
};
/*
** Each SQL function is defined by an instance of the following
** structure. A pointer to this structure is stored in the sqlite.aFunc
** hash table. When multiple functions have the same name, the hash table
** points to a linked list of these structures.
*/
struct FuncDef {
i16 nArg; /* Number of arguments. -1 means unlimited */
u8 iPrefEnc; /* Preferred text encoding (SQLITE_UTF8, 16LE, 16BE) */
u8 flags; /* Some combination of SQLITE_FUNC_* */
void *pUserData; /* User data parameter */
FuncDef *pSameName; /* Next with a different name but the same hash */
void (*xFunc)(sqlite4_context*,int,sqlite4_value**); /* Regular function */
void (*xStep)(sqlite4_context*,int,sqlite4_value**); /* Aggregate step */
void (*xFinalize)(sqlite4_context*); /* Aggregate finalizer */
char *zName; /* SQL name of the function. */
FuncDef *pNextName; /* Next function with a different name */
FuncDestructor *pDestructor; /* Reference counted destructor function */
};
/*
** A table of SQL functions.
**
** The content is a linked list of FuncDef structures with branches. When
** there are two or more FuncDef objects with the same name, they are
** connected using FuncDef.pSameName. FuncDef objects with different names
** are connected using FuncDef.pNextName.
*/
struct FuncDefTable {
FuncDef *pFirst; /* First function definition */
FuncDef *pLast; /* Last function definition */
FuncDef *pSame; /* Tail of pSameName list for pLast */
};
/*
** An instance of the following structure stores a database schema.
**
** Most Schema objects are associated with a database file. The exception is
** the Schema for the TEMP databaes (sqlite4.aDb[1]) which is free-standing.
**
** Schema objects are automatically deallocated when the last database that
** references them is destroyed. The TEMP Schema is manually freed by
** sqlite4_close().
*
** A thread must be holding a mutex on the corresponding database in order
** to access Schema content. This implies that the thread must also be
** holding a mutex on the sqlite4 connection pointer that owns the database
** For a TEMP Schema, only the connection mutex is required.
*/
struct Schema {
int schema_cookie; /* Database schema version number for this file */
int iGeneration; /* Generation counter. Incremented with each change */
Hash tblHash; /* All tables indexed by name */
Hash idxHash; /* All (named) indices indexed by name */
Hash trigHash; /* All triggers indexed by name */
Hash fkeyHash; /* All foreign keys by referenced table name */
Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */
u8 file_format; /* Schema format version for this file */
u8 enc; /* Text encoding used by this database */
u16 flags; /* Flags associated with this schema */
int cache_size; /* Number of pages to use in the cache */
};
/*
** 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->flags&(P))==(P))
#define DbHasAnyProperty(D,I,P) (((D)->aDb[I].pSchema->flags&(P))!=0)
#define DbSetProperty(D,I,P) (D)->aDb[I].pSchema->flags|=(P)
#define DbClearProperty(D,I,P) (D)->aDb[I].pSchema->flags&=~(P)
/*
** Allowed values for the DB.pSchema->flags field.
**
** The DB_SchemaLoaded flag is set after the database schema has been
** read into internal hash tables.
**
** DB_UnresetViews means that one or more views have column names that
** have been filled out. If the schema changes, these column names might
** changes and so the view will need to be reset.
*/
#define DB_SchemaLoaded 0x0001 /* The schema has been loaded */
#define DB_UnresetViews 0x0002 /* Some views have defined column names */
#define DB_Empty 0x0004 /* The file is empty (length 0 bytes) */
/*
** The number of different kinds of things that can be limited
** using the sqlite4_limit() interface.
*/
#define SQLITE_N_LIMIT (SQLITE_LIMIT_TRIGGER_DEPTH+1)
/*
** Lookaside malloc is a set of fixed-size buffers that can be used
** to satisfy small transient memory allocation requests for objects
** associated with a particular database connection. The use of
** lookaside malloc provides a significant performance enhancement
** (approx 10%) by avoiding numerous malloc/free requests while parsing
** SQL statements.
**
** The Lookaside structure holds configuration information about the
** lookaside malloc subsystem. Each available memory allocation in
** the lookaside subsystem is stored on a linked list of LookasideSlot
** objects.
**
** Lookaside allocations are only allowed for objects that are associated
** with a particular database connection. Hence, schema information cannot
** be stored in lookaside because in shared cache mode the schema information
** is shared by multiple database connections. Therefore, while parsing
** schema information, the Lookaside.bEnabled flag is cleared so that
** lookaside allocations are not used to construct the schema objects.
*/
struct Lookaside {
u16 sz; /* Size of each buffer in bytes */
u8 bEnabled; /* False to disable new lookaside allocations */
u8 bMalloced; /* True if pStart obtained from sqlite4_malloc() */
int nOut; /* Number of buffers currently checked out */
int mxOut; /* Highwater mark for nOut */
int anStat[3]; /* 0: hits. 1: size misses. 2: full misses */
LookasideSlot *pFree; /* List of available buffers */
void *pStart; /* First byte of available memory space */
void *pEnd; /* First byte past end of available space */
};
struct LookasideSlot {
LookasideSlot *pNext; /* Next buffer in the list of free buffers */
};
/*
** Each database connection is an instance of the following structure.
**
** The sqlite.lastRowid records the last insert rowid generated by an
** insert statement. Inserts on views do not affect its value. Each
** trigger has its own context, so that lastRowid can be updated inside
** triggers as usual. The previous value will be restored once the trigger
** exits. Upon entering a before or instead of trigger, lastRowid is no
** longer (since after version 2.8.12) reset to -1.
**
** The sqlite.nChange does not count changes within triggers and keeps no
** context. It is reset at start of sqlite4_exec.
** The sqlite.lsChange represents the number of changes made by the last
** insert, update, or delete statement. It remains constant throughout the
** length of a statement and is then updated by OP_SetCounts. It keeps a
** context stack just like lastRowid so that the count of changes
** within a trigger is not seen outside the trigger. Changes to views do not
** affect the value of lsChange.
** The sqlite.csChange keeps track of the number of current changes (since
** the last statement) and is used to update sqlite_lsChange.
**
** The member variables sqlite.errCode, sqlite.zErrMsg and sqlite.zErrMsg16
** store the most recent error code and, if applicable, string. The
** internal function sqlite4Error() is used to set these variables
** consistently.
*/
struct sqlite4 {
sqlite4_env *pEnv; /* The run-time environment */
int nDb; /* Number of backends currently in use */
Db *aDb; /* All backends */
int flags; /* Miscellaneous flags. See below */
unsigned int openFlags; /* Flags passed to sqlite4_vfs.xOpen() */
int errCode; /* Most recent error code (SQLITE_*) */
u8 temp_store; /* 1: file 2: memory 0: default */
u8 mallocFailed; /* True if we have seen a malloc failure */
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() */
int nextPagesize; /* Pagesize after VACUUM if >0 */
int nTable; /* Number of tables in the database */
CollSeq *pDfltColl; /* The default collating sequence (BINARY) */
i64 lastRowid; /* ROWID of most recent insert (see above) */
u32 magic; /* Magic number for detect library misuse */
int nChange; /* Value returned by sqlite4_changes() */
int nTotalChange; /* Value returned by sqlite4_total_changes() */
sqlite4_mutex *mutex; /* Connection mutex */
int aLimit[SQLITE_N_LIMIT]; /* Limits */
struct sqlite4InitInfo { /* Information used during initialization */
int iDb; /* When back is being initialized */
int newTnum; /* Rootpage of table being initialized */
u8 busy; /* TRUE if currently initializing */
u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */
} init;
int nExtension; /* Number of loaded extensions */
void **aExtension; /* Array of shared library handles */
struct Vdbe *pVdbe; /* List of active virtual machines */
int activeVdbeCnt; /* Number of VDBEs currently executing */
int writeVdbeCnt; /* Number of active VDBEs that are writing */
int vdbeExecCnt; /* Number of nested calls to VdbeExec() */
void (*xTrace)(void*,const char*); /* Trace function */
void *pTraceArg; /* Argument to the trace function */
void (*xProfile)(void*,const char*,u64); /* Profiling function */
void *pProfileArg; /* Argument to profile function */
#ifndef SQLITE_OMIT_WAL
int (*xWalCallback)(void *, sqlite4 *, const char *, int);
void *pWalArg;
#endif
void(*xCollNeeded)(void*,sqlite4*,int eTextRep,const char*);
void(*xCollNeeded16)(void*,sqlite4*,int eTextRep,const void*);
void *pCollNeededArg;
sqlite4_value *pErr; /* Most recent error message */
char *zErrMsg; /* Most recent error message (UTF-8 encoded) */
char *zErrMsg16; /* Most recent error message (UTF-16 encoded) */
union {
volatile int isInterrupted; /* True if sqlite4_interrupt has been called */
double notUsed1; /* Spacer */
} u1;
Lookaside lookaside; /* Lookaside malloc configuration */
#ifndef SQLITE_OMIT_AUTHORIZATION
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
/* Access authorization function */
void *pAuthArg; /* 1st argument to the access auth function */
#endif
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
int (*xProgress)(void *); /* The progress callback */
void *pProgressArg; /* Argument to the progress callback */
int nProgressOps; /* Number of opcodes for progress callback */
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
Hash aModule; /* populated by sqlite4_create_module() */
VtabCtx *pVtabCtx; /* Context for active vtab connect/create */
VTable **aVTrans; /* Virtual tables with open transactions */
int nVTrans; /* Allocated size of aVTrans */
VTable *pDisconnect; /* Disconnect these in next sqlite4_prepare() */
#endif
FuncDefTable aFunc; /* Hash table of connection functions */
Hash aCollSeq; /* All collating sequences */
Db aDbStatic[2]; /* Static space for the 2 default backends */
Savepoint *pSavepoint; /* List of active savepoints */
int nSavepoint; /* Number of open savepoints */
int nStatement; /* Number of nested statement-transactions */
i64 nDeferredCons; /* Net deferred constraints this transaction. */
int *pnBytesFreed; /* If not NULL, increment this in DbFree() */
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
/* The following variables are all protected by the STATIC_MASTER
** mutex, not by sqlite4.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.
**
** When X.pBlockingConnection==Y, that means that something that X tried
** tried to do recently failed with an SQLITE_LOCKED error due to locks
** held by Y.
*/
sqlite4 *pBlockingConnection; /* Connection that caused SQLITE_LOCKED */
sqlite4 *pUnlockConnection; /* Connection to watch for unlock */
void *pUnlockArg; /* Argument to xUnlockNotify */
void (*xUnlockNotify)(void **, int); /* Unlock notify callback */
sqlite4 *pNextBlocked; /* Next in list of all blocked connections */
#endif
};
/*
** A macro to discover the encoding of a database.
*/
#define ENC(db) ((db)->aDb[0].pSchema->enc)
/*
** Possible values for the sqlite4.flags.
*/
#define SQLITE_VdbeTrace 0x00000100 /* True to trace VDBE execution */
#define SQLITE_InternChanges 0x00000200 /* Uncommitted Hash table changes */
#define SQLITE_CountRows 0x00001000 /* Count rows changed by INSERT, */
/* DELETE, or UPDATE and return */
/* the count using a callback. */
#define SQLITE_SqlTrace 0x00004000 /* Debug print SQL as it executes */
#define SQLITE_VdbeListing 0x00008000 /* Debug listings of VDBE programs */
#define SQLITE_WriteSchema 0x00010000 /* OK to update SQLITE_MASTER */
#define SQLITE_KvTrace 0x00020000 /* Trace Key/value storage calls */
#define SQLITE_IgnoreChecks 0x00040000 /* Do not enforce check constraints */
#define SQLITE_ReadUncommitted 0x0080000 /* For shared-cache mode */
#define SQLITE_LegacyFileFmt 0x00100000 /* Create new databases in format 1 */
#define SQLITE_RecoveryMode 0x00800000 /* Ignore schema errors */
#define SQLITE_ReverseOrder 0x01000000 /* Reverse unordered SELECTs */
#define SQLITE_RecTriggers 0x02000000 /* Enable recursive triggers */
#define SQLITE_ForeignKeys 0x04000000 /* Enforce foreign key constraints */
#define SQLITE_AutoIndex 0x08000000 /* Enable automatic indexes */
#define SQLITE_PreferBuiltin 0x10000000 /* Preference to built-in funcs */
#define SQLITE_EnableTrigger 0x40000000 /* True to enable triggers */
/*
** Bits of the sqlite4.flags field that are used by the
** sqlite4_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface.
** These must be the low-order bits of the flags field.
*/
#define SQLITE_QueryFlattener 0x01 /* Disable query flattening */
#define SQLITE_ColumnCache 0x02 /* Disable the column cache */
#define SQLITE_IndexSort 0x04 /* Disable indexes for sorting */
#define SQLITE_IndexSearch 0x08 /* Disable indexes for searching */
#define SQLITE_IndexCover 0x10 /* Disable index covering table */
#define SQLITE_GroupByOrder 0x20 /* Disable GROUPBY cover of ORDERBY */
#define SQLITE_FactorOutConst 0x40 /* Disable factoring out constants */
#define SQLITE_IdxRealAsInt 0x80 /* Store REAL as INT in indices */
#define SQLITE_DistinctOpt 0x80 /* DISTINCT using indexes */
#define SQLITE_OptMask 0xff /* Mask of all disablable opts */
/*
** Possible values for the sqlite.magic field.
** The numbers are obtained at random and have no special meaning, other
** than being distinct from one another.
*/
#define SQLITE_MAGIC_OPEN 0xa029a697 /* Database is open */
#define SQLITE_MAGIC_CLOSED 0x9f3c2d33 /* Database is closed */
#define SQLITE_MAGIC_SICK 0x4b771290 /* Error and awaiting close */
#define SQLITE_MAGIC_BUSY 0xf03b7906 /* Database currently in use */
#define SQLITE_MAGIC_ERROR 0xb5357930 /* An SQLITE_MISUSE error occurred */
/*
** 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
** 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
** FuncDestructor.
**
** Thereafter, when one of the FuncDef objects is deleted, the reference
** count on this object is decremented. When it reaches 0, the destructor
** is invoked and the FuncDestructor structure freed.
*/
struct FuncDestructor {
int nRef;
void (*xDestroy)(void *);
void *pUserData;
};
/*
** Possible values for FuncDef.flags
*/
#define SQLITE_FUNC_LIKE 0x01 /* Candidate for the LIKE optimization */
#define SQLITE_FUNC_CASE 0x02 /* Case-sensitive LIKE-type function */
#define SQLITE_FUNC_EPHEM 0x04 /* Ephemeral. Delete with VDBE */
#define SQLITE_FUNC_NEEDCOLL 0x08 /* sqlite4GetFuncCollSeq() might be called */
#define SQLITE_FUNC_PRIVATE 0x10 /* Allowed for internal use only */
#define SQLITE_FUNC_COUNT 0x20 /* Built-in count(*) aggregate */
#define SQLITE_FUNC_COALESCE 0x40 /* Built-in coalesce() or ifnull() function */
/*
** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
** 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
** 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 (sqlite4_user_data()) for the function. If
** argument bNC is true, then the SQLITE_FUNC_NEEDCOLL flag is set.
**
** 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
** are interpreted in the same way as the first 4 parameters to
** 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
** function likeFunc. Argument pArg is cast to a (void *) and made
** available as the function user-data (sqlite4_user_data()). The
** FuncDef.flags variable is set to the value passed as the flags
** parameter.
*/
#define FUNCTION(zName, nArg, iArg, bNC, xFunc) \
{nArg, SQLITE_UTF8, bNC*SQLITE_FUNC_NEEDCOLL, \
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0}
#define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \
{nArg, SQLITE_UTF8, bNC*SQLITE_FUNC_NEEDCOLL, \
pArg, 0, xFunc, 0, 0, #zName, 0, 0}
#define LIKEFUNC(zName, nArg, arg, flags) \
{nArg, SQLITE_UTF8, flags, (void *)arg, 0, likeFunc, 0, 0, #zName, 0, 0}
#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \
{nArg, SQLITE_UTF8, nc*SQLITE_FUNC_NEEDCOLL, \
SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0}
/*
** All current savepoints are stored in a linked list starting at
** sqlite4.pSavepoint. The first element in the list is the most recently
** opened savepoint. Savepoints are added to the list by the vdbe
** OP_Savepoint instruction.
*/
struct Savepoint {
char *zName; /* Savepoint name (nul-terminated) */
i64 nDeferredCons; /* Number of deferred fk violations */
Savepoint *pNext; /* Parent savepoint (if any) */
};
/*
** The following are used as the second parameter to sqlite4Savepoint(),
** and as the P1 argument to the OP_Savepoint instruction.
*/
#define SAVEPOINT_BEGIN 0
#define SAVEPOINT_RELEASE 1
#define SAVEPOINT_ROLLBACK 2
/*
** Each SQLite module (virtual table definition) is defined by an
** instance of the following structure, stored in the sqlite4.aModule
** hash table.
*/
struct Module {
const sqlite4_module *pModule; /* Callback pointers */
const char *zName; /* Name passed to create_module() */
void *pAux; /* pAux passed to create_module() */
void (*xDestroy)(void *); /* Module destructor function */
};
/*
** information about each column of an SQL table is held in an instance
** of this structure.
*/
struct Column {
char *zName; /* Name of this column */
Expr *pDflt; /* Default value of this column */
char *zDflt; /* Original text of the default value */
char *zType; /* Data type for this column */
char *zColl; /* Collating sequence. If NULL, use the default */
u8 notNull; /* True if there is a NOT NULL constraint */
u8 isPrimKey; /* True if this column is part of the PRIMARY KEY */
char affinity; /* One of the SQLITE_AFF_... values */
#ifndef SQLITE_OMIT_VIRTUALTABLE
u8 isHidden; /* True if this column is 'hidden' */
#endif
};
/*
** A "Collating Sequence" is defined by an instance of the following
** structure. Conceptually, a collating sequence consists of a name and
** a comparison routine that defines the order of that sequence.
**
** There may two separate implementations of the collation function, one
** that processes text in UTF-8 encoding (CollSeq.xCmp) and another that
** processes text encoded in UTF-16 (CollSeq.xCmp16), using the machine
** native byte order. When a collation sequence is invoked, SQLite selects
** the version that will require the least expensive encoding
** translations, if any.
**
** The CollSeq.pUser member variable is an extra parameter that passed in
** as the first argument to the UTF-8 comparison function, xCmp.
** CollSeq.pUser16 is the equivalent for the UTF-16 comparison function,
** xCmp16.
**
** If both CollSeq.xCmp and CollSeq.xCmp16 are NULL, it means that the
** collating sequence is undefined. Indices built on an undefined
** collating sequence may not be read or written.
*/
struct CollSeq {
char *zName; /* Name of the collating sequence, UTF-8 encoded */
u8 enc; /* Text encoding handled by xCmp() */
void *pUser; /* First argument to xCmp() */
int (*xCmp)(void*,int, const void*, int, const void*);
int (*xMkKey)(void*,int, const void*, int, void*);
void (*xDel)(void*); /* Destructor for pUser */
};
/*
** A sort order can be either ASC or DESC.
*/
#define SQLITE_SO_ASC 0 /* Sort in ascending order */
#define SQLITE_SO_DESC 1 /* Sort in ascending order */
/*
** 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.
**
** But rather than start with 0 or 1, we begin with 'a'. That way,
** when multiple affinity types are concatenated into a string and
** used as the P4 operand, they will be more readable.
**
** Note also that the numeric types are grouped together so that testing
** for a numeric type is a single comparison.
*/
#define SQLITE_AFF_TEXT 'a'
#define SQLITE_AFF_NONE 'b'
#define SQLITE_AFF_NUMERIC 'c'
#define SQLITE_AFF_INTEGER 'd'
#define SQLITE_AFF_REAL 'e'
#define sqlite4IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC)
/*
** The SQLITE_AFF_MASK values masks off the significant bits of an
** affinity value.
*/
#define SQLITE_AFF_MASK 0x67
/*
** Additional bit values that can be ORed with an affinity without
** changing the affinity.
*/
#define SQLITE_JUMPIFNULL 0x08 /* jumps if either operand is NULL */
#define SQLITE_STOREP2 0x10 /* Store result in reg[P2] rather than jump */
#define SQLITE_NULLEQ 0x80 /* NULL=NULL */
/*
** An object of this type is created for each virtual table present in
** the database schema.
**
** If the database schema is shared, then there is one instance of this
** structure for each database connection (sqlite4*) that uses the shared
** schema. This is because each database connection requires its own unique
** instance of the sqlite4_vtab* handle used to access the virtual table
** implementation. sqlite4_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
** connection as that used to execute SQL operations on the virtual table.
**
** All VTable objects that correspond to a single table in a shared
** database schema are initially stored in a linked-list pointed to by
** the Table.pVTable member variable of the corresponding Table object.
** When an sqlite4_prepare() operation is required to access the virtual
** table, it searches the list for the VTable that corresponds to the
** database connection doing the preparing so as to use the correct
** sqlite4_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 sqlite4_vtab* handles are not xDisconnect()ed
** immediately. Instead, they are moved from the Table.pVTable list to
** another linked list headed by the sqlite4.pDisconnect member of the
** corresponding sqlite4 structure. They are then deleted/xDisconnected
** next time a statement is prepared using said sqlite4*. This is done
** to avoid deadlock issues involving multiple sqlite4.mutex mutexes.
** Refer to comments above function sqlite4VtabUnlockList() for an
** explanation as to why it is safe to add an entry to an sqlite4.pDisconnect
** list without holding the corresponding sqlite4.mutex mutex.
**
** The memory for objects of this type is always allocated by
** sqlite4DbMalloc(), using the connection handle stored in VTable.db as
** the first argument.
*/
struct VTable {
sqlite4 *db; /* Database connection associated with this table */
Module *pMod; /* Pointer to module implementation */
sqlite4_vtab *pVtab; /* Pointer to vtab instance */
int nRef; /* Number of pointers to this structure */
u8 bConstraint; /* True if constraints are supported */
int iSavepoint; /* Depth of the SAVEPOINT stack */
VTable *pNext; /* Next in linked list (see above) */
};
/*
** Each SQL table is represented in memory by an instance of the
** following structure.
**
** Table.zName is the name of the table. The case of the original
** CREATE TABLE statement is stored, but case is not significant for
** comparisons.
**
** Table.nCol is the number of columns in this table. Table.aCol is a
** pointer to an array of Column structures, one for each column.
**
** If the table has an INTEGER PRIMARY KEY, then Table.iPKey is the index of
** the column that is that key. Otherwise Table.iPKey is negative. Note
** that the datatype of the PRIMARY KEY must be INTEGER for this field to
** be set. An INTEGER PRIMARY KEY is used as the rowid for each row of
** the table. If a table has no INTEGER PRIMARY KEY, then a random rowid
** is generated for each row of the table. TF_HasPrimaryKey is set if
** the table has any PRIMARY KEY, INTEGER or otherwise.
**
** Table.tnum is the page number for the root BTree page of the table in the
** database file. If Table.iDb is the index of the database table backend
** in sqlite.aDb[]. 0 is for the main database and 1 is for the file that
** holds temporary tables and indices. If TF_Ephemeral is set
** then the table is stored in a file that is automatically deleted
** when the VDBE cursor to the table is closed. In this case Table.tnum
** refers VDBE cursor number that holds the table open, not to the root
** page number. Transient tables are used to hold the results of a
** sub-query that appears instead of a real table name in the FROM clause
** of a SELECT statement.
*/
struct Table {
char *zName; /* Name of the table or view */
int nCol; /* Number of columns in this table */
Column *aCol; /* Information about each column */
Index *pIndex; /* List of SQL indexes on this table. */
tRowcnt nRowEst; /* Estimated rows in table - from sqlite_stat1 table */
Select *pSelect; /* NULL for tables. Points to definition if a view. */
u16 nRef; /* Number of pointers to this Table */
u8 tabFlags; /* Mask of TF_* values */
FKey *pFKey; /* Linked list of all foreign keys in this table */
char *zColAff; /* String defining the affinity of each column */
#ifndef SQLITE_OMIT_CHECK
Expr *pCheck; /* The AND of all CHECK constraints */
#endif
#ifndef SQLITE_OMIT_ALTERTABLE
int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
VTable *pVTable; /* List of VTable objects. */
int nModuleArg; /* Number of arguments to the module */
char **azModuleArg; /* Text of all module args. [0] is module name */
#endif
Trigger *pTrigger; /* List of triggers stored in pSchema */
Schema *pSchema; /* Schema that contains this table */
Table *pNextZombie; /* Next on the Parse.pZombieTab list */
};
/*
** Allowed values for Tabe.tabFlags.
*/
#define TF_Readonly 0x01 /* Read-only system table */
#define TF_Ephemeral 0x02 /* An ephemeral table */
#define TF_HasPrimaryKey 0x04 /* Table has a primary key */
#define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */
#define TF_Virtual 0x10 /* Is a virtual table */
#define TF_NeedMetadata 0x20 /* aCol[].zType and aCol[].pColl missing */
/*
** Test to see whether or not a table is a virtual table. This is
** done as a macro so that it will be optimized out when virtual
** table support is omitted from the build.
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
# define IsVirtual(X) (((X)->tabFlags & TF_Virtual)!=0)
# define IsHiddenColumn(X) ((X)->isHidden)
#else
# define IsVirtual(X) 0
# define IsHiddenColumn(X) 0
#endif
/* Test to see if a table is actually a view. */
#ifndef SQLITE_OMIT_VIEW
# define IsView(X) ((X)->pSelect!=0)
#else
# define IsView(X) 0
#endif
/*
** Each foreign key constraint is an instance of the following structure.
**
** A foreign key is associated with two tables. The "from" table is
** the table that contains the REFERENCES clause that creates the foreign
** key. The "to" table is the table that is named in the REFERENCES clause.
** Consider this example:
**
** CREATE TABLE ex1(
** a INTEGER PRIMARY KEY,
** b INTEGER CONSTRAINT fk1 REFERENCES ex2(x)
** );
**
** For foreign key "fk1", the from-table is "ex1" and the to-table is "ex2".
**
** Each REFERENCES clause generates an instance of the following structure
** which is attached to the from-table. The to-table need not exist when
** the from-table is created. The existence of the to-table is not checked.
*/
struct FKey {
Table *pFrom; /* Table containing the REFERENCES clause (aka: Child) */
FKey *pNextFrom; /* Next foreign key in pFrom */
char *zTo; /* Name of table that the key points to (aka: Parent) */
FKey *pNextTo; /* Next foreign key on table named zTo */
FKey *pPrevTo; /* Previous foreign key on table named zTo */
int nCol; /* Number of columns in this key */
/* EV: R-30323-21917 */
u8 isDeferred; /* True if constraint checking is deferred till COMMIT */
u8 aAction[2]; /* ON DELETE and ON UPDATE actions, respectively */
Trigger *apTrigger[2]; /* Triggers for aAction[] actions */
struct sColMap { /* Mapping of columns in pFrom to columns in zTo */
int iFrom; /* Index of column in pFrom */
char *zCol; /* Name of column in zTo. If 0 use PRIMARY KEY */
} aCol[1]; /* One entry for each of nCol column s */
};
/*
** SQLite supports many different ways to resolve a constraint
** error. ROLLBACK processing means that a constraint violation
** causes the operation in process to fail and for the current transaction
** to be rolled back. ABORT processing means the operation in process
** fails and any prior changes from that one operation are backed out,
** but the transaction is not rolled back. FAIL processing means that
** the operation in progress stops and returns an error code. But prior
** changes due to the same operation are not backed out and no rollback
** occurs. IGNORE means that the particular row that caused the constraint
** error is not inserted or updated. Processing continues and no error
** is returned. REPLACE means that preexisting database rows that caused
** a UNIQUE constraint violation are removed so that the new insert or
** update can proceed. Processing continues and no error is reported.
**
** RESTRICT, SETNULL, and CASCADE actions apply only to foreign keys.
** RESTRICT is the same as ABORT for IMMEDIATE foreign keys and the
** same as ROLLBACK for DEFERRED keys. SETNULL means that the foreign
** key is set to NULL. CASCADE means that a DELETE or UPDATE of the
** referenced table row is propagated into the row that holds the
** foreign key.
**
** The following symbolic values are used to record which type
** of action to take.
*/
#define OE_None 0 /* There is no constraint to check */
#define OE_Rollback 1 /* Fail the operation and rollback the transaction */
#define OE_Abort 2 /* Back out changes but do no rollback transaction */
#define OE_Fail 3 /* Stop the operation but leave all prior changes */
#define OE_Ignore 4 /* Ignore the error. Do not do the INSERT or UPDATE */
#define OE_Replace 5 /* Delete existing record, then do INSERT or UPDATE */
#define OE_Restrict 6 /* OE_Abort for IMMEDIATE, OE_Rollback for DEFERRED */
#define OE_SetNull 7 /* Set the foreign key value to NULL */
#define OE_SetDflt 8 /* Set the foreign key value to its default */
#define OE_Cascade 9 /* Cascade the changes */
#define OE_Default 99 /* Do whatever the default action is */
/*
** An instance of the following structure describes an index key. It
** includes information such as sort order and collating sequence for
** each key, and the number of primary key fields appended to the end.
*/
struct KeyInfo {
sqlite4 *db; /* The database connection */
u8 enc; /* Text encoding - one of the SQLITE_UTF* values */
u16 nField; /* Total number of entries in aColl[] */
u16 nPK; /* Number of primary key entries at the end of aColl[] */
u16 nData; /* Number of columns of data in KV entry value */
u8 *aSortOrder; /* Sort order for each column. May be NULL */
CollSeq *aColl[1]; /* Collating sequence for each term of the key */
};
/*
** An instance of the following structure holds information about a
** single index record that has already been parsed out into individual
** values.
**
** A record is an object that contains one or more fields of data.
** Records are used to store the content of a table row and to store
** the key of an index. A blob encoding of a record is created by
** the OP_MakeRecord opcode of the VDBE and is disassembled by the
** OP_Column opcode.
**
** This structure holds a record that has already been disassembled
** into its constituent fields.
*/
struct UnpackedRecord {
KeyInfo *pKeyInfo; /* Collation and sort-order information */
u16 nField; /* Number of entries in apMem[] */
u8 flags; /* Boolean settings. UNPACKED_... below */
i64 rowid; /* Used by UNPACKED_PREFIX_SEARCH */
Mem *aMem; /* Values */
};
/*
** Allowed values of UnpackedRecord.flags
*/
#define UNPACKED_INCRKEY 0x01 /* Make this key an epsilon larger */
#define UNPACKED_PREFIX_MATCH 0x02 /* A prefix match is considered OK */
#define UNPACKED_PREFIX_SEARCH 0x04 /* Ignore final (rowid) field */
/*
** Each SQL index is represented in memory by an
** instance of the following structure.
**
** The columns of the table that are to be indexed are described
** by the aiColumn[] field of this structure. For example, suppose
** we have the following table and index:
**
** CREATE TABLE Ex1(c1 int, c2 int, c3 text);
** CREATE INDEX Ex2 ON Ex1(c3,c1);
**
** 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
** 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.
**
** 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
** algorithm to employ whenever an attempt is made to insert a non-unique
** element.
*/
struct Index {
char *zName; /* Name of this index */
int nColumn; /* Number of columns in the table used by this index */
int *aiColumn; /* Which columns are used by this index. 1st is 0 */
tRowcnt *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */
Table *pTable; /* The SQL table being indexed */
int tnum; /* Page containing root of this index in database file */
u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
u8 eIndexType; /* SQLITE_INDEX_USER, UNIQUE or PRIMARYKEY */
u8 bUnordered; /* Use this index for == or IN queries only */
char *zColAff; /* String defining the affinity of each column */
Index *pNext; /* The next index associated with the same table */
Schema *pSchema; /* Schema containing this index */
u8 *aSortOrder; /* Array of size Index.nColumn. True==DESC, False==ASC */
char **azColl; /* Array of collation sequence names for index */
#ifdef SQLITE_ENABLE_STAT3
int nSample; /* Number of elements in aSample[] */
tRowcnt avgEq; /* Average nEq value for key values not in aSample */
IndexSample *aSample; /* Samples of the left-most key */
#endif
};
/* Index.eIndexType must be set to one of the following. */
#define SQLITE_INDEX_USER 0 /* Index created by CREATE INDEX statement */
#define SQLITE_INDEX_UNIQUE 1 /* Index created by UNIQUE constraint */
#define SQLITE_INDEX_PRIMARYKEY 2 /* Index is the tables PRIMARY KEY */
#define SQLITE_INDEX_TEMP 3 /* Index is an automatic index */
/*
** Each sample stored in the sqlite_stat3 table is represented in memory
** using a structure of this type. See documentation at the top of the
** analyze.c source file for additional information.
*/
struct IndexSample {
union {
char *z; /* Value if eType is SQLITE_TEXT or SQLITE_BLOB */
double r; /* Value if eType is SQLITE_FLOAT */
i64 i; /* Value if eType is SQLITE_INTEGER */
} u;
u8 eType; /* SQLITE_NULL, SQLITE_INTEGER ... etc. */
int nByte; /* Size in byte of text or blob. */
tRowcnt nEq; /* Est. number of rows where the key equals this sample */
tRowcnt nLt; /* Est. number of rows where key is less than this sample */
tRowcnt nDLt; /* Est. number of distinct keys less than this sample */
};
/*
** Each token coming out of the lexer is an instance of
** this structure. Tokens are also used as part of an expression.
**
** Note if Token.z==0 then Token.dyn and Token.n are undefined and
** may contain random values. Do not make any assumptions about Token.dyn
** and Token.n when Token.z==0.
*/
struct Token {
const char *z; /* Text of the token. Not NULL-terminated! */
unsigned int n; /* Number of characters in this token */
};
/*
** An instance of this structure contains information needed to generate
** code for a SELECT that contains aggregate functions.
**
** If Expr.op==TK_AGG_COLUMN or TK_AGG_FUNCTION then Expr.pAggInfo is a
** pointer to this structure. The Expr.iColumn field is the index in
** AggInfo.aCol[] or AggInfo.aFunc[] of information needed to generate
** code for that node.
**
** AggInfo.pGroupBy and AggInfo.aFunc.pExpr point to fields within the
** original Select structure that describes the SELECT statement. These
** fields do not need to be freed when deallocating the AggInfo structure.
*/
struct AggInfo {
u8 directMode; /* Direct rendering mode means take data directly
** from source tables rather than from accumulators */
u8 useSortingIdx; /* In direct mode, reference the sorting index rather
** than the source table */
int sortingIdx; /* Cursor number of the sorting index */
ExprList *pGroupBy; /* The group by clause */
int nSortingColumn; /* Number of columns in the sorting index */
struct AggInfo_col { /* For each column used in source tables */
Table *pTab; /* Source table */
int iTable; /* Cursor number of the source table */
int iColumn; /* Column number within the source table */
int iSorterColumn; /* Column number in the sorting index */
int iMem; /* Memory location that acts as accumulator */
Expr *pExpr; /* The original expression */
} *aCol;
int nColumn; /* Number of used entries in aCol[] */
int nColumnAlloc; /* Number of slots allocated for aCol[] */
int nAccumulator; /* Number of columns that show through to the output.
** Additional columns are used only as parameters to
** aggregate functions */
struct AggInfo_func { /* For each aggregate function */
Expr *pExpr; /* Expression encoding the function */
FuncDef *pFunc; /* The aggregate function implementation */
int iMem; /* Memory location that acts as accumulator */
int iDistinct; /* Ephemeral table used to enforce DISTINCT */
} *aFunc;
int nFunc; /* Number of entries in aFunc[] */
int nFuncAlloc; /* Number of slots allocated for aFunc[] */
};
/*
** The datatype ynVar is a signed integer, either 16-bit or 32-bit.
** Usually it is 16-bits. But if SQLITE_MAX_VARIABLE_NUMBER is greater
** than 32767 we have to make it 32-bit. 16-bit is preferred because
** it uses less memory in the Expr object, which is a big memory user
** in systems with lots of prepared statements. And few applications
** need more than about 10 or 20 variables. But some extreme users want
** to have prepared statements with over 32767 variables, and for them
** the option is available (at compile-time).
*/
#if SQLITE_MAX_VARIABLE_NUMBER<=32767
typedef i16 ynVar;
#else
typedef int ynVar;
#endif
/*
** Each node of an expression in the parse tree is an instance
** of this structure.
**
** Expr.op is the opcode. The integer parser token codes are reused
** as opcodes here. For example, the parser defines TK_GE to be an integer
** code representing the ">=" operator. This same integer code is reused
** 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,
** or TK_STRING), then Expr.token contains the text of the SQL literal. If
** the expression is a variable (TK_VARIABLE), then Expr.token contains the
** variable name. Finally, if the expression is an SQL function (TK_FUNCTION),
** then Expr.token contains the name of the function.
**
** Expr.pRight and Expr.pLeft are the left and right subexpressions of a
** binary operator. Either or both may be NULL.
**
** Expr.x.pList is a list of arguments if the expression is an SQL function,
** a CASE expression or an IN expression of the form "<lhs> IN (<y>, <z>...)".
** Expr.x.pSelect is used if the expression is a sub-select or an expression of
** the form "<lhs> IN (SELECT ...)". If the EP_xIsSelect bit is set in the
** Expr.flags mask, then Expr.x.pSelect is valid. Otherwise, Expr.x.pList is
** valid.
**
** An expression of the form ID or ID.ID refers to a column in a table.
** For such expressions, Expr.op is set to TK_COLUMN and Expr.iTable is
** the integer cursor number of a VDBE cursor pointing to that table and
** Expr.iColumn is the column number for the specific column. If the
** expression is used as a result in an aggregate SELECT, then the
** value is also stored in the Expr.iAgg column in the aggregate so that
** it can be accessed after all aggregates are computed.
**
** If the expression is an unbound variable marker (a question mark
** character '?' in the original SQL) then the Expr.iTable holds the index
** number for that variable.
**
** If the expression is a subquery then Expr.iColumn holds an integer
** register number containing the result of the subquery. If the
** subquery gives a constant result, then iTable is -1. If the subquery
** gives a different answer at different times during statement processing
** then iTable is the address of a subroutine that computes the subquery.
**
** If the Expr is of type OP_Column, and the table it is selecting from
** is a disk table or the "old.*" pseudo-table, then pTab points to the
** corresponding table definition.
**
** ALLOCATION NOTES:
**
** Expr objects can use a lot of memory space in database schema. To
** help reduce memory requirements, sometimes an Expr object will be
** truncated. And to reduce the number of memory allocations, sometimes
** two or more Expr objects will be stored in a single memory allocation,
** together with Expr.zToken strings.
**
** If the EP_Reduced and EP_TokenOnly flags are set when
** an Expr object is truncated. When EP_Reduced is set, then all
** the child Expr objects in the Expr.pLeft and Expr.pRight subtrees
** are contained within the same memory allocation. Note, however, that
** the subtrees in Expr.x.pList or Expr.x.pSelect are always separately
** allocated, regardless of whether or not EP_Reduced is set.
*/
struct Expr {
u8 op; /* Operation performed by this node */
char affinity; /* The affinity of the column or 0 if not a column */
u16 flags; /* Various flags. EP_* See below */
union {
char *zToken; /* Token value. Zero terminated and dequoted */
int iValue; /* Non-negative integer value if EP_IntValue */
} u;
/* 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.
*********************************************************************/
Expr *pLeft; /* Left subnode */
Expr *pRight; /* Right subnode */
union {
ExprList *pList; /* Function arguments or in "<expr> IN (<expr-list)" */
Select *pSelect; /* Used for sub-selects and "<expr> IN (<select>)" */
} x;
CollSeq *pColl; /* The collation type of the column or 0 */
/* If the EP_Reduced flag is set in the Expr.flags mask, then no
** space is allocated for the fields below this point. An attempt to
** access them will result in a segfault or malfunction.
*********************************************************************/
int iTable; /* TK_COLUMN: cursor number of table holding column
** TK_REGISTER: register number
** TK_TRIGGER: 1 -> new, 0 -> old */
ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid.
** TK_VARIABLE: variable number (always >= 1). */
i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */
u8 flags2; /* Second set of flags. EP2_... */
u8 op2; /* If a TK_REGISTER, the original value of Expr.op */
AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
Table *pTab; /* Table for TK_COLUMN expressions. */
#if SQLITE_MAX_EXPR_DEPTH>0
int nHeight; /* Height of the tree headed by this node */
#endif
};
/*
** The following are the meanings of bits in the Expr.flags field.
*/
#define EP_FromJoin 0x0001 /* Originated in ON or USING clause of a join */
#define EP_Agg 0x0002 /* Contains one or more aggregate functions */
#define EP_Resolved 0x0004 /* IDs have been resolved to COLUMNs */
#define EP_Error 0x0008 /* Expression contains one or more errors */
#define EP_Distinct 0x0010 /* Aggregate function with DISTINCT keyword */
#define EP_VarSelect 0x0020 /* pSelect is correlated, not constant */
#define EP_DblQuoted 0x0040 /* token.z was originally in "..." */
#define EP_InfixFunc 0x0080 /* True for an infix function: LIKE, GLOB, etc */
#define EP_ExpCollate 0x0100 /* Collating sequence specified explicitly */
#define EP_FixedDest 0x0200 /* Result needed in a specific register */
#define EP_IntValue 0x0400 /* Integer value contained in u.iValue */
#define EP_xIsSelect 0x0800 /* x.pSelect is valid (otherwise x.pList is) */
#define EP_Hint 0x1000 /* Optimizer hint. Not required for correctness */
#define EP_Reduced 0x2000 /* Expr struct is EXPR_REDUCEDSIZE bytes only */
#define EP_TokenOnly 0x4000 /* Expr struct is EXPR_TOKENONLYSIZE bytes only */
#define EP_Static 0x8000 /* Held in memory not obtained from malloc() */
/*
** The following are the meanings of bits in the Expr.flags2 field.
*/
#define EP2_MallocedToken 0x0001 /* Need to sqlite4DbFree() Expr.zToken */
#define EP2_Irreducible 0x0002 /* Cannot EXPRDUP_REDUCE this Expr */
/*
** The pseudo-routine sqlite4ExprSetIrreducible sets the EP2_Irreducible
** flag on an expression structure. This flag is used for VV&A only. The
** routine is implemented as a macro that only works when in debugging mode,
** so as not to burden production code.
*/
#ifdef SQLITE_DEBUG
# define ExprSetIrreducible(X) (X)->flags2 |= EP2_Irreducible
#else
# define ExprSetIrreducible(X)
#endif
/*
** These macros can be used to test, set, or clear bits in the
** Expr.flags field.
*/
#define ExprHasProperty(E,P) (((E)->flags&(P))==(P))
#define ExprHasAnyProperty(E,P) (((E)->flags&(P))!=0)
#define ExprSetProperty(E,P) (E)->flags|=(P)
#define ExprClearProperty(E,P) (E)->flags&=~(P)
/*
** Macros to determine the number of bytes required by a normal Expr
** struct, an Expr struct with the EP_Reduced flag set in Expr.flags
** and an Expr struct with the EP_TokenOnly flag set.
*/
#define EXPR_FULLSIZE sizeof(Expr) /* Full size */
#define EXPR_REDUCEDSIZE offsetof(Expr,iTable) /* Common features */
#define EXPR_TOKENONLYSIZE offsetof(Expr,pLeft) /* Fewer features */
/*
** Flags passed to the sqlite4ExprDup() function. See the header comment
** above sqlite4ExprDup() for details.
*/
#define EXPRDUP_REDUCE 0x0001 /* Used reduced-size Expr nodes */
/*
** A list of expressions. Each expression may optionally have a
** name. An expr/name combination can be used in several ways, such
** as the list of "expr AS ID" fields following a "SELECT" or in the
** list of "ID = expr" items in an UPDATE. A list of expressions can
** also be used as the argument to a function, in which case the a.zName
** field is not used.
*/
struct ExprList {
int nExpr; /* Number of expressions on the list */
int nAlloc; /* Number of entries allocated below */
int iECursor; /* VDBE Cursor associated with this ExprList */
struct ExprList_item {
Expr *pExpr; /* The list of expressions */
char *zName; /* Token associated with this expression */
char *zSpan; /* Original text of the expression */
u8 sortOrder; /* 1 for DESC or 0 for ASC */
u8 done; /* A flag to indicate when processing is finished */
u16 iOrderByCol; /* For ORDER BY, column number in result set */
u16 iAlias; /* Index into Parse.aAlias[] for zName */
} *a; /* One entry for each expression */
};
/*
** An instance of this structure is used by the parser to record both
** the parse tree for an expression and the span of input text for an
** expression.
*/
struct ExprSpan {
Expr *pExpr; /* The expression parse tree */
const char *zStart; /* First character of input text */
const char *zEnd; /* One character past the end of input text */
};
/*
** An instance of this structure can hold a simple list of identifiers,
** such as the list "a,b,c" in the following statements:
**
** INSERT INTO t(a,b,c) VALUES ...;
** CREATE INDEX idx ON t(a,b,c);
** CREATE TRIGGER trig BEFORE UPDATE ON t(a,b,c) ...;
**
** The IdList.a.idx field is used when the IdList represents the list of
** column names after a table name in an INSERT statement. In the statement
**
** INSERT INTO t(a,b,c) ...
**
** If "a" is the k-th column of table "t", then IdList.a[0].idx==k.
*/
struct IdList {
struct IdList_item {
char *zName; /* Name of the identifier */
int idx; /* Index in some Table.aCol[] of a column named zName */
} *a;
int nId; /* Number of identifiers on the list */
int nAlloc; /* Number of entries allocated for a[] below */
};
/*
** The bitmask datatype defined below is used for various optimizations.
**
** Changing this from a 64-bit to a 32-bit type limits the number of
** tables in a join to 32 instead of 64. But it also reduces the size
** of the library by 738 bytes on ix86.
*/
typedef u64 Bitmask;
/*
** The number of bits in a Bitmask. "BMS" means "BitMask Size".
*/
#define BMS ((int)(sizeof(Bitmask)*8))
/*
** The following structure describes the FROM clause of a SELECT statement.
** Each table or subquery in the FROM clause is a separate element of
** the SrcList.a[] array.
**
** With the addition of multiple database support, the following structure
** can also be used to describe a particular table such as the table that
** is modified by an INSERT, DELETE, or UPDATE statement. In standard SQL,
** such a table must be a simple name: ID. But in SQLite, the table can
** now be identified by a database name, a dot, then the table name: ID.ID.
**
** The jointype starts out showing the join type between the current table
** and the next table on the list. The parser builds the list this way.
** But sqlite4SrcListShiftJoinType() later shifts the jointypes so that each
** jointype expresses the join between the table and the previous table.
**
** In the colUsed field, the high-order bit (bit 63) is set if the table
** contains more than 63 columns and the 64-th or later column is used.
*/
struct SrcList {
i16 nSrc; /* Number of tables or subqueries in the FROM clause */
i16 nAlloc; /* Number of entries allocated in a[] below */
struct SrcList_item {
char *zDatabase; /* Name of database holding this table */
char *zName; /* Name of the table */
char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */
Table *pTab; /* An SQL table corresponding to zName */
Select *pSelect; /* A SELECT statement used in place of a table name */
int addrFillSub; /* Address of subroutine to manifest a subquery */
int regReturn; /* Register holding return address of addrFillSub */
u8 jointype; /* Type of join between this able and the previous */
u8 notIndexed; /* True if there is a NOT INDEXED clause */
u8 isCorrelated; /* True if sub-query is correlated */
#ifndef SQLITE_OMIT_EXPLAIN
u8 iSelectId; /* If pSelect!=0, the id of the sub-select in EQP */
#endif
int iCursor; /* The VDBE cursor number used to access this table */
Expr *pOn; /* The ON clause of a join */
IdList *pUsing; /* The USING clause of a join */
Bitmask colUsed; /* Bit N (1<<N) set if column N of pTab is used */
char *zIndex; /* Identifier from "INDEXED BY <zIndex>" clause */
Index *pIndex; /* Index structure corresponding to zIndex, if any */
} a[1]; /* One entry for each identifier on the list */
};
/*
** Permitted values of the SrcList.a.jointype field
*/
#define JT_INNER 0x0001 /* Any kind of inner or cross join */
#define JT_CROSS 0x0002 /* Explicit use of the CROSS keyword */
#define JT_NATURAL 0x0004 /* True for a "natural" join */
#define JT_LEFT 0x0008 /* Left outer join */
#define JT_RIGHT 0x0010 /* Right outer join */
#define JT_OUTER 0x0020 /* The "OUTER" keyword is present */
#define JT_ERROR 0x0040 /* unknown or unsupported join type */
/*
** A WherePlan object holds information that describes a lookup
** strategy.
**
** This object is intended to be opaque outside of the where.c module.
** It is included here only so that that compiler will know how big it
** is. None of the fields in this object should be used outside of
** the where.c module.
**
** Within the union, pIdx is only used when wsFlags&WHERE_INDEXED is true.
** pTerm is only used when wsFlags&WHERE_MULTI_OR is true. And pVtabIdx
** is only used when wsFlags&WHERE_VIRTUALTABLE is true. It is never the
** case that more than one of these conditions is true.
*/
struct WherePlan {
u32 wsFlags; /* WHERE_* flags that describe the strategy */
u32 nEq; /* Number of == constraints */
double nRow; /* Estimated number of rows (for EQP) */
union {
Index *pIdx; /* Index when WHERE_INDEXED is true */
struct WhereTerm *pTerm; /* WHERE clause term for OR-search */
sqlite4_index_info *pVtabIdx; /* Virtual table index to use */
} u;
};
/*
** For each nested loop in a WHERE clause implementation, the WhereInfo
** structure contains a single instance of this structure. This structure
** is intended to be private the the where.c module and should not be
** access or modified by other modules.
**
** The pIdxInfo field is used to help pick the best index on a
** virtual table. The pIdxInfo pointer contains indexing
** information for the i-th table in the FROM clause before reordering.
** All the pIdxInfo pointers are freed by whereInfoFree() in where.c.
** All other information in the i-th WhereLevel object for the i-th table
** after FROM clause ordering.
*/
struct WhereLevel {
WherePlan plan; /* query plan for this element of the FROM clause */
int iLeftJoin; /* Memory cell used to implement LEFT OUTER JOIN */
int iTabCur; /* The VDBE cursor used to access the table */
int iIdxCur; /* The VDBE cursor used to access pIdx */
int addrBrk; /* Jump here to break out of the loop */
int addrNxt; /* Jump here to start the next IN combination */
int addrCont; /* Jump here to continue with the next loop cycle */
int addrFirst; /* First instruction of interior of the loop */
u8 iFrom; /* Which entry in the FROM clause */
u8 op, p5; /* Opcode and P5 of the opcode that ends the loop */
int p1, p2; /* Operands of the opcode used to ends the loop */
union { /* Information that depends on plan.wsFlags */
struct {
int nIn; /* Number of entries in aInLoop[] */
struct InLoop {
int iCur; /* The VDBE cursor used by this IN operator */
int addrInTop; /* Top of the IN loop */
} *aInLoop; /* Information about each nested IN operator */
} in; /* Used when plan.wsFlags&WHERE_IN_ABLE */
} u;
/* The following field is really not part of the current level. But
** we need a place to cache virtual table index information for each
** virtual table in the FROM clause and the WhereLevel structure is
** a convenient place since there is one WhereLevel for each FROM clause
** element.
*/
sqlite4_index_info *pIdxInfo; /* Index info for n-th source table */
};
/*
** Flags appropriate for the wctrlFlags parameter of sqlite4WhereBegin()
** and the WhereInfo.wctrlFlags member.
*/
#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_DUPLICATES_OK 0x0008 /* Ok to return a row more than once */
#define WHERE_OMIT_OPEN_CLOSE 0x0010 /* Table cursors are already open */
#define WHERE_NO_AUTOINDEX 0x0020 /* Do not use an auto-index search */
#define WHERE_ONETABLE_ONLY 0x0040 /* Only code the 1st table in pTabList */
#define WHERE_AND_ONLY 0x0080 /* Don't use indices for OR terms */
/*
** The WHERE clause processing routine has two halves. The
** first part does the start of the WHERE loop and the second
** half does the tail of the WHERE loop. An instance of
** this structure is returned by the first half and passed
** into the second half to give some continuity.
*/
struct WhereInfo {
Parse *pParse; /* Parsing and code generating context */
u16 wctrlFlags; /* Flags originally passed to sqlite4WhereBegin() */
u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE or DELETE */
u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */
u8 eDistinct;
SrcList *pTabList; /* List of tables in the join */
int iTop; /* The very beginning of the WHERE loop */
int iContinue; /* Jump here to continue with next record */
int iBreak; /* Jump here to break out of the loop */
int nLevel; /* Number of nested loop */
struct WhereClause *pWC; /* Decomposition of the WHERE clause */
double savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
double nRowOut; /* Estimated number of output rows */
WhereLevel a[1]; /* Information about each nest loop in WHERE */
};
#define WHERE_DISTINCT_UNIQUE 1
#define WHERE_DISTINCT_ORDERED 2
/*
** A NameContext defines a context in which to resolve table and column
** names. The context consists of a list of tables (the pSrcList) field and
** a list of named expression (pEList). The named expression list may
** be NULL. The pSrc corresponds to the FROM clause of a SELECT or
** to the table being operated on by INSERT, UPDATE, or DELETE. The
** 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
** 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.
**
** Each subquery gets a new NameContext. The pNext field points to the
** NameContext in the parent query. Thus the process of scanning the
** NameContext list corresponds to searching through successively outer
** subqueries looking for a match.
*/
struct NameContext {
Parse *pParse; /* The parser */
SrcList *pSrcList; /* One or more tables used to resolve names */
ExprList *pEList; /* Optional list of named expressions */
int nRef; /* Number of names resolved by this context */
int nErr; /* Number of errors encountered while resolving names */
u8 allowAgg; /* Aggregate functions allowed here */
u8 hasAgg; /* True if aggregates are seen */
u8 isCheck; /* True if resolving names in a CHECK constraint */
int nDepth; /* Depth of subquery recursion. 1 for no recursion */
AggInfo *pAggInfo; /* Information about aggregates at this level */
NameContext *pNext; /* Next outer name context. NULL for outermost */
};
/*
** An instance of the following structure contains all information
** needed to generate code for a single SELECT statement.
**
** nLimit is set to -1 if there is no LIMIT clause. nOffset is set to 0.
** If there is a LIMIT clause, the parser sets nLimit to the value of the
** limit and nOffset to the value of the offset (or 0 if there is not
** offset). But later on, nLimit and nOffset become the memory locations
** in the VDBE that record the limit and offset counters.
**
** addrOpenEphm[] entries contain the address of OP_OpenEphemeral opcodes.
** These addresses must be stored so that we can go back and fill in
** the P4_KEYINFO and P2 parameters later. Neither the KeyInfo nor
** the number of columns in P2 can be computed at the same time
** as the OP_OpenEphm instruction is coded because not
** enough information about the compound query is known at that point.
** The KeyInfo for addrOpenTran[0] and [1] contains collating sequences
** for the result set. The KeyInfo for addrOpenTran[2] contains collating
** sequences for the ORDER BY clause.
*/
struct Select {
ExprList *pEList; /* The fields of the result */
u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
char affinity; /* MakeRecord with this affinity for SRT_Set */
u16 selFlags; /* Various SF_* values */
SrcList *pSrc; /* The FROM clause */
Expr *pWhere; /* The WHERE clause */
ExprList *pGroupBy; /* The GROUP BY clause */
Expr *pHaving; /* The HAVING clause */
ExprList *pOrderBy; /* The ORDER BY clause */
Select *pPrior; /* Prior select in a compound select statement */
Select *pNext; /* Next select to the left in a compound */
Select *pRightmost; /* Right-most select in a compound select statement */
Expr *pLimit; /* LIMIT expression. NULL means not used. */
Expr *pOffset; /* OFFSET expression. NULL means not used. */
int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */
int addrOpenEphm[3]; /* OP_OpenEphem opcodes related to this select */
double nSelectRow; /* Estimated number of result rows */
};
/*
** Allowed values for Select.selFlags. The "SF" prefix stands for
** "Select Flag".
*/
#define SF_Distinct 0x01 /* Output should be DISTINCT */
#define SF_Resolved 0x02 /* Identifiers have been resolved */
#define SF_Aggregate 0x04 /* Contains aggregate functions */
#define SF_UsesEphemeral 0x08 /* Uses the OpenEphemeral opcode */
#define SF_Expanded 0x10 /* sqlite4SelectExpand() called on this */
#define SF_HasTypeInfo 0x20 /* FROM subqueries have Table metadata */
#define SF_UseSorter 0x40 /* Sort using a sorter */
/*
** The results of a select can be distributed in several ways. The
** "SRT" prefix means "SELECT Result Type".
*/
#define SRT_Union 1 /* Store result as keys in an index */
#define SRT_Except 2 /* Remove result from a UNION index */
#define SRT_Exists 3 /* Store 1 if the result is not empty */
#define SRT_Discard 4 /* Do not save the results anywhere */
/* The ORDER BY clause is ignored for all of the above */
#define IgnorableOrderby(X) ((X->eDest)<=SRT_Discard)
#define SRT_Output 5 /* Output each row of result */
#define SRT_Mem 6 /* Store result in a memory cell */
#define SRT_Set 7 /* Store results as keys in an index */
#define SRT_Table 8 /* Store result as data with an automatic rowid */
#define SRT_EphemTab 9 /* Create transient tab and store like SRT_Table */
#define SRT_Coroutine 10 /* Generate a single row of result */
/*
** A structure used to customize the behavior of sqlite4Select(). See
** comments above sqlite4Select() for details.
*/
typedef struct SelectDest SelectDest;
struct SelectDest {
u8 eDest; /* How to dispose of the results */
u8 affinity; /* Affinity used when eDest==SRT_Set */
int iParm; /* A parameter used by the eDest disposal method */
int iMem; /* Base register where results are written */
int nMem; /* Number of registers allocated */
};
/*
** 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 down within triggers. Triggers do not
** normally coordinate their activities, but we do need to coordinate the
** loading and saving of autoincrement information.
*/
struct AutoincInfo {
AutoincInfo *pNext; /* Next info block in a list of them all */
Table *pTab; /* Table this info block refers to */
int iDb; /* Index in sqlite4.aDb[] of database holding pTab */
int regCtr; /* Memory register holding the rowid counter */
};
/*
** Size of the column cache
*/
#ifndef SQLITE_N_COLCACHE
# define SQLITE_N_COLCACHE 10
#endif
/*
** 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
** completed.
**
** A Vdbe sub-program that implements the body and WHEN clause of trigger
** TriggerPrg.pTrigger, assuming a default ON CONFLICT clause of
** TriggerPrg.orconf, is stored in the TriggerPrg.pProgram variable.
** The Parse.pTriggerPrg list never contains two entries with the same
** 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
** statements). Similarly, the TriggerPrg.aColmask[1] variable is set to
** a mask of new.* columns used by the program.
*/
struct TriggerPrg {
Trigger *pTrigger; /* Trigger this program was coded from */
int orconf; /* Default ON CONFLICT policy */
SubProgram *pProgram; /* Program implementing pTrigger/orconf */
u32 aColmask[2]; /* Masks of old.*, new.* columns accessed */
TriggerPrg *pNext; /* Next entry in Parse.pTriggerPrg list */
};
/*
** The yDbMask datatype for the bitmask of all attached databases.
*/
#if SQLITE_MAX_ATTACHED>30
typedef sqlite4_uint64 yDbMask;
#else
typedef unsigned int yDbMask;
#endif
/*
** An SQL parser context. A copy of this structure is passed through
** the parser and down into all the parser action routine in order to
** carry around information that is global to the entire parse.
**
** The structure is divided into two parts. When the parser and code
** generate call themselves recursively, the first part of the structure
** is constant but the second part is reset at the beginning and end of
** each recursion.
*/
struct Parse {
sqlite4 *db; /* The main database structure */
int rc; /* Return code from execution */
char *zErrMsg; /* An error message */
Vdbe *pVdbe; /* An engine for executing database bytecode */
u8 colNamesSet; /* TRUE after OP_ColumnName has been issued to pVdbe */
u8 checkSchema; /* Causes schema cookie check after an error */
u8 nested; /* Number of nested calls to the parser/code generator */
u8 nTempReg; /* Number of temporary registers in aTempReg[] */
u8 nTempInUse; /* Number of aTempReg[] currently checked out */
int aTempReg[8]; /* Holding area for temporary registers */
int nRangeReg; /* Size of the temporary register block */
int iRangeReg; /* First register in temporary register block */
int nErr; /* Number of errors seen */
int nTab; /* Number of previously allocated VDBE cursors */
int nMem; /* Number of memory cells used so far */
int nSet; /* Number of sets used so far */
int nOnce; /* Number of OP_Once instructions so far */
int ckBase; /* Base register of data during check constraints */
int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
int iCacheCnt; /* Counter used to generate aColCache[].lru values */
int iNewidxReg; /* First argument to OP_NewIdxid */
u8 nColCache; /* Number of entries in aColCache[] */
u8 iColCache; /* Next entry in aColCache[] to replace */
struct yColCache {
int iTable; /* Table cursor number */
int iColumn; /* Table column number */
u8 tempReg; /* iReg is a temp register that needs to be freed */
int iLevel; /* Nesting level */
int iReg; /* Reg with value of this column. 0 means none. */
int lru; /* Least recently used entry has the smallest value */
} aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */
yDbMask writeMask; /* Start a write transaction on these databases */
yDbMask cookieMask; /* Bitmask of schema verified databases */
u8 isMultiWrite; /* True if statement may affect/insert multiple rows */
u8 mayAbort; /* True if statement may throw an ABORT exception */
int cookieGoto; /* Address of OP_Goto to cookie verifier subroutine */
int cookieValue[SQLITE_MAX_ATTACHED+2]; /* Values of cookies to verify */
int regRowid; /* Register holding rowid of CREATE TABLE entry */
AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */
int nMaxArg; /* Max args passed to user function by sub-program */
/* Information used while coding trigger programs. */
Parse *pToplevel; /* Parse structure for main program (or NULL) */
Table *pTriggerTab; /* Table triggers are being coded for */
u32 oldmask; /* Mask of old.* columns referenced */
u32 newmask; /* Mask of new.* columns referenced */
u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */
u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */
u8 disableTriggers; /* True to disable triggers */
double nQueryLoop; /* Estimated number of iterations of a query */
/* Above is constant between recursions. Below is reset before and after
** each recursion */
int nVar; /* Number of '?' variables seen in the SQL so far */
int nzVar; /* Number of available slots in azVar[] */
char **azVar; /* Pointers to names of parameters */
Vdbe *pReprepare; /* VM being reprepared (sqlite4Reprepare()) */
int nAlias; /* Number of aliased result set columns */
int *aAlias; /* Register used to hold aliased result */
u8 explain; /* True if the EXPLAIN flag is found on the query */
Token sNameToken; /* Token with unqualified schema object name */
Token sLastToken; /* The last token parsed */
const char *zTail; /* All SQL text past the last semicolon parsed */
Table *pNewTable; /* A table being constructed by CREATE TABLE */
Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */
const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
#ifndef SQLITE_OMIT_VIRTUALTABLE
Token sArg; /* Complete text of a module argument */
u8 declareVtab; /* True if inside sqlite4_declare_vtab() */
int nVtabLock; /* Number of virtual tables to lock */
Table **apVtabLock; /* Pointer to virtual tables needing locking */
#endif
int nHeight; /* Expression tree height of current sub-select */
Table *pZombieTab; /* List of Table objects to delete after code gen */
TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */
#ifndef SQLITE_OMIT_EXPLAIN
int iSelectId;
int iNextSelectId;
#endif
};
#ifdef SQLITE_OMIT_VIRTUALTABLE
#define IN_DECLARE_VTAB 0
#else
#define IN_DECLARE_VTAB (pParse->declareVtab)
#endif
/*
** An instance of the following structure can be declared on a stack and used
** to save the Parse.zAuthContext value so that it can be restored later.
*/
struct AuthContext {
const char *zAuthContext; /* Put saved Parse.zAuthContext here */
Parse *pParse; /* The Parse structure */
};
/*
** Bitfield flags for P5 value in OP_Insert and OP_Delete
*/
#define OPFLAG_NCHANGE 0x01 /* Set to update db->nChange */
#define OPFLAG_LASTROWID 0x02 /* 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 on insert */
#define OPFLAG_CLEARCACHE 0x20 /* Clear pseudo-table cache in OP_Column */
#define OPFLAG_APPENDBIAS 0x40 /* Bias inserts for appending */
/*
* Each trigger present in the database schema is stored as an instance of
* struct Trigger.
*
* Pointers to instances of struct Trigger are stored in two ways.
* 1. In the "trigHash" hash table (part of the sqlite4* 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
* linked list is stored as the "pTrigger" member of the associated
* struct Table.
*
* The "step_list" member points to the first element of a linked list
* containing the SQL statements specified as the trigger program.
*/
struct Trigger {
char *zName; /* The name of the trigger */
char *table; /* The table or view to which the trigger applies */
u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT */
u8 tr_tm; /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
Expr *pWhen; /* The WHEN clause of the expression (may be NULL) */
IdList *pColumns; /* If this is an UPDATE OF <column-list> trigger,
the <column-list> is stored here */
Schema *pSchema; /* Schema containing the trigger */
Schema *pTabSchema; /* Schema containing the table */
TriggerStep *step_list; /* Link list of trigger program steps */
Trigger *pNext; /* Next trigger associated with the table */
};
/*
** A trigger is either a BEFORE or an AFTER trigger. The following constants
** 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.
*/
#define TRIGGER_BEFORE 1
#define TRIGGER_AFTER 2
/*
* An instance of struct TriggerStep is used to store a single SQL statement
* 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
* 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
* value of "op" as follows:
*
* (op == TK_INSERT)
* orconf -> stores the ON CONFLICT algorithm
* pSelect -> If this is an INSERT INTO ... SELECT ... statement, then
* this stores a pointer to the SELECT statement. Otherwise NULL.
* target -> A token holding the quoted name of the table to insert into.
* 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 ...
* statement, then this stores the column-names to be
* inserted into.
*
* (op == TK_DELETE)
* target -> A token holding the quoted name of the table to delete from.
* pWhere -> The WHERE clause of the DELETE statement if one is specified.
* Otherwise NULL.
*
* (op == TK_UPDATE)
* target -> A token holding the quoted name of the table to update rows of.
* pWhere -> The WHERE clause of the UPDATE statement if one is specified.
* Otherwise NULL.
* pExprList -> A list of the columns to update and the expressions to update
* them to. See sqlite4Update() documentation of "pChanges"
* argument.
*
*/
struct TriggerStep {
u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
u8 orconf; /* OE_Rollback etc. */
Trigger *pTrig; /* The trigger that this step is a part of */
Select *pSelect; /* SELECT statment or RHS of INSERT INTO .. SELECT ... */
Token target; /* Target table for DELETE, UPDATE, INSERT */
Expr *pWhere; /* The WHERE clause for DELETE or UPDATE steps */
ExprList *pExprList; /* SET clause for UPDATE. VALUES clause for INSERT */
IdList *pIdList; /* Column names for INSERT */
TriggerStep *pNext; /* Next in the link-list */
TriggerStep *pLast; /* Last element in link-list. Valid for 1st elem only */
};
/*
** The following structure contains information used by the sqliteFix...
** routines as they walk the parse tree to make database references
** explicit.
*/
typedef struct DbFixer DbFixer;
struct DbFixer {
Parse *pParse; /* The parsing context. Error messages written here */
const char *zDb; /* Make sure all objects are contained in this database */
const char *zType; /* Type of the container - used for error messages */
const Token *pName; /* Name of the container - used for error messages */
};
/*
** An objected used to accumulate the text of a string where we
** do not necessarily know how big the string will be in the end.
*/
struct StrAccum {
sqlite4 *db; /* Optional database for lookaside. Can be NULL */
sqlite4_env *pEnv; /* Malloc context */
char *zBase; /* A base allocation. Not from malloc. */
char *zText; /* The string collected so far */
int nChar; /* Length of the string so far */
int nAlloc; /* Amount of space allocated in zText */
int mxAlloc; /* Maximum allowed string length */
u8 mallocFailed; /* Becomes true if any memory allocation fails */
u8 useMalloc; /* 0: none, 1: sqlite4DbMalloc, 2: sqlite4_malloc */
u8 tooBig; /* Becomes true if string size exceeds limits */
};
/*
** A pointer to this structure is used to communicate information
** from sqlite4Init and OP_ParseSchema into the sqlite4InitCallback.
*/
typedef struct {
sqlite4 *db; /* The database being initialized */
int iDb; /* 0 for main database. 1 for TEMP, 2.. for ATTACHed */
char **pzErrMsg; /* Error message stored here */
int rc; /* Result code stored here */
} InitData;
/*
** A pluggable storage engine
*/
typedef struct KVFactory {
struct KVFactory *pNext; /* Next in list of them all */
const char *zName; /* Name of this factory */
int (*xFactory)(sqlite4_env*,sqlite4_kvstore**,const char*,unsigned);
int isPerm; /* True if a built-in. Cannot be popped */
} KVFactory;
/*
** An instance of this structure defines the run-time environment.
*/
struct sqlite4_env {
int nByte; /* Size of this object in bytes */
int iVersion; /* Version number of this structure */
int bMemstat; /* True to enable memory status */
int bCoreMutex; /* True to enable core mutexing */
int bFullMutex; /* True to enable full mutexing */
int mxStrlen; /* Maximum string length */
int szLookaside; /* Default lookaside buffer size */
int nLookaside; /* Default lookaside buffer count */
sqlite4_mem_methods m; /* Low-level memory allocation interface */
sqlite4_mutex_methods mutex; /* Low-level mutex interface */
void *pHeap; /* Heap storage space */
int nHeap; /* Size of pHeap[] */
int mnReq, mxReq; /* Min and max heap requests sizes */
int mxParserStack; /* maximum depth of the parser stack */
KVFactory *pFactory; /* List of factories */
int (*xRandomness)(sqlite4_env*, int, unsigned char*);
int (*xCurrentTime)(sqlite4_env*, sqlite4_uint64*);
/* The above might be initialized to non-zero. The following need to always
** initially be zero, however. */
int isInit; /* True after initialization has finished */
sqlite4_mutex *pFactoryMutex; /* Mutex for pFactory */
sqlite4_mutex *pPrngMutex; /* Mutex for the PRNG */
u32 prngX, prngY; /* State of the PRNG */
void (*xLog)(void*,int,const char*); /* Function for logging */
void *pLogArg; /* First argument to xLog() */
int bLocaltimeFault; /* True to fail localtime() calls */
sqlite4_mutex *pMemMutex; /* Mutex for nowValue[] and mxValue[] */
sqlite4_uint64 nowValue[4]; /* sqlite4_env_status() current values */
sqlite4_uint64 mxValue[4]; /* sqlite4_env_status() max values */
FuncDefTable aGlobalFuncs; /* Lookup table of global functions */
};
/*
** Context pointer passed down through the tree-walk.
*/
struct Walker {
int (*xExprCallback)(Walker*, Expr*); /* Callback for expressions */
int (*xSelectCallback)(Walker*,Select*); /* Callback for SELECTs */
Parse *pParse; /* Parser context. */
union { /* Extra data for callback */
NameContext *pNC; /* Naming context */
int i; /* Integer value */
} u;
};
/* Forward declarations */
SQLITE_PRIVATE int sqlite4WalkExpr(Walker*, Expr*);
SQLITE_PRIVATE int sqlite4WalkExprList(Walker*, ExprList*);
SQLITE_PRIVATE int sqlite4WalkSelect(Walker*, Select*);
SQLITE_PRIVATE int sqlite4WalkSelectExpr(Walker*, Select*);
SQLITE_PRIVATE int sqlite4WalkSelectFrom(Walker*, Select*);
/*
** Return code from the parse-tree walking primitives and their
** callbacks.
*/
#define WRC_Continue 0 /* Continue down into children */
#define WRC_Prune 1 /* Omit children but continue walking siblings */
#define WRC_Abort 2 /* Abandon the tree walk */
/*
** Assuming zIn points to the first byte of a UTF-8 character,
** advance zIn to point to the first byte of the next UTF-8 character.
*/
#define SQLITE_SKIP_UTF8(zIn) { \
if( (*(zIn++))>=0xc0 ){ \
while( (*zIn & 0xc0)==0x80 ){ zIn++; } \
} \
}
/*
** The SQLITE_*_BKPT macros are substitutes for the error codes with
** the same name but without the _BKPT suffix. These macros invoke
** routines that report the line-number on which the error originated
** using sqlite4_log(). The routines also provide a convenient place
** to set a debugger breakpoint.
*/
SQLITE_PRIVATE int sqlite4CorruptError(int);
SQLITE_PRIVATE int sqlite4MisuseError(int);
SQLITE_PRIVATE int sqlite4CantopenError(int);
#define SQLITE_CORRUPT_BKPT sqlite4CorruptError(__LINE__)
#define SQLITE_MISUSE_BKPT sqlite4MisuseError(__LINE__)
#define SQLITE_CANTOPEN_BKPT sqlite4CantopenError(__LINE__)
/*
** FTS4 is really an extension for FTS3. It is enabled using the
** SQLITE_ENABLE_FTS3 macro. But to avoid confusion we also all
** the SQLITE_ENABLE_FTS4 macro to serve as an alisse for SQLITE_ENABLE_FTS3.
*/
#if defined(SQLITE_ENABLE_FTS4) && !defined(SQLITE_ENABLE_FTS3)
# define SQLITE_ENABLE_FTS3
#endif
/*
** The ctype.h header is needed for non-ASCII systems. It is also
** needed by FTS3 when FTS3 is included in the amalgamation.
*/
#if !defined(SQLITE_ASCII) || \
(defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_AMALGAMATION))
# include <ctype.h>
#endif
/*
** The following macros mimic the standard library functions toupper(),
** isspace(), isalnum(), isdigit() and isxdigit(), respectively. The
** sqlite versions only work for ASCII characters, regardless of locale.
*/
#ifdef SQLITE_ASCII
# define sqlite4Toupper(x) ((x)&~(sqlite4CtypeMap[(unsigned char)(x)]&0x20))
# define sqlite4Isspace(x) (sqlite4CtypeMap[(unsigned char)(x)]&0x01)
# define sqlite4Isalnum(x) (sqlite4CtypeMap[(unsigned char)(x)]&0x06)
# define sqlite4Isalpha(x) (sqlite4CtypeMap[(unsigned char)(x)]&0x02)
# define sqlite4Isdigit(x) (sqlite4CtypeMap[(unsigned char)(x)]&0x04)
# define sqlite4Isxdigit(x) (sqlite4CtypeMap[(unsigned char)(x)]&0x08)
# define sqlite4Tolower(x) (sqlite4UpperToLower[(unsigned char)(x)])
#else
# define sqlite4Toupper(x) toupper((unsigned char)(x))
# define sqlite4Isspace(x) isspace((unsigned char)(x))
# define sqlite4Isalnum(x) isalnum((unsigned char)(x))
# define sqlite4Isalpha(x) isalpha((unsigned char)(x))
# define sqlite4Isdigit(x) isdigit((unsigned char)(x))
# define sqlite4Isxdigit(x) isxdigit((unsigned char)(x))
# define sqlite4Tolower(x) tolower((unsigned char)(x))
#endif
/*
** Internal function prototypes
*/
SQLITE_PRIVATE int sqlite4StrICmp(const char *, const char *);
SQLITE_PRIVATE int sqlite4Strlen30(const char*);
#define sqlite4StrNICmp sqlite4_strnicmp
SQLITE_PRIVATE int sqlite4MallocInit(sqlite4_env*);
SQLITE_PRIVATE void sqlite4MallocEnd(sqlite4_env*);
SQLITE_PRIVATE void *sqlite4Malloc(sqlite4_env*, int);
SQLITE_PRIVATE void *sqlite4MallocZero(sqlite4_env*, int);
SQLITE_PRIVATE void *sqlite4DbMallocZero(sqlite4*, int);
SQLITE_PRIVATE void *sqlite4DbMallocRaw(sqlite4*, int);
SQLITE_PRIVATE char *sqlite4DbStrDup(sqlite4*,const char*);
SQLITE_PRIVATE char *sqlite4DbStrNDup(sqlite4*,const char*, int);
SQLITE_PRIVATE void *sqlite4Realloc(sqlite4_env*, void*, int);
SQLITE_PRIVATE void *sqlite4DbReallocOrFree(sqlite4 *, void *, int);
SQLITE_PRIVATE void *sqlite4DbRealloc(sqlite4 *, void *, int);
SQLITE_PRIVATE void sqlite4DbFree(sqlite4*, void*);
SQLITE_PRIVATE int sqlite4MallocSize(sqlite4_env*, void*);
SQLITE_PRIVATE int sqlite4DbMallocSize(sqlite4*, void*);
SQLITE_PRIVATE void sqlite4MemSetDefault(sqlite4_env*);
SQLITE_PRIVATE void sqlite4BenignMallocHooks(sqlite4_env*,void (*)(void), void (*)(void));
/*
** On systems with ample stack space and that support alloca(), make
** use of alloca() to obtain space for large automatic objects. By default,
** obtain space from malloc().
**
** The alloca() routine never returns NULL. This will cause code paths
** that deal with sqlite4StackAlloc() failures to be unreachable.
*/
#ifdef SQLITE_USE_ALLOCA
# define sqlite4StackAllocRaw(D,N) alloca(N)
# define sqlite4StackAllocZero(D,N) memset(alloca(N), 0, N)
# define sqlite4StackFree(D,P)
#else
# define sqlite4StackAllocRaw(D,N) sqlite4DbMallocRaw(D,N)
# define sqlite4StackAllocZero(D,N) sqlite4DbMallocZero(D,N)
# define sqlite4StackFree(D,P) sqlite4DbFree(D,P)
#endif
#ifdef SQLITE_ENABLE_MEMSYS3
SQLITE_PRIVATE const sqlite4_mem_methods *sqlite4MemGetMemsys3(void);
#endif
#ifdef SQLITE_ENABLE_MEMSYS5
SQLITE_PRIVATE const sqlite4_mem_methods *sqlite4MemGetMemsys5(void);
#endif
#ifndef SQLITE_MUTEX_OMIT
SQLITE_PRIVATE sqlite4_mutex_methods const *sqlite4DefaultMutex(void);
SQLITE_PRIVATE sqlite4_mutex_methods const *sqlite4NoopMutex(void);
SQLITE_PRIVATE sqlite4_mutex *sqlite4MutexAlloc(sqlite4_env*,int);
SQLITE_PRIVATE int sqlite4MutexInit(sqlite4_env*);
SQLITE_PRIVATE int sqlite4MutexEnd(sqlite4_env*);
#endif
SQLITE_PRIVATE void sqlite4StatusAdd(sqlite4_env*, int, sqlite4_int64);
SQLITE_PRIVATE void sqlite4StatusSet(sqlite4_env*, int, sqlite4_uint64);
#ifndef SQLITE_OMIT_FLOATING_POINT
SQLITE_PRIVATE int sqlite4IsNaN(double);
SQLITE_PRIVATE int sqlite4IsInf(double);
#else
# define sqlite4IsNaN(X) 0
# define sqlite4IsInf(X) 0
#endif
SQLITE_PRIVATE void sqlite4VXPrintf(StrAccum*, int, const char*, va_list);
#ifndef SQLITE_OMIT_TRACE
SQLITE_PRIVATE void sqlite4XPrintf(StrAccum*, const char*, ...);
#endif
SQLITE_PRIVATE char *sqlite4MPrintf(sqlite4*,const char*, ...);
SQLITE_PRIVATE char *sqlite4VMPrintf(sqlite4*,const char*, va_list);
SQLITE_PRIVATE char *sqlite4MAppendf(sqlite4*,char*,const char*,...);
#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
SQLITE_PRIVATE void sqlite4DebugPrintf(const char*, ...);
#endif
#if defined(SQLITE_TEST)
SQLITE_PRIVATE void *sqlite4TestTextToPtr(const char*);
#endif
/* Output formatting for SQLITE_TESTCTRL_EXPLAIN */
#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
SQLITE_PRIVATE void sqlite4ExplainBegin(Vdbe*);
SQLITE_PRIVATE void sqlite4ExplainPrintf(Vdbe*, const char*, ...);
SQLITE_PRIVATE void sqlite4ExplainNL(Vdbe*);
SQLITE_PRIVATE void sqlite4ExplainPush(Vdbe*);
SQLITE_PRIVATE void sqlite4ExplainPop(Vdbe*);
SQLITE_PRIVATE void sqlite4ExplainFinish(Vdbe*);
SQLITE_PRIVATE void sqlite4ExplainSelect(Vdbe*, Select*);
SQLITE_PRIVATE void sqlite4ExplainExpr(Vdbe*, Expr*);
SQLITE_PRIVATE void sqlite4ExplainExprList(Vdbe*, ExprList*);
SQLITE_PRIVATE const char *sqlite4VdbeExplanation(Vdbe*);
#else
# define sqlite4ExplainBegin(X)
# define sqlite4ExplainSelect(A,B)
# define sqlite4ExplainExpr(A,B)
# define sqlite4ExplainExprList(A,B)
# define sqlite4ExplainFinish(X)
# define sqlite4VdbeExplanation(X) 0
#endif
SQLITE_PRIVATE void sqlite4SetString(char **, sqlite4*, const char*, ...);
SQLITE_PRIVATE void sqlite4ErrorMsg(Parse*, const char*, ...);
SQLITE_PRIVATE int sqlite4Dequote(char*);
SQLITE_PRIVATE int sqlite4KeywordCode(const unsigned char*, int);
SQLITE_PRIVATE int sqlite4RunParser(Parse*, const char*, char **);
SQLITE_PRIVATE void sqlite4FinishCoding(Parse*);
SQLITE_PRIVATE int sqlite4GetTempReg(Parse*);
SQLITE_PRIVATE void sqlite4ReleaseTempReg(Parse*,int);
SQLITE_PRIVATE int sqlite4GetTempRange(Parse*,int);
SQLITE_PRIVATE void sqlite4ReleaseTempRange(Parse*,int,int);
SQLITE_PRIVATE void sqlite4ClearTempRegCache(Parse*);
SQLITE_PRIVATE Expr *sqlite4ExprAlloc(sqlite4*,int,const Token*,int);
SQLITE_PRIVATE Expr *sqlite4Expr(sqlite4*,int,const char*);
SQLITE_PRIVATE void sqlite4ExprAttachSubtrees(sqlite4*,Expr*,Expr*,Expr*);
SQLITE_PRIVATE Expr *sqlite4PExpr(Parse*, int, Expr*, Expr*, const Token*);
SQLITE_PRIVATE Expr *sqlite4ExprAnd(sqlite4*,Expr*, Expr*);
SQLITE_PRIVATE Expr *sqlite4ExprFunction(Parse*,ExprList*, Token*);
SQLITE_PRIVATE void sqlite4ExprAssignVarNumber(Parse*, Expr*);
SQLITE_PRIVATE void sqlite4ExprDelete(sqlite4*, Expr*);
SQLITE_PRIVATE ExprList *sqlite4ExprListAppend(Parse*,ExprList*,Expr*);
SQLITE_PRIVATE void sqlite4ExprListSetName(Parse*,ExprList*,Token*,int);
SQLITE_PRIVATE void sqlite4ExprListSetSpan(Parse*,ExprList*,ExprSpan*);
SQLITE_PRIVATE void sqlite4ExprListDelete(sqlite4*, ExprList*);
SQLITE_PRIVATE int sqlite4Init(sqlite4*, char**);
SQLITE_PRIVATE int sqlite4InitCallback(void*, int, char**, char**);
SQLITE_PRIVATE void sqlite4Pragma(Parse*,Token*,Token*,Token*,int);
SQLITE_PRIVATE void sqlite4ResetInternalSchema(sqlite4*, int);
SQLITE_PRIVATE void sqlite4BeginParse(Parse*,int);
SQLITE_PRIVATE void sqlite4CommitInternalChanges(sqlite4*);
SQLITE_PRIVATE Table *sqlite4ResultSetOfSelect(Parse*,Select*);
SQLITE_PRIVATE void sqlite4OpenMasterTable(Parse *, int);
SQLITE_PRIVATE void sqlite4StartTable(Parse*,Token*,Token*,int,int,int,int);
SQLITE_PRIVATE void sqlite4AddColumn(Parse*,Token*);
SQLITE_PRIVATE void sqlite4AddNotNull(Parse*, int);
SQLITE_PRIVATE void sqlite4AddPrimaryKey(Parse*, ExprList*, int, int, int);
SQLITE_PRIVATE void sqlite4AddCheckConstraint(Parse*, Expr*);
SQLITE_PRIVATE void sqlite4AddColumnType(Parse*,Token*);
SQLITE_PRIVATE void sqlite4AddDefaultValue(Parse*,ExprSpan*);
SQLITE_PRIVATE void sqlite4AddCollateType(Parse*, Token*);
SQLITE_PRIVATE void sqlite4EndTable(Parse*,Token*,Token*,Select*);
SQLITE_PRIVATE int sqlite4ParseUri(sqlite4_env*,const char*,unsigned int*,char**,char **);
SQLITE_PRIVATE int sqlite4CodeOnce(Parse *);
SQLITE_PRIVATE RowSet *sqlite4RowSetInit(sqlite4 *, void *, unsigned int);
SQLITE_PRIVATE void sqlite4RowSetClear(RowSet *);
SQLITE_PRIVATE void sqlite4RowSetInsert(RowSet *, u8 *, int);
SQLITE_PRIVATE int sqlite4RowSetNext(RowSet *);
SQLITE_PRIVATE const u8 *sqlite4RowSetRead(RowSet *, int *);
SQLITE_PRIVATE int sqlite4RowSetTest(RowSet *, u8, u8 *, int);
SQLITE_PRIVATE void sqlite4CreateView(Parse*,Token*,Token*,Token*,Select*,int,int);
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
SQLITE_PRIVATE int sqlite4ViewGetColumnNames(Parse*,Table*);
#else
# define sqlite4ViewGetColumnNames(A,B) 0
#endif
SQLITE_PRIVATE void sqlite4DropTable(Parse*, SrcList*, int, int);
SQLITE_PRIVATE void sqlite4CodeDropTable(Parse*, Table*, int, int);
SQLITE_PRIVATE void sqlite4DeleteTable(sqlite4*, Table*);
#ifndef SQLITE_OMIT_AUTOINCREMENT
SQLITE_PRIVATE void sqlite4AutoincrementBegin(Parse *pParse);
SQLITE_PRIVATE void sqlite4AutoincrementEnd(Parse *pParse);
#else
# define sqlite4AutoincrementBegin(X)
# define sqlite4AutoincrementEnd(X)
#endif
SQLITE_PRIVATE void sqlite4Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int);
SQLITE_PRIVATE void *sqlite4ArrayAllocate(sqlite4*,void*,int,int,int*,int*,int*);
SQLITE_PRIVATE IdList *sqlite4IdListAppend(sqlite4*, IdList*, Token*);
SQLITE_PRIVATE int sqlite4IdListIndex(IdList*,const char*);
SQLITE_PRIVATE SrcList *sqlite4SrcListEnlarge(sqlite4*, SrcList*, int, int);
SQLITE_PRIVATE SrcList *sqlite4SrcListAppend(sqlite4*, SrcList*, Token*, Token*);
SQLITE_PRIVATE SrcList *sqlite4SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*,
Token*, Select*, Expr*, IdList*);
SQLITE_PRIVATE void sqlite4SrcListIndexedBy(Parse *, SrcList *, Token *);
SQLITE_PRIVATE int sqlite4IndexedByLookup(Parse *, struct SrcList_item *);
SQLITE_PRIVATE void sqlite4SrcListShiftJoinType(SrcList*);
SQLITE_PRIVATE void sqlite4SrcListAssignCursors(Parse*, SrcList*);
SQLITE_PRIVATE void sqlite4IdListDelete(sqlite4*, IdList*);
SQLITE_PRIVATE void sqlite4SrcListDelete(sqlite4*, SrcList*);
SQLITE_PRIVATE Index *sqlite4CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
Token*, int, int, int);
SQLITE_PRIVATE void sqlite4DropIndex(Parse*, SrcList*, int);
SQLITE_PRIVATE int sqlite4Select(Parse*, Select*, SelectDest*);
SQLITE_PRIVATE Select *sqlite4SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
Expr*,ExprList*,int,Expr*,Expr*);
SQLITE_PRIVATE void sqlite4SelectDelete(sqlite4*, Select*);
SQLITE_PRIVATE Table *sqlite4SrcListLookup(Parse*, SrcList*);
SQLITE_PRIVATE int sqlite4IsReadOnly(Parse*, Table*, int);
SQLITE_PRIVATE void sqlite4OpenTable(Parse*, int iCur, int iDb, Table*, int);
#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
SQLITE_PRIVATE Expr *sqlite4LimitWhere(Parse *, SrcList *, Expr *, ExprList *, Expr *, Expr *, char *);
#endif
SQLITE_PRIVATE void sqlite4DeleteFrom(Parse*, SrcList*, Expr*);
SQLITE_PRIVATE void sqlite4Update(Parse*, SrcList*, ExprList*, Expr*, int);
SQLITE_PRIVATE WhereInfo *sqlite4WhereBegin(Parse*, SrcList*, Expr*, ExprList**,ExprList*,u16);
SQLITE_PRIVATE void sqlite4WhereEnd(WhereInfo*);
SQLITE_PRIVATE int sqlite4ExprCodeGetColumn(Parse*, Table*, int, int, int);
SQLITE_PRIVATE void sqlite4ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
SQLITE_PRIVATE void sqlite4ExprCodeMove(Parse*, int, int, int);
SQLITE_PRIVATE void sqlite4ExprCodeCopy(Parse*, int, int, int);
SQLITE_PRIVATE void sqlite4ExprCacheStore(Parse*, int, int, int);
SQLITE_PRIVATE void sqlite4ExprCachePush(Parse*);
SQLITE_PRIVATE void sqlite4ExprCachePop(Parse*, int);
SQLITE_PRIVATE void sqlite4ExprCacheRemove(Parse*, int, int);
SQLITE_PRIVATE void sqlite4ExprCacheClear(Parse*);
SQLITE_PRIVATE void sqlite4ExprCacheAffinityChange(Parse*, int, int);
SQLITE_PRIVATE int sqlite4ExprCode(Parse*, Expr*, int);
SQLITE_PRIVATE int sqlite4ExprCodeTemp(Parse*, Expr*, int*);
SQLITE_PRIVATE int sqlite4ExprCodeTarget(Parse*, Expr*, int);
SQLITE_PRIVATE int sqlite4ExprCodeAndCache(Parse*, Expr*, int);
SQLITE_PRIVATE void sqlite4ExprCodeConstants(Parse*, Expr*);
SQLITE_PRIVATE int sqlite4ExprCodeExprList(Parse*, ExprList*, int, int);
SQLITE_PRIVATE void sqlite4ExprIfTrue(Parse*, Expr*, int, int);
SQLITE_PRIVATE void sqlite4ExprIfFalse(Parse*, Expr*, int, int);
SQLITE_PRIVATE Table *sqlite4FindTable(sqlite4*,const char*, const char*);
SQLITE_PRIVATE Table *sqlite4LocateTable(Parse*,int isView,const char*, const char*);
SQLITE_PRIVATE Index *sqlite4FindIndex(sqlite4*,const char*, const char*);
SQLITE_PRIVATE void sqlite4UnlinkAndDeleteTable(sqlite4*,int,const char*);
SQLITE_PRIVATE void sqlite4UnlinkAndDeleteIndex(sqlite4*,int,const char*);
SQLITE_PRIVATE void sqlite4Vacuum(Parse*);
SQLITE_PRIVATE int sqlite4RunVacuum(char**, sqlite4*);
SQLITE_PRIVATE char *sqlite4NameFromToken(sqlite4*, Token*);
SQLITE_PRIVATE int sqlite4ExprCompare(Expr*, Expr*);
SQLITE_PRIVATE int sqlite4ExprListCompare(ExprList*, ExprList*);
SQLITE_PRIVATE void sqlite4ExprAnalyzeAggregates(NameContext*, Expr*);
SQLITE_PRIVATE void sqlite4ExprAnalyzeAggList(NameContext*,ExprList*);
SQLITE_PRIVATE Vdbe *sqlite4GetVdbe(Parse*);
SQLITE_PRIVATE void sqlite4PrngSaveState(void);
SQLITE_PRIVATE void sqlite4PrngRestoreState(void);
SQLITE_PRIVATE void sqlite4PrngResetState(void);
SQLITE_PRIVATE void sqlite4CodeVerifySchema(Parse*, int);
SQLITE_PRIVATE void sqlite4CodeVerifyNamedSchema(Parse*, const char *zDb);
SQLITE_PRIVATE void sqlite4BeginTransaction(Parse*, int);
SQLITE_PRIVATE void sqlite4EndTransaction(Parse *, int);
SQLITE_PRIVATE void sqlite4Savepoint(Parse*, int, Token*);
SQLITE_PRIVATE void sqlite4CloseSavepoints(sqlite4 *);
SQLITE_PRIVATE int sqlite4ExprIsConstant(Expr*);
SQLITE_PRIVATE int sqlite4ExprIsConstantNotJoin(Expr*);
SQLITE_PRIVATE int sqlite4ExprIsConstantOrFunction(Expr*);
SQLITE_PRIVATE int sqlite4ExprIsInteger(Expr*, int*);
SQLITE_PRIVATE int sqlite4ExprCanBeNull(const Expr*);
SQLITE_PRIVATE void sqlite4ExprCodeIsNullJump(Vdbe*, const Expr*, int, int);
SQLITE_PRIVATE int sqlite4ExprNeedsNoAffinityChange(const Expr*, char);
SQLITE_PRIVATE void sqlite4GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int);
SQLITE_PRIVATE void sqlite4GenerateRowIndexDelete(Parse*, Table*, int, int, int*);
SQLITE_PRIVATE void sqlite4EncodeIndexKey(Parse *, Index *, int, Index *, int, int, int);
SQLITE_PRIVATE void sqlite4GenerateConstraintChecks(Parse*,Table*,int,int,
int*,int,int,int,int,int*);
SQLITE_PRIVATE void sqlite4CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
SQLITE_PRIVATE int sqlite4OpenTableAndIndices(Parse*, Table*, int, int);
SQLITE_PRIVATE void sqlite4BeginWriteOperation(Parse*, int, int);
SQLITE_PRIVATE void sqlite4MultiWrite(Parse*);
SQLITE_PRIVATE void sqlite4MayAbort(Parse*);
SQLITE_PRIVATE void sqlite4HaltConstraint(Parse*, int, char*, int);
SQLITE_PRIVATE Expr *sqlite4ExprDup(sqlite4*,Expr*,int);
SQLITE_PRIVATE ExprList *sqlite4ExprListDup(sqlite4*,ExprList*,int);
SQLITE_PRIVATE SrcList *sqlite4SrcListDup(sqlite4*,SrcList*,int);
SQLITE_PRIVATE IdList *sqlite4IdListDup(sqlite4*,IdList*);
SQLITE_PRIVATE Select *sqlite4SelectDup(sqlite4*,Select*,int);
SQLITE_PRIVATE void sqlite4FuncDefInsert(FuncDefTable*, FuncDef*, int);
SQLITE_PRIVATE FuncDef *sqlite4FindFunction(sqlite4*,const char*,int,int,u8,int);
SQLITE_PRIVATE void sqlite4RegisterBuiltinFunctions(sqlite4*);
SQLITE_PRIVATE void sqlite4RegisterDateTimeFunctions(sqlite4_env*);
SQLITE_PRIVATE void sqlite4RegisterGlobalFunctions(sqlite4_env*);
SQLITE_PRIVATE int sqlite4SafetyCheckOk(sqlite4*);
SQLITE_PRIVATE int sqlite4SafetyCheckSickOrOk(sqlite4*);
SQLITE_PRIVATE void sqlite4ChangeCookie(Parse*, int);
#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
SQLITE_PRIVATE void sqlite4MaterializeView(Parse*, Table*, Expr*, int);
#else
# define sqlite4MaterializeView(w,x,y,z)
#endif
#ifndef SQLITE_OMIT_TRIGGER
SQLITE_PRIVATE void sqlite4BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*,
Expr*,int, int);
SQLITE_PRIVATE void sqlite4FinishTrigger(Parse*, TriggerStep*, Token*);
SQLITE_PRIVATE void sqlite4DropTrigger(Parse*, SrcList*, int);
SQLITE_PRIVATE void sqlite4DropTriggerPtr(Parse*, Trigger*);
SQLITE_PRIVATE Trigger *sqlite4TriggersExist(Parse *, Table*, int, ExprList*, int *pMask);
SQLITE_PRIVATE Trigger *sqlite4TriggerList(Parse *, Table *);
SQLITE_PRIVATE void sqlite4CodeRowTrigger(Parse*, Trigger *, int, ExprList*, int, Table *,
int, int, int);
SQLITE_PRIVATE void sqlite4CodeRowTriggerDirect(Parse *, Trigger *, Table *, int, int, int);
void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*);
SQLITE_PRIVATE void sqlite4DeleteTriggerStep(sqlite4*, TriggerStep*);
SQLITE_PRIVATE TriggerStep *sqlite4TriggerSelectStep(sqlite4*,Select*);
SQLITE_PRIVATE TriggerStep *sqlite4TriggerInsertStep(sqlite4*,Token*, IdList*,
ExprList*,Select*,u8);
SQLITE_PRIVATE TriggerStep *sqlite4TriggerUpdateStep(sqlite4*,Token*,ExprList*, Expr*, u8);
SQLITE_PRIVATE TriggerStep *sqlite4TriggerDeleteStep(sqlite4*,Token*, Expr*);
SQLITE_PRIVATE void sqlite4DeleteTrigger(sqlite4*, Trigger*);
SQLITE_PRIVATE void sqlite4UnlinkAndDeleteTrigger(sqlite4*,int,const char*);
SQLITE_PRIVATE u32 sqlite4TriggerColmask(Parse*,Trigger*,ExprList*,int,int,Table*,int);
# define sqlite4ParseToplevel(p) ((p)->pToplevel ? (p)->pToplevel : (p))
#else
# define sqlite4TriggersExist(B,C,D,E,F) 0
# define sqlite4DeleteTrigger(A,B)
# define sqlite4DropTriggerPtr(A,B)
# define sqlite4UnlinkAndDeleteTrigger(A,B,C)
# define sqlite4CodeRowTrigger(A,B,C,D,E,F,G,H,I)
# define sqlite4CodeRowTriggerDirect(A,B,C,D,E,F)
# define sqlite4TriggerList(X, Y) 0
# define sqlite4ParseToplevel(p) p
# define sqlite4TriggerColmask(A,B,C,D,E,F,G) 0
#endif
SQLITE_PRIVATE int sqlite4JoinType(Parse*, Token*, Token*, Token*);
SQLITE_PRIVATE void sqlite4CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int);
SQLITE_PRIVATE void sqlite4DeferForeignKey(Parse*, int);
#ifndef SQLITE_OMIT_AUTHORIZATION
SQLITE_PRIVATE void sqlite4AuthRead(Parse*,Expr*,Schema*,SrcList*);
SQLITE_PRIVATE int sqlite4AuthCheck(Parse*,int, const char*, const char*, const char*);
SQLITE_PRIVATE void sqlite4AuthContextPush(Parse*, AuthContext*, const char*);
SQLITE_PRIVATE void sqlite4AuthContextPop(AuthContext*);
SQLITE_PRIVATE int sqlite4AuthReadCol(Parse*, const char *, const char *, int);
#else
# define sqlite4AuthRead(a,b,c,d)
# define sqlite4AuthCheck(a,b,c,d,e) SQLITE_OK
# define sqlite4AuthContextPush(a,b,c)
# define sqlite4AuthContextPop(a) ((void)(a))
#endif
SQLITE_PRIVATE void sqlite4Attach(Parse*, Expr*, Expr*, Expr*);
SQLITE_PRIVATE void sqlite4Detach(Parse*, Expr*);
SQLITE_PRIVATE int sqlite4FixInit(DbFixer*, Parse*, int, const char*, const Token*);
SQLITE_PRIVATE int sqlite4FixSrcList(DbFixer*, SrcList*);
SQLITE_PRIVATE int sqlite4FixSelect(DbFixer*, Select*);
SQLITE_PRIVATE int sqlite4FixExpr(DbFixer*, Expr*);
SQLITE_PRIVATE int sqlite4FixExprList(DbFixer*, ExprList*);
SQLITE_PRIVATE int sqlite4FixTriggerStep(DbFixer*, TriggerStep*);
SQLITE_PRIVATE int sqlite4AtoF(const char *z, double*, int, u8);
SQLITE_PRIVATE int sqlite4GetInt32(const char *, int*);
SQLITE_PRIVATE int sqlite4Atoi(const char*);
SQLITE_PRIVATE int sqlite4Utf16ByteLen(const void *pData, int nChar);
SQLITE_PRIVATE int sqlite4Utf8CharLen(const char *pData, int nByte);
SQLITE_PRIVATE u32 sqlite4Utf8Read(const u8*, const u8**);
/*
** Routines to read and write variable-length integers. These used to
** be defined locally, but now we use the varint routines in the util.c
** file. Code should use the MACRO forms below, as the Varint32 versions
** are coded to assume the single byte case is already handled (which
** the MACRO form does).
*/
SQLITE_PRIVATE int sqlite4PutVarint(unsigned char*, u64);
SQLITE_PRIVATE int sqlite4PutVarint32(unsigned char*, u32);
SQLITE_PRIVATE u8 sqlite4GetVarint(const unsigned char *, u64 *);
SQLITE_PRIVATE u8 sqlite4GetVarint32(const unsigned char *, u32 *);
SQLITE_PRIVATE int sqlite4VarintLen(u64 v);
SQLITE_PRIVATE int sqlite4GetVarint64(const unsigned char*, int, sqlite4_uint64 *pResult);
SQLITE_PRIVATE int sqlite4PutVarint64(unsigned char*, sqlite4_uint64);
/*
** The header of a record consists of a sequence variable-length integers.
** These integers are almost always small and are encoded as a single byte.
** The following macros take advantage this fact to provide a fast encode
** and decode of the integers in a record header. It is faster for the common
** case where the integer is a single byte. It is a little slower when the
** integer is two or more bytes. But overall it is faster.
**
** The following expressions are equivalent:
**
** x = sqlite4GetVarint32( A, &B );
** x = sqlite4PutVarint32( A, B );
**
** x = getVarint32( A, B );
** x = putVarint32( A, B );
**
*/
#define getVarint32(A,B) (u8)((*(A)<(u8)0x80) ? ((B) = (u32)*(A)),1 : sqlite4GetVarint32((A), (u32 *)&(B)))
#define putVarint32(A,B) (u8)(((u32)(B)<(u32)0x80) ? (*(A) = (unsigned char)(B)),1 : sqlite4PutVarint32((A), (B)))
#define getVarint sqlite4GetVarint
#define putVarint sqlite4PutVarint
SQLITE_PRIVATE const char *sqlite4IndexAffinityStr(Vdbe *, Index *);
SQLITE_PRIVATE void sqlite4TableAffinityStr(Vdbe *, Table *);
SQLITE_PRIVATE char sqlite4CompareAffinity(Expr *pExpr, char aff2);
SQLITE_PRIVATE int sqlite4IndexAffinityOk(Expr *pExpr, char idx_affinity);
SQLITE_PRIVATE char sqlite4ExprAffinity(Expr *pExpr);
SQLITE_PRIVATE int sqlite4Atoi64(const char*, i64*, int, u8);
SQLITE_PRIVATE void sqlite4Error(sqlite4*, int, const char*,...);
SQLITE_PRIVATE void *sqlite4HexToBlob(sqlite4*, const char *z, int n);
SQLITE_PRIVATE u8 sqlite4HexToInt(int h);
SQLITE_PRIVATE int sqlite4TwoPartName(Parse *, Token *, Token *, Token **);
SQLITE_PRIVATE const char *sqlite4ErrStr(int);
SQLITE_PRIVATE int sqlite4ReadSchema(Parse *pParse);
SQLITE_PRIVATE CollSeq *sqlite4FindCollSeq(sqlite4*,u8 enc, const char*,int);
SQLITE_PRIVATE CollSeq *sqlite4LocateCollSeq(Parse *pParse, const char*zName);
SQLITE_PRIVATE CollSeq *sqlite4ExprCollSeq(Parse *pParse, Expr *pExpr);
SQLITE_PRIVATE Expr *sqlite4ExprSetColl(Expr*, CollSeq*);
SQLITE_PRIVATE Expr *sqlite4ExprSetCollByToken(Parse *pParse, Expr*, Token*);
SQLITE_PRIVATE int sqlite4CheckCollSeq(Parse *, CollSeq *);
SQLITE_PRIVATE int sqlite4CheckObjectName(Parse *, const char *);
SQLITE_PRIVATE void sqlite4VdbeSetChanges(sqlite4 *, int);
SQLITE_PRIVATE int sqlite4AddInt64(i64*,i64);
SQLITE_PRIVATE int sqlite4SubInt64(i64*,i64);
SQLITE_PRIVATE int sqlite4MulInt64(i64*,i64);
SQLITE_PRIVATE int sqlite4AbsInt32(int);
#ifdef SQLITE_ENABLE_8_3_NAMES
SQLITE_PRIVATE void sqlite4FileSuffix3(const char*, char*);
#else
# define sqlite4FileSuffix3(X,Y)
#endif
SQLITE_PRIVATE u8 sqlite4GetBoolean(const char *z);
SQLITE_PRIVATE const void *sqlite4ValueText(sqlite4_value*, u8);
SQLITE_PRIVATE int sqlite4ValueBytes(sqlite4_value*, u8);
SQLITE_PRIVATE void sqlite4ValueSetStr(sqlite4_value*, int, const void *,u8,
void(*)(void*));
SQLITE_PRIVATE void sqlite4ValueFree(sqlite4_value*);
SQLITE_PRIVATE sqlite4_value *sqlite4ValueNew(sqlite4 *);
SQLITE_PRIVATE char *sqlite4Utf16to8(sqlite4 *, const void*, int, u8);
#ifdef SQLITE_ENABLE_STAT3
SQLITE_PRIVATE char *sqlite4Utf8to16(sqlite4 *, u8, char *, int, int *);
#endif
SQLITE_PRIVATE int sqlite4ValueFromExpr(sqlite4 *, Expr *, u8, u8, sqlite4_value **);
SQLITE_PRIVATE void sqlite4ValueApplyAffinity(sqlite4_value *, u8, u8);
#ifndef SQLITE_AMALGAMATION
SQLITE_PRIVATE const unsigned char sqlite4OpcodeProperty[];
SQLITE_PRIVATE const unsigned char sqlite4UpperToLower[];
SQLITE_PRIVATE const unsigned char sqlite4CtypeMap[];
SQLITE_PRIVATE const Token sqlite4IntTokens[];
SQLITE_PRIVATE struct sqlite4_env sqlite4DefaultEnv;
SQLITE_PRIVATE struct KVFactory sqlite4BuiltinFactory;
#endif
SQLITE_PRIVATE void sqlite4RootPageMoved(sqlite4*, int, int, int);
SQLITE_PRIVATE void sqlite4Reindex(Parse*, Token*, Token*);
SQLITE_PRIVATE void sqlite4AlterFunctions(sqlite4_env*);
SQLITE_PRIVATE void sqlite4AlterRenameTable(Parse*, SrcList*, Token*);
SQLITE_PRIVATE int sqlite4GetToken(const unsigned char *, int *);
SQLITE_PRIVATE void sqlite4NestedParse(Parse*, const char*, ...);
SQLITE_PRIVATE void sqlite4ExpirePreparedStatements(sqlite4*);
SQLITE_PRIVATE int sqlite4CodeSubselect(Parse *, Expr *, int, int);
SQLITE_PRIVATE void sqlite4SelectPrep(Parse*, Select*, NameContext*);
SQLITE_PRIVATE int sqlite4ResolveExprNames(NameContext*, Expr*);
SQLITE_PRIVATE void sqlite4ResolveSelectNames(Parse*, Select*, NameContext*);
SQLITE_PRIVATE int sqlite4ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
SQLITE_PRIVATE void sqlite4ColumnDefault(Vdbe *, Table *, int, int);
SQLITE_PRIVATE void sqlite4AlterFinishAddColumn(Parse *, Token *);
SQLITE_PRIVATE void sqlite4AlterBeginAddColumn(Parse *, SrcList *);
SQLITE_PRIVATE CollSeq *sqlite4GetCollSeq(sqlite4*, u8, CollSeq *, const char*);
SQLITE_PRIVATE char sqlite4AffinityType(const char*);
SQLITE_PRIVATE void sqlite4Analyze(Parse*, Token*, Token*);
SQLITE_PRIVATE int sqlite4FindDb(sqlite4*, Token*);
SQLITE_PRIVATE int sqlite4FindDbName(sqlite4 *, const char *);
SQLITE_PRIVATE int sqlite4AnalysisLoad(sqlite4*,int iDB);
SQLITE_PRIVATE void sqlite4DeleteIndexSamples(sqlite4*,Index*);
SQLITE_PRIVATE void sqlite4DefaultRowEst(Index*);
SQLITE_PRIVATE void sqlite4RegisterLikeFunctions(sqlite4*, int);
SQLITE_PRIVATE int sqlite4IsLikeFunction(sqlite4*,Expr*,int*,char*);
SQLITE_PRIVATE void sqlite4SchemaClear(sqlite4_env*,Schema*);
SQLITE_PRIVATE Schema *sqlite4SchemaGet(sqlite4*);
SQLITE_PRIVATE int sqlite4SchemaToIndex(sqlite4 *db, Schema *);
SQLITE_PRIVATE KeyInfo *sqlite4IndexKeyinfo(Parse *, Index *);
SQLITE_PRIVATE int sqlite4CreateFunc(sqlite4 *, const char *, int, int, void *,
void (*)(sqlite4_context*,int,sqlite4_value **),
void (*)(sqlite4_context*,int,sqlite4_value **), void (*)(sqlite4_context*),
FuncDestructor *pDestructor
);
SQLITE_PRIVATE int sqlite4ApiExit(sqlite4 *db, int);
SQLITE_PRIVATE int sqlite4OpenTempDatabase(Parse *);
SQLITE_PRIVATE void sqlite4StrAccumInit(StrAccum*, char*, int, int);
SQLITE_PRIVATE void sqlite4StrAccumAppend(StrAccum*,const char*,int);
SQLITE_PRIVATE void sqlite4AppendSpace(StrAccum*,int);
SQLITE_PRIVATE char *sqlite4StrAccumFinish(StrAccum*);
SQLITE_PRIVATE void sqlite4StrAccumReset(StrAccum*);
SQLITE_PRIVATE void sqlite4SelectDestInit(SelectDest*,int,int);
SQLITE_PRIVATE Expr *sqlite4CreateColumnExpr(sqlite4 *, SrcList *, int, int);
SQLITE_PRIVATE void sqlite4OpenPrimaryKey(Parse*, int iCur, int iDb, Table*, int);
SQLITE_PRIVATE void sqlite4OpenIndex(Parse*, int iCur, int iDb, Index*, int);
SQLITE_PRIVATE int sqlite4OpenAllIndexes(Parse *, Table *, int, int);
SQLITE_PRIVATE void sqlite4CloseAllIndexes(Parse *, Table *, int);
SQLITE_PRIVATE Index *sqlite4FindPrimaryKey(Table *, int *);
/*
** The interface to the LEMON-generated parser
*/
SQLITE_PRIVATE void *sqlite4ParserAlloc(void*(*)(void*,size_t), void*);
SQLITE_PRIVATE void sqlite4ParserFree(void*, void(*)(void*,void*));
SQLITE_PRIVATE void sqlite4Parser(void*, int, Token, Parse*);
#ifdef YYTRACKMAXSTACKDEPTH
SQLITE_PRIVATE int sqlite4ParserStackPeak(void*);
#endif
SQLITE_PRIVATE void sqlite4AutoLoadExtensions(sqlite4*);
#ifndef SQLITE_OMIT_LOAD_EXTENSION
SQLITE_PRIVATE void sqlite4CloseExtensions(sqlite4*);
#else
# define sqlite4CloseExtensions(X)
#endif
#ifdef SQLITE_TEST
SQLITE_PRIVATE int sqlite4Utf8To8(unsigned char*);
#endif
#ifdef SQLITE_OMIT_VIRTUALTABLE
# define sqlite4VtabClear(Y)
# define sqlite4VtabSync(X,Y) SQLITE_OK
# define sqlite4VtabRollback(X)
# define sqlite4VtabCommit(X)
# define sqlite4VtabInSync(db) 0
# define sqlite4VtabLock(X)
# define sqlite4VtabUnlock(X)
# define sqlite4VtabUnlockList(X)
# define sqlite4VtabSavepoint(X, Y, Z) SQLITE_OK
# define sqlite4GetVTable(X,Y) ((VTable*)0)
#else
SQLITE_PRIVATE void sqlite4VtabClear(sqlite4 *db, Table*);
SQLITE_PRIVATE int sqlite4VtabSync(sqlite4 *db, char **);
SQLITE_PRIVATE int sqlite4VtabRollback(sqlite4 *db);
SQLITE_PRIVATE int sqlite4VtabCommit(sqlite4 *db);
SQLITE_PRIVATE void sqlite4VtabLock(VTable *);
SQLITE_PRIVATE void sqlite4VtabUnlock(VTable *);
SQLITE_PRIVATE void sqlite4VtabUnlockList(sqlite4*);
SQLITE_PRIVATE int sqlite4VtabSavepoint(sqlite4 *, int, int);
SQLITE_PRIVATE VTable *sqlite4GetVTable(sqlite4*, Table*);
# define sqlite4VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
#endif
SQLITE_PRIVATE void sqlite4VtabMakeWritable(Parse*,Table*);
SQLITE_PRIVATE void sqlite4VtabBeginParse(Parse*, Token*, Token*, Token*);
SQLITE_PRIVATE void sqlite4VtabFinishParse(Parse*, Token*);
SQLITE_PRIVATE void sqlite4VtabArgInit(Parse*);
SQLITE_PRIVATE void sqlite4VtabArgExtend(Parse*, Token*);
SQLITE_PRIVATE int sqlite4VtabCallCreate(sqlite4*, int, const char *, char **);
SQLITE_PRIVATE int sqlite4VtabCallConnect(Parse*, Table*);
SQLITE_PRIVATE int sqlite4VtabCallDestroy(sqlite4*, int, const char *);
SQLITE_PRIVATE int sqlite4VtabBegin(sqlite4 *, VTable *);
SQLITE_PRIVATE FuncDef *sqlite4VtabOverloadFunction(sqlite4 *,FuncDef*, int nArg, Expr*);
SQLITE_PRIVATE void sqlite4InvalidFunction(sqlite4_context*,int,sqlite4_value**);
SQLITE_PRIVATE int sqlite4VdbeParameterIndex(Vdbe*, const char*, int);
SQLITE_PRIVATE int sqlite4TransferBindings(sqlite4_stmt *, sqlite4_stmt *);
SQLITE_PRIVATE int sqlite4Reprepare(Vdbe*);
SQLITE_PRIVATE void sqlite4ExprListCheckLength(Parse*, ExprList*, const char*);
SQLITE_PRIVATE CollSeq *sqlite4BinaryCompareCollSeq(Parse *, Expr *, Expr *);
SQLITE_PRIVATE int sqlite4TempInMemory(const sqlite4*);
SQLITE_PRIVATE const char *sqlite4JournalModename(int);
SQLITE_PRIVATE int sqlite4Checkpoint(sqlite4*, int, int, int*, int*);
SQLITE_PRIVATE int sqlite4WalDefaultHook(void*,sqlite4*,const char*,int);
/* Declarations for functions in fkey.c. All of these are replaced by
** 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
** provided (enforcement of FK constraints requires the triggers sub-system).
*/
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
SQLITE_PRIVATE void sqlite4FkCheck(Parse*, Table*, int, int);
SQLITE_PRIVATE void sqlite4FkDropTable(Parse*, SrcList *, Table*);
SQLITE_PRIVATE void sqlite4FkActions(Parse*, Table*, ExprList*, int);
SQLITE_PRIVATE int sqlite4FkRequired(Parse*, Table*, int*);
SQLITE_PRIVATE u32 sqlite4FkOldmask(Parse*, Table*);
SQLITE_PRIVATE FKey *sqlite4FkReferences(Table *);
#else
#define sqlite4FkActions(a,b,c,d)
#define sqlite4FkCheck(a,b,c,d)
#define sqlite4FkDropTable(a,b,c)
#define sqlite4FkOldmask(a,b) 0
#define sqlite4FkRequired(a,b,c) 0
#endif
#ifndef SQLITE_OMIT_FOREIGN_KEY
SQLITE_PRIVATE void sqlite4FkDelete(sqlite4 *, Table*);
#else
#define sqlite4FkDelete(a,b)
#endif
/*
** Available fault injectors. Should be numbered beginning with 0.
*/
#define SQLITE_FAULTINJECTOR_MALLOC 0
#define SQLITE_FAULTINJECTOR_COUNT 1
/*
** The interface to the code in fault.c used for identifying "benign"
** malloc failures. This is only present if SQLITE_OMIT_BUILTIN_TEST
** is not defined.
*/
#ifndef SQLITE_OMIT_BUILTIN_TEST
SQLITE_PRIVATE void sqlite4BeginBenignMalloc(sqlite4_env*);
SQLITE_PRIVATE void sqlite4EndBenignMalloc(sqlite4_env*);
#else
#define sqlite4BeginBenignMalloc(X)
#define sqlite4EndBenignMalloc(X)
#endif
#define IN_INDEX_ROWID 1
#define IN_INDEX_EPH 2
#define IN_INDEX_INDEX 3
SQLITE_PRIVATE int sqlite4FindInIndex(Parse *, Expr *, int*);
SQLITE_PRIVATE Index *sqlite4FindExistingInIndex(Parse *, Expr *, int);
#if SQLITE_MAX_EXPR_DEPTH>0
SQLITE_PRIVATE void sqlite4ExprSetHeight(Parse *pParse, Expr *p);
SQLITE_PRIVATE int sqlite4SelectExprHeight(Select *);
SQLITE_PRIVATE int sqlite4ExprCheckHeight(Parse*, int);
#else
#define sqlite4ExprSetHeight(x,y)
#define sqlite4SelectExprHeight(x) 0
#define sqlite4ExprCheckHeight(x,y)
#endif
SQLITE_PRIVATE u32 sqlite4Get4byte(const u8*);
SQLITE_PRIVATE void sqlite4Put4byte(u8*, u32);
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
SQLITE_PRIVATE void sqlite4ConnectionBlocked(sqlite4 *, sqlite4 *);
SQLITE_PRIVATE void sqlite4ConnectionUnlocked(sqlite4 *db);
SQLITE_PRIVATE void sqlite4ConnectionClosed(sqlite4 *db);
#else
#define sqlite4ConnectionBlocked(x,y)
#define sqlite4ConnectionUnlocked(x)
#define sqlite4ConnectionClosed(x)
#endif
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE void sqlite4ParserTrace(FILE*, char *);
#endif
/*
** If the SQLITE_ENABLE IOTRACE exists then the global variable
** sqlite4IoTrace is a pointer to a printf-like routine used to
** print I/O tracing messages.
*/
#ifdef SQLITE_ENABLE_IOTRACE
# define IOTRACE(A) if( sqlite4IoTrace ){ sqlite4IoTrace A; }
SQLITE_PRIVATE void sqlite4VdbeIOTraceSql(Vdbe*);
SQLITE_PRIVATE void (*sqlite4IoTrace)(const char*,...);
#else
# define IOTRACE(A)
# define sqlite4VdbeIOTraceSql(X)
#endif
/*
** These routines are available for the mem2.c debugging memory allocator
** only. They are used to verify that different "types" of memory
** allocations are properly tracked by the system.
**
** sqlite4MemdebugSetType() sets the "type" of an allocation to one of
** the MEMTYPE_* macros defined below. The type must be a bitmask with
** a single bit set.
**
** sqlite4MemdebugHasType() returns true if any of the bits in its second
** argument match the type set by the previous sqlite4MemdebugSetType().
** sqlite4MemdebugHasType() is intended for use inside assert() statements.
**
** sqlite4MemdebugNoType() returns true if none of the bits in its second
** argument match the type set by the previous sqlite4MemdebugSetType().
**
** Perhaps the most important point is the difference between MEMTYPE_HEAP
** and MEMTYPE_LOOKASIDE. If an allocation is MEMTYPE_LOOKASIDE, that means
** it might have been allocated by lookaside, except the allocation was
** too large or lookaside was already full. It is important to verify
** 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.
**
** All of this is no-op for a production build. It only comes into
** play when the SQLITE_MEMDEBUG compile-time option is used.
*/
#ifdef SQLITE_MEMDEBUG
SQLITE_PRIVATE void sqlite4MemdebugSetType(void*,u8);
SQLITE_PRIVATE int sqlite4MemdebugHasType(const void*,u8);
SQLITE_PRIVATE int sqlite4MemdebugNoType(const void*,u8);
#else
# define sqlite4MemdebugSetType(X,Y) /* no-op */
# define sqlite4MemdebugHasType(X,Y) 1
# define sqlite4MemdebugNoType(X,Y) 1
#endif
#define MEMTYPE_HEAP 0x01 /* General heap allocations */
#define MEMTYPE_LOOKASIDE 0x02 /* Might have been lookaside memory */
#define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */
#define MEMTYPE_DB 0x10 /* Uses sqlite4DbMalloc, not sqlite_malloc */
#endif /* _SQLITEINT_H_ */
/************** End of sqliteInt.h *******************************************/
/************** Begin file global.c ******************************************/
/*
** 2008 June 13
**
** 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 definitions of global variables and contants.
*/
/* An array to map all upper-case characters into their corresponding
** lower-case character.
**
** SQLite only considers US-ASCII (or EBCDIC) characters. We do not
** handle case conversions for the UTF character set since the tables
** involved are nearly as big or bigger than SQLite itself.
*/
SQLITE_PRIVATE const unsigned char sqlite4UpperToLower[] = {
#ifdef SQLITE_ASCII
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 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,
36, 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, 63, 64, 97, 98, 99,100,101,102,103,
104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,
122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107,
108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,
126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,
162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,
180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,
198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,
216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,
234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,
252,253,254,255
#endif
#ifdef SQLITE_EBCDIC
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 0x */
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 1x */
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 2x */
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 3x */
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 4x */
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 5x */
96, 97, 66, 67, 68, 69, 70, 71, 72, 73,106,107,108,109,110,111, /* 6x */
112, 81, 82, 83, 84, 85, 86, 87, 88, 89,122,123,124,125,126,127, /* 7x */
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, /* 8x */
144,145,146,147,148,149,150,151,152,153,154,155,156,157,156,159, /* 9x */
160,161,162,163,164,165,166,167,168,169,170,171,140,141,142,175, /* Ax */
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, /* Bx */
192,129,130,131,132,133,134,135,136,137,202,203,204,205,206,207, /* Cx */
208,145,146,147,148,149,150,151,152,153,218,219,220,221,222,223, /* Dx */
224,225,162,163,164,165,166,167,168,169,232,203,204,205,206,207, /* Ex */
239,240,241,242,243,244,245,246,247,248,249,219,220,221,222,255, /* Fx */
#endif
};
/*
** The following 256 byte lookup table is used to support SQLites built-in
** equivalents to the following standard library functions:
**
** isspace() 0x01
** isalpha() 0x02
** isdigit() 0x04
** isalnum() 0x06
** isxdigit() 0x08
** toupper() 0x20
** SQLite identifier character 0x40
**
** Bit 0x20 is set if the mapped character requires translation to upper
** case. i.e. if the character is a lower-case ASCII character.
** If x is a lower-case ASCII character, then its upper-case equivalent
** is (x - 0x20). Therefore toupper() can be implemented as:
**
** (x & ~(map[x]&0x20))
**
** Standard function tolower() is implemented using the sqlite4UpperToLower[]
** array. tolower() is used more often than toupper() by SQLite.
**
** Bit 0x40 is set if the character non-alphanumeric and can be used in an
** SQLite identifier. Identifiers are alphanumerics, "_", "$", and any
** non-ASCII UTF character. Hence the test for whether or not a character is
** part of an identifier is 0x46.
**
** SQLite's versions are identical to the standard versions assuming a
** locale of "C". They are implemented as macros in sqliteInt.h.
*/
#ifdef SQLITE_ASCII
SQLITE_PRIVATE const unsigned char sqlite4CtypeMap[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00..07 ........ */
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, /* 08..0f ........ */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 10..17 ........ */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 18..1f ........ */
0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, /* 20..27 !"#$%&' */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 28..2f ()*+,-./ */
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, /* 30..37 01234567 */
0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 38..3f 89:;<=>? */
0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x02, /* 40..47 @ABCDEFG */
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 48..4f HIJKLMNO */
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 50..57 PQRSTUVW */
0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x40, /* 58..5f XYZ[\]^_ */
0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22, /* 60..67 `abcdefg */
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 68..6f hijklmno */
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 70..77 pqrstuvw */
0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, /* 78..7f xyz{|}~. */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 80..87 ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 88..8f ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 90..97 ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 98..9f ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* a0..a7 ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* a8..af ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* b0..b7 ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* b8..bf ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* c0..c7 ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* c8..cf ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* d0..d7 ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* d8..df ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* e0..e7 ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* e8..ef ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* f0..f7 ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 /* f8..ff ........ */
};
#endif
/*
** Default factory objects
*/
static KVFactory memFactory = {
0,
"temp",
sqlite4KVStoreOpenMem,
1
};
SQLITE_PRIVATE KVFactory sqlite4BuiltinFactory = {
&memFactory,
"main",
sqlite4KVStoreOpenLsm,
1
};
/*
** The following singleton contains the global configuration for
** the SQLite library.
*/
SQLITE_PRIVATE struct sqlite4_env sqlite4DefaultEnv = {
sizeof(sqlite4_env), /* nByte */
1, /* iVersion */
SQLITE_DEFAULT_MEMSTATUS, /* bMemstat */
1, /* bCoreMutex */
SQLITE_THREADSAFE==1, /* bFullMutex */
0x7ffffffe, /* mxStrlen */
128, /* szLookaside */
500, /* nLookaside */
{0,0,0,0,0,0,0,0,0}, /* m */
{0,0,0,0,0,0,0,0,0,0}, /* mutex */
(void*)0, /* pHeap */
0, /* nHeap */
0, 0, /* mnHeap, mxHeap */
0, /* mxParserStack */
&sqlite4BuiltinFactory, /* pFactory */
sqlite4OsRandomness, /* xRandomness */
sqlite4OsCurrentTime, /* xCurrentTime */
/* All the rest should always be initialized to zero */
0, /* isInit */
0, /* pPrngMutex */
0, 0, /* prngX, prngY */
0, /* xLog */
0, /* pLogArg */
0, /* bLocaltimeFault */
0, /* pMemMutex */
{0,0,0,0}, /* nowValue[] */
{0,0,0,0}, /* mxValue[] */
{0,} /* hashGlobalFunc */
};
/*
** Return the default environment
*/
SQLITE_API sqlite4_env *sqlite4_env_default(void){ return &sqlite4DefaultEnv; }
/*
** Constant tokens for values 0 and 1.
*/
SQLITE_PRIVATE const Token sqlite4IntTokens[] = {
{ "0", 1 },
{ "1", 1 }
};
/*
** Properties of opcodes. The OPFLG_INITIALIZER macro is
** created by mkopcodeh.awk during compilation. Data is obtained
** from the comments following the "case OP_xxxx:" statements in
** the vdbe.c file.
*/
SQLITE_PRIVATE const unsigned char sqlite4OpcodeProperty[] = OPFLG_INITIALIZER;
/************** End of global.c **********************************************/
/************** Begin file ctime.c *******************************************/
/*
** 2010 February 23
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file implements routines used to report what compile-time options
** SQLite was built with.
*/
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
/*
** An array of names of all compile-time options. This array should
** be sorted A-Z.
**
** This array looks large, but in a typical installation actually uses
** only a handful of compile-time options, so most times this array is usually
** rather short and uses little memory space.
*/
static const char * const azCompileOpt[] = {
/* These macros are provided to "stringify" the value of the define
** for those options in which the value is meaningful. */
#define CTIMEOPT_VAL_(opt) #opt
#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
#ifdef SQLITE_32BIT_ROWID
"32BIT_ROWID",
#endif
#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC
"4_BYTE_ALIGNED_MALLOC",
#endif
#ifdef SQLITE_CASE_SENSITIVE_LIKE
"CASE_SENSITIVE_LIKE",
#endif
#ifdef SQLITE_CHECK_PAGES
"CHECK_PAGES",
#endif
#ifdef SQLITE_COVERAGE_TEST
"COVERAGE_TEST",
#endif
#ifdef SQLITE_DEBUG
"DEBUG",
#endif
#ifdef SQLITE_DEFAULT_LOCKING_MODE
"DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE),
#endif
#ifdef SQLITE_DISABLE_DIRSYNC
"DISABLE_DIRSYNC",
#endif
#ifdef SQLITE_DISABLE_LFS
"DISABLE_LFS",
#endif
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
"ENABLE_ATOMIC_WRITE",
#endif
#ifdef SQLITE_ENABLE_CEROD
"ENABLE_CEROD",
#endif
#ifdef SQLITE_ENABLE_COLUMN_METADATA
"ENABLE_COLUMN_METADATA",
#endif
#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
"ENABLE_EXPENSIVE_ASSERT",
#endif
#ifdef SQLITE_ENABLE_FTS1
"ENABLE_FTS1",
#endif
#ifdef SQLITE_ENABLE_FTS2
"ENABLE_FTS2",
#endif
#ifdef SQLITE_ENABLE_FTS3
"ENABLE_FTS3",
#endif
#ifdef SQLITE_ENABLE_FTS3_PARENTHESIS
"ENABLE_FTS3_PARENTHESIS",
#endif
#ifdef SQLITE_ENABLE_FTS4
"ENABLE_FTS4",
#endif
#ifdef SQLITE_ENABLE_ICU
"ENABLE_ICU",
#endif
#ifdef SQLITE_ENABLE_IOTRACE
"ENABLE_IOTRACE",
#endif
#ifdef SQLITE_ENABLE_LOAD_EXTENSION
"ENABLE_LOAD_EXTENSION",
#endif
#ifdef SQLITE_ENABLE_LOCKING_STYLE
"ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE),
#endif
#ifdef SQLITE_ENABLE_MEMSYS3
"ENABLE_MEMSYS3",
#endif
#ifdef SQLITE_ENABLE_MEMSYS5
"ENABLE_MEMSYS5",
#endif
#ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK
"ENABLE_OVERSIZE_CELL_CHECK",
#endif
#ifdef SQLITE_ENABLE_RTREE
"ENABLE_RTREE",
#endif
#ifdef SQLITE_ENABLE_STAT3
"ENABLE_STAT3",
#endif
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
"ENABLE_UNLOCK_NOTIFY",
#endif
#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
"ENABLE_UPDATE_DELETE_LIMIT",
#endif
#ifdef SQLITE_HAS_CODEC
"HAS_CODEC",
#endif
#ifdef SQLITE_HAVE_ISNAN
"HAVE_ISNAN",
#endif
#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
"HOMEGROWN_RECURSIVE_MUTEX",
#endif
#ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS
"IGNORE_AFP_LOCK_ERRORS",
#endif
#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
"IGNORE_FLOCK_LOCK_ERRORS",
#endif
#ifdef SQLITE_INT64_TYPE
"INT64_TYPE",
#endif
#ifdef SQLITE_LOCK_TRACE
"LOCK_TRACE",
#endif
#ifdef SQLITE_MAX_SCHEMA_RETRY
"MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY),
#endif
#ifdef SQLITE_MEMDEBUG
"MEMDEBUG",
#endif
#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
"MIXED_ENDIAN_64BIT_FLOAT",
#endif
#ifdef SQLITE_NO_SYNC
"NO_SYNC",
#endif
#ifdef SQLITE_OMIT_ALTERTABLE
"OMIT_ALTERTABLE",
#endif
#ifdef SQLITE_OMIT_ANALYZE
"OMIT_ANALYZE",
#endif
#ifdef SQLITE_OMIT_ATTACH
"OMIT_ATTACH",
#endif
#ifdef SQLITE_OMIT_AUTHORIZATION
"OMIT_AUTHORIZATION",
#endif
#ifdef SQLITE_OMIT_AUTOINCREMENT
"OMIT_AUTOINCREMENT",
#endif
#ifdef SQLITE_OMIT_AUTOINIT
"OMIT_AUTOINIT",
#endif
#ifdef SQLITE_OMIT_AUTOMATIC_INDEX
"OMIT_AUTOMATIC_INDEX",
#endif
#ifdef SQLITE_OMIT_AUTORESET
"OMIT_AUTORESET",
#endif
#ifdef SQLITE_OMIT_BETWEEN_OPTIMIZATION
"OMIT_BETWEEN_OPTIMIZATION",
#endif
#ifdef SQLITE_OMIT_BLOB_LITERAL
"OMIT_BLOB_LITERAL",
#endif
#ifdef SQLITE_OMIT_BUILTIN_TEST
"OMIT_BUILTIN_TEST",
#endif
#ifdef SQLITE_OMIT_CAST
"OMIT_CAST",
#endif
#ifdef SQLITE_OMIT_CHECK
"OMIT_CHECK",
#endif
/* // redundant
** #ifdef SQLITE_OMIT_COMPILEOPTION_DIAGS
** "OMIT_COMPILEOPTION_DIAGS",
** #endif
*/
#ifdef SQLITE_OMIT_COMPLETE
"OMIT_COMPLETE",
#endif
#ifdef SQLITE_OMIT_COMPOUND_SELECT
"OMIT_COMPOUND_SELECT",
#endif
#ifdef SQLITE_OMIT_DATETIME_FUNCS
"OMIT_DATETIME_FUNCS",
#endif
#ifdef SQLITE_OMIT_DECLTYPE
"OMIT_DECLTYPE",
#endif
#ifdef SQLITE_OMIT_DEPRECATED
"OMIT_DEPRECATED",
#endif
#ifdef SQLITE_OMIT_DISKIO
"OMIT_DISKIO",
#endif
#ifdef SQLITE_OMIT_EXPLAIN
"OMIT_EXPLAIN",
#endif
#ifdef SQLITE_OMIT_FLAG_PRAGMAS
"OMIT_FLAG_PRAGMAS",
#endif
#ifdef SQLITE_OMIT_FLOATING_POINT
"OMIT_FLOATING_POINT",
#endif
#ifdef SQLITE_OMIT_FOREIGN_KEY
"OMIT_FOREIGN_KEY",
#endif
#ifdef SQLITE_OMIT_GET_TABLE
"OMIT_GET_TABLE",
#endif
#ifdef SQLITE_OMIT_INTEGRITY_CHECK
"OMIT_INTEGRITY_CHECK",
#endif
#ifdef SQLITE_OMIT_LIKE_OPTIMIZATION
"OMIT_LIKE_OPTIMIZATION",
#endif
#ifdef SQLITE_OMIT_LOAD_EXTENSION
"OMIT_LOAD_EXTENSION",
#endif
#ifdef SQLITE_OMIT_LOCALTIME
"OMIT_LOCALTIME",
#endif
#ifdef SQLITE_OMIT_LOOKASIDE
"OMIT_LOOKASIDE",
#endif
#ifdef SQLITE_OMIT_MEMORYDB
"OMIT_MEMORYDB",
#endif
#ifdef SQLITE_OMIT_OR_OPTIMIZATION
"OMIT_OR_OPTIMIZATION",
#endif
#ifdef SQLITE_OMIT_PAGER_PRAGMAS
"OMIT_PAGER_PRAGMAS",
#endif
#ifdef SQLITE_OMIT_PRAGMA
"OMIT_PRAGMA",
#endif
#ifdef SQLITE_OMIT_PROGRESS_CALLBACK
"OMIT_PROGRESS_CALLBACK",
#endif
#ifdef SQLITE_OMIT_QUICKBALANCE
"OMIT_QUICKBALANCE",
#endif
#ifdef SQLITE_OMIT_REINDEX
"OMIT_REINDEX",
#endif
#ifdef SQLITE_OMIT_SCHEMA_PRAGMAS
"OMIT_SCHEMA_PRAGMAS",
#endif
#ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
"OMIT_SCHEMA_VERSION_PRAGMAS",
#endif
#ifdef SQLITE_OMIT_SUBQUERY
"OMIT_SUBQUERY",
#endif
#ifdef SQLITE_OMIT_TCL_VARIABLE
"OMIT_TCL_VARIABLE",
#endif
#ifdef SQLITE_OMIT_TEMPDB
"OMIT_TEMPDB",
#endif
#ifdef SQLITE_OMIT_TRACE
"OMIT_TRACE",
#endif
#ifdef SQLITE_OMIT_TRIGGER
"OMIT_TRIGGER",
#endif
#ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
"OMIT_TRUNCATE_OPTIMIZATION",
#endif
#ifdef SQLITE_OMIT_UTF16
"OMIT_UTF16",
#endif
#ifdef SQLITE_OMIT_VIEW
"OMIT_VIEW",
#endif
#ifdef SQLITE_OMIT_VIRTUALTABLE
"OMIT_VIRTUALTABLE",
#endif
#ifdef SQLITE_OMIT_XFER_OPT
"OMIT_XFER_OPT",
#endif
#ifdef SQLITE_PERFORMANCE_TRACE
"PERFORMANCE_TRACE",
#endif
#ifdef SQLITE_PROXY_DEBUG
"PROXY_DEBUG",
#endif
#ifdef SQLITE_SECURE_DELETE
"SECURE_DELETE",
#endif
#ifdef SQLITE_SMALL_STACK
"SMALL_STACK",
#endif
#ifdef SQLITE_SOUNDEX
"SOUNDEX",
#endif
#ifdef SQLITE_TCL
"TCL",
#endif
#ifdef SQLITE_TEMP_STORE
"TEMP_STORE=" CTIMEOPT_VAL(SQLITE_TEMP_STORE),
#endif
#ifdef SQLITE_TEST
"TEST",
#endif
#ifdef SQLITE_THREADSAFE
"THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE),
#endif
#ifdef SQLITE_USE_ALLOCA
"USE_ALLOCA",
#endif
#ifdef SQLITE_ZERO_MALLOC
"ZERO_MALLOC"
#endif
};
/*
** 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 sqlite4_compileoption_used(const char *zOptName){
int i, n;
if( sqlite4StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7;
n = sqlite4Strlen30(zOptName);
/* Since ArraySize(azCompileOpt) is normally in single digits, a
** linear search is adequate. No need for a binary search. */
for(i=0; i<ArraySize(azCompileOpt); i++){
if( (sqlite4StrNICmp(zOptName, azCompileOpt[i], n)==0)
&& ( (azCompileOpt[i][n]==0) || (azCompileOpt[i][n]=='=') ) ) 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 *sqlite4_compileoption_get(int N){
if( N>=0 && N<ArraySize(azCompileOpt) ){
return azCompileOpt[N];
}
return 0;
}
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
/************** End of ctime.c ***********************************************/
/************** Begin file status.c ******************************************/
/*
** 2008 June 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 module implements the sqlite4_status() interface and related
** functionality.
*/
/************** Include vdbeInt.h in the middle of status.c ******************/
/************** Begin file vdbeInt.h *****************************************/
/*
** 2003 September 6
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This is the header file for information that is private to the
** VDBE. This information used to all be at the top of the single
** source code file "vdbe.c". When that file became too big (over
** 6000 lines long) it was split up into several smaller files and
** this header information was factored out.
*/
#ifndef _VDBEINT_H_
#define _VDBEINT_H_
/*
** SQL is translated into a sequence of instructions to be
** executed by a virtual machine. Each instruction is an instance
** of the following structure.
*/
typedef struct VdbeOp Op;
/*
** Boolean values
*/
typedef unsigned char Bool;
/* Opaque type used by code in vdbesort.c */
typedef struct VdbeSorter VdbeSorter;
/* Opaque type used by the explainer */
typedef struct Explain Explain;
/* Opaque type used by vdbecodec.c */
typedef struct ValueDecoder ValueDecoder;
/*
** A cursor is a pointer into a single database.
** The cursor can seek to an entry with a particular key, or
** loop over all entries. You can also insert new
** entries or retrieve the key or data from the entry that the cursor
** is currently pointing to.
**
** Every cursor that the virtual machine has open is represented by an
** instance of the following structure.
*/
struct VdbeCursor {
KVCursor *pKVCur; /* The cursor structure of the backend */
KVStore *pTmpKV; /* Separate file holding a temporary table */
KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */
int iDb; /* Index of cursor database in db->aDb[] (or -1) */
int iRoot; /* Root page of the table */
int pseudoTableReg; /* Register holding pseudotable content. */
int nField; /* Number of fields in the header */
Bool zeroed; /* True if zeroed out and ready for reuse */
Bool rowidIsValid; /* True if lastRowid is valid */
Bool atFirst; /* True if pointing to first entry */
Bool nullRow; /* True if pointing to a row with no data */
Bool isTable; /* True if a table requiring integer keys */
Bool isIndex; /* True if an index containing keys only - no data */
Bool isOrdered; /* True if the underlying table is BTREE_UNORDERED */
sqlite4_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */
const sqlite4_module *pModule; /* Module for cursor pVtabCursor */
i64 seqCount; /* Sequence counter */
i64 movetoTarget; /* Argument to the deferred move-to */
i64 lastRowid; /* Last rowid from a Next or NextIdx operation */
VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */
/* Result of last sqlite4-Moveto() done by an OP_NotExists or
** OP_IsUnique opcode on this cursor. */
int seekResult;
};
/*
** 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
** values stored in the Vdbe struct. When the sub-program is finished,
** these values are copied back to the Vdbe from the VdbeFrame structure,
** restoring the state of the VM to as it was before the sub-program
** began executing.
**
** The memory for a VdbeFrame object is allocated and managed by a memory
** cell in the parent (calling) frame. When the memory cell is deleted or
** overwritten, the VdbeFrame object is not freed immediately. Instead, it
** is linked into the Vdbe.pDelFrame list. The contents of the Vdbe.pDelFrame
** list is deleted when the VM is reset in VdbeHalt(). The reason for doing
** this instead of deleting the VdbeFrame immediately is to avoid recursive
** calls to sqlite4VdbeMemRelease() when the memory cells belonging to the
** child frame are released.
**
** The currently executing frame is stored in Vdbe.pFrame. Vdbe.pFrame is
** set to NULL if the currently executing frame is the main program.
*/
typedef struct VdbeFrame VdbeFrame;
struct VdbeFrame {
Vdbe *v; /* VM this frame belongs to */
int pc; /* Program Counter in parent (calling) frame */
Op *aOp; /* Program instructions for parent frame */
int nOp; /* Size of aOp array */
Mem *aMem; /* Array of memory cells for parent frame */
int nMem; /* Number of entries in aMem */
u8 *aOnceFlag; /* Array of OP_Once flags for parent frame */
int nOnceFlag; /* Number of entries in aOnceFlag */
VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */
u16 nCursor; /* Number of entries in apCsr */
void *token; /* Copy of SubProgram.token */
int nChildMem; /* Number of memory cells for child frame */
int nChildCsr; /* Number of cursors for child frame */
i64 lastRowid; /* Last insert rowid (sqlite4.lastRowid) */
int nChange; /* Statement changes (Vdbe.nChanges) */
VdbeFrame *pParent; /* Parent of this frame, or NULL if parent is main */
};
#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
/*
** A value for VdbeCursor.cacheValid that means the cache is always invalid.
*/
#define CACHE_STALE 0
/*
** Internally, the vdbe manipulates nearly all SQL values as Mem
** structures. Each Mem struct may cache multiple representations (string,
** integer etc.) of the same value.
*/
struct Mem {
sqlite4 *db; /* The associated database connection */
char *z; /* String or BLOB value */
double r; /* Real value */
union {
i64 i; /* Integer value used when MEM_Int is set in flags */
int nZero; /* Used when bit MEM_Zero is set in flags */
FuncDef *pDef; /* Used only when flags==MEM_Agg */
RowSet *pRowSet; /* Used only when flags==MEM_RowSet */
VdbeFrame *pFrame; /* Used when flags==MEM_Frame */
} u;
int n; /* Number of characters in string value, excluding '\0' */
u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
u8 type; /* One of SQLITE_NULL, SQLITE_TEXT, SQLITE_INTEGER, etc */
u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
#ifdef SQLITE_DEBUG
Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */
void *pFiller; /* So that sizeof(Mem) is a multiple of 8 */
#endif
void (*xDel)(void *); /* If not null, call this function to delete Mem.z */
char *zMalloc; /* Dynamic buffer allocated by sqlite4_malloc() */
};
/* One or more of the following flags are set to indicate the validOK
** representations of the value stored in the Mem struct.
**
** If the MEM_Null flag is set, then the value is an SQL NULL value.
** No other flags may be set in this case.
**
** 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
** database (see below for exceptions). If the MEM_Term flag is also
** 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 */
#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 */
#define MEM_Blob 0x0010 /* Value is a BLOB */
#define MEM_RowSet 0x0020 /* Value is a RowSet object */
#define MEM_Frame 0x0040 /* Value is a VdbeFrame object */
#define MEM_Invalid 0x0080 /* Value is undefined */
#define MEM_TypeMask 0x00ff /* Mask of type bits */
/* Whenever Mem contains a valid string or blob representation, one of
** the following flags must be set to determine the memory management
** policy for Mem.z. The MEM_Term flag tells us whether or not the
** string is \000 or \u0000 terminated
*/
#define MEM_Term 0x0200 /* String rep is nul terminated */
#define MEM_Dyn 0x0400 /* Need to call sqliteFree() 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 */
/*
** Clear any existing type flags from a Mem and replace them with f
*/
#define MemSetTypeFlag(p, f) \
((p)->flags = ((p)->flags&~(MEM_TypeMask|MEM_Zero))|f)
/*
** Return true if a memory cell is not marked as invalid. This macro
** is for use inside assert() statements only.
*/
#ifdef SQLITE_DEBUG
#define memIsValid(M) ((M)->flags & MEM_Invalid)==0
#endif
/* A VdbeFunc is just a FuncDef (defined in sqliteInt.h) that contains
** additional information about auxiliary information bound to arguments
** of the function. This is used to implement the sqlite4_get_auxdata()
** and sqlite4_set_auxdata() APIs. The "auxdata" is some auxiliary data
** that can be associated with a constant argument to a function. This
** allows functions such as "regexp" to compile their constant regular
** expression argument once and reused the compiled code for multiple
** invocations.
*/
struct VdbeFunc {
FuncDef *pFunc; /* The definition of the function */
int nAux; /* Number of entries allocated for apAux[] */
struct AuxData {
void *pAux; /* Aux data for the i-th argument */
void (*xDelete)(void *); /* Destructor for the aux data */
} apAux[1]; /* One slot for each function argument */
};
/*
** The "context" argument for a installable function. A pointer to an
** instance of this structure is the first argument to the routines used
** implement the SQL functions.
**
** There is a typedef for this structure in sqlite.h. So all routines,
** even the public interface to SQLite, can use a pointer to this structure.
** But this file is the only place where the internal details of this
** structure are known.
**
** This structure is defined inside of vdbeInt.h because it uses substructures
** (Mem) which are only defined there.
*/
struct sqlite4_context {
FuncDef *pFunc; /* Pointer to function information. MUST BE FIRST */
VdbeFunc *pVdbeFunc; /* Auxilary data, if created. */
Mem s; /* The return value is stored here */
Mem *pMem; /* Memory cell used to store aggregate context */
int isError; /* Error code returned by the function. */
CollSeq *pColl; /* Collating sequence */
};
/*
** An Explain object accumulates indented output which is helpful
** in describing recursive data structures.
*/
struct Explain {
Vdbe *pVdbe; /* Attach the explanation to this Vdbe */
StrAccum str; /* The string being accumulated */
int nIndent; /* Number of elements in aIndent */
u16 aIndent[100]; /* Levels of indentation */
char zBase[100]; /* Initial space */
};
/*
** An instance of the virtual machine. This structure contains the complete
** state of the virtual machine.
**
** The "sqlite4_stmt" structure pointer that is returned by sqlite4_prepare()
** is really a pointer to an instance of this structure.
**
** The Vdbe.inVtabMethod variable is set to non-zero for the duration of
** any virtual table method invocations made by the vdbe program. It is
** set to 2 for xDestroy method calls and 1 for all other methods. This
** variable is used for two purposes: to allow xDestroy methods to execute
** "DROP TABLE" statements and to prevent some nasty side effects of
** malloc failure when SQLite is invoked recursively by a virtual table
** method function.
*/
struct Vdbe {
sqlite4 *db; /* The database connection that owns this statement */
Op *aOp; /* Space to hold the virtual machine's program */
Mem *aMem; /* The memory locations */
Mem **apArg; /* Arguments to currently executing user function */
Mem *aColName; /* Column names to return */
Mem *pResultSet; /* Pointer to an array of results */
int nMem; /* Number of memory locations currently allocated */
int nOp; /* Number of instructions in the program */
int nOpAlloc; /* Number of slots allocated for aOp[] */
int nLabel; /* Number of labels used */
int nLabelAlloc; /* Number of slots allocated in aLabel[] */
int *aLabel; /* Space to hold the labels */
u16 nResColumn; /* Number of columns in one row of the result set */
u16 nCursor; /* Number of slots in apCsr[] */
u32 magic; /* Magic number for sanity checking */
char *zErrMsg; /* Error message written here */
Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
VdbeCursor **apCsr; /* One element of this array for each open cursor */
Mem *aVar; /* Values for the OP_Variable opcode. */
char **azVar; /* Name of variables */
ynVar nVar; /* Number of entries in aVar[] */
ynVar nzVar; /* Number of entries in azVar[] */
u32 cacheCtr; /* VdbeCursor row cache generation counter */
int pc; /* The program counter */
int rc; /* Value to return */
u8 errorAction; /* Recovery action to do in case of an error */
u8 explain; /* True if EXPLAIN present on SQL command */
u8 changeCntOn; /* True to update the change-counter */
u8 expired; /* True if the VM needs to be recompiled */
u8 runOnlyOnce; /* Automatically expire on reset */
u8 minWriteFileFormat; /* Minimum file format for writable database files */
u8 inVtabMethod; /* See comments above */
u8 needSavepoint; /* True if a change might abort and needs savepoint */
u8 readOnly; /* True for read-only statements */
int nChange; /* Number of db changes made since last reset */
yDbMask stmtTransMask; /* db->aDb[] entries that have a subtransaction */
int aCounter[3]; /* Counters used by sqlite4_stmt_status() */
#ifndef SQLITE_OMIT_TRACE
i64 startTime; /* Time when query started - used for profiling */
#endif
i64 nFkConstraint; /* Number of imm. FK constraints this VM */
i64 nStmtDefCons; /* Number of def. constraints when stmt started */
char *zSql; /* Text of the SQL statement that generated this */
void *pFree; /* Free this when deleting the vdbe */
#ifdef SQLITE_DEBUG
FILE *trace; /* Write an execution trace here, if not NULL */
#endif
#ifdef SQLITE_ENABLE_TREE_EXPLAIN
Explain *pExplain; /* The explainer */
char *zExplain; /* Explanation of data structures */
#endif
VdbeFrame *pFrame; /* Parent frame */
VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */
int nFrame; /* Number of frames in pFrame list */
u32 expmask; /* Binding to these vars invalidates VM */
SubProgram *pProgram; /* Linked list of all sub-programs used by VM */
int nOnceFlag; /* Size of array aOnceFlag[] */
u8 *aOnceFlag; /* Flags for OP_Once */
};
/*
** The following are allowed values for Vdbe.magic
*/
#define VDBE_MAGIC_INIT 0x26bceaa5 /* Building a VDBE program */
#define VDBE_MAGIC_RUN 0xbdf20da3 /* VDBE is ready to execute */
#define VDBE_MAGIC_HALT 0x519c2973 /* VDBE has completed execution */
#define VDBE_MAGIC_DEAD 0xb606c3c8 /* The VDBE has been deallocated */
/*
** Function prototypes
*/
SQLITE_PRIVATE void sqlite4VdbeFreeCursor(Vdbe *, VdbeCursor*);
void sqliteVdbePopStack(Vdbe*,int);
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
SQLITE_PRIVATE void sqlite4VdbePrintOp(FILE*, int, Op*);
#endif
SQLITE_PRIVATE u32 sqlite4VdbeSerialTypeLen(u32);
SQLITE_PRIVATE u32 sqlite4VdbeSerialType(Mem*, int);
SQLITE_PRIVATE u32 sqlite4VdbeSerialPut(unsigned char*, int, Mem*, int);
SQLITE_PRIVATE u32 sqlite4VdbeSerialGet(const unsigned char*, u32, Mem*);
SQLITE_PRIVATE void sqlite4VdbeDeleteAuxData(VdbeFunc*, int);
SQLITE_PRIVATE int sqlite4VdbeCreateDecoder(
sqlite4 *db, /* The database connection */
const unsigned char *aIn, /* The input data blob */
int nIn, /* Number of bytes in aIn[] */
int mxCol, /* Maximum number of columns in aIn[] */
ValueDecoder **ppOut /* The newly generated decoder object */
);
SQLITE_PRIVATE int sqlite4VdbeDestroyDecoder(ValueDecoder *pDecoder);
SQLITE_PRIVATE int sqlite4VdbeDecodeValue(
ValueDecoder *pDecoder, /* The decoder for the whole string */
int iVal, /* Index of the value to decode. First is 0 */
Mem *pDefault, /* The default value. Often NULL */
Mem *pOut /* Write the result here */
);
SQLITE_PRIVATE int sqlite4VdbeEncodeData(
sqlite4 *db, /* The database connection */
Mem *aIn, /* Array of values to encode */
int nIn, /* Number of entries in aIn[] */
u8 **pzOut, /* The output data record */
int *pnOut /* Bytes of content in pzOut */
);
SQLITE_PRIVATE int sqlite4VdbeEncodeKey(
sqlite4 *db, /* The database connection */
Mem *aIn, /* Values to be encoded */
int nIn, /* Number of entries in aIn[] */
int iTabno, /* The table this key applies to */
KeyInfo *pKeyInfo, /* Collating sequence information */
u8 **pzOut, /* Write the resulting key here */
int *pnOut, /* Number of bytes in the key */
int bIncr /* Make the key "incrementable" */
);
SQLITE_PRIVATE int sqlite4VdbeEncodeIntKey(u8 *aBuf,sqlite4_int64 v);
SQLITE_PRIVATE int sqlite4VdbeDecodeIntKey(const KVByteArray*, KVSize, sqlite4_int64*);
SQLITE_PRIVATE int sqlite4VdbeShortKey(const u8 *, int, int);
SQLITE_PRIVATE int sqlite4MemCompare(const Mem*, const Mem*, const CollSeq*);
SQLITE_PRIVATE int sqlite4VdbeExec(Vdbe*);
SQLITE_PRIVATE int sqlite4VdbeList(Vdbe*);
SQLITE_PRIVATE int sqlite4VdbeHalt(Vdbe*);
SQLITE_PRIVATE int sqlite4VdbeChangeEncoding(Mem *, int);
SQLITE_PRIVATE int sqlite4VdbeMemTooBig(Mem*);
SQLITE_PRIVATE int sqlite4VdbeMemCopy(Mem*, const Mem*);
SQLITE_PRIVATE void sqlite4VdbeMemShallowCopy(Mem*, const Mem*, int);
SQLITE_PRIVATE void sqlite4VdbeMemMove(Mem*, Mem*);
SQLITE_PRIVATE int sqlite4VdbeMemNulTerminate(Mem*);
SQLITE_PRIVATE int sqlite4VdbeMemSetStr(Mem*, const char*, int, u8, void(*)(void*));
SQLITE_PRIVATE void sqlite4VdbeMemSetInt64(Mem*, i64);
#ifdef SQLITE_OMIT_FLOATING_POINT
# define sqlite4VdbeMemSetDouble sqlite4VdbeMemSetInt64
#else
SQLITE_PRIVATE void sqlite4VdbeMemSetDouble(Mem*, double);
#endif
SQLITE_PRIVATE void sqlite4VdbeMemSetNull(Mem*);
SQLITE_PRIVATE void sqlite4VdbeMemSetZeroBlob(Mem*,int);
SQLITE_PRIVATE int sqlite4VdbeMemMakeWriteable(Mem*);
SQLITE_PRIVATE int sqlite4VdbeMemStringify(Mem*, int);
SQLITE_PRIVATE i64 sqlite4VdbeIntValue(Mem*);
SQLITE_PRIVATE int sqlite4VdbeMemIntegerify(Mem*);
SQLITE_PRIVATE double sqlite4VdbeRealValue(Mem*);
SQLITE_PRIVATE void sqlite4VdbeIntegerAffinity(Mem*);
SQLITE_PRIVATE int sqlite4VdbeMemRealify(Mem*);
SQLITE_PRIVATE int sqlite4VdbeMemNumerify(Mem*);
SQLITE_PRIVATE void sqlite4VdbeMemSetRowSet(Mem *pMem);
SQLITE_PRIVATE void sqlite4VdbeMemRelease(Mem *p);
SQLITE_PRIVATE void sqlite4VdbeMemReleaseExternal(Mem *p);
#define VdbeMemRelease(X) \
if((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame)) \
sqlite4VdbeMemReleaseExternal(X);
SQLITE_PRIVATE int sqlite4VdbeMemFinalize(Mem*, FuncDef*);
SQLITE_PRIVATE const char *sqlite4OpcodeName(int);
SQLITE_PRIVATE int sqlite4VdbeMemGrow(Mem *pMem, int n, int preserve);
SQLITE_PRIVATE int sqlite4VdbeCloseStatement(Vdbe *, int);
SQLITE_PRIVATE void sqlite4VdbeFrameDelete(VdbeFrame*);
SQLITE_PRIVATE int sqlite4VdbeFrameRestore(VdbeFrame *);
SQLITE_PRIVATE void sqlite4VdbeMemStoreType(Mem *pMem);
SQLITE_PRIVATE int sqlite4VdbeTransferError(Vdbe *p);
SQLITE_PRIVATE int sqlite4VdbeSeekEnd(VdbeCursor*, int);
SQLITE_PRIVATE int sqlite4VdbeNext(VdbeCursor*);
SQLITE_PRIVATE int sqlite4VdbePrevious(VdbeCursor*);
SQLITE_PRIVATE int sqlite4VdbeRollback(sqlite4 *db, int iLevel);
SQLITE_PRIVATE int sqlite4VdbeCommit(sqlite4 *db, int iLevel);
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE void sqlite4VdbeMemAboutToChange(Vdbe*,Mem*);
#endif
#ifndef SQLITE_OMIT_FOREIGN_KEY
SQLITE_PRIVATE int sqlite4VdbeCheckFk(Vdbe *, int);
#else
# define sqlite4VdbeCheckFk(p,i) 0
#endif
SQLITE_PRIVATE int sqlite4VdbeMemTranslate(Mem*, u8);
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE void sqlite4VdbePrintSql(Vdbe*);
SQLITE_PRIVATE void sqlite4VdbeMemPrettyPrint(Mem *pMem, char *zBuf);
#endif
SQLITE_PRIVATE int sqlite4VdbeMemHandleBom(Mem *pMem);
#define sqlite4VdbeMemExpandBlob(x) SQLITE_OK
#define ExpandBlob(P) SQLITE_OK
#endif /* !defined(_VDBEINT_H_) */
/************** End of vdbeInt.h *********************************************/
/************** Continuing where we left off in status.c *********************/
/*
** Add N to the value of a status record. It is assumed that the
** caller holds appropriate locks.
*/
SQLITE_PRIVATE void sqlite4StatusAdd(sqlite4_env *pEnv, int op, sqlite4_int64 N){
assert( op>=0 && op<ArraySize(pEnv->nowValue) );
pEnv->nowValue[op] += N;
if( pEnv->nowValue[op]>pEnv->mxValue[op] ){
pEnv->mxValue[op] = pEnv->nowValue[op];
}
}
/*
** Set the value of a status to X.
*/
SQLITE_PRIVATE void sqlite4StatusSet(sqlite4_env *pEnv, int op, sqlite4_uint64 X){
assert( op>=0 && op<ArraySize(pEnv->nowValue) );
pEnv->nowValue[op] = X;
if( pEnv->nowValue[op]>pEnv->mxValue[op] ){
pEnv->mxValue[op] = pEnv->nowValue[op];
}
}
/*
** Query status information.
**
** This implementation assumes that reading or writing an aligned
** 32-bit integer is an atomic operation. If that assumption is not true,
** then this routine is not threadsafe.
*/
SQLITE_API int sqlite4_env_status(
sqlite4_env *pEnv,
int op,
sqlite4_uint64 *pCurrent,
sqlite4_uint64 *pHighwater,
int resetFlag
){
if( pEnv==0 ) pEnv = sqlite4_env_default();
if( op<0 || op>=ArraySize(pEnv->nowValue) ){
return SQLITE_MISUSE_BKPT;
}
*pCurrent = pEnv->nowValue[op];
*pHighwater = pEnv->mxValue[op];
if( resetFlag ){
pEnv->mxValue[op] = pEnv->nowValue[op];
}
return SQLITE_OK;
}
/*
** Query status information for a single database connection
*/
SQLITE_API int sqlite4_db_status(
sqlite4 *db, /* The database connection whose status is desired */
int op, /* Status verb */
int *pCurrent, /* Write current value here */
int *pHighwater, /* Write high-water mark here */
int resetFlag /* Reset high-water mark if true */
){
int rc = SQLITE_OK; /* Return code */
sqlite4_env *pEnv;
sqlite4_mutex_enter(db->mutex);
pEnv = db->pEnv;
switch( op ){
case SQLITE_DBSTATUS_LOOKASIDE_USED: {
*pCurrent = db->lookaside.nOut;
*pHighwater = db->lookaside.mxOut;
if( resetFlag ){
db->lookaside.mxOut = db->lookaside.nOut;
}
break;
}
case SQLITE_DBSTATUS_LOOKASIDE_HIT:
case SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE:
case SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL: {
testcase( op==SQLITE_DBSTATUS_LOOKASIDE_HIT );
testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE );
testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL );
assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)>=0 );
assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)<3 );
*pCurrent = 0;
*pHighwater = db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT];
if( resetFlag ){
db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT] = 0;
}
break;
}
/*
** Return an approximation for the amount of memory currently used
** by all pagers associated with the given database connection. The
** highwater mark is meaningless and is returned as zero.
*/
case SQLITE_DBSTATUS_CACHE_USED: {
int totalUsed = 0;
*pCurrent = totalUsed;
*pHighwater = 0;
break;
}
/*
** *pCurrent gets an accurate estimate of the amount of memory used
** to store the schema for all databases (main, temp, and any ATTACHed
** databases. *pHighwater is set to zero.
*/
case SQLITE_DBSTATUS_SCHEMA_USED: {
int i; /* Used to iterate through schemas */
int nByte = 0; /* Used to accumulate return value */
db->pnBytesFreed = &nByte;
for(i=0; i<db->nDb; i++){
Schema *pSchema = db->aDb[i].pSchema;
if( ALWAYS(pSchema!=0) ){
HashElem *p;
nByte += sizeof(HashElem) * (
pSchema->tblHash.count
+ pSchema->trigHash.count
+ pSchema->idxHash.count
+ pSchema->fkeyHash.count
);
nByte += sqlite4MallocSize(pEnv, pSchema->tblHash.ht);
nByte += sqlite4MallocSize(pEnv, pSchema->trigHash.ht);
nByte += sqlite4MallocSize(pEnv, pSchema->idxHash.ht);
nByte += sqlite4MallocSize(pEnv, pSchema->fkeyHash.ht);
for(p=sqliteHashFirst(&pSchema->trigHash); p; p=sqliteHashNext(p)){
sqlite4DeleteTrigger(db, (Trigger*)sqliteHashData(p));
}
for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){
sqlite4DeleteTable(db, (Table *)sqliteHashData(p));
}
}
}
db->pnBytesFreed = 0;
*pHighwater = 0;
*pCurrent = nByte;
break;
}
/*
** *pCurrent gets an accurate estimate of the amount of memory used
** to store all prepared statements.
** *pHighwater is set to zero.
*/
case SQLITE_DBSTATUS_STMT_USED: {
struct Vdbe *pVdbe; /* Used to iterate through VMs */
int nByte = 0; /* Used to accumulate return value */
db->pnBytesFreed = &nByte;
for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){
sqlite4VdbeDeleteObject(db, pVdbe);
}
db->pnBytesFreed = 0;
*pHighwater = 0;
*pCurrent = nByte;
break;
}
/*
** Set *pCurrent to the total cache hits or misses encountered by all
** pagers the database handle is connected to. *pHighwater is always set
** to zero.
*/
case SQLITE_DBSTATUS_CACHE_HIT:
case SQLITE_DBSTATUS_CACHE_MISS: {
int nRet = 0;
*pHighwater = 0;
*pCurrent = nRet;
break;
}
default: {
rc = SQLITE_ERROR;
}
}
sqlite4_mutex_leave(db->mutex);
return rc;
}
/************** End of status.c **********************************************/
/************** Begin file date.c ********************************************/
/*
** 2003 October 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 contains the C functions that implement date and time
** functions for SQLite.
**
** There is only one exported symbol in this file - the function
** sqlite4RegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope.
**
** SQLite processes all times and dates as Julian Day numbers. The
** dates and times are stored as the number of days since noon
** in Greenwich on November 24, 4714 B.C. according to the Gregorian
** calendar system.
**
** 1970-01-01 00:00:00 is JD 2440587.5
** 2000-01-01 00:00:00 is JD 2451544.5
**
** This implemention requires years to be expressed as a 4-digit number
** which means that only dates between 0000-01-01 and 9999-12-31 can
** be represented, even though julian day numbers allow a much wider
** range of dates.
**
** The Gregorian calendar system is used for all dates and times,
** even those that predate the Gregorian calendar. Historians usually
** use the Julian calendar for dates prior to 1582-10-15 and for some
** dates afterwards, depending on locale. Beware of this difference.
**
** The conversion algorithms are implemented based on descriptions
** in the following text:
**
** Jean Meeus
** Astronomical Algorithms, 2nd Edition, 1998
** ISBM 0-943396-61-1
** Willmann-Bell, Inc
** Richmond, Virginia (USA)
*/
/* #include <stdlib.h> */
/* #include <assert.h> */
#include <time.h>
#ifndef SQLITE_OMIT_DATETIME_FUNCS
/*
** A structure for holding a single date and time.
*/
typedef struct DateTime DateTime;
struct DateTime {
sqlite4_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 validYMD; /* True (1) if Y,M,D are valid */
char validHMS; /* True (1) if h,m,s are valid */
char validJD; /* True (1) if iJD is valid */
char validTZ; /* True (1) if tz is valid */
};
/*
** Convert zDate into one or more integers. Additional arguments
** come in groups of 5 as follows:
**
** N number of digits in the integer
** min minimum allowed value of the integer
** max maximum allowed value of the integer
** nextC first character after the integer
** pVal where to write the integers value.
**
** Conversions continue until one with nextC==0 is encountered.
** The function returns the number of successful conversions.
*/
static int getDigits(const char *zDate, ...){
va_list ap;
int val;
int N;
int min;
int max;
int nextC;
int *pVal;
int cnt = 0;
va_start(ap, zDate);
do{
N = va_arg(ap, int);
min = va_arg(ap, int);
max = va_arg(ap, int);
nextC = va_arg(ap, int);
pVal = va_arg(ap, int*);
val = 0;
while( N-- ){
if( !sqlite4Isdigit(*zDate) ){
goto end_getDigits;
}
val = val*10 + *zDate - '0';
zDate++;
}
if( val<min || val>max || (nextC!=0 && nextC!=*zDate) ){
goto end_getDigits;
}
*pVal = val;
zDate++;
cnt++;
}while( nextC );
end_getDigits:
va_end(ap);
return cnt;
}
/*
** Parse a timezone extension on the end of a date-time.
** The extension is of the form:
**
** (+/-)HH:MM
**
** Or the "zulu" notation:
**
** Z
**
** If the parse is successful, write the number of minutes
** of change in p->tz and return 0. If a parser error occurs,
** return non-zero.
**
** A missing specifier is not considered an error.
*/
static int parseTimezone(const char *zDate, DateTime *p){
int sgn = 0;
int nHr, nMn;
int c;
while( sqlite4Isspace(*zDate) ){ zDate++; }
p->tz = 0;
c = *zDate;
if( c=='-' ){
sgn = -1;
}else if( c=='+' ){
sgn = +1;
}else if( c=='Z' || c=='z' ){
zDate++;
goto zulu_time;
}else{
return c!=0;
}
zDate++;
if( getDigits(zDate, 2, 0, 14, ':', &nHr, 2, 0, 59, 0, &nMn)!=2 ){
return 1;
}
zDate += 5;
p->tz = sgn*(nMn + nHr*60);
zulu_time:
while( sqlite4Isspace(*zDate) ){ zDate++; }
return *zDate!=0;
}
/*
** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF.
** The HH, MM, and SS must each be exactly 2 digits. The
** fractional seconds FFFF can be one or more digits.
**
** Return 1 if there is a parsing error and 0 on success.
*/
static int parseHhMmSs(const char *zDate, DateTime *p){
int h, m, s;
double ms = 0.0;
if( getDigits(zDate, 2, 0, 24, ':', &h, 2, 0, 59, 0, &m)!=2 ){
return 1;
}
zDate += 5;
if( *zDate==':' ){
zDate++;
if( getDigits(zDate, 2, 0, 59, 0, &s)!=1 ){
return 1;
}
zDate += 2;
if( *zDate=='.' && sqlite4Isdigit(zDate[1]) ){
double rScale = 1.0;
zDate++;
while( sqlite4Isdigit(*zDate) ){
ms = ms*10.0 + *zDate - '0';
rScale *= 10.0;
zDate++;
}
ms /= rScale;
}
}else{
s = 0;
}
p->validJD = 0;
p->validHMS = 1;
p->h = h;
p->m = m;
p->s = s + ms;
if( parseTimezone(zDate, p) ) return 1;
p->validTZ = (p->tz!=0)?1:0;
return 0;
}
/*
** 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.
**
** Reference: Meeus page 61
*/
static void computeJD(DateTime *p){
int Y, M, D, A, B, X1, X2;
if( p->validJD ) return;
if( p->validYMD ){
Y = p->Y;
M = p->M;
D = p->D;
}else{
Y = 2000; /* If no YMD specified, assume 2000-Jan-01 */
M = 1;
D = 1;
}
if( M<=2 ){
Y--;
M += 12;
}
A = Y/100;
B = 2 - A + (A/4);
X1 = 36525*(Y+4716)/100;
X2 = 306001*(M+1)/10000;
p->iJD = (sqlite4_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000);
p->validJD = 1;
if( p->validHMS ){
p->iJD += p->h*3600000 + p->m*60000 + (sqlite4_int64)(p->s*1000);
if( p->validTZ ){
p->iJD -= p->tz*60000;
p->validYMD = 0;
p->validHMS = 0;
p->validTZ = 0;
}
}
}
/*
** Parse dates of the form
**
** YYYY-MM-DD HH:MM:SS.FFF
** YYYY-MM-DD HH:MM:SS
** YYYY-MM-DD HH:MM
** YYYY-MM-DD
**
** Write the result into the DateTime structure and return 0
** on success and 1 if the input string is not a well-formed
** date.
*/
static int parseYyyyMmDd(const char *zDate, DateTime *p){
int Y, M, D, neg;
if( zDate[0]=='-' ){
zDate++;
neg = 1;
}else{
neg = 0;
}
if( getDigits(zDate,4,0,9999,'-',&Y,2,1,12,'-',&M,2,1,31,0,&D)!=3 ){
return 1;
}
zDate += 10;
while( sqlite4Isspace(*zDate) || 'T'==*(u8*)zDate ){ zDate++; }
if( parseHhMmSs(zDate, p)==0 ){
/* We got the time */
}else if( *zDate==0 ){
p->validHMS = 0;
}else{
return 1;
}
p->validJD = 0;
p->validYMD = 1;
p->Y = neg ? -Y : Y;
p->M = M;
p->D = D;
if( p->validTZ ){
computeJD(p);
}
return 0;
}
/*
** Set the time to the current time reported by the VFS.
**
** Return the number of errors.
*/
static int setDateTimeToCurrent(sqlite4_context *context, DateTime *p){
sqlite4 *db = sqlite4_context_db_handle(context);
if( sqlite4OsCurrentTime(0, &p->iJD)==SQLITE_OK ){
p->validJD = 1;
return 0;
}else{
return 1;
}
}
/*
** Attempt to parse the given string into a Julian Day Number. Return
** the number of errors.
**
** The following are acceptable forms for the input string:
**
** YYYY-MM-DD HH:MM:SS.FFF +/-HH:MM
** DDDD.DD
** now
**
** In the first form, the +/-HH:MM is always optional. The fractional
** seconds extension (the ".FFF") is optional. The seconds portion
** (":SS.FFF") is option. The year and date can be omitted as long
** as there is a time string. The time string can be omitted as long
** as there is a year and date.
*/
static int parseDateOrTime(
sqlite4_context *context,
const char *zDate,
DateTime *p
){
double r;
if( parseYyyyMmDd(zDate,p)==0 ){
return 0;
}else if( parseHhMmSs(zDate, p)==0 ){
return 0;
}else if( sqlite4StrICmp(zDate,"now")==0){
return setDateTimeToCurrent(context, p);
}else if( sqlite4AtoF(zDate, &r, sqlite4Strlen30(zDate), SQLITE_UTF8) ){
p->iJD = (sqlite4_int64)(r*86400000.0 + 0.5);
p->validJD = 1;
return 0;
}
return 1;
}
/*
** Compute the Year, Month, and Day from the julian day number.
*/
static void computeYMD(DateTime *p){
int Z, A, B, C, D, E, X1;
if( p->validYMD ) return;
if( !p->validJD ){
p->Y = 2000;
p->M = 1;
p->D = 1;
}else{
Z = (int)((p->iJD + 43200000)/86400000);
A = (int)((Z - 1867216.25)/36524.25);
A = Z + 1 + A - (A/4);
B = A + 1524;
C = (int)((B - 122.1)/365.25);
D = (36525*C)/100;
E = (int)((B-D)/30.6001);
X1 = (int)(30.6001*E);
p->D = B - D - X1;
p->M = E<14 ? E-1 : E-13;
p->Y = p->M>2 ? C - 4716 : C - 4715;
}
p->validYMD = 1;
}
/*
** Compute the Hour, Minute, and Seconds from the julian day number.
*/
static void computeHMS(DateTime *p){
int s;
if( p->validHMS ) return;
computeJD(p);
s = (int)((p->iJD + 43200000) % 86400000);
p->s = s/1000.0;
s = (int)p->s;
p->s -= s;
p->h = s/3600;
s -= p->h*3600;
p->m = s/60;
p->s += s - p->m*60;
p->validHMS = 1;
}
/*
** Compute both YMD and HMS
*/
static void computeYMD_HMS(DateTime *p){
computeYMD(p);
computeHMS(p);
}
/*
** Clear the YMD and HMS and the TZ
*/
static void clearYMD_HMS_TZ(DateTime *p){
p->validYMD = 0;
p->validHMS = 0;
p->validTZ = 0;
}
/*
** On recent Windows platforms, the localtime_s() function is available
** as part of the "Secure CRT". It is essentially equivalent to
** localtime_r() available under most POSIX platforms, except that the
** order of the parameters is reversed.
**
** See http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx.
**
** If the user has not indicated to use localtime_r() or localtime_s()
** already, check for an MSVC build environment that provides
** localtime_s().
*/
#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S) && \
defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE)
#define HAVE_LOCALTIME_S 1
#endif
#ifndef SQLITE_OMIT_LOCALTIME
/*
** The following routine implements the rough equivalent of localtime_r()
** using whatever operating-system specific localtime facility that
** is available. This routine returns 0 on success and
** non-zero on any kind of error.
**
** If the sqlite4DefaultEnv.bLocaltimeFault variable is true then this
** routine will always fail.
*/
static int osLocaltime(time_t *t, struct tm *pTm){
int rc;
#if (!defined(HAVE_LOCALTIME_R) || !HAVE_LOCALTIME_R) \
&& (!defined(HAVE_LOCALTIME_S) || !HAVE_LOCALTIME_S)
struct tm *pX;
#if SQLITE_THREADSAFE>0
sqlite4_mutex *mutex = sqlite4MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
#endif
sqlite4_mutex_enter(mutex);
pX = localtime(t);
#ifndef SQLITE_OMIT_BUILTIN_TEST
if( sqlite4DefaultEnv.bLocaltimeFault ) pX = 0;
#endif
if( pX ) *pTm = *pX;
sqlite4_mutex_leave(mutex);
rc = pX==0;
#else
#ifndef SQLITE_OMIT_BUILTIN_TEST
if( sqlite4DefaultEnv.bLocaltimeFault ) return 1;
#endif
#if defined(HAVE_LOCALTIME_R) && HAVE_LOCALTIME_R
rc = localtime_r(t, pTm)==0;
#else
rc = localtime_s(pTm, t);
#endif /* HAVE_LOCALTIME_R */
#endif /* HAVE_LOCALTIME_R || HAVE_LOCALTIME_S */
return rc;
}
#endif /* SQLITE_OMIT_LOCALTIME */
#ifndef SQLITE_OMIT_LOCALTIME
/*
** Compute the difference (in milliseconds) between localtime and UTC
** (a.k.a. GMT) for the time value p where p is in UTC. If no error occurs,
** return this value and set *pRc to SQLITE_OK.
**
** Or, if an error does occur, set *pRc to SQLITE_ERROR. The returned value
** is undefined in this case.
*/
static sqlite4_int64 localtimeOffset(
DateTime *p, /* Date at which to calculate offset */
sqlite4_context *pCtx, /* Write error here if one occurs */
int *pRc /* OUT: Error code. SQLITE_OK or ERROR */
){
DateTime x, y;
time_t t;
struct tm sLocal;
/* Initialize the contents of sLocal to avoid a compiler warning. */
memset(&sLocal, 0, sizeof(sLocal));
x = *p;
computeYMD_HMS(&x);
if( x.Y<1971 || x.Y>=2038 ){
x.Y = 2000;
x.M = 1;
x.D = 1;
x.h = 0;
x.m = 0;
x.s = 0.0;
} else {
int s = (int)(x.s + 0.5);
x.s = s;
}
x.tz = 0;
x.validJD = 0;
computeJD(&x);
t = (time_t)(x.iJD/1000 - 21086676*(i64)10000);
if( osLocaltime(&t, &sLocal) ){
sqlite4_result_error(pCtx, "local time unavailable", -1);
*pRc = SQLITE_ERROR;
return 0;
}
y.Y = sLocal.tm_year + 1900;
y.M = sLocal.tm_mon + 1;
y.D = sLocal.tm_mday;
y.h = sLocal.tm_hour;
y.m = sLocal.tm_min;
y.s = sLocal.tm_sec;
y.validYMD = 1;
y.validHMS = 1;
y.validJD = 0;
y.validTZ = 0;
computeJD(&y);
*pRc = SQLITE_OK;
return y.iJD - x.iJD;
}
#endif /* SQLITE_OMIT_LOCALTIME */
/*
** Process a modifier to a date-time stamp. The modifiers are
** as follows:
**
** NNN days
** NNN hours
** NNN minutes
** NNN.NNNN seconds
** NNN months
** NNN years
** start of month
** start of year
** start of week
** start of day
** weekday N
** unixepoch
** localtime
** utc
**
** Return 0 on success and 1 if there is any kind of error. If the error
** is in a system call (i.e. localtime()), then an error message is written
** to context pCtx. If the error is an unrecognized modifier, no error is
** written to pCtx.
*/
static int parseModifier(sqlite4_context *pCtx, const char *zMod, DateTime *p){
int rc = 1;
int n;
double r;
char *z, zBuf[30];
z = zBuf;
for(n=0; n<ArraySize(zBuf)-1 && zMod[n]; n++){
z[n] = (char)sqlite4UpperToLower[(u8)zMod[n]];
}
z[n] = 0;
switch( z[0] ){
#ifndef SQLITE_OMIT_LOCALTIME
case 'l': {
/* localtime
**
** Assuming the current time value is UTC (a.k.a. GMT), shift it to
** show local time.
*/
if( strcmp(z, "localtime")==0 ){
computeJD(p);
p->iJD += localtimeOffset(p, pCtx, &rc);
clearYMD_HMS_TZ(p);
}
break;
}
#endif
case 'u': {
/*
** unixepoch
**
** Treat the current value of p->iJD as the number of
** seconds since 1970. Convert to a real julian day number.
*/
if( strcmp(z, "unixepoch")==0 && p->validJD ){
p->iJD = (p->iJD + 43200)/86400 + 21086676*(i64)10000000;
clearYMD_HMS_TZ(p);
rc = 0;
}
#ifndef SQLITE_OMIT_LOCALTIME
else if( strcmp(z, "utc")==0 ){
sqlite4_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);
}
}
#endif
break;
}
case 'w': {
/*
** weekday N
**
** Move the date to the same time on the next occurrence of
** 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( strncmp(z, "weekday ", 8)==0
&& sqlite4AtoF(&z[8], &r, sqlite4Strlen30(&z[8]), SQLITE_UTF8)
&& (n=(int)r)==r && n>=0 && r<7 ){
sqlite4_int64 Z;
computeYMD_HMS(p);
p->validTZ = 0;
p->validJD = 0;
computeJD(p);
Z = ((p->iJD + 129600000)/86400000) % 7;
if( Z>n ) Z -= 7;
p->iJD += (n - Z)*86400000;
clearYMD_HMS_TZ(p);
rc = 0;
}
break;
}
case 's': {
/*
** start of TTTTT
**
** Move the date backwards to the beginning of the current day,
** or month or year.
*/
if( strncmp(z, "start of ", 9)!=0 ) break;
z += 9;
computeYMD(p);
p->validHMS = 1;
p->h = p->m = 0;
p->s = 0.0;
p->validTZ = 0;
p->validJD = 0;
if( strcmp(z,"month")==0 ){
p->D = 1;
rc = 0;
}else if( strcmp(z,"year")==0 ){
computeYMD(p);
p->M = 1;
p->D = 1;
rc = 0;
}else if( strcmp(z,"day")==0 ){
rc = 0;
}
break;
}
case '+':
case '-':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': {
double rRounder;
for(n=1; z[n] && z[n]!=':' && !sqlite4Isspace(z[n]); n++){}
if( !sqlite4AtoF(z, &r, n, SQLITE_UTF8) ){
rc = 1;
break;
}
if( z[n]==':' ){
/* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the
** specified number of hours, minutes, seconds, and fractional seconds
** to the time. The ".FFF" may be omitted. The ":SS.FFF" may be
** omitted.
*/
const char *z2 = z;
DateTime tx;
sqlite4_int64 day;
if( !sqlite4Isdigit(*z2) ) z2++;
memset(&tx, 0, sizeof(tx));
if( parseHhMmSs(z2, &tx) ) break;
computeJD(&tx);
tx.iJD -= 43200000;
day = tx.iJD/86400000;
tx.iJD -= day*86400000;
if( z[0]=='-' ) tx.iJD = -tx.iJD;
computeJD(p);
clearYMD_HMS_TZ(p);
p->iJD += tx.iJD;
rc = 0;
break;
}
z += n;
while( sqlite4Isspace(*z) ) z++;
n = sqlite4Strlen30(z);
if( n>10 || n<3 ) break;
if( z[n-1]=='s' ){ z[n-1] = 0; n--; }
computeJD(p);
rc = 0;
rRounder = r<0 ? -0.5 : +0.5;
if( n==3 && strcmp(z,"day")==0 ){
p->iJD += (sqlite4_int64)(r*86400000.0 + rRounder);
}else if( n==4 && strcmp(z,"hour")==0 ){
p->iJD += (sqlite4_int64)(r*(86400000.0/24.0) + rRounder);
}else if( n==6 && strcmp(z,"minute")==0 ){
p->iJD += (sqlite4_int64)(r*(86400000.0/(24.0*60.0)) + rRounder);
}else if( n==6 && strcmp(z,"second")==0 ){
p->iJD += (sqlite4_int64)(r*(86400000.0/(24.0*60.0*60.0)) + rRounder);
}else if( n==5 && strcmp(z,"month")==0 ){
int x, y;
computeYMD_HMS(p);
p->M += (int)r;
x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
p->Y += x;
p->M -= x*12;
p->validJD = 0;
computeJD(p);
y = (int)r;
if( y!=r ){
p->iJD += (sqlite4_int64)((r - y)*30.0*86400000.0 + rRounder);
}
}else if( n==4 && strcmp(z,"year")==0 ){
int y = (int)r;
computeYMD_HMS(p);
p->Y += y;
p->validJD = 0;
computeJD(p);
if( y!=r ){
p->iJD += (sqlite4_int64)((r - y)*365.0*86400000.0 + rRounder);
}
}else{
rc = 1;
}
clearYMD_HMS_TZ(p);
break;
}
default: {
break;
}
}
return rc;
}
/*
** Process time function arguments. argv[0] is a date-time stamp.
** argv[1] and following are modifiers. Parse them all and write
** the resulting time into the DateTime structure p. Return 0
** on success and 1 if there are any errors.
**
** If there are zero parameters (if even argv[0] is undefined)
** then assume a default value of "now" for argv[0].
*/
static int isDate(
sqlite4_context *context,
int argc,
sqlite4_value **argv,
DateTime *p
){
int i;
const unsigned char *z;
int eType;
memset(p, 0, sizeof(*p));
if( argc==0 ){
return setDateTimeToCurrent(context, p);
}
if( (eType = sqlite4_value_type(argv[0]))==SQLITE_FLOAT
|| eType==SQLITE_INTEGER ){
p->iJD = (sqlite4_int64)(sqlite4_value_double(argv[0])*86400000.0 + 0.5);
p->validJD = 1;
}else{
z = sqlite4_value_text(argv[0]);
if( !z || parseDateOrTime(context, (char*)z, p) ){
return 1;
}
}
for(i=1; i<argc; i++){
z = sqlite4_value_text(argv[i]);
if( z==0 || parseModifier(context, (char*)z, p) ) return 1;
}
return 0;
}
/*
** The following routines implement the various date and time functions
** of SQLite.
*/
/*
** julianday( TIMESTRING, MOD, MOD, ...)
**
** Return the julian day number of the date specified in the arguments
*/
static void juliandayFunc(
sqlite4_context *context,
int argc,
sqlite4_value **argv
){
DateTime x;
if( isDate(context, argc, argv, &x)==0 ){
computeJD(&x);
sqlite4_result_double(context, x.iJD/86400000.0);
}
}
/*
** datetime( TIMESTRING, MOD, MOD, ...)
**
** Return YYYY-MM-DD HH:MM:SS
*/
static void datetimeFunc(
sqlite4_context *context,
int argc,
sqlite4_value **argv
){
DateTime x;
if( isDate(context, argc, argv, &x)==0 ){
char zBuf[100];
computeYMD_HMS(&x);
sqlite4_snprintf(zBuf,sizeof(zBuf), "%04d-%02d-%02d %02d:%02d:%02d",
x.Y, x.M, x.D, x.h, x.m, (int)(x.s));
sqlite4_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
}
}
/*
** time( TIMESTRING, MOD, MOD, ...)
**
** Return HH:MM:SS
*/
static void timeFunc(
sqlite4_context *context,
int argc,
sqlite4_value **argv
){
DateTime x;
if( isDate(context, argc, argv, &x)==0 ){
char zBuf[100];
computeHMS(&x);
sqlite4_snprintf(zBuf,sizeof(zBuf), "%02d:%02d:%02d", x.h, x.m, (int)x.s);
sqlite4_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
}
}
/*
** date( TIMESTRING, MOD, MOD, ...)
**
** Return YYYY-MM-DD
*/
static void dateFunc(
sqlite4_context *context,
int argc,
sqlite4_value **argv
){
DateTime x;
if( isDate(context, argc, argv, &x)==0 ){
char zBuf[100];
computeYMD(&x);
sqlite4_snprintf(zBuf,sizeof(zBuf), "%04d-%02d-%02d", x.Y, x.M, x.D);
sqlite4_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
}
}
/*
** strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
**
** Return a string described by FORMAT. Conversions as follows:
**
** %d day of month
** %f ** fractional seconds SS.SSS
** %H hour 00-24
** %j day of year 000-366
** %J ** Julian day number
** %m month 01-12
** %M minute 00-59
** %s seconds since 1970-01-01
** %S seconds 00-59
** %w day of week 0-6 sunday==0
** %W week of year 00-53
** %Y year 0000-9999
** %% %
*/
static void strftimeFunc(
sqlite4_context *context,
int argc,
sqlite4_value **argv
){
DateTime x;
u64 n;
size_t i,j;
char *z;
sqlite4 *db;
const char *zFmt = (const char*)sqlite4_value_text(argv[0]);
char zBuf[100];
if( zFmt==0 || isDate(context, argc-1, argv+1, &x) ) return;
db = sqlite4_context_db_handle(context);
for(i=0, n=1; zFmt[i]; i++, n++){
if( zFmt[i]=='%' ){
switch( zFmt[i+1] ){
case 'd':
case 'H':
case 'm':
case 'M':
case 'S':
case 'W':
n++;
/* fall thru */
case 'w':
case '%':
break;
case 'f':
n += 8;
break;
case 'j':
n += 3;
break;
case 'Y':
n += 8;
break;
case 's':
case 'J':
n += 50;
break;
default:
return; /* ERROR. return a NULL */
}
i++;
}
}
testcase( n==sizeof(zBuf)-1 );
testcase( n==sizeof(zBuf) );
testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH] );
if( n<sizeof(zBuf) ){
z = zBuf;
}else if( n>(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ){
sqlite4_result_error_toobig(context);
return;
}else{
z = sqlite4DbMallocRaw(db, (int)n);
if( z==0 ){
sqlite4_result_error_nomem(context);
return;
}
}
computeJD(&x);
computeYMD_HMS(&x);
for(i=j=0; zFmt[i]; i++){
if( zFmt[i]!='%' ){
z[j++] = zFmt[i];
}else{
i++;
switch( zFmt[i] ){
case 'd': sqlite4_snprintf(&z[j],3,"%02d",x.D); j+=2; break;
case 'f': {
double s = x.s;
if( s>59.999 ) s = 59.999;
j += sqlite4_snprintf(&z[j],7,"%06.3f", s);
break;
}
case 'H': sqlite4_snprintf(&z[j],3,"%02d",x.h); j+=2; break;
case 'W': /* Fall thru */
case 'j': {
int nDay; /* Number of days since 1st day of year */
DateTime y = x;
y.validJD = 0;
y.M = 1;
y.D = 1;
computeJD(&y);
nDay = (int)((x.iJD-y.iJD+43200000)/86400000);
if( zFmt[i]=='W' ){
int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */
wd = (int)(((x.iJD+43200000)/86400000)%7);
sqlite4_snprintf(&z[j],3,"%02d",(nDay+7-wd)/7);
j += 2;
}else{
sqlite4_snprintf(&z[j],4,"%03d",nDay+1);
j += 3;
}
break;
}
case 'J': {
j += sqlite4_snprintf(&z[j],20,"%.16g",x.iJD/86400000.0);
break;
}
case 'm': sqlite4_snprintf(&z[j],3,"%02d",x.M); j+=2; break;
case 'M': sqlite4_snprintf(&z[j],3,"%02d",x.m); j+=2; break;
case 's': {
j += sqlite4_snprintf(&z[j],30,"%lld",
(i64)(x.iJD/1000 - 21086676*(i64)10000));
break;
}
case 'S': sqlite4_snprintf(&z[j],3,"%02d",(int)x.s); j+=2; break;
case 'w': {
z[j++] = (char)(((x.iJD+129600000)/86400000) % 7) + '0';
break;
}
case 'Y': {
sqlite4_snprintf(&z[j],5,"%04d",x.Y); j+=sqlite4Strlen30(&z[j]);
break;
}
default: z[j++] = '%'; break;
}
}
}
z[j] = 0;
sqlite4_result_text(context, z, -1,
z==zBuf ? SQLITE_TRANSIENT : SQLITE_DYNAMIC);
}
/*
** current_time()
**
** This function returns the same value as time('now').
*/
static void ctimeFunc(
sqlite4_context *context,
int NotUsed,
sqlite4_value **NotUsed2
){
UNUSED_PARAMETER2(NotUsed, NotUsed2);
timeFunc(context, 0, 0);
}
/*
** current_date()
**
** This function returns the same value as date('now').
*/
static void cdateFunc(
sqlite4_context *context,
int NotUsed,
sqlite4_value **NotUsed2
){
UNUSED_PARAMETER2(NotUsed, NotUsed2);
dateFunc(context, 0, 0);
}
/*
** current_timestamp()
**
** This function returns the same value as datetime('now').
*/
static void ctimestampFunc(
sqlite4_context *context,
int NotUsed,
sqlite4_value **NotUsed2
){
UNUSED_PARAMETER2(NotUsed, NotUsed2);
datetimeFunc(context, 0, 0);
}
#endif /* !defined(SQLITE_OMIT_DATETIME_FUNCS) */
#ifdef SQLITE_OMIT_DATETIME_FUNCS
/*
** If the library is compiled to omit the full-scale date and time
** handling (to get a smaller binary), the following minimal version
** of the functions current_time(), current_date() and current_timestamp()
** are included instead. This is to support column declarations that
** include "DEFAULT CURRENT_TIME" etc.
**
** This function uses the C-library functions time(), gmtime()
** and strftime(). The format string to pass to strftime() is supplied
** as the user-data for the function.
*/
static void currentTimeFunc(
sqlite4_context *context,
int argc,
sqlite4_value **argv
){
time_t t;
char *zFormat = (char *)sqlite4_user_data(context);
sqlite4 *db;
sqlite4_int64 iT;
struct tm *pTm;
struct tm sNow;
char zBuf[20];
UNUSED_PARAMETER(argc);
UNUSED_PARAMETER(argv);
db = sqlite4_context_db_handle(context);
if( sqlite4OsCurrentTime(db->pEnv, &iT) ) return;
t = iT/1000 - 10000*(sqlite4_int64)21086676;
#ifdef HAVE_GMTIME_R
pTm = gmtime_r(&t, &sNow);
#else
sqlite4_mutex_enter(sqlite4MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
pTm = gmtime(&t);
if( pTm ) memcpy(&sNow, pTm, sizeof(sNow));
sqlite4_mutex_leave(sqlite4MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
#endif
if( pTm ){
strftime(zBuf, 20, zFormat, &sNow);
sqlite4_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
}
}
#endif
/*
** This function registered all of the above C functions as SQL
** functions. This should be the only routine in this file with
** external linkage.
*/
SQLITE_PRIVATE void sqlite4RegisterDateTimeFunctions(sqlite4_env *pEnv){
static FuncDef aDateTimeFuncs[] = {
#ifndef SQLITE_OMIT_DATETIME_FUNCS
FUNCTION(julianday, -1, 0, 0, juliandayFunc ),
FUNCTION(date, -1, 0, 0, dateFunc ),
FUNCTION(time, -1, 0, 0, timeFunc ),
FUNCTION(datetime, -1, 0, 0, datetimeFunc ),
FUNCTION(strftime, -1, 0, 0, strftimeFunc ),
FUNCTION(current_time, 0, 0, 0, ctimeFunc ),
FUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc),
FUNCTION(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
};
int i;
FuncDefTable *pFuncTab = &pEnv->aGlobalFuncs;
FuncDef *aFunc = (FuncDef*)aDateTimeFuncs;
for(i=0; i<ArraySize(aDateTimeFuncs); i++){
sqlite4FuncDefInsert(pFuncTab, &aFunc[i], 1);
}
}
/************** End of date.c ************************************************/
/************** Begin file os.c **********************************************/
/*
** 2005 November 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.
**
******************************************************************************
**
** This file contains OS interface code that is common to all
** architectures.
*/
#define _SQLITE_OS_C_ 1
#undef _SQLITE_OS_C_
#if SQLITE_OS_UNIX
#include <sys/time.h>
#endif
/*
** The following variable, if set to a non-zero value, is interpreted as
** the number of seconds since 1970 and is used to set the result of
** sqlite4OsCurrentTime() during testing.
*/
SQLITE_API unsigned int sqlite4_current_time = 0; /* Fake system time */
SQLITE_PRIVATE int sqlite4OsCurrentTime(sqlite4_env *pEnv, sqlite4_uint64 *pTimeOut){
int rc = SQLITE_OK;
if( sqlite4_current_time ){
*pTimeOut = (sqlite4_uint64)sqlite4_current_time * 1000;
return SQLITE_OK;
}
#if SQLITE_OS_UNIX
static const sqlite4_int64 unixEpoch = 24405875*(sqlite4_int64)8640000;
struct timeval sNow;
if( gettimeofday(&sNow, 0)==0 ){
*pTimeOut = unixEpoch + 1000*(sqlite4_int64)sNow.tv_sec + sNow.tv_usec/1000;
}else{
rc = SQLITE_ERROR;
}
UNUSED_PARAMETER(pEnv);
#endif
#if SQLITE_OS_WIN
FILETIME ft;
static const sqlite4_int64 winFiletimeEpoch =
23058135*(sqlite4_int64)8640000;
/* 2^32 - to avoid use of LL and warnings in gcc */
static const sqlite4_int64 max32BitValue =
(sqlite4_int64)2000000000 + (sqlite4_int64)2000000000
+ (sqlite4_int64)294967296;
GetSystemTimeAsFileTime( &ft );
*pTimeOut = winFiletimeEpoch +
((((sqlite4_int64)ft.dwHighDateTime)*max32BitValue) +
(sqlite4_int64)ft.dwLowDateTime)/(sqlite4_int64)10000;
UNUSED_PARAMETER(pEnv);
#endif
return rc;
}
/*
** Write nByte bytes of randomness into zBufOut[]. This is used to initialize
** the PRNGs. nByte will always be 8.
*/
SQLITE_PRIVATE int sqlite4OsRandomness(sqlite4_env *pEnv, int nByte, unsigned char *zBufOut){
static sqlite4_uint64 cnt = 0;
unsigned char *p;
int i;
sqlite4_uint64 now;
sqlite4_uint64 x = 0;
#if 0 && SQLITE_OS_UNIX
int fd = open("/dev/urandom", O_RDONLY, 0);
if( fd>=0 ){
read(fd, zBufOut, nByte);
close(fd);
}
x = getpid();
#endif
sqlite4OsCurrentTime(pEnv, &now);
x ^= now;
memset(zBufOut, 0, nByte);
cnt++;
x ^= cnt;
p = (unsigned char*)&x;
for(i=0; i<8; i++) zBufOut[i%nByte] ^= p[i];
return SQLITE_OK;
}
/*
** This function is a wrapper around the OS specific implementation of
** sqlite4_os_init(). The purpose of the wrapper is to provide the
** ability to simulate a malloc failure, so that the handling of an
** error in sqlite4_os_init() by the upper layers can be tested.
*/
SQLITE_PRIVATE int sqlite4OsInit(sqlite4_env *pEnv){
void *p = sqlite4_malloc(pEnv, 10);
if( p==0 ) return SQLITE_NOMEM;
sqlite4_free(pEnv, p);
sqlite4OsRandomness(pEnv, 8, (unsigned char*)&pEnv->prngX);
return SQLITE_OK; /*sqlite4_os_init();*/
}
/************** End of os.c **************************************************/
/************** Begin file fault.c *******************************************/
/*
** 2008 Jan 22
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code to support the concept of "benign"
** malloc failures (when the xMalloc() or xRealloc() method of the
** sqlite4_mem_methods structure fails to allocate a block of memory
** and returns 0).
**
** Most malloc failures are non-benign. After they occur, SQLite
** abandons the current operation and returns an error code (usually
** SQLITE_NOMEM) to the user. However, sometimes a fault is not necessarily
** fatal. For example, if a malloc fails while resizing a hash table, this
** is completely recoverable simply by not carrying out the resize. The
** hash table will continue to function normally. So a malloc failure
** during a hash table resize is a benign fault.
*/
#ifndef SQLITE_OMIT_BUILTIN_TEST
/*
** This (sqlite4EndBenignMalloc()) is called by SQLite code to indicate that
** subsequent malloc failures are benign. A call to sqlite4EndBenignMalloc()
** indicates that subsequent malloc failures are non-benign.
*/
SQLITE_PRIVATE void sqlite4BeginBenignMalloc(sqlite4_env *pEnv){
if( pEnv->m.xBeginBenign ) pEnv->m.xBeginBenign(pEnv->m.pMemEnv);
}
SQLITE_PRIVATE void sqlite4EndBenignMalloc(sqlite4_env *pEnv){
if( pEnv->m.xEndBenign ) pEnv->m.xEndBenign(pEnv->m.pMemEnv);
}
#endif /* #ifndef SQLITE_OMIT_BUILTIN_TEST */
/************** End of fault.c ***********************************************/
/************** Begin file mem0.c ********************************************/
/*
** 2008 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 no-op memory allocation drivers for use when
** SQLITE_ZERO_MALLOC is defined. The allocation drivers implemented
** here always fail. SQLite will not operate with these drivers. These
** are merely placeholders. Real drivers must be substituted using
** sqlite4_config() before SQLite will operate.
*/
/*
** This version of the memory allocator is the default. It is
** used when no other memory allocator is specified using compile-time
** macros.
*/
#ifdef SQLITE_ZERO_MALLOC
/*
** No-op versions of all memory allocation routines
*/
static void *sqlite4MemMalloc(void *p, sqlite4_size_t nByte){ return 0; }
static void sqlite4MemFree(void *p, void *pPrior){ return; }
static void *sqlite4MemRealloc(void *p, void *pPrior, sqlite4_size_t nByte){
return 0;
}
static int sqlite4MemSize(void*p, void *pPrior){ return 0; }
static int sqlite4MemInit(void *NotUsed){ return SQLITE_OK; }
static void sqlite4MemShutdown(void *NotUsed){ return; }
/*
** This routine is the only routine in this file with external linkage.
**
** Populate the low-level memory allocation function pointers in
** sqlite4DefaultEnv.m with pointers to the routines in this file.
*/
SQLITE_PRIVATE void sqlite4MemSetDefault(sqlite4_env *pEnv){
static const sqlite4_mem_methods defaultMethods = {
sqlite4MemMalloc,
sqlite4MemFree,
sqlite4MemRealloc,
sqlite4MemSize,
sqlite4MemInit,
sqlite4MemShutdown,
0,
0,
0
};
pEnv->m = defaultMethods;
pEnv->m.pMemEnv = (void*)pEnv;
}
#endif /* SQLITE_ZERO_MALLOC */
/************** End of mem0.c ************************************************/
/************** Begin file mem1.c ********************************************/
/*
** 2007 August 14
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains low-level memory allocation drivers for when
** SQLite will use the standard C-library malloc/realloc/free interface
** to obtain the memory it needs.
**
** This file contains implementations of the low-level memory allocation
** routines specified in the sqlite4_mem_methods object. The content of
** this file is only used if SQLITE_SYSTEM_MALLOC is defined. The
** SQLITE_SYSTEM_MALLOC macro is defined automatically if neither the
** SQLITE_MEMDEBUG nor the SQLITE_WIN32_MALLOC macros are defined. The
** default configuration is to use memory allocation routines in this
** file.
**
** C-preprocessor macro summary:
**
** HAVE_MALLOC_USABLE_SIZE The configure script sets this symbol if
** the malloc_usable_size() interface exists
** on the target platform. Or, this symbol
** can be set manually, if desired.
** If an equivalent interface exists by
** a different name, using a separate -D
** option to rename it. This symbol will
** be enabled automatically on windows
** systems, and malloc_usable_size() will
** be redefined to _msize(), unless the
** SQLITE_WITHOUT_MSIZE macro is defined.
**
** SQLITE_WITHOUT_ZONEMALLOC Some older macs lack support for the zone
** memory allocator. Set this symbol to enable
** building on older macs.
**
** SQLITE_WITHOUT_MSIZE Set this symbol to disable the use of
** _msize() on windows systems. This might
** be necessary when compiling for Delphi,
** for example.
*/
/*
** This version of the memory allocator is the default. It is
** used when no other memory allocator is specified using compile-time
** macros.
*/
#ifdef SQLITE_SYSTEM_MALLOC
/*
** Windows systems have malloc_usable_size() but it is called _msize().
** The use of _msize() is automatic, but can be disabled by compiling
** with -DSQLITE_WITHOUT_MSIZE
*/
#if !defined(HAVE_MALLOC_USABLE_SIZE) && SQLITE_OS_WIN \
&& !defined(SQLITE_WITHOUT_MSIZE)
# define HAVE_MALLOC_USABLE_SIZE 1
# define SQLITE_MALLOCSIZE _msize
#endif
#if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC)
/*
** Use the zone allocator available on apple products unless the
** SQLITE_WITHOUT_ZONEMALLOC symbol is defined.
*/
#include <sys/sysctl.h>
#include <malloc/malloc.h>
#include <libkern/OSAtomic.h>
static malloc_zone_t* _sqliteZone_;
#define SQLITE_MALLOC(x) malloc_zone_malloc(_sqliteZone_, (x))
#define SQLITE_FREE(x) malloc_zone_free(_sqliteZone_, (x));
#define SQLITE_REALLOC(x,y) malloc_zone_realloc(_sqliteZone_, (x), (y))
#define SQLITE_MALLOCSIZE(x) \
(_sqliteZone_ ? _sqliteZone_->size(_sqliteZone_,x) : malloc_size(x))
#else /* if not __APPLE__ */
/*
** Use standard C library malloc and free on non-Apple systems.
** Also used by Apple systems if SQLITE_WITHOUT_ZONEMALLOC is defined.
*/
#define SQLITE_MALLOC(x) malloc(x)
#define SQLITE_FREE(x) free(x)
#define SQLITE_REALLOC(x,y) realloc((x),(y))
#ifdef HAVE_MALLOC_USABLE_SIZE
# ifndef SQLITE_MALLOCSIZE
# include <malloc.h>
# define SQLITE_MALLOCSIZE(x) malloc_usable_size(x)
# endif
#else
# undef SQLITE_MALLOCSIZE
#endif
#endif /* __APPLE__ or not __APPLE__ */
/*
** Like malloc(), but remember the size of the allocation
** so that we can find it later using sqlite4MemSize().
**
** For this low-level routine, we are guaranteed that nByte>0 because
** cases of nByte<=0 will be intercepted and dealt with by higher level
** routines.
*/
static void *sqlite4MemMalloc(void *NotUsed, sqlite4_size_t nByte){
#ifdef SQLITE_MALLOCSIZE
void *p = SQLITE_MALLOC( nByte );
UNUSED_PARAMETER(NotUsed);
if( p==0 ){
testcase( sqlite4DefaultEnv.xLog!=0 );
sqlite4_log(0,SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
}
return p;
#else
sqlite4_int64 *p;
assert( nByte>0 );
UNUSED_PARAMETER(NotUsed);
nByte = ROUND8(nByte);
p = SQLITE_MALLOC( nByte+8 );
if( p ){
p[0] = nByte;
p++;
}else{
testcase( sqlite4DefaultEnv.xLog!=0 );
sqlite4_log(0,SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
}
return (void *)p;
#endif
}
/*
** Like free() but works for allocations obtained from sqlite4MemMalloc()
** or sqlite4MemRealloc().
**
** For this low-level routine, we already know that pPrior!=0 since
** cases where pPrior==0 will have been intecepted and dealt with
** by higher-level routines.
*/
static void sqlite4MemFree(void *NotUsed, void *pPrior){
#ifdef SQLITE_MALLOCSIZE
UNUSED_PARAMETER(NotUsed);
SQLITE_FREE(pPrior);
#else
sqlite4_int64 *p = (sqlite4_int64*)pPrior;
UNUSED_PARAMETER(NotUsed);
assert( pPrior!=0 );
p--;
SQLITE_FREE(p);
#endif
}
/*
** Report the allocated size of a prior return from xMalloc()
** or xRealloc().
*/
static sqlite4_size_t sqlite4MemSize(void *NotUsed, void *pPrior){
#ifdef SQLITE_MALLOCSIZE
UNUSED_PARAMETER(NotUsed);
return pPrior ? (int)SQLITE_MALLOCSIZE(pPrior) : 0;
#else
sqlite4_int64 *p;
UNUSED_PARAMETER(NotUsed);
if( pPrior==0 ) return 0;
p = (sqlite4_int64*)pPrior;
p--;
return (sqlite4_size_t)p[0];
#endif
}
/*
** Like realloc(). Resize an allocation previously obtained from
** sqlite4MemMalloc().
**
** For this low-level interface, we know that pPrior!=0. Cases where
** pPrior==0 while have been intercepted by higher-level routine and
** redirected to xMalloc. Similarly, we know that nByte>0 becauses
** cases where nByte<=0 will have been intercepted by higher-level
** routines and redirected to xFree.
*/
static void *sqlite4MemRealloc(void *NotUsed, void *pPrior, int nByte){
#ifdef SQLITE_MALLOCSIZE
void *p = SQLITE_REALLOC(pPrior, nByte);
UNUSED_PARAMETER(NotUsed);
if( p==0 ){
testcase( sqlite4DefaultEnv.xLog!=0 );
sqlite4_log(0,SQLITE_NOMEM,
"failed memory resize %u to %u bytes",
SQLITE_MALLOCSIZE(pPrior), nByte);
}
return p;
#else
sqlite4_int64 *p = (sqlite4_int64*)pPrior;
assert( pPrior!=0 && nByte>0 );
assert( nByte==ROUND8(nByte) ); /* EV: R-46199-30249 */
UNUSED_PARAMETER(NotUsed);
p--;
p = SQLITE_REALLOC(p, nByte+8 );
if( p ){
p[0] = nByte;
p++;
}else{
testcase( sqlite4DefaultEnv.xLog!=0 );
sqlite4_log(0,SQLITE_NOMEM,
"failed memory resize %u to %u bytes",
sqlite4MemSize(0, pPrior), nByte);
}
return (void*)p;
#endif
}
/*
** Initialize this module.
*/
static int sqlite4MemInit(void *NotUsed){
#if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC)
int cpuCount;
size_t len;
if( _sqliteZone_ ){
return SQLITE_OK;
}
len = sizeof(cpuCount);
/* One usually wants to use hw.acctivecpu for MT decisions, but not here */
sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0);
if( cpuCount>1 ){
/* defer MT decisions to system malloc */
_sqliteZone_ = malloc_default_zone();
}else{
/* only 1 core, use our own zone to contention over global locks,
** e.g. we have our own dedicated locks */
bool success;
malloc_zone_t* newzone = malloc_create_zone(4096, 0);
malloc_set_zone_name(newzone, "Sqlite_Heap");
do{
success = OSAtomicCompareAndSwapPtrBarrier(NULL, newzone,
(void * volatile *)&_sqliteZone_);
}while(!_sqliteZone_);
if( !success ){
/* somebody registered a zone first */
malloc_destroy_zone(newzone);
}
}
#endif
UNUSED_PARAMETER(NotUsed);
return SQLITE_OK;
}
/*
** Deinitialize this module.
*/
static void sqlite4MemShutdown(void *NotUsed){
UNUSED_PARAMETER(NotUsed);
return;
}
/*
** This routine is the only routine in this file with external linkage.
**
** Populate the low-level memory allocation function pointers in
** sqlite4DefaultEnv.m with pointers to the routines in this file.
*/
SQLITE_PRIVATE void sqlite4MemSetDefault(sqlite4_env *pEnv){
static const sqlite4_mem_methods defaultMethods = {
sqlite4MemMalloc,
sqlite4MemFree,
sqlite4MemRealloc,
sqlite4MemSize,
sqlite4MemInit,
sqlite4MemShutdown,
0,
0,
0
};
pEnv->m = defaultMethods;
pEnv->m.pMemEnv = (void*)pEnv;
}
#endif /* SQLITE_SYSTEM_MALLOC */
/************** End of mem1.c ************************************************/
/************** Begin file mem2.c ********************************************/
/*
** 2007 August 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.
**
*************************************************************************
**
** This file contains low-level memory allocation drivers for when
** SQLite will use the standard C-library malloc/realloc/free interface
** to obtain the memory it needs while adding lots of additional debugging
** information to each allocation in order to help detect and fix memory
** leaks and memory usage errors.
**
** This file contains implementations of the low-level memory allocation
** routines specified in the sqlite4_mem_methods object.
*/
/*
** This version of the memory allocator is used only if the
** SQLITE_MEMDEBUG macro is defined
*/
#ifdef SQLITE_MEMDEBUG
/*
** The backtrace functionality is only available with GLIBC
*/
#ifdef __GLIBC__
extern int backtrace(void**,int);
extern void backtrace_symbols_fd(void*const*,int,int);
#else
# define backtrace(A,B) 1
# define backtrace_symbols_fd(A,B,C)
#endif
/* #include <stdio.h> */
/*
** Each memory allocation looks like this:
**
** ------------------------------------------------------------------------
** | Title | backtrace pointers | MemBlockHdr | allocation | EndGuard |
** ------------------------------------------------------------------------
**
** The application code sees only a pointer to the allocation. We have
** to back up from the allocation pointer to find the MemBlockHdr. The
** MemBlockHdr tells us the size of the allocation and the number of
** backtrace pointers. There is also a guard word at the end of the
** MemBlockHdr.
*/
struct MemBlockHdr {
i64 iSize; /* Size of this allocation */
struct MemBlockHdr *pNext, *pPrev; /* Linked list of all unfreed memory */
char nBacktrace; /* Number of backtraces on this alloc */
char nBacktraceSlots; /* Available backtrace slots */
u8 nTitle; /* Bytes of title; includes '\0' */
u8 eType; /* Allocation type code */
int iForeGuard; /* Guard word for sanity */
};
/*
** Guard words
*/
#define FOREGUARD 0x80F5E153
#define REARGUARD 0xE4676B53
/*
** Number of malloc size increments to track.
*/
#define NCSIZE 1000
/*
** All of the static variables used by this module are collected
** into a single structure named "mem". This is to keep the
** static variables organized and to reduce namespace pollution
** when this module is combined with other in the amalgamation.
*/
static struct {
/*
** Mutex to control access to the memory allocation subsystem.
*/
sqlite4_mutex *mutex;
/*
** Head and tail of a linked list of all outstanding allocations
*/
struct MemBlockHdr *pFirst;
struct MemBlockHdr *pLast;
/*
** The number of levels of backtrace to save in new allocations.
*/
int nBacktrace;
void (*xBacktrace)(int, int, void **);
/*
** Title text to insert in front of each block
*/
int nTitle; /* Bytes of zTitle to save. Includes '\0' and padding */
char zTitle[100]; /* The title text */
/*
** sqlite4MallocDisallow() increments the following counter.
** sqlite4MallocAllow() decrements it.
*/
int disallow; /* Do not allow memory allocation */
/*
** Gather statistics on the sizes of memory allocations.
** nAlloc[i] is the number of allocation attempts of i*8
** bytes. i==NCSIZE is the number of allocation attempts for
** sizes more than NCSIZE*8 bytes.
*/
int nAlloc[NCSIZE]; /* Total number of allocations */
int nCurrent[NCSIZE]; /* Current number of allocations */
int mxCurrent[NCSIZE]; /* Highwater mark for nCurrent */
} mem2;
/*
** Adjust memory usage statistics
*/
static void adjustStats(int iSize, int increment){
int i = ROUND8(iSize)/8;
if( i>NCSIZE-1 ){
i = NCSIZE - 1;
}
if( increment>0 ){
mem2.nAlloc[i]++;
mem2.nCurrent[i]++;
if( mem2.nCurrent[i]>mem2.mxCurrent[i] ){
mem2.mxCurrent[i] = mem2.nCurrent[i];
}
}else{
mem2.nCurrent[i]--;
assert( mem2.nCurrent[i]>=0 );
}
}
/*
** Given an allocation, find the MemBlockHdr for that allocation.
**
** This routine checks the guards at either end of the allocation and
** if they are incorrect it asserts.
*/
static struct MemBlockHdr *sqlite4MemsysGetHeader(void *pAllocation){
struct MemBlockHdr *p;
int *pInt;
u8 *pU8;
int nReserve;
p = (struct MemBlockHdr*)pAllocation;
p--;
assert( p->iForeGuard==(int)FOREGUARD );
nReserve = ROUND8(p->iSize);
pInt = (int*)pAllocation;
pU8 = (u8*)pAllocation;
assert( pInt[nReserve/sizeof(int)]==(int)REARGUARD );
/* This checks any of the "extra" bytes allocated due
** to rounding up to an 8 byte boundary to ensure
** they haven't been overwritten.
*/
while( nReserve-- > p->iSize ) assert( pU8[nReserve]==0x65 );
return p;
}
/*
** Return the number of bytes currently allocated at address p.
*/
static int sqlite4MemSize(void *pMem, void *p){
struct MemBlockHdr *pHdr;
assert( pMem==(void*)&mem2 );
if( !p ){
return 0;
}
pHdr = sqlite4MemsysGetHeader(p);
return pHdr->iSize;
}
/*
** Initialize the memory allocation subsystem.
*/
static int sqlite4MemInit(void *pMallocEnv){
sqlite4_env *pEnv = (sqlite4_env*)pMallocEnv;
int rc = SQLITE_OK;
assert( (sizeof(struct MemBlockHdr)&7) == 0 );
if( !pEnv->bMemstat ){
mem2.mutex = sqlite4MutexAlloc(pEnv, SQLITE_MUTEX_FAST);
if( mem2.mutex==0 && pEnv->bCoreMutex ) rc = SQLITE_NOMEM;
}
return rc;
}
/*
** Deinitialize the memory allocation subsystem.
*/
static void sqlite4MemShutdown(void *NotUsed){
UNUSED_PARAMETER(NotUsed);
sqlite4_mutex_free(mem2.mutex);
mem2.mutex = 0;
}
/*
** Fill a buffer with pseudo-random bytes. This is used to preset
** the content of a new memory allocation to unpredictable values and
** to clear the content of a freed allocation to unpredictable values.
*/
static void randomFill(char *pBuf, int nByte){
unsigned int x, y, r;
x = SQLITE_PTR_TO_INT(pBuf);
y = nByte | 1;
while( nByte >= 4 ){
x = (x>>1) ^ (-(x&1) & 0xd0000001);
y = y*1103515245 + 12345;
r = x ^ y;
*(int*)pBuf = r;
pBuf += 4;
nByte -= 4;
}
while( nByte-- > 0 ){
x = (x>>1) ^ (-(x&1) & 0xd0000001);
y = y*1103515245 + 12345;
r = x ^ y;
*(pBuf++) = r & 0xff;
}
}
/*
** Allocate nByte bytes of memory.
*/
static void *sqlite4MemMalloc(void *pMem, sqlite4_size_t nByte){
struct MemBlockHdr *pHdr;
void **pBt;
char *z;
int *pInt;
void *p = 0;
int totalSize;
int nReserve;
sqlite4_mutex_enter(mem2.mutex);
assert( mem2.disallow==0 );
nReserve = ROUND8(nByte);
totalSize = nReserve + sizeof(*pHdr) + sizeof(int) +
mem2.nBacktrace*sizeof(void*) + mem2.nTitle;
assert( pMem==(void*)&mem2 );
p = malloc(totalSize);
if( p ){
z = p;
pBt = (void**)&z[mem2.nTitle];
pHdr = (struct MemBlockHdr*)&pBt[mem2.nBacktrace];
pHdr->pNext = 0;
pHdr->pPrev = mem2.pLast;
if( mem2.pLast ){
mem2.pLast->pNext = pHdr;
}else{
mem2.pFirst = pHdr;
}
mem2.pLast = pHdr;
pHdr->iForeGuard = FOREGUARD;
pHdr->eType = MEMTYPE_HEAP;
pHdr->nBacktraceSlots = mem2.nBacktrace;
pHdr->nTitle = mem2.nTitle;
if( mem2.nBacktrace ){
void *aAddr[40];
pHdr->nBacktrace = backtrace(aAddr, mem2.nBacktrace+1)-1;
memcpy(pBt, &aAddr[1], pHdr->nBacktrace*sizeof(void*));
assert(pBt[0]);
if( mem2.xBacktrace ){
mem2.xBacktrace(nByte, pHdr->nBacktrace-1, &aAddr[1]);
}
}else{
pHdr->nBacktrace = 0;
}
if( mem2.nTitle ){
memcpy(z, mem2.zTitle, mem2.nTitle);
}
pHdr->iSize = nByte;
adjustStats(nByte, +1);
pInt = (int*)&pHdr[1];
pInt[nReserve/sizeof(int)] = REARGUARD;
randomFill((char*)pInt, nByte);
memset(((char*)pInt)+nByte, 0x65, nReserve-nByte);
p = (void*)pInt;
}
sqlite4_mutex_leave(mem2.mutex);
return p;
}
/*
** Free memory.
*/
static void sqlite4MemFree(void *pMem, void *pPrior){
struct MemBlockHdr *pHdr;
void **pBt;
char *z;
assert( pMem==(void*)&mem2 );
assert( sqlite4DefaultEnv.bMemstat || sqlite4DefaultEnv.bCoreMutex==0
|| mem2.mutex!=0 );
pHdr = sqlite4MemsysGetHeader(pPrior);
pBt = (void**)pHdr;
pBt -= pHdr->nBacktraceSlots;
sqlite4_mutex_enter(mem2.mutex);
if( pHdr->pPrev ){
assert( pHdr->pPrev->pNext==pHdr );
pHdr->pPrev->pNext = pHdr->pNext;
}else{
assert( mem2.pFirst==pHdr );
mem2.pFirst = pHdr->pNext;
}
if( pHdr->pNext ){
assert( pHdr->pNext->pPrev==pHdr );
pHdr->pNext->pPrev = pHdr->pPrev;
}else{
assert( mem2.pLast==pHdr );
mem2.pLast = pHdr->pPrev;
}
z = (char*)pBt;
z -= pHdr->nTitle;
adjustStats(pHdr->iSize, -1);
randomFill(z, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) +
pHdr->iSize + sizeof(int) + pHdr->nTitle);
free(z);
sqlite4_mutex_leave(mem2.mutex);
}
/*
** Change the size of an existing memory allocation.
**
** For this debugging implementation, we *always* make a copy of the
** allocation into a new place in memory. In this way, if the
** higher level code is using pointer to the old allocation, it is
** much more likely to break and we are much more liking to find
** the error.
*/
static void *sqlite4MemRealloc(void *p, void *pPrior, sqlite4_size_t nByte){
struct MemBlockHdr *pOldHdr;
void *pNew;
assert( p==(void*)&mem2 );
assert( mem2.disallow==0 );
assert( (nByte & 7)==0 ); /* EV: R-46199-30249 */
pOldHdr = sqlite4MemsysGetHeader(pPrior);
pNew = sqlite4MemMalloc(p, nByte);
if( pNew ){
memcpy(pNew, pPrior, nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize);
if( nByte>pOldHdr->iSize ){
randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - pOldHdr->iSize);
}
sqlite4MemFree(p, pPrior);
}
return pNew;
}
/*
** Populate the low-level memory allocation function pointers in
** sqlite4DefaultEnv.m with pointers to the routines in this file.
*/
SQLITE_PRIVATE void sqlite4MemSetDefault(sqlite4_env *pEnv){
static const sqlite4_mem_methods defaultMethods = {
sqlite4MemMalloc,
sqlite4MemFree,
sqlite4MemRealloc,
sqlite4MemSize,
sqlite4MemInit,
sqlite4MemShutdown,
0,
0,
&mem2
};
pEnv->m = defaultMethods;
}
/*
** Set the "type" of an allocation.
*/
SQLITE_PRIVATE void sqlite4MemdebugSetType(void *p, u8 eType){
if( p && sqlite4DefaultEnv.m.xMalloc==sqlite4MemMalloc ){
struct MemBlockHdr *pHdr;
pHdr = sqlite4MemsysGetHeader(p);
assert( pHdr->iForeGuard==FOREGUARD );
pHdr->eType = eType;
}
}
/*
** Return TRUE if the mask of type in eType matches the type of the
** allocation p. Also return true if p==NULL.
**
** This routine is designed for use within an assert() statement, to
** verify the type of an allocation. For example:
**
** assert( sqlite4MemdebugHasType(p, MEMTYPE_DB) );
*/
SQLITE_PRIVATE int sqlite4MemdebugHasType(const void *p, u8 eType){
int rc = 1;
if( p && sqlite4DefaultEnv.m.xMalloc==sqlite4MemMalloc ){
struct MemBlockHdr *pHdr;
pHdr = sqlite4MemsysGetHeader(p);
assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */
if( (pHdr->eType&eType)==0 ){
rc = 0;
}
}
return rc;
}
/*
** Return TRUE if the mask of type in eType matches no bits of the type of the
** allocation p. Also return true if p==NULL.
**
** This routine is designed for use within an assert() statement, to
** verify the type of an allocation. For example:
**
** assert( sqlite4MemdebugNoType(p, MEMTYPE_DB) );
*/
SQLITE_PRIVATE int sqlite4MemdebugNoType(const void *p, u8 eType){
int rc = 1;
if( p && sqlite4DefaultEnv.m.xMalloc==sqlite4MemMalloc ){
struct MemBlockHdr *pHdr;
pHdr = sqlite4MemsysGetHeader(p);
assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */
if( (pHdr->eType&eType)!=0 ){
rc = 0;
}
}
return rc;
}
/*
** Set the number of backtrace levels kept for each allocation.
** A value of zero turns off backtracing. The number is always rounded
** up to a multiple of 2.
*/
SQLITE_PRIVATE void sqlite4MemdebugBacktrace(int depth){
if( depth<0 ){ depth = 0; }
if( depth>20 ){ depth = 20; }
depth = (depth+1)&0xfe;
mem2.nBacktrace = depth;
}
SQLITE_PRIVATE void sqlite4MemdebugBacktraceCallback(void (*xBacktrace)(int, int, void **)){
mem2.xBacktrace = xBacktrace;
}
/*
** Set the title string for subsequent allocations.
*/
SQLITE_PRIVATE void sqlite4MemdebugSettitle(const char *zTitle){
unsigned int n = sqlite4Strlen30(zTitle) + 1;
sqlite4_mutex_enter(mem2.mutex);
if( n>=sizeof(mem2.zTitle) ) n = sizeof(mem2.zTitle)-1;
memcpy(mem2.zTitle, zTitle, n);
mem2.zTitle[n] = 0;
mem2.nTitle = ROUND8(n);
sqlite4_mutex_leave(mem2.mutex);
}
SQLITE_PRIVATE void sqlite4MemdebugSync(){
struct MemBlockHdr *pHdr;
for(pHdr=mem2.pFirst; pHdr; pHdr=pHdr->pNext){
void **pBt = (void**)pHdr;
pBt -= pHdr->nBacktraceSlots;
mem2.xBacktrace(pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]);
}
}
/*
** Open the file indicated and write a log of all unfreed memory
** allocations into that log.
*/
SQLITE_PRIVATE void sqlite4MemdebugDump(const char *zFilename){
FILE *out;
struct MemBlockHdr *pHdr;
void **pBt;
int i;
out = fopen(zFilename, "w");
if( out==0 ){
fprintf(stderr, "** Unable to output memory debug output log: %s **\n",
zFilename);
return;
}
for(pHdr=mem2.pFirst; pHdr; pHdr=pHdr->pNext){
char *z = (char*)pHdr;
z -= pHdr->nBacktraceSlots*sizeof(void*) + pHdr->nTitle;
fprintf(out, "**** %lld bytes at %p from %s ****\n",
pHdr->iSize, &pHdr[1], pHdr->nTitle ? z : "???");
if( pHdr->nBacktrace ){
fflush(out);
pBt = (void**)pHdr;
pBt -= pHdr->nBacktraceSlots;
backtrace_symbols_fd(pBt, pHdr->nBacktrace, fileno(out));
fprintf(out, "\n");
}
}
fprintf(out, "COUNTS:\n");
for(i=0; i<NCSIZE-1; i++){
if( mem2.nAlloc[i] ){
fprintf(out, " %5d: %10d %10d %10d\n",
i*8, mem2.nAlloc[i], mem2.nCurrent[i], mem2.mxCurrent[i]);
}
}
if( mem2.nAlloc[NCSIZE-1] ){
fprintf(out, " %5d: %10d %10d %10d\n",
NCSIZE*8-8, mem2.nAlloc[NCSIZE-1],
mem2.nCurrent[NCSIZE-1], mem2.mxCurrent[NCSIZE-1]);
}
fclose(out);
}
/*
** Return the number of times sqlite4MemMalloc() has been called.
*/
SQLITE_PRIVATE int sqlite4MemdebugMallocCount(){
int i;
int nTotal = 0;
for(i=0; i<NCSIZE; i++){
nTotal += mem2.nAlloc[i];
}
return nTotal;
}
#endif /* SQLITE_MEMDEBUG */
/************** End of mem2.c ************************************************/
/************** Begin file mem3.c ********************************************/
/*
** 2007 October 14
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the C functions that implement a memory
** allocation subsystem for use by SQLite.
**
** This version of the memory allocation subsystem omits all
** use of malloc(). The SQLite user supplies a block of memory
** before calling sqlite4_initialize() from which allocations
** are made and returned by the xMalloc() and xRealloc()
** implementations. Once sqlite4_initialize() has been called,
** the amount of memory available to SQLite is fixed and cannot
** be changed.
**
** This version of the memory allocation subsystem is included
** in the build only if SQLITE_ENABLE_MEMSYS3 is defined.
*/
/*
** This version of the memory allocator is only built into the library
** SQLITE_ENABLE_MEMSYS3 is defined. Defining this symbol does not
** mean that the library will use a memory-pool by default, just that
** it is available. The mempool allocator is activated by calling
** sqlite4_config().
*/
#ifdef SQLITE_ENABLE_MEMSYS3
/*
** Maximum size (in Mem3Blocks) of a "small" chunk.
*/
#define MX_SMALL 10
/*
** Number of freelist hash slots
*/
#define N_HASH 61
/*
** A memory allocation (also called a "chunk") consists of two or
** more blocks where each block is 8 bytes. The first 8 bytes are
** a header that is not returned to the user.
**
** A chunk is two or more blocks that is either checked out or
** free. The first block has format u.hdr. u.hdr.size4x is 4 times the
** size of the allocation in blocks if the allocation is free.
** The u.hdr.size4x&1 bit is true if the chunk is checked out and
** false if the chunk is on the freelist. The u.hdr.size4x&2 bit
** is true if the previous chunk is checked out and false if the
** previous chunk is free. The u.hdr.prevSize field is the size of
** the previous chunk in blocks if the previous chunk is on the
** freelist. If the previous chunk is checked out, then
** u.hdr.prevSize can be part of the data for that chunk and should
** not be read or written.
**
** We often identify a chunk by its index in mem3.aPool[]. When
** this is done, the chunk index refers to the second block of
** the chunk. In this way, the first chunk has an index of 1.
** A chunk index of 0 means "no such chunk" and is the equivalent
** of a NULL pointer.
**
** The second block of free chunks is of the form u.list. The
** two fields form a double-linked list of chunks of related sizes.
** Pointers to the head of the list are stored in mem3.aiSmall[]
** for smaller chunks and mem3.aiHash[] for larger chunks.
**
** The second block of a chunk is user data if the chunk is checked
** out. If a chunk is checked out, the user data may extend into
** the u.hdr.prevSize value of the following chunk.
*/
typedef struct Mem3Block Mem3Block;
struct Mem3Block {
union {
struct {
u32 prevSize; /* Size of previous chunk in Mem3Block elements */
u32 size4x; /* 4x the size of current chunk in Mem3Block elements */
} hdr;
struct {
u32 next; /* Index in mem3.aPool[] of next free chunk */
u32 prev; /* Index in mem3.aPool[] of previous free chunk */
} list;
} u;
};
/*
** All of the static variables used by this module are collected
** into a single structure named "mem3". This is to keep the
** static variables organized and to reduce namespace pollution
** when this module is combined with other in the amalgamation.
*/
static SQLITE_WSD struct Mem3Global {
/*
** Memory available for allocation. nPool is the size of the array
** (in Mem3Blocks) pointed to by aPool less 2.
*/
u32 nPool;
Mem3Block *aPool;
/*
** True if we are evaluating an out-of-memory callback.
*/
int alarmBusy;
/*
** Mutex to control access to the memory allocation subsystem.
*/
sqlite4_mutex *mutex;
/*
** The minimum amount of free space that we have seen.
*/
u32 mnMaster;
/*
** iMaster is the index of the master chunk. Most new allocations
** occur off of this chunk. szMaster is the size (in Mem3Blocks)
** of the current master. iMaster is 0 if there is not master chunk.
** The master chunk is not in either the aiHash[] or aiSmall[].
*/
u32 iMaster;
u32 szMaster;
/*
** Array of lists of free blocks according to the block size
** for smaller chunks, or a hash on the block size for larger
** chunks.
*/
u32 aiSmall[MX_SMALL-1]; /* For sizes 2 through MX_SMALL, inclusive */
u32 aiHash[N_HASH]; /* For sizes MX_SMALL+1 and larger */
} mem3 = { 97535575 };
/*
** Unlink the chunk at mem3.aPool[i] from list it is currently
** on. *pRoot is the list that i is a member of.
*/
static void memsys3UnlinkFromList(u32 i, u32 *pRoot){
u32 next = mem3.aPool[i].u.list.next;
u32 prev = mem3.aPool[i].u.list.prev;
assert( sqlite4_mutex_held(mem3.mutex) );
if( prev==0 ){
*pRoot = next;
}else{
mem3.aPool[prev].u.list.next = next;
}
if( next ){
mem3.aPool[next].u.list.prev = prev;
}
mem3.aPool[i].u.list.next = 0;
mem3.aPool[i].u.list.prev = 0;
}
/*
** Unlink the chunk at index i from
** whatever list is currently a member of.
*/
static void memsys3Unlink(u32 i){
u32 size, hash;
assert( sqlite4_mutex_held(mem3.mutex) );
assert( (mem3.aPool[i-1].u.hdr.size4x & 1)==0 );
assert( i>=1 );
size = mem3.aPool[i-1].u.hdr.size4x/4;
assert( size==mem3.aPool[i+size-1].u.hdr.prevSize );
assert( size>=2 );
if( size <= MX_SMALL ){
memsys3UnlinkFromList(i, &mem3.aiSmall[size-2]);
}else{
hash = size % N_HASH;
memsys3UnlinkFromList(i, &mem3.aiHash[hash]);
}
}
/*
** Link the chunk at mem3.aPool[i] so that is on the list rooted
** at *pRoot.
*/
static void memsys3LinkIntoList(u32 i, u32 *pRoot){
assert( sqlite4_mutex_held(mem3.mutex) );
mem3.aPool[i].u.list.next = *pRoot;
mem3.aPool[i].u.list.prev = 0;
if( *pRoot ){
mem3.aPool[*pRoot].u.list.prev = i;
}
*pRoot = i;
}
/*
** Link the chunk at index i into either the appropriate
** small chunk list, or into the large chunk hash table.
*/
static void memsys3Link(u32 i){
u32 size, hash;
assert( sqlite4_mutex_held(mem3.mutex) );
assert( i>=1 );
assert( (mem3.aPool[i-1].u.hdr.size4x & 1)==0 );
size = mem3.aPool[i-1].u.hdr.size4x/4;
assert( size==mem3.aPool[i+size-1].u.hdr.prevSize );
assert( size>=2 );
if( size <= MX_SMALL ){
memsys3LinkIntoList(i, &mem3.aiSmall[size-2]);
}else{
hash = size % N_HASH;
memsys3LinkIntoList(i, &mem3.aiHash[hash]);
}
}
/*
** If the STATIC_MEM mutex is not already held, obtain it now. The mutex
** will already be held (obtained by code in malloc.c) if
** sqlite4DefaultEnv.bMemStat is true.
*/
static void memsys3Enter(void){
if( sqlite4DefaultEnv.bMemstat==0 && mem3.mutex==0 ){
mem3.mutex = sqlite4MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
}
sqlite4_mutex_enter(mem3.mutex);
}
static void memsys3Leave(void){
sqlite4_mutex_leave(mem3.mutex);
}
/*
** Called when we are unable to satisfy an allocation of nBytes.
*/
static void memsys3OutOfMemory(int nByte){
if( !mem3.alarmBusy ){
mem3.alarmBusy = 1;
assert( sqlite4_mutex_held(mem3.mutex) );
sqlite4_mutex_leave(mem3.mutex);
sqlite4_release_memory(nByte);
sqlite4_mutex_enter(mem3.mutex);
mem3.alarmBusy = 0;
}
}
/*
** Chunk i is a free chunk that has been unlinked. Adjust its
** size parameters for check-out and return a pointer to the
** user portion of the chunk.
*/
static void *memsys3Checkout(u32 i, u32 nBlock){
u32 x;
assert( sqlite4_mutex_held(mem3.mutex) );
assert( i>=1 );
assert( mem3.aPool[i-1].u.hdr.size4x/4==nBlock );
assert( mem3.aPool[i+nBlock-1].u.hdr.prevSize==nBlock );
x = mem3.aPool[i-1].u.hdr.size4x;
mem3.aPool[i-1].u.hdr.size4x = nBlock*4 | 1 | (x&2);
mem3.aPool[i+nBlock-1].u.hdr.prevSize = nBlock;
mem3.aPool[i+nBlock-1].u.hdr.size4x |= 2;
return &mem3.aPool[i];
}
/*
** Carve a piece off of the end of the mem3.iMaster free chunk.
** Return a pointer to the new allocation. Or, if the master chunk
** is not large enough, return 0.
*/
static void *memsys3FromMaster(u32 nBlock){
assert( sqlite4_mutex_held(mem3.mutex) );
assert( mem3.szMaster>=nBlock );
if( nBlock>=mem3.szMaster-1 ){
/* Use the entire master */
void *p = memsys3Checkout(mem3.iMaster, mem3.szMaster);
mem3.iMaster = 0;
mem3.szMaster = 0;
mem3.mnMaster = 0;
return p;
}else{
/* Split the master block. Return the tail. */
u32 newi, x;
newi = mem3.iMaster + mem3.szMaster - nBlock;
assert( newi > mem3.iMaster+1 );
mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = nBlock;
mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x |= 2;
mem3.aPool[newi-1].u.hdr.size4x = nBlock*4 + 1;
mem3.szMaster -= nBlock;
mem3.aPool[newi-1].u.hdr.prevSize = mem3.szMaster;
x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2;
mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x;
if( mem3.szMaster < mem3.mnMaster ){
mem3.mnMaster = mem3.szMaster;
}
return (void*)&mem3.aPool[newi];
}
}
/*
** *pRoot is the head of a list of free chunks of the same size
** or same size hash. In other words, *pRoot is an entry in either
** mem3.aiSmall[] or mem3.aiHash[].
**
** This routine examines all entries on the given list and tries
** to coalesce each entries with adjacent free chunks.
**
** If it sees a chunk that is larger than mem3.iMaster, it replaces
** the current mem3.iMaster with the new larger chunk. In order for
** this mem3.iMaster replacement to work, the master chunk must be
** linked into the hash tables. That is not the normal state of
** affairs, of course. The calling routine must link the master
** chunk before invoking this routine, then must unlink the (possibly
** changed) master chunk once this routine has finished.
*/
static void memsys3Merge(u32 *pRoot){
u32 iNext, prev, size, i, x;
assert( sqlite4_mutex_held(mem3.mutex) );
for(i=*pRoot; i>0; i=iNext){
iNext = mem3.aPool[i].u.list.next;
size = mem3.aPool[i-1].u.hdr.size4x;
assert( (size&1)==0 );
if( (size&2)==0 ){
memsys3UnlinkFromList(i, pRoot);
assert( i > mem3.aPool[i-1].u.hdr.prevSize );
prev = i - mem3.aPool[i-1].u.hdr.prevSize;
if( prev==iNext ){
iNext = mem3.aPool[prev].u.list.next;
}
memsys3Unlink(prev);
size = i + size/4 - prev;
x = mem3.aPool[prev-1].u.hdr.size4x & 2;
mem3.aPool[prev-1].u.hdr.size4x = size*4 | x;
mem3.aPool[prev+size-1].u.hdr.prevSize = size;
memsys3Link(prev);
i = prev;
}else{
size /= 4;
}
if( size>mem3.szMaster ){
mem3.iMaster = i;
mem3.szMaster = size;
}
}
}
/*
** Return a block of memory of at least nBytes in size.
** Return NULL if unable.
**
** This function assumes that the necessary mutexes, if any, are
** already held by the caller. Hence "Unsafe".
*/
static void *memsys3MallocUnsafe(int nByte){
u32 i;
u32 nBlock;
u32 toFree;
assert( sqlite4_mutex_held(mem3.mutex) );
assert( sizeof(Mem3Block)==8 );
if( nByte<=12 ){
nBlock = 2;
}else{
nBlock = (nByte + 11)/8;
}
assert( nBlock>=2 );
/* STEP 1:
** Look for an entry of the correct size in either the small
** chunk table or in the large chunk hash table. This is
** successful most of the time (about 9 times out of 10).
*/
if( nBlock <= MX_SMALL ){
i = mem3.aiSmall[nBlock-2];
if( i>0 ){
memsys3UnlinkFromList(i, &mem3.aiSmall[nBlock-2]);
return memsys3Checkout(i, nBlock);
}
}else{
int hash = nBlock % N_HASH;
for(i=mem3.aiHash[hash]; i>0; i=mem3.aPool[i].u.list.next){
if( mem3.aPool[i-1].u.hdr.size4x/4==nBlock ){
memsys3UnlinkFromList(i, &mem3.aiHash[hash]);
return memsys3Checkout(i, nBlock);
}
}
}
/* STEP 2:
** Try to satisfy the allocation by carving a piece off of the end
** of the master chunk. This step usually works if step 1 fails.
*/
if( mem3.szMaster>=nBlock ){
return memsys3FromMaster(nBlock);
}
/* STEP 3:
** Loop through the entire memory pool. Coalesce adjacent free
** chunks. Recompute the master chunk as the largest free chunk.
** Then try again to satisfy the allocation by carving a piece off
** of the end of the master chunk. This step happens very
** rarely (we hope!)
*/
for(toFree=nBlock*16; toFree<(mem3.nPool*16); toFree *= 2){
memsys3OutOfMemory(toFree);
if( mem3.iMaster ){
memsys3Link(mem3.iMaster);
mem3.iMaster = 0;
mem3.szMaster = 0;
}
for(i=0; i<N_HASH; i++){
memsys3Merge(&mem3.aiHash[i]);
}
for(i=0; i<MX_SMALL-1; i++){
memsys3Merge(&mem3.aiSmall[i]);
}
if( mem3.szMaster ){
memsys3Unlink(mem3.iMaster);
if( mem3.szMaster>=nBlock ){
return memsys3FromMaster(nBlock);
}
}
}
/* If none of the above worked, then we fail. */
return 0;
}
/*
** Free an outstanding memory allocation.
**
** This function assumes that the necessary mutexes, if any, are
** already held by the caller. Hence "Unsafe".
*/
static void memsys3FreeUnsafe(void *pOld){
Mem3Block *p = (Mem3Block*)pOld;
int i;
u32 size, x;
assert( sqlite4_mutex_held(mem3.mutex) );
assert( p>mem3.aPool && p<&mem3.aPool[mem3.nPool] );
i = p - mem3.aPool;
assert( (mem3.aPool[i-1].u.hdr.size4x&1)==1 );
size = mem3.aPool[i-1].u.hdr.size4x/4;
assert( i+size<=mem3.nPool+1 );
mem3.aPool[i-1].u.hdr.size4x &= ~1;
mem3.aPool[i+size-1].u.hdr.prevSize = size;
mem3.aPool[i+size-1].u.hdr.size4x &= ~2;
memsys3Link(i);
/* Try to expand the master using the newly freed chunk */
if( mem3.iMaster ){
while( (mem3.aPool[mem3.iMaster-1].u.hdr.size4x&2)==0 ){
size = mem3.aPool[mem3.iMaster-1].u.hdr.prevSize;
mem3.iMaster -= size;
mem3.szMaster += size;
memsys3Unlink(mem3.iMaster);
x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2;
mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x;
mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = mem3.szMaster;
}
x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2;
while( (mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x&1)==0 ){
memsys3Unlink(mem3.iMaster+mem3.szMaster);
mem3.szMaster += mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x/4;
mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x;
mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = mem3.szMaster;
}
}
}
/*
** Return the size of an outstanding allocation, in bytes. The
** size returned omits the 8-byte header overhead. This only
** works for chunks that are currently checked out.
*/
static int memsys3Size(void *p){
Mem3Block *pBlock;
if( p==0 ) return 0;
pBlock = (Mem3Block*)p;
assert( (pBlock[-1].u.hdr.size4x&1)!=0 );
return (pBlock[-1].u.hdr.size4x&~3)*2 - 4;
}
/*
** Round up a request size to the next valid allocation size.
*/
static int memsys3Roundup(int n){
if( n<=12 ){
return 12;
}else{
return ((n+11)&~7) - 4;
}
}
/*
** Allocate nBytes of memory.
*/
static void *memsys3Malloc(int nBytes){
sqlite4_int64 *p;
assert( nBytes>0 ); /* malloc.c filters out 0 byte requests */
memsys3Enter();
p = memsys3MallocUnsafe(nBytes);
memsys3Leave();
return (void*)p;
}
/*
** Free memory.
*/
static void memsys3Free(void *pPrior){
assert( pPrior );
memsys3Enter();
memsys3FreeUnsafe(pPrior);
memsys3Leave();
}
/*
** Change the size of an existing memory allocation
*/
static void *memsys3Realloc(sqlite4_env*pEnv, void *pPrior, int nBytes){
int nOld;
void *p;
if( pPrior==0 ){
return sqlite4_malloc(pEnv, nBytes);
}
if( nBytes<=0 ){
sqlite4_free(pEnv, pPrior);
return 0;
}
nOld = memsys3Size(pPrior);
if( nBytes<=nOld && nBytes>=nOld-128 ){
return pPrior;
}
memsys3Enter();
p = memsys3MallocUnsafe(nBytes);
if( p ){
if( nOld<nBytes ){
memcpy(p, pPrior, nOld);
}else{
memcpy(p, pPrior, nBytes);
}
memsys3FreeUnsafe(pPrior);
}
memsys3Leave();
return p;
}
/*
** Initialize this module.
*/
static int memsys3Init(void *NotUsed){
UNUSED_PARAMETER(NotUsed);
if( !sqlite4DefaultEnv.pHeap ){
return SQLITE_ERROR;
}
/* Store a pointer to the memory block in global structure mem3. */
assert( sizeof(Mem3Block)==8 );
mem3.aPool = (Mem3Block *)sqlite4DefaultEnv.pHeap;
mem3.nPool = (sqlite4DefaultEnv.nHeap / sizeof(Mem3Block)) - 2;
/* Initialize the master block. */
mem3.szMaster = mem3.nPool;
mem3.mnMaster = mem3.szMaster;
mem3.iMaster = 1;
mem3.aPool[0].u.hdr.size4x = (mem3.szMaster<<2) + 2;
mem3.aPool[mem3.nPool].u.hdr.prevSize = mem3.nPool;
mem3.aPool[mem3.nPool].u.hdr.size4x = 1;
return SQLITE_OK;
}
/*
** Deinitialize this module.
*/
static void memsys3Shutdown(void *NotUsed){
UNUSED_PARAMETER(NotUsed);
mem3.mutex = 0;
return;
}
/*
** Open the file indicated and write a log of all unfreed memory
** allocations into that log.
*/
SQLITE_PRIVATE void sqlite4Memsys3Dump(const char *zFilename){
#ifdef SQLITE_DEBUG
FILE *out;
u32 i, j;
u32 size;
if( zFilename==0 || zFilename[0]==0 ){
out = stdout;
}else{
out = fopen(zFilename, "w");
if( out==0 ){
fprintf(stderr, "** Unable to output memory debug output log: %s **\n",
zFilename);
return;
}
}
memsys3Enter();
fprintf(out, "CHUNKS:\n");
for(i=1; i<=mem3.nPool; i+=size/4){
size = mem3.aPool[i-1].u.hdr.size4x;
if( size/4<=1 ){
fprintf(out, "%p size error\n", &mem3.aPool[i]);
assert( 0 );
break;
}
if( (size&1)==0 && mem3.aPool[i+size/4-1].u.hdr.prevSize!=size/4 ){
fprintf(out, "%p tail size does not match\n", &mem3.aPool[i]);
assert( 0 );
break;
}
if( ((mem3.aPool[i+size/4-1].u.hdr.size4x&2)>>1)!=(size&1) ){
fprintf(out, "%p tail checkout bit is incorrect\n", &mem3.aPool[i]);
assert( 0 );
break;
}
if( size&1 ){
fprintf(out, "%p %6d bytes checked out\n", &mem3.aPool[i], (size/4)*8-8);
}else{
fprintf(out, "%p %6d bytes free%s\n", &mem3.aPool[i], (size/4)*8-8,
i==mem3.iMaster ? " **master**" : "");
}
}
for(i=0; i<MX_SMALL-1; i++){
if( mem3.aiSmall[i]==0 ) continue;
fprintf(out, "small(%2d):", i);
for(j = mem3.aiSmall[i]; j>0; j=mem3.aPool[j].u.list.next){
fprintf(out, " %p(%d)", &mem3.aPool[j],
(mem3.aPool[j-1].u.hdr.size4x/4)*8-8);
}
fprintf(out, "\n");
}
for(i=0; i<N_HASH; i++){
if( mem3.aiHash[i]==0 ) continue;
fprintf(out, "hash(%2d):", i);
for(j = mem3.aiHash[i]; j>0; j=mem3.aPool[j].u.list.next){
fprintf(out, " %p(%d)", &mem3.aPool[j],
(mem3.aPool[j-1].u.hdr.size4x/4)*8-8);
}
fprintf(out, "\n");
}
fprintf(out, "master=%d\n", mem3.iMaster);
fprintf(out, "nowUsed=%d\n", mem3.nPool*8 - mem3.szMaster*8);
fprintf(out, "mxUsed=%d\n", mem3.nPool*8 - mem3.mnMaster*8);
sqlite4_mutex_leave(mem3.mutex);
if( out==stdout ){
fflush(stdout);
}else{
fclose(out);
}
#else
UNUSED_PARAMETER(zFilename);
#endif
}
/*
** This routine is the only routine in this file with external
** linkage.
**
** Populate the low-level memory allocation function pointers in
** sqlite4DefaultEnv.m with pointers to the routines in this file. The
** arguments specify the block of memory to manage.
**
** This routine is only called by sqlite4_config(), and therefore
** is not required to be threadsafe (it is not).
*/
SQLITE_PRIVATE const sqlite4_mem_methods *sqlite4MemGetMemsys3(void){
static const sqlite4_mem_methods mempoolMethods = {
memsys3Malloc,
memsys3Free,
memsys3Realloc,
memsys3Size,
memsys3Roundup,
memsys3Init,
memsys3Shutdown,
0
};
return &mempoolMethods;
}
#endif /* SQLITE_ENABLE_MEMSYS3 */
/************** End of mem3.c ************************************************/
/************** Begin file mem5.c ********************************************/
/*
** 2007 October 14
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the C functions that implement a memory
** allocation subsystem for use by SQLite.
**
** This version of the memory allocation subsystem omits all
** use of malloc(). The application gives SQLite a block of memory
** before calling sqlite4_initialize() from which allocations
** are made and returned by the xMalloc() and xRealloc()
** implementations. Once sqlite4_initialize() has been called,
** the amount of memory available to SQLite is fixed and cannot
** be changed.
**
** This version of the memory allocation subsystem is included
** in the build only if SQLITE_ENABLE_MEMSYS5 is defined.
**
** This memory allocator uses the following algorithm:
**
** 1. All memory allocations 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 coalesed into the single larger block.
**
** 3. New memory is allocated from the first available free block.
**
** This algorithm is described in: J. M. Robson. "Bounds for Some Functions
** Concerning Dynamic Storage Allocation". Journal of the Association for
** Computing Machinery, Volume 21, Number 8, July 1974, pages 491-499.
**
** Let n be the size of the largest allocation divided by the minimum
** allocation size (after rounding all sizes up to a power of 2.) Let M
** be the maximum amount of memory ever outstanding at one time. Let
** N be the total amount of memory available for allocation. Robson
** proved that this memory allocator will never breakdown due to
** fragmentation as long as the following constraint holds:
**
** N >= M*(1 + log2(n)/2) - n + 1
**
** The sqlite4_status() logic tracks the maximum values of n and M so
** that an application can, at any time, verify this constraint.
*/
/*
** This version of the memory allocator is used only when
** SQLITE_ENABLE_MEMSYS5 is defined.
*/
#ifdef SQLITE_ENABLE_MEMSYS5
/*
** A minimum allocation is an instance of the following structure.
** Larger allocations are an array of these structures where the
** size of the array is a power of 2.
**
** The size of this object must be a power of two. That fact is
** verified in memsys5Init().
*/
typedef struct Mem5Link Mem5Link;
struct Mem5Link {
int next; /* Index of next free chunk */
int prev; /* Index of previous free chunk */
};
/*
** Maximum size of any allocation is ((1<<LOGMAX)*mem5.szAtom). Since
** mem5.szAtom is always at least 8 and 32-bit integers are used,
** it is not actually possible to reach this limit.
*/
#define LOGMAX 30
/*
** Masks used for mem5.aCtrl[] elements.
*/
#define CTRL_LOGSIZE 0x1f /* Log2 Size of this block */
#define CTRL_FREE 0x20 /* True if not checked out */
/*
** All of the static variables used by this module are collected
** into a single structure named "mem5". This is to keep the
** static variables organized and to reduce namespace pollution
** when this module is combined with other in the amalgamation.
*/
static SQLITE_WSD struct Mem5Global {
/*
** Memory available for allocation
*/
int szAtom; /* Smallest possible allocation in bytes */
int nBlock; /* Number of szAtom sized blocks in zPool */
u8 *zPool; /* Memory available to be allocated */
/*
** Mutex to control access to the memory allocation subsystem.
*/
sqlite4_mutex *mutex;
/*
** Performance statistics
*/
u64 nAlloc; /* Total number of calls to malloc */
u64 totalAlloc; /* Total of all malloc calls - includes internal frag */
u64 totalExcess; /* Total internal fragmentation */
u32 currentOut; /* Current checkout, including internal fragmentation */
u32 currentCount; /* Current number of distinct checkouts */
u32 maxOut; /* Maximum instantaneous currentOut */
u32 maxCount; /* Maximum instantaneous currentCount */
u32 maxRequest; /* Largest allocation (exclusive of internal frag) */
/*
** Lists of free blocks. aiFreelist[0] is a list of free blocks of
** size mem5.szAtom. aiFreelist[1] holds blocks of size szAtom*2.
** and so forth.
*/
int aiFreelist[LOGMAX+1];
/*
** Space for tracking which blocks are checked out and the size
** of each block. One byte per block.
*/
u8 *aCtrl;
} mem5;
/*
** Assuming mem5.zPool is divided up into an array of Mem5Link
** structures, return a pointer to the idx-th such lik.
*/
#define MEM5LINK(idx) ((Mem5Link *)(&mem5.zPool[(idx)*mem5.szAtom]))
/*
** Unlink the chunk at mem5.aPool[i] from list it is currently
** on. It should be found on mem5.aiFreelist[iLogsize].
*/
static void memsys5Unlink(int i, int iLogsize){
int next, prev;
assert( i>=0 && i<mem5.nBlock );
assert( iLogsize>=0 && iLogsize<=LOGMAX );
assert( (mem5.aCtrl[i] & CTRL_LOGSIZE)==iLogsize );
next = MEM5LINK(i)->next;
prev = MEM5LINK(i)->prev;
if( prev<0 ){
mem5.aiFreelist[iLogsize] = next;
}else{
MEM5LINK(prev)->next = next;
}
if( next>=0 ){
MEM5LINK(next)->prev = prev;
}
}
/*
** Link the chunk at mem5.aPool[i] so that is on the iLogsize
** free list.
*/
static void memsys5Link(int i, int iLogsize){
int x;
assert( sqlite4_mutex_held(mem5.mutex) );
assert( i>=0 && i<mem5.nBlock );
assert( iLogsize>=0 && iLogsize<=LOGMAX );
assert( (mem5.aCtrl[i] & CTRL_LOGSIZE)==iLogsize );
x = MEM5LINK(i)->next = mem5.aiFreelist[iLogsize];
MEM5LINK(i)->prev = -1;
if( x>=0 ){
assert( x<mem5.nBlock );
MEM5LINK(x)->prev = i;
}
mem5.aiFreelist[iLogsize] = i;
}
/*
** If the STATIC_MEM mutex is not already held, obtain it now. The mutex
** will already be held (obtained by code in malloc.c) if
** sqlite4DefaultEnv.bMemStat is true.
*/
static void memsys5Enter(void){
sqlite4_mutex_enter(mem5.mutex);
}
static void memsys5Leave(void){
sqlite4_mutex_leave(mem5.mutex);
}
/*
** Return the size of an outstanding allocation, in bytes. The
** size returned omits the 8-byte header overhead. This only
** works for chunks that are currently checked out.
*/
static int memsys5Size(void *p){
int iSize = 0;
if( p ){
int i = ((u8 *)p-mem5.zPool)/mem5.szAtom;
assert( i>=0 && i<mem5.nBlock );
iSize = mem5.szAtom * (1 << (mem5.aCtrl[i]&CTRL_LOGSIZE));
}
return iSize;
}
/*
** Find the first entry on the freelist iLogsize. Unlink that
** entry and return its index.
*/
static int memsys5UnlinkFirst(int iLogsize){
int i;
int iFirst;
assert( iLogsize>=0 && iLogsize<=LOGMAX );
i = iFirst = mem5.aiFreelist[iLogsize];
assert( iFirst>=0 );
while( i>0 ){
if( i<iFirst ) iFirst = i;
i = MEM5LINK(i)->next;
}
memsys5Unlink(iFirst, iLogsize);
return iFirst;
}
/*
** Return a block of memory of at least nBytes in size.
** Return NULL if unable. Return NULL if nBytes==0.
**
** The caller guarantees that nByte positive.
**
** The caller has obtained a mutex prior to invoking this
** routine so there is never any chance that two or more
** threads can be in this routine at the same time.
*/
static void *memsys5MallocUnsafe(int nByte){
int i; /* Index of a mem5.aPool[] slot */
int iBin; /* Index into mem5.aiFreelist[] */
int iFullSz; /* Size of allocation rounded up to power of 2 */
int iLogsize; /* Log2 of iFullSz/POW2_MIN */
/* nByte must be a positive */
assert( nByte>0 );
/* Keep track of the maximum allocation request. Even unfulfilled
** requests are counted */
if( (u32)nByte>mem5.maxRequest ){
mem5.maxRequest = nByte;
}
/* Abort if the requested allocation size is larger than the largest
** power of two that we can represent using 32-bit signed integers.
*/
if( nByte > 0x40000000 ){
return 0;
}
/* Round nByte up to the next valid power of two */
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
** two in order to create a new free block of size iLogsize.
*/
for(iBin=iLogsize; mem5.aiFreelist[iBin]<0 && iBin<=LOGMAX; iBin++){}
if( iBin>LOGMAX ){
testcase( sqlite4DefaultEnv.xLog!=0 );
sqlite4_log(0,SQLITE_NOMEM, "failed to allocate %u bytes", nByte);
return 0;
}
i = memsys5UnlinkFirst(iBin);
while( iBin>iLogsize ){
int newSize;
iBin--;
newSize = 1 << iBin;
mem5.aCtrl[i+newSize] = CTRL_FREE | iBin;
memsys5Link(i+newSize, iBin);
}
mem5.aCtrl[i] = iLogsize;
/* Update allocator performance statistics. */
mem5.nAlloc++;
mem5.totalAlloc += iFullSz;
mem5.totalExcess += iFullSz - nByte;
mem5.currentCount++;
mem5.currentOut += iFullSz;
if( mem5.maxCount<mem5.currentCount ) mem5.maxCount = mem5.currentCount;
if( mem5.maxOut<mem5.currentOut ) mem5.maxOut = mem5.currentOut;
/* Return a pointer to the allocated memory. */
return (void*)&mem5.zPool[i*mem5.szAtom];
}
/*
** Free an outstanding memory allocation.
*/
static void memsys5FreeUnsafe(void *pOld){
u32 size, iLogsize;
int iBlock;
/* Set iBlock to the index of the block pointed to by pOld in
** the array of mem5.szAtom byte blocks pointed to by mem5.zPool.
*/
iBlock = ((u8 *)pOld-mem5.zPool)/mem5.szAtom;
/* Check that the pointer pOld points to a valid, non-free block. */
assert( iBlock>=0 && iBlock<mem5.nBlock );
assert( ((u8 *)pOld-mem5.zPool)%mem5.szAtom==0 );
assert( (mem5.aCtrl[iBlock] & CTRL_FREE)==0 );
iLogsize = mem5.aCtrl[iBlock] & CTRL_LOGSIZE;
size = 1<<iLogsize;
assert( iBlock+size-1<(u32)mem5.nBlock );
mem5.aCtrl[iBlock] |= CTRL_FREE;
mem5.aCtrl[iBlock+size-1] |= CTRL_FREE;
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 );
mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize;
while( ALWAYS(iLogsize<LOGMAX) ){
int iBuddy;
if( (iBlock>>iLogsize) & 1 ){
iBuddy = iBlock - size;
}else{
iBuddy = iBlock + size;
}
assert( iBuddy>=0 );
if( (iBuddy+(1<<iLogsize))>mem5.nBlock ) break;
if( mem5.aCtrl[iBuddy]!=(CTRL_FREE | iLogsize) ) break;
memsys5Unlink(iBuddy, iLogsize);
iLogsize++;
if( iBuddy<iBlock ){
mem5.aCtrl[iBuddy] = CTRL_FREE | iLogsize;
mem5.aCtrl[iBlock] = 0;
iBlock = iBuddy;
}else{
mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize;
mem5.aCtrl[iBuddy] = 0;
}
size *= 2;
}
memsys5Link(iBlock, iLogsize);
}
/*
** Allocate nBytes of memory
*/
static void *memsys5Malloc(int nBytes){
sqlite4_int64 *p = 0;
if( nBytes>0 ){
memsys5Enter();
p = memsys5MallocUnsafe(nBytes);
memsys5Leave();
}
return (void*)p;
}
/*
** Free memory.
**
** The outer layer memory allocator prevents this routine from
** being called with pPrior==0.
*/
static void memsys5Free(void *pPrior){
assert( pPrior!=0 );
memsys5Enter();
memsys5FreeUnsafe(pPrior);
memsys5Leave();
}
/*
** Change the size of an existing memory allocation.
**
** The outer layer memory allocator prevents this routine from
** being called with pPrior==0.
**
** nBytes is always a value obtained from a prior call to
** memsys5Round(). Hence nBytes is always a non-negative power
** of two. If nBytes==0 that means that an oversize allocation
** (an allocation larger than 0x40000000) was requested and this
** routine should return 0 without freeing pPrior.
*/
static void *memsys5Realloc(void *pPrior, int nBytes){
int nOld;
void *p;
assert( pPrior!=0 );
assert( (nBytes&(nBytes-1))==0 ); /* EV: R-46199-30249 */
assert( nBytes>=0 );
if( nBytes==0 ){
return 0;
}
nOld = memsys5Size(pPrior);
if( nBytes<=nOld ){
return pPrior;
}
memsys5Enter();
p = memsys5MallocUnsafe(nBytes);
if( p ){
memcpy(p, pPrior, nOld);
memsys5FreeUnsafe(pPrior);
}
memsys5Leave();
return p;
}
/*
** Round up a request size to the next valid allocation size. If
** the allocation is too large to be handled by this allocation system,
** return 0.
**
** All allocations must be a power of two and must be expressed by a
** 32-bit signed integer. Hence the largest allocation is 0x40000000
** or 1073741824 bytes.
*/
static int memsys5Roundup(int n){
int iFullSz;
if( n > 0x40000000 ) return 0;
for(iFullSz=mem5.szAtom; iFullSz<n; iFullSz *= 2);
return iFullSz;
}
/*
** Return the ceiling of the logarithm base 2 of iValue.
**
** Examples: memsys5Log(1) -> 0
** memsys5Log(2) -> 1
** memsys5Log(4) -> 2
** memsys5Log(5) -> 3
** memsys5Log(8) -> 3
** memsys5Log(9) -> 4
*/
static int memsys5Log(int iValue){
int iLog;
for(iLog=0; (iLog<(int)((sizeof(int)*8)-1)) && (1<<iLog)<iValue; iLog++);
return iLog;
}
/*
** Initialize the memory allocator.
**
** This routine is not threadsafe. The caller must be holding a mutex
** to prevent multiple threads from entering at the same time.
*/
static int memsys5Init(void *NotUsed){
int ii; /* Loop counter */
int nByte; /* Number of bytes of memory available to this allocator */
u8 *zByte; /* Memory usable by this allocator */
int nMinLog; /* Log base 2 of minimum allocation size in bytes */
int iOffset; /* An offset into mem5.aCtrl[] */
UNUSED_PARAMETER(NotUsed);
/* For the purposes of this routine, disable the mutex */
mem5.mutex = 0;
/* The size of a Mem5Link object must be a power of two. Verify that
** this is case.
*/
assert( (sizeof(Mem5Link)&(sizeof(Mem5Link)-1))==0 );
nByte = sqlite4DefaultEnv.nHeap;
zByte = (u8*)sqlite4DefaultEnv.pHeap;
assert( zByte!=0 ); /* sqlite4_config() does not allow otherwise */
/* boundaries on sqlite4DefaultEnv.mnReq are enforced in sqlite4_config() */
nMinLog = memsys5Log(sqlite4DefaultEnv.mnReq);
mem5.szAtom = (1<<nMinLog);
while( (int)sizeof(Mem5Link)>mem5.szAtom ){
mem5.szAtom = mem5.szAtom << 1;
}
mem5.nBlock = (nByte / (mem5.szAtom+sizeof(u8)));
mem5.zPool = zByte;
mem5.aCtrl = (u8 *)&mem5.zPool[mem5.nBlock*mem5.szAtom];
for(ii=0; ii<=LOGMAX; ii++){
mem5.aiFreelist[ii] = -1;
}
iOffset = 0;
for(ii=LOGMAX; ii>=0; ii--){
int nAlloc = (1<<ii);
if( (iOffset+nAlloc)<=mem5.nBlock ){
mem5.aCtrl[iOffset] = ii | CTRL_FREE;
memsys5Link(iOffset, ii);
iOffset += nAlloc;
}
assert((iOffset+nAlloc)>mem5.nBlock);
}
/* If a mutex is required for normal operation, allocate one */
if( sqlite4DefaultEnv.bMemstat==0 ){
mem5.mutex = sqlite4MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
}
return SQLITE_OK;
}
/*
** Deinitialize this module.
*/
static void memsys5Shutdown(void *NotUsed){
UNUSED_PARAMETER(NotUsed);
mem5.mutex = 0;
return;
}
#ifdef SQLITE_TEST
/*
** Open the file indicated and write a log of all unfreed memory
** allocations into that log.
*/
SQLITE_PRIVATE void sqlite4Memsys5Dump(const char *zFilename){
FILE *out;
int i, j, n;
int nMinLog;
if( zFilename==0 || zFilename[0]==0 ){
out = stdout;
}else{
out = fopen(zFilename, "w");
if( out==0 ){
fprintf(stderr, "** Unable to output memory debug output log: %s **\n",
zFilename);
return;
}
}
memsys5Enter();
nMinLog = memsys5Log(mem5.szAtom);
for(i=0; i<=LOGMAX && i+nMinLog<32; i++){
for(n=0, j=mem5.aiFreelist[i]; j>=0; j = MEM5LINK(j)->next, n++){}
fprintf(out, "freelist items of size %d: %d\n", mem5.szAtom << i, n);
}
fprintf(out, "mem5.nAlloc = %llu\n", mem5.nAlloc);
fprintf(out, "mem5.totalAlloc = %llu\n", mem5.totalAlloc);
fprintf(out, "mem5.totalExcess = %llu\n", mem5.totalExcess);
fprintf(out, "mem5.currentOut = %u\n", mem5.currentOut);
fprintf(out, "mem5.currentCount = %u\n", mem5.currentCount);
fprintf(out, "mem5.maxOut = %u\n", mem5.maxOut);
fprintf(out, "mem5.maxCount = %u\n", mem5.maxCount);
fprintf(out, "mem5.maxRequest = %u\n", mem5.maxRequest);
memsys5Leave();
if( out==stdout ){
fflush(stdout);
}else{
fclose(out);
}
}
#endif
/*
** This routine is the only routine in this file with external
** linkage. It returns a pointer to a static sqlite4_mem_methods
** struct populated with the memsys5 methods.
*/
SQLITE_PRIVATE const sqlite4_mem_methods *sqlite4MemGetMemsys5(void){
static const sqlite4_mem_methods memsys5Methods = {
memsys5Malloc,
memsys5Free,
memsys5Realloc,
memsys5Size,
memsys5Roundup,
memsys5Init,
memsys5Shutdown,
0
};
return &memsys5Methods;
}
#endif /* SQLITE_ENABLE_MEMSYS5 */
/************** End of mem5.c ************************************************/
/************** Begin file mutex.c *******************************************/
/*
** 2007 August 14
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the C functions that implement mutexes.
**
** This file contains code that is common across all mutex implementations.
*/
#ifndef SQLITE_MUTEX_OMIT
/*
** Initialize the mutex system.
*/
SQLITE_PRIVATE int sqlite4MutexInit(sqlite4_env *pEnv){
int rc = SQLITE_OK;
if( !pEnv->mutex.xMutexAlloc ){
if( pEnv->bCoreMutex ){
pEnv->mutex = *sqlite4DefaultMutex();
}else{
pEnv->mutex = *sqlite4NoopMutex();
}
pEnv->mutex.pMutexEnv = pEnv;
}
rc = pEnv->mutex.xMutexInit(pEnv->mutex.pMutexEnv);
return rc;
}
/*
** Shutdown the mutex system. This call frees resources allocated by
** sqlite4MutexInit().
*/
SQLITE_PRIVATE int sqlite4MutexEnd(sqlite4_env *pEnv){
int rc = SQLITE_OK;
if( pEnv->mutex.xMutexEnd ){
rc = pEnv->mutex.xMutexEnd(pEnv->mutex.pMutexEnv);
}
return rc;
}
/*
** Retrieve a pointer to a static mutex or allocate a new dynamic one.
*/
SQLITE_API sqlite4_mutex *sqlite4_mutex_alloc(sqlite4_env *pEnv, int id){
if( pEnv==0 ) pEnv = &sqlite4DefaultEnv;
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite4_initialize(pEnv) ) return 0;
#endif
return pEnv->mutex.xMutexAlloc(pEnv->mutex.pMutexEnv, id);
}
SQLITE_PRIVATE sqlite4_mutex *sqlite4MutexAlloc(sqlite4_env *pEnv, int id){
if( !pEnv->bCoreMutex ){
return 0;
}
return pEnv->mutex.xMutexAlloc(pEnv->mutex.pMutexEnv, id);
}
/*
** Free a dynamic mutex.
*/
SQLITE_API void sqlite4_mutex_free(sqlite4_mutex *p){
if( p ){
p->pMutexMethods->xMutexFree(p);
}
}
/*
** Obtain the mutex p. If some other thread already has the mutex, block
** until it can be obtained.
*/
SQLITE_API void sqlite4_mutex_enter(sqlite4_mutex *p){
if( p ){
p->pMutexMethods->xMutexEnter(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 sqlite4_mutex_try(sqlite4_mutex *p){
int rc = SQLITE_OK;
if( p ){
return p->pMutexMethods->xMutexTry(p);
}
return rc;
}
/*
** The sqlite4_mutex_leave() routine exits a mutex that was previously
** entered by the same thread. The behavior is undefined if the mutex
** is not currently entered. If a NULL pointer is passed as an argument
** this function is a no-op.
*/
SQLITE_API void sqlite4_mutex_leave(sqlite4_mutex *p){
if( p ){
p->pMutexMethods->xMutexLeave(p);
}
}
#ifndef NDEBUG
/*
** The sqlite4_mutex_held() and sqlite4_mutex_notheld() routine are
** intended for use inside assert() statements.
*/
SQLITE_API int sqlite4_mutex_held(sqlite4_mutex *p){
return p==0 || p->pMutexMethods->xMutexHeld(p);
}
SQLITE_API int sqlite4_mutex_notheld(sqlite4_mutex *p){
return p==0 || p->pMutexMethods->xMutexNotheld(p);
}
#endif
#endif /* !defined(SQLITE_MUTEX_OMIT) */
/************** End of mutex.c ***********************************************/
/************** Begin file mutex_noop.c **************************************/
/*
** 2008 October 07
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the C functions that implement mutexes.
**
** This implementation in this file does not provide any mutual
** exclusion and is thus suitable for use only in applications
** that use SQLite in a single thread. The routines defined
** here are place-holders. Applications can substitute working
** mutex routines at start-time using the
**
** sqlite4_config(pEnv, SQLITE_CONFIG_MUTEX,...)
**
** interface.
**
** If compiled with SQLITE_DEBUG, then additional logic is inserted
** that does error checking on mutexes to make sure they are being
** called correctly.
*/
#ifndef SQLITE_MUTEX_OMIT
#ifndef SQLITE_DEBUG
/*
** Stub routines for all mutex methods.
**
** This routines provide no mutual exclusion or error checking.
*/
static int noopMutexInit(void *p){ UNUSED_PARAMETER(p); return SQLITE_OK; }
static int noopMutexEnd(void *p){ UNUSED_PARAMETER(p); return SQLITE_OK; }
static sqlite4_mutex *noopMutexAlloc(sqlite4_env *pEnv, int id){
UNUSED_PARAMETER(pEnv);
UNUSED_PARAMETER(id);
return (sqlite4_mutex*)8;
}
static void noopMutexFree(sqlite4_mutex *p){ UNUSED_PARAMETER(p); return; }
static void noopMutexEnter(sqlite4_mutex *p){ UNUSED_PARAMETER(p); return; }
static int noopMutexTry(sqlite4_mutex *p){
UNUSED_PARAMETER(p);
return SQLITE_OK;
}
static void noopMutexLeave(sqlite4_mutex *p){ UNUSED_PARAMETER(p); return; }
SQLITE_PRIVATE sqlite4_mutex_methods const *sqlite4NoopMutex(void){
static const sqlite4_mutex_methods sMutex = {
noopMutexInit,
noopMutexEnd,
noopMutexAlloc,
noopMutexFree,
noopMutexEnter,
noopMutexTry,
noopMutexLeave,
0,
0,
0
};
return &sMutex;
}
#endif /* !SQLITE_DEBUG */
#ifdef SQLITE_DEBUG
/*
** In this implementation, error checking is provided for testing
** and debugging purposes. The mutexes still do not provide any
** mutual exclusion.
*/
/*
** The mutex object
*/
typedef struct sqlite4DebugMutex {
sqlite4_mutex base; /* Base class. Must be first */
sqlite4_env *pEnv; /* Run-time environment */
int id; /* Type of mutex */
int cnt; /* Number of entries without a matching leave */
} sqlite4DebugMutex;
/*
** The sqlite4_mutex_held() and sqlite4_mutex_notheld() routine are
** intended for use inside assert() statements.
*/
static int debugMutexHeld(sqlite4_mutex *pX){
sqlite4DebugMutex *p = (sqlite4DebugMutex*)pX;
return p==0 || p->cnt>0;
}
static int debugMutexNotheld(sqlite4_mutex *pX){
sqlite4DebugMutex *p = (sqlite4DebugMutex*)pX;
return p==0 || p->cnt==0;
}
/*
** Initialize and deinitialize the mutex subsystem.
*/
static int debugMutexInit(void *p){ UNUSED_PARAMETER(p); return SQLITE_OK; }
static int debugMutexEnd(void *p){ UNUSED_PARAMETER(p); return SQLITE_OK; }
/*
** The sqlite4_mutex_alloc() routine allocates a new
** mutex and returns a pointer to it. If it returns NULL
** that means that a mutex could not be allocated.
*/
static sqlite4_mutex *debugMutexAlloc(sqlite4_env *pEnv, int id){
sqlite4DebugMutex *pNew = 0;
pNew = sqlite4Malloc(pEnv, sizeof(*pNew));
if( pNew ){
pNew->id = id;
pNew->cnt = 0;
pNew->pEnv = pEnv;
}
return (sqlite4_mutex*)pNew;
}
/*
** This routine deallocates a previously allocated mutex.
*/
static void debugMutexFree(sqlite4_mutex *pX){
sqlite4DebugMutex *p = (sqlite4DebugMutex*)pX;
assert( p->cnt==0 );
sqlite4_free(p->pEnv, p);
}
/*
** The sqlite4_mutex_enter() and sqlite4_mutex_try() routines attempt
** to enter a mutex. If another thread is already within the mutex,
** sqlite4_mutex_enter() will block and sqlite4_mutex_try() will return
** SQLITE_BUSY. The sqlite4_mutex_try() interface returns SQLITE_OK
** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
** be entered multiple times by the same thread. In such cases the,
** mutex must be exited an equal number of times before another thread
** can enter. If the same thread tries to enter any other kind of mutex
** more than once, the behavior is undefined.
*/
static void debugMutexEnter(sqlite4_mutex *pX){
sqlite4DebugMutex *p = (sqlite4DebugMutex*)pX;
assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
p->cnt++;
}
static int debugMutexTry(sqlite4_mutex *pX){
sqlite4DebugMutex *p = (sqlite4DebugMutex*)pX;
assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
p->cnt++;
return SQLITE_OK;
}
/*
** The sqlite4_mutex_leave() routine exits a mutex that was
** previously entered by the same thread. The behavior
** is undefined if the mutex is not currently entered or
** is not currently allocated. SQLite will never do either.
*/
static void debugMutexLeave(sqlite4_mutex *pX){
sqlite4DebugMutex *p = (sqlite4DebugMutex*)pX;
assert( debugMutexHeld(pX) );
p->cnt--;
assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
}
SQLITE_PRIVATE sqlite4_mutex_methods const *sqlite4NoopMutex(void){
static const sqlite4_mutex_methods sMutex = {
debugMutexInit,
debugMutexEnd,
debugMutexAlloc,
debugMutexFree,
debugMutexEnter,
debugMutexTry,
debugMutexLeave,
debugMutexHeld,
debugMutexNotheld,
0
};
return &sMutex;
}
#endif /* SQLITE_DEBUG */
/*
** If compiled with SQLITE_MUTEX_NOOP, then the no-op mutex implementation
** is used regardless of the run-time threadsafety setting.
*/
#ifdef SQLITE_MUTEX_NOOP
SQLITE_PRIVATE sqlite4_mutex_methods const *sqlite4DefaultMutex(void){
return sqlite4NoopMutex();
}
#endif /* defined(SQLITE_MUTEX_NOOP) */
#endif /* !defined(SQLITE_MUTEX_OMIT) */
/************** End of mutex_noop.c ******************************************/
/************** Begin file mutex_unix.c **************************************/
/*
** 2007 August 28
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the C functions that implement mutexes for pthreads
*/
/*
** The code in this file is only used if we are compiling threadsafe
** under unix with pthreads.
**
** Note that this implementation requires a version of pthreads that
** supports recursive mutexes.
*/
#ifdef SQLITE_MUTEX_PTHREADS
#include <pthread.h>
/*
** The sqlite4_mutex.id, sqlite4_mutex.nRef, and sqlite4_mutex.owner fields
** are necessary under two condidtions: (1) Debug builds and (2) using
** home-grown mutexes. Encapsulate these conditions into a single #define.
*/
#if defined(SQLITE_DEBUG) || defined(SQLITE_HOMEGROWN_RECURSIVE_MUTEX)
# define SQLITE_MUTEX_NREF 1
#else
# define SQLITE_MUTEX_NREF 0
#endif
/*
** Each recursive mutex is an instance of the following structure.
*/
typedef struct sqlite4UnixMutex {
sqlite4_mutex base; /* Base class. Must be first */
pthread_mutex_t mutex; /* Mutex controlling the lock */
#if SQLITE_MUTEX_NREF
int id; /* Mutex type */
volatile int nRef; /* Number of entrances */
volatile pthread_t owner; /* Thread that is within this mutex */
int trace; /* True to trace changes */
#endif
} sqlite4UnixMutex;
#if SQLITE_MUTEX_NREF
#define SQLITE3_MUTEX_INITIALIZER \
{ 0, PTHREAD_MUTEX_INITIALIZER, 0, 0, (pthread_t)0, 0 }
#else
#define SQLITE3_MUTEX_INITIALIZER { 0, PTHREAD_MUTEX_INITIALIZER }
#endif
/*
** The sqlite4_mutex_held() and sqlite4_mutex_notheld() routine are
** intended for use only inside assert() statements. On some platforms,
** there might be race conditions that can cause these routines to
** deliver incorrect results. In particular, if pthread_equal() is
** not an atomic operation, then these routines might delivery
** incorrect results. On most platforms, pthread_equal() is a
** comparison of two integers and is therefore atomic. But we are
** told that HPUX is not such a platform. If so, then these routines
** will not always work correctly on HPUX.
**
** On those platforms where pthread_equal() is not atomic, SQLite
** should be compiled without -DSQLITE_DEBUG and with -DNDEBUG to
** make sure no assert() statements are evaluated and hence these
** routines are never called.
*/
#if !defined(NDEBUG) || defined(SQLITE_DEBUG)
static int pthreadMutexHeld(sqlite4_mutex *pMutex){
sqlite4UnixMutex *p = (sqlite4UnixMutex*)pMutex;
return (p->nRef!=0 && pthread_equal(p->owner, pthread_self()));
}
static int pthreadMutexNotheld(sqlite4_mutex *pMutex){
sqlite4UnixMutex *p = (sqlite4UnixMutex*)pMutex;
return p->nRef==0 || pthread_equal(p->owner, pthread_self())==0;
}
#endif
/*
** Initialize and deinitialize the mutex subsystem.
*/
static int pthreadMutexInit(void *p){ UNUSED_PARAMETER(p); return SQLITE_OK; }
static int pthreadMutexEnd(void *p){ UNUSED_PARAMETER(p); return SQLITE_OK; }
/*
** The sqlite4_mutex_alloc() routine allocates a new
** mutex and returns a pointer to it. If it returns NULL
** that means that a mutex could not be allocated. SQLite
** will unwind its stack and return an error. The argument
** to sqlite4_mutex_alloc() is one of these integer constants:
**
** <ul>
** <li> SQLITE_MUTEX_FAST
** <li> SQLITE_MUTEX_RECURSIVE
** <li> SQLITE_MUTEX_STATIC_MASTER
** <li> SQLITE_MUTEX_STATIC_MEM
** <li> SQLITE_MUTEX_STATIC_MEM2
** <li> SQLITE_MUTEX_STATIC_PRNG
** <li> SQLITE_MUTEX_STATIC_LRU
** <li> SQLITE_MUTEX_STATIC_PMEM
** </ul>
**
** The first two constants cause sqlite4_mutex_alloc() to create
** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
** The mutex implementation does not need to make a distinction
** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
** not want to. But SQLite will only request a recursive mutex in
** cases where it really needs one. If a faster non-recursive mutex
** implementation is available on the host platform, the mutex subsystem
** might return such a mutex in response to SQLITE_MUTEX_FAST.
**
** The other allowed parameters to sqlite4_mutex_alloc() each return
** a pointer to a static preexisting mutex. Six static mutexes are
** used by the current version of SQLite. Future versions of SQLite
** may add additional static mutexes. Static mutexes are for internal
** use by SQLite only. Applications that use SQLite mutexes should
** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
** SQLITE_MUTEX_RECURSIVE.
**
** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
** or SQLITE_MUTEX_RECURSIVE) is used then sqlite4_mutex_alloc()
** returns a different mutex on every call. But for the static
** mutex types, the same mutex is returned on every call that has
** the same type number.
*/
static sqlite4_mutex *pthreadMutexAlloc(void *pMutexEnv, int iType){
sqlite4_env *pEnv = (sqlite4_env*)pMutexEnv;
sqlite4UnixMutex *p;
switch( iType ){
case SQLITE_MUTEX_RECURSIVE: {
p = sqlite4MallocZero(pEnv, sizeof(*p) );
if( p ){
#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
/* If recursive mutexes are not available, we will have to
** build our own. See below. */
pthread_mutex_init(&p->mutex, 0);
#else
/* Use a recursive mutex if it is available */
pthread_mutexattr_t recursiveAttr;
pthread_mutexattr_init(&recursiveAttr);
pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&p->mutex, &recursiveAttr);
pthread_mutexattr_destroy(&recursiveAttr);
#endif
#if SQLITE_MUTEX_NREF
p->id = iType;
#endif
p->base.pMutexMethods = &pEnv->mutex;
}
break;
}
case SQLITE_MUTEX_FAST: {
p = sqlite4MallocZero(pEnv, sizeof(*p) );
if( p ){
#if SQLITE_MUTEX_NREF
p->id = iType;
#endif
pthread_mutex_init(&p->mutex, 0);
p->base.pMutexMethods = &pEnv->mutex;
assert( p->base.pMutexMethods->pMutexEnv==(void*)pEnv );
}
break;
}
default: {
p = 0;
break;
}
}
return (sqlite4_mutex*)p;
}
/*
** This routine deallocates a previously
** allocated mutex. SQLite is careful to deallocate every
** mutex that it allocates.
*/
static void pthreadMutexFree(sqlite4_mutex *pMutex){
sqlite4UnixMutex *p = (sqlite4UnixMutex*)pMutex;
sqlite4_env *pEnv;
assert( p->nRef==0 );
assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
pthread_mutex_destroy(&p->mutex);
pEnv = (sqlite4_env*)p->base.pMutexMethods->pMutexEnv;
sqlite4_free(pEnv, p);
}
/*
** The sqlite4_mutex_enter() and sqlite4_mutex_try() routines attempt
** to enter a mutex. If another thread is already within the mutex,
** sqlite4_mutex_enter() will block and sqlite4_mutex_try() will return
** SQLITE_BUSY. The sqlite4_mutex_try() interface returns SQLITE_OK
** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
** be entered multiple times by the same thread. In such cases the,
** mutex must be exited an equal number of times before another thread
** can enter. If the same thread tries to enter any other kind of mutex
** more than once, the behavior is undefined.
*/
static void pthreadMutexEnter(sqlite4_mutex *pMutex){
sqlite4UnixMutex *p = (sqlite4UnixMutex*)pMutex;
assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(pMutex) );
#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
/* If recursive mutexes are not available, then we have to grow
** our own. This implementation assumes that pthread_equal()
** is atomic - that it cannot be deceived into thinking self
** and p->owner are equal if p->owner changes between two values
** that are not equal to self while the comparison is taking place.
** This implementation also assumes a coherent cache - that
** separate processes cannot read different values from the same
** address at the same time. If either of these two conditions
** are not met, then the mutexes will fail and problems will result.
*/
{
pthread_t self = pthread_self();
if( p->nRef>0 && pthread_equal(p->owner, self) ){
p->nRef++;
}else{
pthread_mutex_lock(&p->mutex);
assert( p->nRef==0 );
p->owner = self;
p->nRef = 1;
}
}
#else
/* Use the built-in recursive mutexes if they are available.
*/
pthread_mutex_lock(&p->mutex);
#if SQLITE_MUTEX_NREF
assert( p->nRef>0 || p->owner==0 );
p->owner = pthread_self();
p->nRef++;
#endif
#endif
#ifdef SQLITE_DEBUG
if( p->trace ){
printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
}
#endif
}
static int pthreadMutexTry(sqlite4_mutex *pMutex){
int rc;
sqlite4UnixMutex *p = (sqlite4UnixMutex*)pMutex;
assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(pMutex) );
#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
/* If recursive mutexes are not available, then we have to grow
** our own. This implementation assumes that pthread_equal()
** is atomic - that it cannot be deceived into thinking self
** and p->owner are equal if p->owner changes between two values
** that are not equal to self while the comparison is taking place.
** This implementation also assumes a coherent cache - that
** separate processes cannot read different values from the same
** address at the same time. If either of these two conditions
** are not met, then the mutexes will fail and problems will result.
*/
{
pthread_t self = pthread_self();
if( p->nRef>0 && pthread_equal(p->owner, self) ){
p->nRef++;
rc = SQLITE_OK;
}else if( pthread_mutex_trylock(&p->mutex)==0 ){
assert( p->nRef==0 );
p->owner = self;
p->nRef = 1;
rc = SQLITE_OK;
}else{
rc = SQLITE_BUSY;
}
}
#else
/* Use the built-in recursive mutexes if they are available.
*/
if( pthread_mutex_trylock(&p->mutex)==0 ){
#if SQLITE_MUTEX_NREF
p->owner = pthread_self();
p->nRef++;
#endif
rc = SQLITE_OK;
}else{
rc = SQLITE_BUSY;
}
#endif
#ifdef SQLITE_DEBUG
if( rc==SQLITE_OK && p->trace ){
printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
}
#endif
return rc;
}
/*
** The sqlite4_mutex_leave() routine exits a mutex that was
** previously entered by the same thread. The behavior
** is undefined if the mutex is not currently entered or
** is not currently allocated. SQLite will never do either.
*/
static void pthreadMutexLeave(sqlite4_mutex *pMutex){
sqlite4UnixMutex *p = (sqlite4UnixMutex*)pMutex;
assert( pthreadMutexHeld(pMutex) );
#if SQLITE_MUTEX_NREF
p->nRef--;
if( p->nRef==0 ) p->owner = 0;
#endif
assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
if( p->nRef==0 ){
pthread_mutex_unlock(&p->mutex);
}
#else
pthread_mutex_unlock(&p->mutex);
#endif
#ifdef SQLITE_DEBUG
if( p->trace ){
printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
}
#endif
}
SQLITE_PRIVATE sqlite4_mutex_methods const *sqlite4DefaultMutex(void){
static const sqlite4_mutex_methods sMutex = {
pthreadMutexInit,
pthreadMutexEnd,
pthreadMutexAlloc,
pthreadMutexFree,
pthreadMutexEnter,
pthreadMutexTry,
pthreadMutexLeave,
#ifdef SQLITE_DEBUG
pthreadMutexHeld,
pthreadMutexNotheld,
#else
0,
0,
#endif
0
};
return &sMutex;
}
#endif /* SQLITE_MUTEX_PTHREADS */
/************** End of mutex_unix.c ******************************************/
/************** Begin file mutex_w32.c ***************************************/
/*
** 2007 August 14
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the C functions that implement mutexes for win32
*/
/*
** The code in this file is only used if we are compiling multithreaded
** on a win32 system.
*/
#ifdef SQLITE_MUTEX_W32
/*
** Each recursive mutex is an instance of the following structure.
*/
struct sqlite4_mutex {
CRITICAL_SECTION mutex; /* Mutex controlling the lock */
int id; /* Mutex type */
#ifdef SQLITE_DEBUG
volatile int nRef; /* Number of enterances */
volatile DWORD owner; /* Thread holding this mutex */
int trace; /* True to trace changes */
#endif
};
#define SQLITE_W32_MUTEX_INITIALIZER { 0 }
#ifdef SQLITE_DEBUG
#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, 0L, (DWORD)0, 0 }
#else
#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 }
#endif
/*
** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
** or WinCE. Return false (zero) for Win95, Win98, or WinME.
**
** Here is an interesting observation: Win95, Win98, and WinME lack
** the LockFileEx() API. But we can still statically link against that
** API as long as we don't call it win running Win95/98/ME. A call to
** this routine is used to determine if the host is Win95/98/ME or
** WinNT/2K/XP so that we will know whether or not we can safely call
** the LockFileEx() API.
**
** mutexIsNT() is only used for the TryEnterCriticalSection() API call,
** which is only available if your application was compiled with
** _WIN32_WINNT defined to a value >= 0x0400. Currently, the only
** call to TryEnterCriticalSection() is #ifdef'ed out, so #ifdef
** this out as well.
*/
#if 0
#if SQLITE_OS_WINCE
# define mutexIsNT() (1)
#else
static int mutexIsNT(void){
static int osType = 0;
if( osType==0 ){
OSVERSIONINFO sInfo;
sInfo.dwOSVersionInfoSize = sizeof(sInfo);
GetVersionEx(&sInfo);
osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
}
return osType==2;
}
#endif /* SQLITE_OS_WINCE */
#endif
#ifdef SQLITE_DEBUG
/*
** The sqlite4_mutex_held() and sqlite4_mutex_notheld() routine are
** intended for use only inside assert() statements.
*/
static int winMutexHeld(sqlite4_mutex *p){
return p->nRef!=0 && p->owner==GetCurrentThreadId();
}
static int winMutexNotheld2(sqlite4_mutex *p, DWORD tid){
return p->nRef==0 || p->owner!=tid;
}
static int winMutexNotheld(sqlite4_mutex *p){
DWORD tid = GetCurrentThreadId();
return winMutexNotheld2(p, tid);
}
#endif
/*
** Initialize and deinitialize the mutex subsystem.
*/
static sqlite4_mutex winMutex_staticMutexes[6] = {
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER
};
static int winMutex_isInit = 0;
/* As winMutexInit() and winMutexEnd() are called as part
** of the sqlite4_initialize and sqlite4_shutdown()
** processing, the "interlocked" magic is probably not
** strictly necessary.
*/
static long winMutex_lock = 0;
static int winMutexInit(void){
/* The first to increment to 1 does actual initialization */
if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){
int i;
for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
InitializeCriticalSection(&winMutex_staticMutexes[i].mutex);
}
winMutex_isInit = 1;
}else{
/* Someone else is in the process of initing the static mutexes */
while( !winMutex_isInit ){
Sleep(1);
}
}
return SQLITE_OK;
}
static int winMutexEnd(void){
/* The first to decrement to 0 does actual shutdown
** (which should be the last to shutdown.) */
if( InterlockedCompareExchange(&winMutex_lock, 0, 1)==1 ){
if( winMutex_isInit==1 ){
int i;
for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
DeleteCriticalSection(&winMutex_staticMutexes[i].mutex);
}
winMutex_isInit = 0;
}
}
return SQLITE_OK;
}
/*
** The sqlite4_mutex_alloc() routine allocates a new
** mutex and returns a pointer to it. If it returns NULL
** that means that a mutex could not be allocated. SQLite
** will unwind its stack and return an error. The argument
** to sqlite4_mutex_alloc() is one of these integer constants:
**
** <ul>
** <li> SQLITE_MUTEX_FAST
** <li> SQLITE_MUTEX_RECURSIVE
** <li> SQLITE_MUTEX_STATIC_MASTER
** <li> SQLITE_MUTEX_STATIC_MEM
** <li> SQLITE_MUTEX_STATIC_MEM2
** <li> SQLITE_MUTEX_STATIC_PRNG
** <li> SQLITE_MUTEX_STATIC_LRU
** <li> SQLITE_MUTEX_STATIC_PMEM
** </ul>
**
** The first two constants cause sqlite4_mutex_alloc() to create
** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
** The mutex implementation does not need to make a distinction
** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
** not want to. But SQLite will only request a recursive mutex in
** cases where it really needs one. If a faster non-recursive mutex
** implementation is available on the host platform, the mutex subsystem
** might return such a mutex in response to SQLITE_MUTEX_FAST.
**
** The other allowed parameters to sqlite4_mutex_alloc() each return
** a pointer to a static preexisting mutex. Six static mutexes are
** used by the current version of SQLite. Future versions of SQLite
** may add additional static mutexes. Static mutexes are for internal
** use by SQLite only. Applications that use SQLite mutexes should
** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
** SQLITE_MUTEX_RECURSIVE.
**
** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
** or SQLITE_MUTEX_RECURSIVE) is used then sqlite4_mutex_alloc()
** returns a different mutex on every call. But for the static
** mutex types, the same mutex is returned on every call that has
** the same type number.
*/
static sqlite4_mutex *winMutexAlloc(int iType){
sqlite4_mutex *p;
switch( iType ){
case SQLITE_MUTEX_FAST:
case SQLITE_MUTEX_RECURSIVE: {
p = sqlite4MallocZero(0, sizeof(*p) );
if( p ){
#ifdef SQLITE_DEBUG
p->id = iType;
#endif
InitializeCriticalSection(&p->mutex);
}
break;
}
default: {
assert( winMutex_isInit==1 );
assert( iType-2 >= 0 );
assert( iType-2 < ArraySize(winMutex_staticMutexes) );
p = &winMutex_staticMutexes[iType-2];
#ifdef SQLITE_DEBUG
p->id = iType;
#endif
break;
}
}
return p;
}
/*
** This routine deallocates a previously
** allocated mutex. SQLite is careful to deallocate every
** mutex that it allocates.
*/
static void winMutexFree(sqlite4_mutex *p){
assert( p );
assert( p->nRef==0 && p->owner==0 );
assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
DeleteCriticalSection(&p->mutex);
sqlite4_free(0, p);
}
/*
** The sqlite4_mutex_enter() and sqlite4_mutex_try() routines attempt
** to enter a mutex. If another thread is already within the mutex,
** sqlite4_mutex_enter() will block and sqlite4_mutex_try() will return
** SQLITE_BUSY. The sqlite4_mutex_try() interface returns SQLITE_OK
** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
** be entered multiple times by the same thread. In such cases the,
** mutex must be exited an equal number of times before another thread
** can enter. If the same thread tries to enter any other kind of mutex
** more than once, the behavior is undefined.
*/
static void winMutexEnter(sqlite4_mutex *p){
#ifdef SQLITE_DEBUG
DWORD tid = GetCurrentThreadId();
assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) );
#endif
EnterCriticalSection(&p->mutex);
#ifdef SQLITE_DEBUG
assert( p->nRef>0 || p->owner==0 );
p->owner = tid;
p->nRef++;
if( p->trace ){
printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
}
#endif
}
static int winMutexTry(sqlite4_mutex *p){
#ifndef NDEBUG
DWORD tid = GetCurrentThreadId();
#endif
int rc = SQLITE_BUSY;
assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) );
/*
** The sqlite4_mutex_try() routine is very rarely used, and when it
** is used it is merely an optimization. So it is OK for it to always
** fail.
**
** The TryEnterCriticalSection() interface is only available on WinNT.
** And some windows compilers complain if you try to use it without
** first doing some #defines that prevent SQLite from building on Win98.
** For that reason, we will omit this optimization for now. See
** ticket #2685.
*/
#if 0
if( mutexIsNT() && TryEnterCriticalSection(&p->mutex) ){
p->owner = tid;
p->nRef++;
rc = SQLITE_OK;
}
#else
UNUSED_PARAMETER(p);
#endif
#ifdef SQLITE_DEBUG
if( rc==SQLITE_OK && p->trace ){
printf("try mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
}
#endif
return rc;
}
/*
** The sqlite4_mutex_leave() routine exits a mutex that was
** previously entered by the same thread. The behavior
** is undefined if the mutex is not currently entered or
** is not currently allocated. SQLite will never do either.
*/
static void winMutexLeave(sqlite4_mutex *p){
#ifndef NDEBUG
DWORD tid = GetCurrentThreadId();
assert( p->nRef>0 );
assert( p->owner==tid );
p->nRef--;
if( p->nRef==0 ) p->owner = 0;
assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
#endif
LeaveCriticalSection(&p->mutex);
#ifdef SQLITE_DEBUG
if( p->trace ){
printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
}
#endif
}
SQLITE_PRIVATE sqlite4_mutex_methods const *sqlite4DefaultMutex(void){
static const sqlite4_mutex_methods sMutex = {
winMutexInit,
winMutexEnd,
winMutexAlloc,
winMutexFree,
winMutexEnter,
winMutexTry,
winMutexLeave,
#ifdef SQLITE_DEBUG
winMutexHeld,
winMutexNotheld
#else
0,
0
#endif
};
return &sMutex;
}
#endif /* SQLITE_MUTEX_W32 */
/************** End of mutex_w32.c *******************************************/
/************** Begin file malloc.c ******************************************/
/*
** 2001 September 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.
**
*************************************************************************
**
** Memory allocation functions used throughout sqlite.
*/
/* #include <stdarg.h> */
/*
** Initialize the memory allocation subsystem.
*/
SQLITE_PRIVATE int sqlite4MallocInit(sqlite4_env *pEnv){
if( pEnv->m.xMalloc==0 ){
sqlite4MemSetDefault(pEnv);
}
return pEnv->m.xInit(pEnv->m.pMemEnv);
}
/*
** Deinitialize the memory allocation subsystem.
*/
SQLITE_PRIVATE void sqlite4MallocEnd(sqlite4_env *pEnv){
if( pEnv->m.xShutdown ){
pEnv->m.xShutdown(pEnv->m.pMemEnv);
}
}
/*
** Return the amount of memory currently checked out.
*/
SQLITE_API sqlite4_uint64 sqlite4_memory_used(sqlite4_env *pEnv){
sqlite4_uint64 n, mx;
if( pEnv==0 ) pEnv = sqlite4_env_default();
sqlite4_env_status(pEnv, SQLITE_ENVSTATUS_MEMORY_USED, &n, &mx, 0);
return n;
}
/*
** Return the maximum amount of memory that has ever been
** checked out since either the beginning of this process
** or since the most recent reset.
*/
SQLITE_API sqlite4_uint64 sqlite4_memory_highwater(sqlite4_env *pEnv, int resetFlag){
sqlite4_uint64 n, mx;
if( pEnv==0 ) pEnv = sqlite4_env_default();
sqlite4_env_status(pEnv, SQLITE_ENVSTATUS_MEMORY_USED, &n, &mx, resetFlag);
return mx;
}
/*
** Allocate memory. This routine is like sqlite4_malloc() except that it
** assumes the memory subsystem has already been initialized.
*/
SQLITE_PRIVATE void *sqlite4Malloc(sqlite4_env *pEnv, int n){
void *p;
if( pEnv==0 ) pEnv = &sqlite4DefaultEnv;
if( n<=0 /* IMP: R-65312-04917 */
|| n>=0x7fffff00
){
/* A memory allocation of a number of bytes which is near the maximum
** signed integer value might cause an integer overflow inside of the
** xMalloc(). Hence we limit the maximum size to 0x7fffff00, giving
** 255 bytes of overhead. SQLite itself will never use anything near
** this amount. The only way to reach the limit is with sqlite4_malloc() */
p = 0;
}else if( pEnv->bMemstat ){
int nFull = (n + 7)&~7;
sqlite4_mutex_enter(pEnv->pMemMutex);
p = pEnv->m.xMalloc(pEnv->m.pMemEnv, nFull);
if( p ){
nFull = sqlite4MallocSize(pEnv, p);
sqlite4StatusAdd(pEnv, SQLITE_ENVSTATUS_MEMORY_USED, nFull);
sqlite4StatusAdd(pEnv, SQLITE_ENVSTATUS_MALLOC_COUNT, 1);
}
sqlite4StatusSet(pEnv, SQLITE_ENVSTATUS_MALLOC_SIZE, n);
sqlite4_mutex_leave(pEnv->pMemMutex);
}else{
p = pEnv->m.xMalloc(pEnv->m.pMemEnv, n);
}
assert( EIGHT_BYTE_ALIGNMENT(p) ); /* IMP: R-04675-44850 */
return p;
}
/*
** This version of the memory allocation is for use by the application.
** First make sure the memory subsystem is initialized, then do the
** allocation.
*/
SQLITE_API void *sqlite4_malloc(sqlite4_env *pEnv, sqlite4_size_t n){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite4_initialize(pEnv) ) return 0;
#endif
if( n>0x7fff0000 ) return 0;
return sqlite4Malloc(pEnv, (int)n);
}
/*
** TRUE if p is a lookaside memory allocation from db
*/
#ifndef SQLITE_OMIT_LOOKASIDE
static int isLookaside(sqlite4 *db, void *p){
return p && p>=db->lookaside.pStart && p<db->lookaside.pEnd;
}
#else
#define isLookaside(A,B) 0
#endif
/*
** Return the size of a memory allocation previously obtained from
** sqlite4Malloc() or sqlite4_malloc().
*/
SQLITE_PRIVATE int sqlite4MallocSize(sqlite4_env *pEnv, void *p){
assert( sqlite4MemdebugHasType(p, MEMTYPE_HEAP) );
assert( sqlite4MemdebugNoType(p, MEMTYPE_DB) );
if( pEnv==0 ) pEnv = &sqlite4DefaultEnv;
return pEnv->m.xSize(pEnv->m.pMemEnv, p);
}
SQLITE_PRIVATE int sqlite4DbMallocSize(sqlite4 *db, void *p){
assert( db==0 || sqlite4_mutex_held(db->mutex) );
if( db && isLookaside(db, p) ){
return db->lookaside.sz;
}else{
sqlite4_env *pEnv = db->pEnv;
assert( sqlite4MemdebugHasType(p, MEMTYPE_DB) );
assert( sqlite4MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
assert( db!=0 || sqlite4MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
return pEnv->m.xSize(pEnv->m.pMemEnv, p);
}
}
/*
** Free memory previously obtained from sqlite4Malloc().
*/
SQLITE_API void sqlite4_free(sqlite4_env *pEnv, void *p){
if( p==0 ) return; /* IMP: R-49053-54554 */
assert( sqlite4MemdebugNoType(p, MEMTYPE_DB) );
assert( sqlite4MemdebugHasType(p, MEMTYPE_HEAP) );
if( pEnv==0 ) pEnv = &sqlite4DefaultEnv;
if( pEnv->bMemstat ){
sqlite4_mutex_enter(pEnv->pMemMutex);
sqlite4StatusAdd(pEnv,SQLITE_ENVSTATUS_MEMORY_USED,
-sqlite4MallocSize(pEnv, p));
sqlite4StatusAdd(pEnv,SQLITE_ENVSTATUS_MALLOC_COUNT, -1);
pEnv->m.xFree(pEnv->m.pMemEnv, p);
sqlite4_mutex_leave(pEnv->pMemMutex);
}else{
pEnv->m.xFree(pEnv->m.pMemEnv, p);
}
}
/*
** Free memory that might be associated with a particular database
** connection.
*/
SQLITE_PRIVATE void sqlite4DbFree(sqlite4 *db, void *p){
assert( db==0 || sqlite4_mutex_held(db->mutex) );
if( db ){
if( db->pnBytesFreed ){
*db->pnBytesFreed += sqlite4DbMallocSize(db, p);
return;
}
if( isLookaside(db, p) ){
LookasideSlot *pBuf = (LookasideSlot*)p;
pBuf->pNext = db->lookaside.pFree;
db->lookaside.pFree = pBuf;
db->lookaside.nOut--;
return;
}
}
assert( sqlite4MemdebugHasType(p, MEMTYPE_DB) );
assert( sqlite4MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
assert( db!=0 || sqlite4MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
sqlite4MemdebugSetType(p, MEMTYPE_HEAP);
sqlite4_free(db==0 ? 0 : db->pEnv, p);
}
/*
** Change the size of an existing memory allocation
*/
SQLITE_PRIVATE void *sqlite4Realloc(sqlite4_env *pEnv, void *pOld, int nBytes){
int nOld, nNew;
void *pNew;
if( pEnv==0 ) pEnv = &sqlite4DefaultEnv;
if( pOld==0 ){
return sqlite4Malloc(pEnv, nBytes); /* IMP: R-28354-25769 */
}
if( nBytes<=0 ){
sqlite4_free(pEnv, pOld); /* IMP: R-31593-10574 */
return 0;
}
if( nBytes>=0x7fffff00 ){
/* The 0x7ffff00 limit term is explained in comments on sqlite4Malloc() */
return 0;
}
nOld = sqlite4MallocSize(pEnv, pOld);
nNew = (nBytes + 7)&~7;
if( pEnv->bMemstat ){
sqlite4_mutex_enter(pEnv->pMemMutex);
sqlite4StatusSet(pEnv, SQLITE_ENVSTATUS_MALLOC_SIZE, nBytes);
assert( sqlite4MemdebugHasType(pOld, MEMTYPE_HEAP) );
assert( sqlite4MemdebugNoType(pOld, ~MEMTYPE_HEAP) );
pNew = pEnv->m.xRealloc(pEnv->m.pMemEnv, pOld, nNew);
if( pNew ){
nNew = sqlite4MallocSize(pEnv, pNew);
sqlite4StatusAdd(pEnv, SQLITE_ENVSTATUS_MEMORY_USED, nNew-nOld);
}
sqlite4_mutex_leave(pEnv->pMemMutex);
}else{
pNew = pEnv->m.xRealloc(pEnv->m.pMemEnv, pOld, nNew);
}
assert( EIGHT_BYTE_ALIGNMENT(pNew) ); /* IMP: R-04675-44850 */
return pNew;
}
/*
** The public interface to sqlite4Realloc. Make sure that the memory
** subsystem is initialized prior to invoking sqliteRealloc.
*/
SQLITE_API void *sqlite4_realloc(sqlite4_env *pEnv, void *pOld, sqlite4_size_t n){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite4_initialize(pEnv) ) return 0;
#endif
if( n>0x7fff0000 ) return 0;
return sqlite4Realloc(pEnv, pOld, (int)n);
}
/*
** Allocate and zero memory.
*/
SQLITE_PRIVATE void *sqlite4MallocZero(sqlite4_env *pEnv, int n){
void *p = sqlite4Malloc(pEnv, n);
if( p ){
memset(p, 0, n);
}
return p;
}
/*
** Allocate and zero memory. If the allocation fails, make
** the mallocFailed flag in the connection pointer.
*/
SQLITE_PRIVATE void *sqlite4DbMallocZero(sqlite4 *db, int n){
void *p = sqlite4DbMallocRaw(db, n);
if( p ){
memset(p, 0, n);
}
return p;
}
/*
** Allocate and zero memory. If the allocation fails, make
** 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.
** Hence for a particular database connection, once malloc starts
** failing, it fails consistently until mallocFailed is reset.
** This is an important assumption. There are many places in the
** code that do things like this:
**
** int *a = (int*)sqlite4DbMallocRaw(db, 100);
** int *b = (int*)sqlite4DbMallocRaw(db, 200);
** if( b ) a[10] = 9;
**
** In other words, if a subsequent malloc (ex: "b") worked, it is assumed
** that all prior mallocs (ex: "a") worked too.
*/
SQLITE_PRIVATE void *sqlite4DbMallocRaw(sqlite4 *db, int n){
void *p;
assert( db==0 || sqlite4_mutex_held(db->mutex) );
assert( db==0 || db->pnBytesFreed==0 );
#ifndef SQLITE_OMIT_LOOKASIDE
if( db ){
LookasideSlot *pBuf;
if( db->mallocFailed ){
return 0;
}
if( db->lookaside.bEnabled ){
if( n>db->lookaside.sz ){
db->lookaside.anStat[1]++;
}else if( (pBuf = db->lookaside.pFree)==0 ){
db->lookaside.anStat[2]++;
}else{
db->lookaside.pFree = pBuf->pNext;
db->lookaside.nOut++;
db->lookaside.anStat[0]++;
if( db->lookaside.nOut>db->lookaside.mxOut ){
db->lookaside.mxOut = db->lookaside.nOut;
}
return (void*)pBuf;
}
}
}
#else
if( db && db->mallocFailed ){
return 0;
}
#endif
p = sqlite4Malloc((db ? db->pEnv: 0), n);
if( !p && db ){
db->mallocFailed = 1;
}
sqlite4MemdebugSetType(p, MEMTYPE_DB |
((db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
return p;
}
/*
** 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 *sqlite4DbRealloc(sqlite4 *db, void *p, int n){
void *pNew = 0;
assert( db!=0 );
assert( sqlite4_mutex_held(db->mutex) );
if( db->mallocFailed==0 ){
if( p==0 ){
return sqlite4DbMallocRaw(db, n);
}
if( isLookaside(db, p) ){
if( n<=db->lookaside.sz ){
return p;
}
pNew = sqlite4DbMallocRaw(db, n);
if( pNew ){
memcpy(pNew, p, db->lookaside.sz);
sqlite4DbFree(db, p);
}
}else{
assert( sqlite4MemdebugHasType(p, MEMTYPE_DB) );
assert( sqlite4MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
sqlite4MemdebugSetType(p, MEMTYPE_HEAP);
pNew = sqlite4_realloc(db->pEnv, p, n);
if( !pNew ){
sqlite4MemdebugSetType(p, MEMTYPE_DB|MEMTYPE_HEAP);
db->mallocFailed = 1;
}
sqlite4MemdebugSetType(pNew, MEMTYPE_DB |
(db->lookaside.bEnabled ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
}
}
return pNew;
}
/*
** Attempt to reallocate p. If the reallocation fails, then free p
** and set the mallocFailed flag in the database connection.
*/
SQLITE_PRIVATE void *sqlite4DbReallocOrFree(sqlite4 *db, void *p, int n){
void *pNew;
pNew = sqlite4DbRealloc(db, p, n);
if( !pNew ){
sqlite4DbFree(db, p);
}
return pNew;
}
/*
** Make a copy of a string in memory obtained from sqliteMalloc(). These
** functions call sqlite4MallocRaw() directly instead of sqliteMalloc(). This
** is because when memory debugging is turned on, these two functions are
** called via macros that record the current file and line number in the
** ThreadData structure.
*/
SQLITE_PRIVATE char *sqlite4DbStrDup(sqlite4 *db, const char *z){
char *zNew;
size_t n;
if( z==0 ){
return 0;
}
n = sqlite4Strlen30(z) + 1;
assert( (n&0x7fffffff)==n );
zNew = sqlite4DbMallocRaw(db, (int)n);
if( zNew ){
memcpy(zNew, z, n);
}
return zNew;
}
SQLITE_PRIVATE char *sqlite4DbStrNDup(sqlite4 *db, const char *z, int n){
char *zNew;
if( z==0 ){
return 0;
}
assert( (n&0x7fffffff)==n );
zNew = sqlite4DbMallocRaw(db, n+1);
if( zNew ){
memcpy(zNew, z, n);
zNew[n] = 0;
}
return zNew;
}
/*
** Create a string from the zFromat argument and the va_list that follows.
** Store the string in memory obtained from sqliteMalloc() and make *pz
** point to that string.
*/
SQLITE_PRIVATE void sqlite4SetString(char **pz, sqlite4 *db, const char *zFormat, ...){
va_list ap;
char *z;
va_start(ap, zFormat);
z = sqlite4VMPrintf(db, zFormat, ap);
va_end(ap);
sqlite4DbFree(db, *pz);
*pz = z;
}
/*
** This function must be called before exiting any API function (i.e.
** returning control to the user) that has called sqlite4_malloc or
** sqlite4_realloc.
**
** The returned value is normally a copy of the second argument to this
** function. However, if a malloc() failure has occurred since the previous
** invocation SQLITE_NOMEM is returned instead.
**
** If the first argument, db, is not NULL and a malloc() error has occurred,
** then the connection error-code (the value returned by sqlite4_errcode())
** is set to SQLITE_NOMEM.
*/
SQLITE_PRIVATE int sqlite4ApiExit(sqlite4* db, int rc){
/* If the db handle is not NULL, then we must hold the connection handle
** mutex here. Otherwise the read (and possible write) of db->mallocFailed
** is unsafe, as is the call to sqlite4Error().
*/
assert( !db || sqlite4_mutex_held(db->mutex) );
if( db && (db->mallocFailed || rc==SQLITE_IOERR_NOMEM) ){
sqlite4Error(db, SQLITE_NOMEM, 0);
db->mallocFailed = 0;
rc = SQLITE_NOMEM;
}
return rc;
}
/************** End of malloc.c **********************************************/
/************** Begin file printf.c ******************************************/
/*
** The "printf" code that follows dates from the 1980's. It is in
** the public domain. The original comments are included here for
** completeness. They are very out-of-date but might be useful as
** an historical reference. Most of the "enhancements" have been backed
** out so that the functionality is now the same as standard printf().
**
**************************************************************************
**
** This file contains code for a set of "printf"-like routines. These
** routines format strings much like the printf() from the standard C
** library, though the implementation here has enhancements to support
** SQLlite.
*/
/*
** Conversion types fall into various categories as defined by the
** following enumeration.
*/
#define etRADIX 1 /* Integer types. %d, %x, %o, and so forth */
#define etFLOAT 2 /* Floating point. %f */
#define etEXP 3 /* Exponentional notation. %e and %E */
#define etGENERIC 4 /* Floating or exponential, depending on exponent. %g */
#define etSIZE 5 /* Return number of characters processed so far. %n */
#define etSTRING 6 /* Strings. %s */
#define etDYNSTRING 7 /* Dynamically allocated strings. %z */
#define etPERCENT 8 /* Percent symbol. %% */
#define etCHARX 9 /* Characters. %c */
/* The rest are extensions, not normally found in printf() */
#define etSQLESCAPE 10 /* Strings with '\'' doubled. %q */
#define etSQLESCAPE2 11 /* Strings with '\'' doubled and enclosed in '',
NULL pointers replaced by SQL NULL. %Q */
#define etTOKEN 12 /* a pointer to a Token structure */
#define etSRCLIST 13 /* a pointer to a SrcList */
#define etPOINTER 14 /* The %p conversion */
#define etSQLESCAPE3 15 /* %w -> Strings with '\"' doubled */
#define etORDINAL 16 /* %r -> 1st, 2nd, 3rd, 4th, etc. English only */
#define etINVALID 0 /* Any unrecognized conversion type */
/*
** An "etByte" is an 8-bit unsigned value.
*/
typedef unsigned char etByte;
/*
** Each builtin conversion character (ex: the 'd' in "%d") is described
** by an instance of the following structure
*/
typedef struct et_info { /* Information about each format field */
char fmttype; /* The format field code letter */
etByte base; /* The base for radix conversion */
etByte flags; /* One or more of FLAG_ constants below */
etByte type; /* Conversion paradigm */
etByte charset; /* Offset into aDigits[] of the digits string */
etByte prefix; /* Offset into aPrefix[] of the prefix string */
} et_info;
/*
** Allowed values for et_info.flags
*/
#define FLAG_SIGNED 1 /* True if the value to convert is signed */
#define FLAG_INTERN 2 /* True if for internal use only */
#define FLAG_STRING 4 /* Allow infinity precision */
/*
** The following table is searched linearly, so it is good to put the
** most frequently used conversion types first.
*/
static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
static const char aPrefix[] = "-x0\000X0";
static const et_info fmtinfo[] = {
{ 'd', 10, 1, etRADIX, 0, 0 },
{ 's', 0, 4, etSTRING, 0, 0 },
{ 'g', 0, 1, etGENERIC, 30, 0 },
{ 'z', 0, 4, etDYNSTRING, 0, 0 },
{ 'q', 0, 4, etSQLESCAPE, 0, 0 },
{ 'Q', 0, 4, etSQLESCAPE2, 0, 0 },
{ 'w', 0, 4, etSQLESCAPE3, 0, 0 },
{ 'c', 0, 0, etCHARX, 0, 0 },
{ 'o', 8, 0, etRADIX, 0, 2 },
{ 'u', 10, 0, etRADIX, 0, 0 },
{ 'x', 16, 0, etRADIX, 16, 1 },
{ 'X', 16, 0, etRADIX, 0, 4 },
#ifndef SQLITE_OMIT_FLOATING_POINT
{ 'f', 0, 1, etFLOAT, 0, 0 },
{ 'e', 0, 1, etEXP, 30, 0 },
{ 'E', 0, 1, etEXP, 14, 0 },
{ 'G', 0, 1, etGENERIC, 14, 0 },
#endif
{ 'i', 10, 1, etRADIX, 0, 0 },
{ 'n', 0, 0, etSIZE, 0, 0 },
{ '%', 0, 0, etPERCENT, 0, 0 },
{ 'p', 16, 0, etPOINTER, 0, 1 },
/* All the rest have the FLAG_INTERN bit set and are thus for internal
** use only */
{ 'T', 0, 2, etTOKEN, 0, 0 },
{ 'S', 0, 2, etSRCLIST, 0, 0 },
{ 'r', 10, 3, etORDINAL, 0, 0 },
};
/*
** If SQLITE_OMIT_FLOATING_POINT is defined, then none of the floating point
** conversions will work.
*/
#ifndef SQLITE_OMIT_FLOATING_POINT
/*
** "*val" is a double such that 0.1 <= *val < 10.0
** Return the ascii code for the leading digit of *val, then
** multiply "*val" by 10.0 to renormalize.
**
** Example:
** input: *val = 3.14159
** output: *val = 1.4159 function return = '3'
**
** The counter *cnt is incremented each time. After counter exceeds
** 16 (the number of significant digits in a 64-bit float) '0' is
** always returned.
*/
static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
int digit;
LONGDOUBLE_TYPE d;
if( (*cnt)++ >= 16 ) return '0';
digit = (int)*val;
d = digit;
digit += '0';
*val = (*val - d)*10.0;
return (char)digit;
}
#endif /* SQLITE_OMIT_FLOATING_POINT */
/*
** Append N space characters to the given string buffer.
*/
SQLITE_PRIVATE void sqlite4AppendSpace(StrAccum *pAccum, int N){
static const char zSpaces[] = " ";
while( N>=(int)sizeof(zSpaces)-1 ){
sqlite4StrAccumAppend(pAccum, zSpaces, sizeof(zSpaces)-1);
N -= sizeof(zSpaces)-1;
}
if( N>0 ){
sqlite4StrAccumAppend(pAccum, zSpaces, N);
}
}
/*
** On machines with a small stack size, you can redefine the
** SQLITE_PRINT_BUF_SIZE to be something smaller, if desired.
*/
#ifndef SQLITE_PRINT_BUF_SIZE
# define SQLITE_PRINT_BUF_SIZE 70
#endif
#define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */
/*
** Render a string given by "fmt" into the StrAccum object.
*/
SQLITE_PRIVATE void sqlite4VXPrintf(
StrAccum *pAccum, /* Accumulate results here */
int useExtended, /* Allow extended %-conversions */
const char *fmt, /* Format string */
va_list ap /* arguments */
){
int c; /* Next character in the format string */
char *bufpt; /* Pointer to the conversion buffer */
int precision; /* Precision of the current field */
int length; /* Length of the field */
int idx; /* A general purpose loop counter */
int width; /* Width of the current field */
etByte flag_leftjustify; /* True if "-" flag is present */
etByte flag_plussign; /* True if "+" flag is present */
etByte flag_blanksign; /* True if " " flag is present */
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; /* True if "l" flag is present */
etByte flag_longlong; /* True if the "ll" flag is present */
etByte done; /* Loop termination flag */
etByte xtype = 0; /* Conversion paradigm */
char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */
sqlite_uint64 longvalue; /* Value for integer types */
LONGDOUBLE_TYPE realvalue; /* Value for real types */
const et_info *infop; /* Pointer to the appropriate info structure */
char *zOut; /* Rendering buffer */
int nOut; /* Size of the rendering buffer */
char *zExtra; /* Malloced memory used by some conversion */
#ifndef SQLITE_OMIT_FLOATING_POINT
int exp, e2; /* exponent of real numbers */
int nsd; /* Number of significant digits returned */
double rounder; /* Used for rounding floating point values */
etByte flag_dp; /* True if decimal point should be shown */
etByte flag_rtz; /* True if trailing zeros should be removed */
#endif
char buf[etBUFSIZE]; /* Conversion buffer */
bufpt = 0;
for(; (c=(*fmt))!=0; ++fmt){
if( c!='%' ){
int amt;
bufpt = (char *)fmt;
amt = 1;
while( (c=(*++fmt))!='%' && c!=0 ) amt++;
sqlite4StrAccumAppend(pAccum, bufpt, amt);
if( c==0 ) break;
}
if( (c=(*++fmt))==0 ){
sqlite4StrAccumAppend(pAccum, "%", 1);
break;
}
/* Find out what flags are present */
flag_leftjustify = flag_plussign = flag_blanksign =
flag_alternateform = flag_altform2 = flag_zeropad = 0;
done = 0;
do{
switch( c ){
case '-': flag_leftjustify = 1; break;
case '+': flag_plussign = 1; break;
case ' ': flag_blanksign = 1; break;
case '#': flag_alternateform = 1; break;
case '!': flag_altform2 = 1; break;
case '0': flag_zeropad = 1; break;
default: done = 1; break;
}
}while( !done && (c=(*++fmt))!=0 );
/* Get the field width */
width = 0;
if( c=='*' ){
width = va_arg(ap,int);
if( width<0 ){
flag_leftjustify = 1;
width = -width;
}
c = *++fmt;
}else{
while( c>='0' && c<='9' ){
width = width*10 + c - '0';
c = *++fmt;
}
}
/* Get the precision */
if( c=='.' ){
precision = 0;
c = *++fmt;
if( c=='*' ){
precision = va_arg(ap,int);
if( precision<0 ) precision = -precision;
c = *++fmt;
}else{
while( c>='0' && c<='9' ){
precision = precision*10 + c - '0';
c = *++fmt;
}
}
}else{
precision = -1;
}
/* Get the conversion type modifier */
if( c=='l' ){
flag_long = 1;
c = *++fmt;
if( c=='l' ){
flag_longlong = 1;
c = *++fmt;
}else{
flag_longlong = 0;
}
}else{
flag_long = flag_longlong = 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];
if( useExtended || (infop->flags & FLAG_INTERN)==0 ){
xtype = infop->type;
}else{
return;
}
break;
}
}
zExtra = 0;
/*
** At this point, variables are initialized as follows:
**
** flag_alternateform TRUE if a '#' is present.
** flag_altform2 TRUE if a '!' is present.
** flag_plussign TRUE if a '+' is present.
** 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 TRUE if the letter 'l' (ell) prefixed
** the conversion character.
** flag_longlong TRUE if the letter 'll' (ell ell) prefixed
** the conversion character.
** flag_blanksign TRUE if a ' ' is present.
** width The specified field width. This is
** always non-negative. Zero is the default.
** precision The specified precision. The default
** is -1.
** xtype The class of the conversion.
** infop Pointer to the appropriate info struct.
*/
switch( xtype ){
case etPOINTER:
flag_longlong = sizeof(char*)==sizeof(i64);
flag_long = sizeof(char*)==sizeof(long int);
/* Fall through into the next case */
case etORDINAL:
case etRADIX:
if( infop->flags & FLAG_SIGNED ){
i64 v;
if( flag_longlong ){
v = va_arg(ap,i64);
}else if( flag_long ){
v = va_arg(ap,long int);
}else{
v = va_arg(ap,int);
}
if( v<0 ){
if( v==SMALLEST_INT64 ){
longvalue = ((u64)1)<<63;
}else{
longvalue = -v;
}
prefix = '-';
}else{
longvalue = v;
if( flag_plussign ) prefix = '+';
else if( flag_blanksign ) prefix = ' ';
else prefix = 0;
}
}else{
if( flag_longlong ){
longvalue = va_arg(ap,u64);
}else if( flag_long ){
longvalue = va_arg(ap,unsigned long int);
}else{
longvalue = va_arg(ap,unsigned int);
}
prefix = 0;
}
if( longvalue==0 ) flag_alternateform = 0;
if( flag_zeropad && precision<width-(prefix!=0) ){
precision = width-(prefix!=0);
}
if( precision<etBUFSIZE-10 ){
nOut = etBUFSIZE;
zOut = buf;
}else{
nOut = precision + 10;
zOut = zExtra = sqlite4Malloc(pAccum->pEnv, nOut);
if( zOut==0 ){
pAccum->mallocFailed = 1;
return;
}
}
bufpt = &zOut[nOut-1];
if( xtype==etORDINAL ){
static const char zOrd[] = "thstndrd";
int x = (int)(longvalue % 10);
if( x>=4 || (longvalue/10)%10==1 ){
x = 0;
}
*(--bufpt) = zOrd[x*2+1];
*(--bufpt) = zOrd[x*2];
}
{
register const char *cset; /* Use registers for speed */
register int base;
cset = &aDigits[infop->charset];
base = infop->base;
do{ /* Convert to ascii */
*(--bufpt) = cset[longvalue%base];
longvalue = longvalue/base;
}while( longvalue>0 );
}
length = (int)(&zOut[nOut-1]-bufpt);
for(idx=precision-length; idx>0; idx--){
*(--bufpt) = '0'; /* Zero pad */
}
if( prefix ) *(--bufpt) = prefix; /* Add sign */
if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */
const char *pre;
char x;
pre = &aPrefix[infop->prefix];
for(; (x=(*pre))!=0; pre++) *(--bufpt) = x;
}
length = (int)(&zOut[nOut-1]-bufpt);
break;
case etFLOAT:
case etEXP:
case etGENERIC:
realvalue = va_arg(ap,double);
#ifdef SQLITE_OMIT_FLOATING_POINT
length = 0;
#else
if( precision<0 ) precision = 6; /* Set default precision */
if( realvalue<0.0 ){
realvalue = -realvalue;
prefix = '-';
}else{
if( flag_plussign ) prefix = '+';
else if( flag_blanksign ) prefix = ' ';
else prefix = 0;
}
if( xtype==etGENERIC && precision>0 ) precision--;
#if 0
/* Rounding works like BSD when the constant 0.4999 is used. Wierd! */
for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1);
#else
/* It makes more sense to use 0.5 */
for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1){}
#endif
if( xtype==etFLOAT ) realvalue += rounder;
/* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
exp = 0;
if( sqlite4IsNaN((double)realvalue) ){
bufpt = "NaN";
length = 3;
break;
}
if( realvalue>0.0 ){
while( realvalue>=1e32 && exp<=350 ){ realvalue *= 1e-32; exp+=32; }
while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; }
while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; }
while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; }
while( realvalue<1.0 ){ realvalue *= 10.0; exp--; }
if( exp>350 ){
if( prefix=='-' ){
bufpt = "-Inf";
}else if( prefix=='+' ){
bufpt = "+Inf";
}else{
bufpt = "Inf";
}
length = sqlite4Strlen30(bufpt);
break;
}
}
bufpt = buf;
/*
** If the field type is etGENERIC, then convert to either etEXP
** or etFLOAT, as appropriate.
*/
if( xtype!=etFLOAT ){
realvalue += rounder;
if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; }
}
if( xtype==etGENERIC ){
flag_rtz = !flag_alternateform;
if( exp<-4 || exp>precision ){
xtype = etEXP;
}else{
precision = precision - exp;
xtype = etFLOAT;
}
}else{
flag_rtz = 0;
}
if( xtype==etEXP ){
e2 = 0;
}else{
e2 = exp;
}
if( e2+precision+width > etBUFSIZE - 15 ){
bufpt = zExtra = sqlite4Malloc(pAccum->pEnv, e2+precision+width+15 );
if( bufpt==0 ){
pAccum->mallocFailed = 1;
return;
}
}
zOut = bufpt;
nsd = 0;
flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
/* The sign in front of the number */
if( prefix ){
*(bufpt++) = prefix;
}
/* Digits prior to the decimal point */
if( e2<0 ){
*(bufpt++) = '0';
}else{
for(; e2>=0; e2--){
*(bufpt++) = et_getdigit(&realvalue,&nsd);
}
}
/* The decimal point */
if( flag_dp ){
*(bufpt++) = '.';
}
/* "0" digits after the decimal point but before the first
** significant digit of the number */
for(e2++; e2<0; precision--, e2++){
assert( precision>0 );
*(bufpt++) = '0';
}
/* Significant digits after the decimal point */
while( (precision--)>0 ){
*(bufpt++) = et_getdigit(&realvalue,&nsd);
}
/* Remove trailing zeros and the "." if no digits follow the "." */
if( flag_rtz && flag_dp ){
while( bufpt[-1]=='0' ) *(--bufpt) = 0;
assert( bufpt>zOut );
if( bufpt[-1]=='.' ){
if( flag_altform2 ){
*(bufpt++) = '0';
}else{
*(--bufpt) = 0;
}
}
}
/* Add the "eNNN" suffix */
if( xtype==etEXP ){
*(bufpt++) = aDigits[infop->charset];
if( exp<0 ){
*(bufpt++) = '-'; exp = -exp;
}else{
*(bufpt++) = '+';
}
if( exp>=100 ){
*(bufpt++) = (char)((exp/100)+'0'); /* 100's digit */
exp %= 100;
}
*(bufpt++) = (char)(exp/10+'0'); /* 10's digit */
*(bufpt++) = (char)(exp%10+'0'); /* 1's digit */
}
*bufpt = 0;
/* The converted number is in buf[] and zero terminated. Output it.
** Note that the number is in the usual order, not reversed as with
** integer conversions. */
length = (int)(bufpt-zOut);
bufpt = zOut;
/* Special case: Add leading zeros if the flag_zeropad flag is
** set and we are not left justified */
if( flag_zeropad && !flag_leftjustify && length < width){
int i;
int nPad = width - length;
for(i=width; i>=nPad; i--){
bufpt[i] = bufpt[i-nPad];
}
i = prefix!=0;
while( nPad-- ) bufpt[i++] = '0';
length = width;
}
#endif /* !defined(SQLITE_OMIT_FLOATING_POINT) */
break;
case etSIZE:
*(va_arg(ap,int*)) = pAccum->nChar;
length = width = 0;
break;
case etPERCENT:
buf[0] = '%';
bufpt = buf;
length = 1;
break;
case etCHARX:
c = va_arg(ap,int);
buf[0] = (char)c;
if( precision>=0 ){
for(idx=1; idx<precision; idx++) buf[idx] = (char)c;
length = precision;
}else{
length =1;
}
bufpt = buf;
break;
case etSTRING:
case etDYNSTRING:
bufpt = va_arg(ap,char*);
if( bufpt==0 ){
bufpt = "";
}else if( xtype==etDYNSTRING ){
zExtra = bufpt;
}
if( precision>=0 ){
for(length=0; length<precision && bufpt[length]; length++){}
}else{
length = sqlite4Strlen30(bufpt);
}
break;
case etSQLESCAPE:
case etSQLESCAPE2:
case etSQLESCAPE3: {
int i, j, k, n, isnull;
int needQuote;
char ch;
char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote character */
char *escarg = va_arg(ap,char*);
isnull = escarg==0;
if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
k = precision;
for(i=n=0; k!=0 && (ch=escarg[i])!=0; i++, k--){
if( ch==q ) n++;
}
needQuote = !isnull && xtype==etSQLESCAPE2;
n += i + 1 + needQuote*2;
if( n>etBUFSIZE ){
bufpt = zExtra = sqlite4Malloc(pAccum->pEnv, n);
if( bufpt==0 ){
pAccum->mallocFailed = 1;
return;
}
}else{
bufpt = buf;
}
j = 0;
if( needQuote ) bufpt[j++] = q;
k = i;
for(i=0; i<k; i++){
bufpt[j++] = ch = escarg[i];
if( ch==q ) bufpt[j++] = ch;
}
if( needQuote ) bufpt[j++] = q;
bufpt[j] = 0;
length = j;
/* The precision in %q and %Q means how many input characters to
** consume, not the length of the output...
** if( precision>=0 && precision<length ) length = precision; */
break;
}
case etTOKEN: {
Token *pToken = va_arg(ap, Token*);
if( pToken ){
sqlite4StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n);
}
length = width = 0;
break;
}
case etSRCLIST: {
SrcList *pSrc = va_arg(ap, SrcList*);
int k = va_arg(ap, int);
struct SrcList_item *pItem = &pSrc->a[k];
assert( k>=0 && k<pSrc->nSrc );
if( pItem->zDatabase ){
sqlite4StrAccumAppend(pAccum, pItem->zDatabase, -1);
sqlite4StrAccumAppend(pAccum, ".", 1);
}
sqlite4StrAccumAppend(pAccum, pItem->zName, -1);
length = width = 0;
break;
}
default: {
assert( xtype==etINVALID );
return;
}
}/* End switch over the format type */
/*
** The text of the conversion is pointed to by "bufpt" and is
** "length" characters long. The field width is "width". Do
** the output.
*/
if( !flag_leftjustify ){
register int nspace;
nspace = width-length;
if( nspace>0 ){
sqlite4AppendSpace(pAccum, nspace);
}
}
if( length>0 ){
sqlite4StrAccumAppend(pAccum, bufpt, length);
}
if( flag_leftjustify ){
register int nspace;
nspace = width-length;
if( nspace>0 ){
sqlite4AppendSpace(pAccum, nspace);
}
}
sqlite4_free(pAccum->pEnv, zExtra);
}/* End for loop over the format string */
} /* End of function */
/*
** Append N bytes of text from z to the StrAccum object.
*/
SQLITE_PRIVATE void sqlite4StrAccumAppend(StrAccum *p, const char *z, int N){
assert( z!=0 || N==0 );
if( p->tooBig | p->mallocFailed ){
testcase(p->tooBig);
testcase(p->mallocFailed);
return;
}
assert( p->zText!=0 || p->nChar==0 );
if( N<0 ){
N = sqlite4Strlen30(z);
}
if( N==0 || NEVER(z==0) ){
return;
}
if( p->nChar+N >= p->nAlloc ){
char *zNew;
if( !p->useMalloc ){
p->tooBig = 1;
N = p->nAlloc - p->nChar - 1;
if( N<=0 ){
return;
}
}else{
char *zOld = (p->zText==p->zBase ? 0 : p->zText);
i64 szNew = p->nChar;
szNew += N + 1;
if( szNew > p->mxAlloc ){
sqlite4StrAccumReset(p);
p->tooBig = 1;
return;
}else{
p->nAlloc = (int)szNew;
}
if( p->useMalloc==1 ){
zNew = sqlite4DbRealloc(p->db, zOld, p->nAlloc);
}else{
zNew = sqlite4_realloc(p->pEnv, zOld, p->nAlloc);
}
if( zNew ){
if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
p->zText = zNew;
}else{
p->mallocFailed = 1;
sqlite4StrAccumReset(p);
return;
}
}
}
assert( p->zText );
memcpy(&p->zText[p->nChar], z, N);
p->nChar += N;
}
/*
** Finish off a string by making sure it is zero-terminated.
** Return a pointer to the resulting string. Return a NULL
** pointer if any kind of error was encountered.
*/
SQLITE_PRIVATE char *sqlite4StrAccumFinish(StrAccum *p){
if( p->zText ){
p->zText[p->nChar] = 0;
if( p->useMalloc && p->zText==p->zBase ){
if( p->useMalloc==1 ){
p->zText = sqlite4DbMallocRaw(p->db, p->nChar+1 );
}else{
p->zText = sqlite4_malloc(p->pEnv, p->nChar+1);
}
if( p->zText ){
memcpy(p->zText, p->zBase, p->nChar+1);
}else{
p->mallocFailed = 1;
}
}
}
return p->zText;
}
/*
** Reset an StrAccum string. Reclaim all malloced memory.
*/
SQLITE_PRIVATE void sqlite4StrAccumReset(StrAccum *p){
if( p->zText!=p->zBase ){
if( p->useMalloc==1 ){
sqlite4DbFree(p->db, p->zText);
}else{
sqlite4_free(p->pEnv, p->zText);
}
}
p->zText = 0;
}
/*
** Initialize a string accumulator
*/
SQLITE_PRIVATE void sqlite4StrAccumInit(StrAccum *p, char *zBase, int n, int mx){
p->zText = p->zBase = zBase;
p->db = 0;
p->pEnv = 0;
p->nChar = 0;
p->nAlloc = n;
p->mxAlloc = mx;
p->useMalloc = 1;
p->tooBig = 0;
p->mallocFailed = 0;
}
/*
** Print into memory obtained from sqliteMalloc(). Use the internal
** %-conversion extensions.
*/
SQLITE_PRIVATE char *sqlite4VMPrintf(sqlite4 *db, const char *zFormat, va_list ap){
char *z;
char zBase[SQLITE_PRINT_BUF_SIZE];
StrAccum acc;
assert( db!=0 );
sqlite4StrAccumInit(&acc, zBase, sizeof(zBase),
db->aLimit[SQLITE_LIMIT_LENGTH]);
acc.db = db;
sqlite4VXPrintf(&acc, 1, zFormat, ap);
z = sqlite4StrAccumFinish(&acc);
if( acc.mallocFailed ){
db->mallocFailed = 1;
}
return z;
}
/*
** Print into memory obtained from sqliteMalloc(). Use the internal
** %-conversion extensions.
*/
SQLITE_PRIVATE char *sqlite4MPrintf(sqlite4 *db, const char *zFormat, ...){
va_list ap;
char *z;
va_start(ap, zFormat);
z = sqlite4VMPrintf(db, zFormat, ap);
va_end(ap);
return z;
}
/*
** Like sqlite4MPrintf(), but call sqlite4DbFree() on zStr after formatting
** the string and before returnning. This routine is intended to be used
** to modify an existing string. For example:
**
** x = sqlite4MPrintf(db, x, "prefix %s suffix", x);
**
*/
SQLITE_PRIVATE char *sqlite4MAppendf(sqlite4 *db, char *zStr, const char *zFormat, ...){
va_list ap;
char *z;
va_start(ap, zFormat);
z = sqlite4VMPrintf(db, zFormat, ap);
va_end(ap);
sqlite4DbFree(db, zStr);
return z;
}
/*
** Print into memory obtained from sqlite4_malloc(). Omit the internal
** %-conversion extensions.
*/
SQLITE_API char *sqlite4_vmprintf(sqlite4_env *pEnv, const char *zFormat, va_list ap){
char *z;
char zBase[SQLITE_PRINT_BUF_SIZE];
StrAccum acc;
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite4_initialize(pEnv) ) return 0;
#endif
sqlite4StrAccumInit(&acc, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
acc.useMalloc = 2;
acc.pEnv = pEnv;
sqlite4VXPrintf(&acc, 0, zFormat, ap);
z = sqlite4StrAccumFinish(&acc);
return z;
}
/*
** Print into memory obtained from sqlite4_malloc()(). Omit the internal
** %-conversion extensions.
*/
SQLITE_API char *sqlite4_mprintf(sqlite4_env *pEnv, const char *zFormat, ...){
va_list ap;
char *z;
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite4_initialize(pEnv) ) return 0;
#endif
va_start(ap, zFormat);
z = sqlite4_vmprintf(pEnv, zFormat, ap);
va_end(ap);
return z;
}
/*
** sqlite4_snprintf() works like snprintf() except that it ignores the
** current locale settings. This is important for SQLite because we
** are not able to use a "," as the decimal point in place of "." as
** specified by some locales.
**
** Oops: The first two arguments of sqlite4_snprintf() are backwards
** from the snprintf() standard. Unfortunately, it is too late to change
** this without breaking compatibility, so we just have to live with the
** mistake.
**
** sqlite4_vsnprintf() is the varargs version.
*/
SQLITE_API sqlite4_size_t sqlite4_vsnprintf(
char *zBuf, /* Write results here */
sqlite4_size_t n, /* Bytes available in zBuf[] */
const char *zFormat, /* Format string */
va_list ap /* Arguments */
){
StrAccum acc;
if( n<=0 ) return 0;
sqlite4StrAccumInit(&acc, zBuf, n, 0);
acc.useMalloc = 0;
sqlite4VXPrintf(&acc, 0, zFormat, ap);
sqlite4StrAccumFinish(&acc);
return acc.nChar;
}
SQLITE_API sqlite4_size_t sqlite4_snprintf(
char *zBuf, /* Write results here */
sqlite4_size_t n, /* Bytes available in zBuf[] */
const char *zFormat, /* Format string */
... /* Arguments */
){
va_list ap;
va_start(ap,zFormat);
n = sqlite4_vsnprintf(zBuf, n, zFormat, ap);
va_end(ap);
return n;
}
/*
** This is the routine that actually formats the sqlite4_log() message.
** We house it in a separate routine from sqlite4_log() to avoid using
** stack space on small-stack systems when logging is disabled.
**
** sqlite4_log() must render into a static buffer. It cannot dynamically
** allocate memory because it might be called while the memory allocator
** mutex is held.
*/
static void renderLogMsg(
sqlite4_env *pEnv, /* Run-time environment */
int iErrCode, /* Error code */
const char *zFormat, /* Error format string */
va_list ap /* Arguments */
){
StrAccum acc; /* String accumulator */
char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */
sqlite4StrAccumInit(&acc, zMsg, sizeof(zMsg), 0);
acc.useMalloc = 0;
sqlite4VXPrintf(&acc, 0, zFormat, ap);
pEnv->xLog(pEnv->pLogArg, iErrCode, sqlite4StrAccumFinish(&acc));
}
/*
** Format and write a message to the log if logging is enabled.
*/
SQLITE_API void sqlite4_log(sqlite4_env *pEnv, int iErrCode, const char *zFormat, ...){
va_list ap; /* Vararg list */
if( pEnv==0 ) pEnv = &sqlite4DefaultEnv;
if( pEnv->xLog ){
va_start(ap, zFormat);
renderLogMsg(pEnv, iErrCode, zFormat, ap);
va_end(ap);
}
}
#if defined(SQLITE_DEBUG)
/*
** A version of printf() that understands %lld. Used for debugging.
** The printf() built into some versions of windows does not understand %lld
** and segfaults if you give it a long long int.
*/
SQLITE_PRIVATE void sqlite4DebugPrintf(const char *zFormat, ...){
va_list ap;
StrAccum acc;
char zBuf[500];
sqlite4StrAccumInit(&acc, zBuf, sizeof(zBuf), 0);
acc.useMalloc = 0;
va_start(ap,zFormat);
sqlite4VXPrintf(&acc, 0, zFormat, ap);
va_end(ap);
sqlite4StrAccumFinish(&acc);
fprintf(stdout,"%s", zBuf);
fflush(stdout);
}
#endif
#ifndef SQLITE_OMIT_TRACE
/*
** variable-argument wrapper around sqlite4VXPrintf().
*/
SQLITE_PRIVATE void sqlite4XPrintf(StrAccum *p, const char *zFormat, ...){
va_list ap;
va_start(ap,zFormat);
sqlite4VXPrintf(p, 1, zFormat, ap);
va_end(ap);
}
#endif
/************** End of printf.c **********************************************/
/************** Begin file random.c ******************************************/
/*
** 2001 September 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.
**
*************************************************************************
** This file contains code to implement a pseudo-random number
** generator (PRNG) for SQLite.
**
** Random numbers are used by some of the database backends in order
** to generate random integer keys for tables or random filenames.
*/
/*
** Get a single 8-bit random value from the PRNG. The Mutex
** must be held while executing this routine.
*/
static u8 randomByte(sqlite4_env *pEnv){
pEnv->prngX = (pEnv->prngX>>1) ^ ((-(pEnv->prngX&1)) & 0xd0000001);
pEnv->prngY = pEnv->prngY*1103515245 + 12345;
return (u8)((pEnv->prngX ^ pEnv->prngY)&0xff);
}
/*
** Return N random bytes.
*/
SQLITE_API void sqlite4_randomness(sqlite4_env *pEnv, int N, void *pBuf){
unsigned char *zBuf = pBuf;
if( pEnv==0 ) pEnv = &sqlite4DefaultEnv;
sqlite4_mutex_enter(pEnv->pPrngMutex);
while( N-- ){
*(zBuf++) = randomByte(pEnv);
}
sqlite4_mutex_leave(pEnv->pPrngMutex);
}
/************** End of random.c **********************************************/
/************** Begin file utf.c *********************************************/
/*
** 2004 April 13
**
** 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 routines used to translate between UTF-8,
** UTF-16, UTF-16BE, and UTF-16LE.
**
** Notes on UTF-8:
**
** Byte-0 Byte-1 Byte-2 Byte-3 Value
** 0xxxxxxx 00000000 00000000 0xxxxxxx
** 110yyyyy 10xxxxxx 00000000 00000yyy yyxxxxxx
** 1110zzzz 10yyyyyy 10xxxxxx 00000000 zzzzyyyy yyxxxxxx
** 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx 000uuuuu zzzzyyyy yyxxxxxx
**
**
** Notes on UTF-16: (with wwww+1==uuuuu)
**
** Word-0 Word-1 Value
** 110110ww wwzzzzyy 110111yy yyxxxxxx 000uuuuu zzzzyyyy yyxxxxxx
** zzzzyyyy yyxxxxxx 00000000 zzzzyyyy yyxxxxxx
**
**
** BOM or Byte Order Mark:
** 0xff 0xfe little-endian utf-16 follows
** 0xfe 0xff big-endian utf-16 follows
**
*/
/* #include <assert.h> */
#ifndef SQLITE_AMALGAMATION
/*
** The following constant value is used by the SQLITE_BIGENDIAN and
** SQLITE_LITTLEENDIAN macros.
*/
SQLITE_PRIVATE const int sqlite4one = 1;
#endif /* SQLITE_AMALGAMATION */
/*
** This lookup table is used to help decode the first byte of
** a multi-byte UTF8 character.
*/
static const unsigned char sqlite4Utf8Trans1[] = {
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 WRITE_UTF8(zOut, c) { \
if( c<0x00080 ){ \
*zOut++ = (u8)(c&0xFF); \
} \
else if( c<0x00800 ){ \
*zOut++ = 0xC0 + (u8)((c>>6)&0x1F); \
*zOut++ = 0x80 + (u8)(c & 0x3F); \
} \
else if( c<0x10000 ){ \
*zOut++ = 0xE0 + (u8)((c>>12)&0x0F); \
*zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \
*zOut++ = 0x80 + (u8)(c & 0x3F); \
}else{ \
*zOut++ = 0xF0 + (u8)((c>>18) & 0x07); \
*zOut++ = 0x80 + (u8)((c>>12) & 0x3F); \
*zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \
*zOut++ = 0x80 + (u8)(c & 0x3F); \
} \
}
#define WRITE_UTF16LE(zOut, c) { \
if( c<=0xFFFF ){ \
*zOut++ = (u8)(c&0x00FF); \
*zOut++ = (u8)((c>>8)&0x00FF); \
}else{ \
*zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0)); \
*zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03)); \
*zOut++ = (u8)(c&0x00FF); \
*zOut++ = (u8)(0x00DC + ((c>>8)&0x03)); \
} \
}
#define WRITE_UTF16BE(zOut, c) { \
if( c<=0xFFFF ){ \
*zOut++ = (u8)((c>>8)&0x00FF); \
*zOut++ = (u8)(c&0x00FF); \
}else{ \
*zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03)); \
*zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0)); \
*zOut++ = (u8)(0x00DC + ((c>>8)&0x03)); \
*zOut++ = (u8)(c&0x00FF); \
} \
}
#define READ_UTF16LE(zIn, TERM, c){ \
c = (*zIn++); \
c += ((*zIn++)<<8); \
if( c>=0xD800 && c<0xE000 && TERM ){ \
int c2 = (*zIn++); \
c2 += ((*zIn++)<<8); \
c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10); \
} \
}
#define READ_UTF16BE(zIn, TERM, c){ \
c = ((*zIn++)<<8); \
c += (*zIn++); \
if( c>=0xD800 && c<0xE000 && TERM ){ \
int c2 = ((*zIn++)<<8); \
c2 += (*zIn++); \
c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10); \
} \
}
/*
** Translate a single UTF-8 character. Return the unicode value.
**
** During translation, assume that the byte that zTerm points
** is a 0x00.
**
** Write a pointer to the next unread byte back into *pzNext.
**
** Notes On Invalid UTF-8:
**
** * This routine never allows a 7-bit character (0x00 through 0x7f) to
** be encoded as a multi-byte character. Any multi-byte character that
** attempts to encode a value between 0x00 and 0x7f is rendered as 0xfffd.
**
** * This routine never allows a UTF16 surrogate value to be encoded.
** If a multi-byte character attempts to encode a value between
** 0xd800 and 0xe000 then it is rendered as 0xfffd.
**
** * Bytes in the range of 0x80 through 0xbf which occur as the first
** byte of a character are interpreted as single-byte characters
** and rendered as themselves even though they are technically
** invalid characters.
**
** * This routine accepts an infinite number of different UTF8 encodings
** for unicode values 0x80 and greater. It do not change over-length
** encodings to 0xfffd as some systems recommend.
*/
#define READ_UTF8(zIn, zTerm, c) \
c = *(zIn++); \
if( c>=0xc0 ){ \
c = sqlite4Utf8Trans1[c-0xc0]; \
while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \
c = (c<<6) + (0x3f & *(zIn++)); \
} \
if( c<0x80 \
|| (c&0xFFFFF800)==0xD800 \
|| (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \
}
SQLITE_PRIVATE u32 sqlite4Utf8Read(
const unsigned char *zIn, /* First byte of UTF-8 character */
const unsigned char **pzNext /* Write first byte past UTF-8 char here */
){
unsigned int c;
/* Same as READ_UTF8() above but without the zTerm parameter.
** For this routine, we assume the UTF8 string is always zero-terminated.
*/
c = *(zIn++);
if( c>=0xc0 ){
c = sqlite4Utf8Trans1[c-0xc0];
while( (*zIn & 0xc0)==0x80 ){
c = (c<<6) + (0x3f & *(zIn++));
}
if( c<0x80
|| (c&0xFFFFF800)==0xD800
|| (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; }
}
*pzNext = zIn;
return c;
}
/*
** If the TRANSLATE_TRACE macro is defined, the value of each Mem is
** printed on stderr on the way into and out of sqlite4VdbeMemTranslate().
*/
/* #define TRANSLATE_TRACE 1 */
#ifndef SQLITE_OMIT_UTF16
/*
** This routine transforms the internal text encoding used by pMem to
** desiredEnc. It is an error if the string is already of the desired
** encoding, or if *pMem does not contain a string value.
*/
SQLITE_PRIVATE int sqlite4VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
int len; /* Maximum length of output string in bytes */
unsigned char *zOut; /* Output buffer */
unsigned char *zIn; /* Input iterator */
unsigned char *zTerm; /* End of input */
unsigned char *z; /* Output iterator */
unsigned int c;
assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
assert( pMem->flags&MEM_Str );
assert( pMem->enc!=desiredEnc );
assert( pMem->enc!=0 );
assert( pMem->n>=0 );
#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
{
char zBuf[100];
sqlite4VdbeMemPrettyPrint(pMem, zBuf);
fprintf(stderr, "INPUT: %s\n", zBuf);
}
#endif
/* If the translation is between UTF-16 little and big endian, then
** all that is required is to swap the byte order. This case is handled
** differently from the others.
*/
if( pMem->enc!=SQLITE_UTF8 && desiredEnc!=SQLITE_UTF8 ){
u8 temp;
int rc;
rc = sqlite4VdbeMemMakeWriteable(pMem);
if( rc!=SQLITE_OK ){
assert( rc==SQLITE_NOMEM );
return SQLITE_NOMEM;
}
zIn = (u8*)pMem->z;
zTerm = &zIn[pMem->n&~1];
while( zIn<zTerm ){
temp = *zIn;
*zIn = *(zIn+1);
zIn++;
*zIn++ = temp;
}
pMem->enc = desiredEnc;
goto translate_out;
}
/* Set len to the maximum number of bytes required in the output buffer. */
if( desiredEnc==SQLITE_UTF8 ){
/* When converting from UTF-16, the maximum growth results from
** translating a 2-byte character to a 4-byte UTF-8 character.
** A single byte is required for the output string
** nul-terminator.
*/
pMem->n &= ~1;
len = pMem->n * 2 + 1;
}else{
/* When converting from UTF-8 to UTF-16 the maximum growth is caused
** when a 1-byte UTF-8 character is translated into a 2-byte UTF-16
** character. Two bytes are required in the output buffer for the
** nul-terminator.
*/
len = pMem->n * 2 + 2;
}
/* Set zIn to point at the start of the input buffer and zTerm to point 1
** byte past the end.
**
** Variable zOut is set to point at the output buffer, space obtained
** from sqlite4_malloc().
*/
zIn = (u8*)pMem->z;
zTerm = &zIn[pMem->n];
zOut = sqlite4DbMallocRaw(pMem->db, len);
if( !zOut ){
return SQLITE_NOMEM;
}
z = zOut;
if( pMem->enc==SQLITE_UTF8 ){
if( desiredEnc==SQLITE_UTF16LE ){
/* UTF-8 -> UTF-16 Little-endian */
while( zIn<zTerm ){
/* c = sqlite4Utf8Read(zIn, zTerm, (const u8**)&zIn); */
READ_UTF8(zIn, zTerm, c);
WRITE_UTF16LE(z, c);
}
}else{
assert( desiredEnc==SQLITE_UTF16BE );
/* UTF-8 -> UTF-16 Big-endian */
while( zIn<zTerm ){
/* c = sqlite4Utf8Read(zIn, zTerm, (const u8**)&zIn); */
READ_UTF8(zIn, zTerm, c);
WRITE_UTF16BE(z, c);
}
}
pMem->n = (int)(z - zOut);
*z++ = 0;
}else{
assert( desiredEnc==SQLITE_UTF8 );
if( pMem->enc==SQLITE_UTF16LE ){
/* UTF-16 Little-endian -> UTF-8 */
while( zIn<zTerm ){
READ_UTF16LE(zIn, zIn<zTerm, c);
WRITE_UTF8(z, c);
}
}else{
/* UTF-16 Big-endian -> UTF-8 */
while( zIn<zTerm ){
READ_UTF16BE(zIn, zIn<zTerm, c);
WRITE_UTF8(z, c);
}
}
pMem->n = (int)(z - zOut);
}
*z = 0;
assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len );
sqlite4VdbeMemRelease(pMem);
pMem->flags &= ~(MEM_Static|MEM_Dyn|MEM_Ephem);
pMem->enc = desiredEnc;
pMem->flags |= (MEM_Term|MEM_Dyn);
pMem->z = (char*)zOut;
pMem->zMalloc = pMem->z;
translate_out:
#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
{
char zBuf[100];
sqlite4VdbeMemPrettyPrint(pMem, zBuf);
fprintf(stderr, "OUTPUT: %s\n", zBuf);
}
#endif
return SQLITE_OK;
}
/*
** 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
** the encoding of the Mem adjusted. This routine does not do any
** byte-swapping, it just sets Mem.enc appropriately.
**
** The allocation (static, dynamic etc.) and encoding of the Mem may be
** changed by this function.
*/
SQLITE_PRIVATE int sqlite4VdbeMemHandleBom(Mem *pMem){
int rc = SQLITE_OK;
u8 bom = 0;
assert( pMem->n>=0 );
if( pMem->n>1 ){
u8 b1 = *(u8 *)pMem->z;
u8 b2 = *(((u8 *)pMem->z) + 1);
if( b1==0xFE && b2==0xFF ){
bom = SQLITE_UTF16BE;
}
if( b1==0xFF && b2==0xFE ){
bom = SQLITE_UTF16LE;
}
}
if( bom ){
rc = sqlite4VdbeMemMakeWriteable(pMem);
if( rc==SQLITE_OK ){
pMem->n -= 2;
memmove(pMem->z, &pMem->z[2], pMem->n);
pMem->z[pMem->n] = '\0';
pMem->z[pMem->n+1] = '\0';
pMem->flags |= MEM_Term;
pMem->enc = bom;
}
}
return rc;
}
#endif /* SQLITE_OMIT_UTF16 */
/*
** pZ is a UTF-8 encoded unicode string. If nByte is less than zero,
** return the number of unicode characters in pZ up to (but not including)
** the first 0x00 byte. If nByte is not less than zero, return the
** number of unicode characters in the first nByte of pZ (or up to
** the first 0x00, whichever comes first).
*/
SQLITE_PRIVATE int sqlite4Utf8CharLen(const char *zIn, int nByte){
int r = 0;
const u8 *z = (const u8*)zIn;
const u8 *zTerm;
if( nByte>=0 ){
zTerm = &z[nByte];
}else{
zTerm = (const u8*)(-1);
}
assert( z<=zTerm );
while( *z!=0 && z<zTerm ){
SQLITE_SKIP_UTF8(z);
r++;
}
return r;
}
/* This test function is not currently used by the automated test-suite.
** Hence it is only available in debug builds.
*/
#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
/*
** Translate UTF-8 to UTF-8.
**
** This has the effect of making sure that the string is well-formed
** UTF-8. Miscoded characters are removed.
**
** The translation is done in-place and aborted if the output
** overruns the input.
*/
SQLITE_PRIVATE int sqlite4Utf8To8(unsigned char *zIn){
unsigned char *zOut = zIn;
unsigned char *zStart = zIn;
u32 c;
while( zIn[0] && zOut<=zIn ){
c = sqlite4Utf8Read(zIn, (const u8**)&zIn);
if( c!=0xfffd ){
WRITE_UTF8(zOut, c);
}
}
*zOut = 0;
return (int)(zOut - zStart);
}
#endif
#ifndef SQLITE_OMIT_UTF16
/*
** Convert a UTF-16 string in the native encoding into a UTF-8 string.
** Memory to hold the UTF-8 string is obtained from sqlite4_malloc and must
** be freed by the calling function.
**
** NULL is returned if there is an allocation error.
*/
SQLITE_PRIVATE char *sqlite4Utf16to8(sqlite4 *db, const void *z, int nByte, u8 enc){
Mem m;
memset(&m, 0, sizeof(m));
m.db = db;
sqlite4VdbeMemSetStr(&m, z, nByte, enc, SQLITE_STATIC);
sqlite4VdbeChangeEncoding(&m, SQLITE_UTF8);
if( db->mallocFailed ){
sqlite4VdbeMemRelease(&m);
m.z = 0;
}
assert( (m.flags & MEM_Term)!=0 || db->mallocFailed );
assert( (m.flags & MEM_Str)!=0 || db->mallocFailed );
assert( (m.flags & MEM_Dyn)!=0 || db->mallocFailed );
assert( m.z || db->mallocFailed );
return m.z;
}
/*
** Convert a UTF-8 string to the UTF-16 encoding specified by parameter
** enc. A pointer to the new string is returned, and the value of *pnOut
** is set to the length of the returned string in bytes. The call should
** arrange to call sqlite4DbFree() on the returned pointer when it is
** no longer required.
**
** If a malloc failure occurs, NULL is returned and the db.mallocFailed
** flag set.
*/
#ifdef SQLITE_ENABLE_STAT3
SQLITE_PRIVATE char *sqlite4Utf8to16(sqlite4 *db, u8 enc, char *z, int n, int *pnOut){
Mem m;
memset(&m, 0, sizeof(m));
m.db = db;
sqlite4VdbeMemSetStr(&m, z, n, SQLITE_UTF8, SQLITE_STATIC);
if( sqlite4VdbeMemTranslate(&m, enc) ){
assert( db->mallocFailed );
return 0;
}
assert( m.z==m.zMalloc );
*pnOut = m.n;
return m.z;
}
#endif
/*
** zIn is a UTF-16 encoded unicode string at least nChar characters long.
** Return the number of bytes in the first nChar unicode characters
** in pZ. nChar must be non-negative.
*/
SQLITE_PRIVATE int sqlite4Utf16ByteLen(const void *zIn, int nChar){
int c;
unsigned char const *z = zIn;
int n = 0;
if( SQLITE_UTF16NATIVE==SQLITE_UTF16BE ){
while( n<nChar ){
READ_UTF16BE(z, 1, c);
n++;
}
}else{
while( n<nChar ){
READ_UTF16LE(z, 1, c);
n++;
}
}
return (int)(z-(unsigned char const *)zIn);
}
#if defined(SQLITE_TEST)
/*
** This routine is called from the TCL test function "translate_selftest".
** It checks that the primitives for serializing and deserializing
** characters in each encoding are inverses of each other.
*/
SQLITE_PRIVATE void sqlite4UtfSelfTest(void){
unsigned int i, t;
unsigned char zBuf[20];
unsigned char *z;
int n;
unsigned int c;
for(i=0; i<0x00110000; i++){
z = zBuf;
WRITE_UTF8(z, i);
n = (int)(z-zBuf);
assert( n>0 && n<=4 );
z[0] = 0;
z = zBuf;
c = sqlite4Utf8Read(z, (const u8**)&z);
t = i;
if( i>=0xD800 && i<=0xDFFF ) t = 0xFFFD;
if( (i&0xFFFFFFFE)==0xFFFE ) t = 0xFFFD;
assert( c==t );
assert( (z-zBuf)==n );
}
for(i=0; i<0x00110000; i++){
if( i>=0xD800 && i<0xE000 ) continue;
z = zBuf;
WRITE_UTF16LE(z, i);
n = (int)(z-zBuf);
assert( n>0 && n<=4 );
z[0] = 0;
z = zBuf;
READ_UTF16LE(z, 1, c);
assert( c==i );
assert( (z-zBuf)==n );
}
for(i=0; i<0x00110000; i++){
if( i>=0xD800 && i<0xE000 ) continue;
z = zBuf;
WRITE_UTF16BE(z, i);
n = (int)(z-zBuf);
assert( n>0 && n<=4 );
z[0] = 0;
z = zBuf;
READ_UTF16BE(z, 1, c);
assert( c==i );
assert( (z-zBuf)==n );
}
}
#endif /* SQLITE_TEST */
#endif /* SQLITE_OMIT_UTF16 */
/************** End of utf.c *************************************************/
/************** Begin file util.c ********************************************/
/*
** 2001 September 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.
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
*/
/* #include <stdarg.h> */
#ifdef SQLITE_HAVE_ISNAN
# include <math.h>
#endif
/*
** Routine needed to support the testcase() macro.
*/
#ifdef SQLITE_COVERAGE_TEST
SQLITE_PRIVATE void sqlite4Coverage(int x){
static unsigned dummy = 0;
dummy += (unsigned)x;
}
#endif
#ifndef SQLITE_OMIT_FLOATING_POINT
/*
** Return true if the floating point value is Not a Number (NaN).
**
** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN.
** Otherwise, we have our own implementation that works on most systems.
*/
SQLITE_PRIVATE int sqlite4IsNaN(double x){
int rc; /* The value return */
#if !defined(SQLITE_HAVE_ISNAN)
/*
** Systems that support the isnan() library function should probably
** make use of it by compiling with -DSQLITE_HAVE_ISNAN. But we have
** found that many systems do not have a working isnan() function so
** this implementation is provided as an alternative.
**
** This NaN test sometimes fails if compiled on GCC with -ffast-math.
** On the other hand, the use of -ffast-math comes with the following
** warning:
**
** This option [-ffast-math] should never be turned on by any
** -O option since it can result in incorrect output for programs
** which depend on an exact implementation of IEEE or ISO
** rules/specifications for math functions.
**
** Under MSVC, this NaN test may fail if compiled with a floating-
** point precision mode other than /fp:precise. From the MSDN
** documentation:
**
** The compiler [with /fp:precise] will properly handle comparisons
** involving NaN. For example, x != x evaluates to true if x is NaN
** ...
*/
#ifdef __FAST_MATH__
# error SQLite will not work correctly with the -ffast-math option of GCC.
#endif
volatile double y = x;
volatile double z = y;
rc = (y!=z);
#else /* if defined(SQLITE_HAVE_ISNAN) */
rc = isnan(x);
#endif /* SQLITE_HAVE_ISNAN */
testcase( rc );
return rc;
}
/*
** If r is not infinity, return 0. If it is negative infinity return negative.
** Return positive if r is positive infinity.
*/
SQLITE_PRIVATE int sqlite4IsInf(double r){
return isinf(r);
}
#endif /* SQLITE_OMIT_FLOATING_POINT */
/*
** 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.
*/
SQLITE_PRIVATE int sqlite4Strlen30(const char *z){
const char *z2 = z;
if( z==0 ) return 0;
while( *z2 ){ z2++; }
return 0x3fffffff & (int)(z2 - z);
}
/*
** Set the most recent error code and error string for the sqlite
** handle "db". The error code is set to "err_code".
**
** If it is not NULL, string zFormat specifies the format of the
** error string in the style of the printf functions: The following
** format characters are allowed:
**
** %s Insert a string
** %z A string that should be freed after use
** %d Insert an integer
** %T Insert a token
** %S Insert the first element of a SrcList
**
** zFormat and any string tokens that follow it are assumed to be
** encoded in UTF-8.
**
** To clear the most recent error for sqlite handle "db", sqlite4Error
** should be called with err_code set to SQLITE_OK and zFormat set
** to NULL.
*/
SQLITE_PRIVATE void sqlite4Error(sqlite4 *db, int err_code, const char *zFormat, ...){
if( db && (db->pErr || (db->pErr = sqlite4ValueNew(db))!=0) ){
db->errCode = err_code;
if( zFormat ){
char *z;
va_list ap;
va_start(ap, zFormat);
z = sqlite4VMPrintf(db, zFormat, ap);
va_end(ap);
sqlite4ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, SQLITE_DYNAMIC);
}else{
sqlite4ValueSetStr(db->pErr, 0, 0, SQLITE_UTF8, SQLITE_STATIC);
}
}
}
/*
** Add an error message to pParse->zErrMsg and increment pParse->nErr.
** The following formatting characters are allowed:
**
** %s Insert a string
** %z A string that should be freed after use
** %d Insert an integer
** %T Insert a token
** %S Insert the first element of a SrcList
**
** This function should be used to report any error that occurs whilst
** compiling an SQL statement (i.e. within sqlite4_prepare()). The
** last thing the sqlite4_prepare() function does is copy the error
** stored by this function into the database handle using sqlite4Error().
** Function sqlite4Error() should be used during statement execution
** (sqlite4_step() etc.).
*/
SQLITE_PRIVATE void sqlite4ErrorMsg(Parse *pParse, const char *zFormat, ...){
char *zMsg;
va_list ap;
sqlite4 *db = pParse->db;
va_start(ap, zFormat);
zMsg = sqlite4VMPrintf(db, zFormat, ap);
va_end(ap);
if( db->suppressErr ){
sqlite4DbFree(db, zMsg);
}else{
pParse->nErr++;
sqlite4DbFree(db, pParse->zErrMsg);
pParse->zErrMsg = zMsg;
pParse->rc = SQLITE_ERROR;
}
}
/*
** 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.
**
** The input string must be zero-terminated. A new zero-terminator
** is added to the dequoted string.
**
** The return value is -1 if no dequoting occurs or the length of the
** dequoted string, exclusive of the zero terminator, if dequoting does
** occur.
**
** 2002-Feb-14: This routine is extended to remove MS-Access style
** brackets from around identifers. For example: "[a-b-c]" becomes
** "a-b-c".
*/
SQLITE_PRIVATE int sqlite4Dequote(char *z){
char quote;
int i, j;
if( z==0 ) return -1;
quote = z[0];
switch( quote ){
case '\'': break;
case '"': break;
case '`': break; /* For MySQL compatibility */
case '[': quote = ']'; break; /* For MS SqlServer compatibility */
default: return -1;
}
for(i=1, j=0; ALWAYS(z[i]); i++){
if( z[i]==quote ){
if( z[i+1]==quote ){
z[j++] = quote;
i++;
}else{
break;
}
}else{
z[j++] = z[i];
}
}
z[j] = 0;
return j;
}
/* Convenient short-hand */
#define UpperToLower sqlite4UpperToLower
/*
** Some systems have stricmp(). Others have strcasecmp(). Because
** there is no consistency, we will define our own.
**
** IMPLEMENTATION-OF: R-20522-24639 The sqlite4_strnicmp() API allows
** applications and extensions to compare the contents of two buffers
** containing UTF-8 strings in a case-independent fashion, using the same
** definition of case independence that SQLite uses internally when
** comparing identifiers.
*/
SQLITE_PRIVATE int sqlite4StrICmp(const char *zLeft, const char *zRight){
register unsigned char *a, *b;
a = (unsigned char *)zLeft;
b = (unsigned char *)zRight;
while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
return UpperToLower[*a] - UpperToLower[*b];
}
SQLITE_API int sqlite4_strnicmp(const char *zLeft, const char *zRight, int N){
register unsigned char *a, *b;
a = (unsigned char *)zLeft;
b = (unsigned char *)zRight;
while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b];
}
/*
** The string z[] is an text representation of a real number.
** Convert this string to a double and write it into *pResult.
**
** The string z[] is length bytes in length (bytes, not characters) and
** uses the encoding enc. The string is not necessarily zero-terminated.
**
** Return TRUE if the result is a valid real number (or integer) and FALSE
** if the string is empty or contains extraneous text. Valid numbers
** are in one of these formats:
**
** [+-]digits[E[+-]digits]
** [+-]digits.[digits][E[+-]digits]
** [+-].digits[E[+-]digits]
**
** Leading and trailing whitespace is ignored for the purpose of determining
** validity.
**
** If some prefix of the input string is a valid number, this routine
** returns FALSE but it still converts the prefix and writes the result
** into *pResult.
*/
SQLITE_PRIVATE int sqlite4AtoF(const char *z, double *pResult, int length, u8 enc){
#ifndef SQLITE_OMIT_FLOATING_POINT
int incr = (enc==SQLITE_UTF8?1:2);
const char *zEnd = z + length;
/* sign * significand * (10 ^ (esign * exponent)) */
int sign = 1; /* sign of significand */
i64 s = 0; /* significand */
int d = 0; /* adjust exponent for shifting decimal point */
int esign = 1; /* sign of exponent */
int e = 0; /* exponent */
int eValid = 1; /* True exponent is either not used or is well-formed */
double result;
int nDigits = 0;
*pResult = 0.0; /* Default return value, in case of an error */
if( enc==SQLITE_UTF16BE ) z++;
/* skip leading spaces */
while( z<zEnd && sqlite4Isspace(*z) ) z+=incr;
if( z>=zEnd ) return 0;
/* get sign of significand */
if( *z=='-' ){
sign = -1;
z+=incr;
}else if( *z=='+' ){
z+=incr;
}
/* skip leading zeroes */
while( z<zEnd && z[0]=='0' ) z+=incr, nDigits++;
/* copy max significant digits to significand */
while( z<zEnd && sqlite4Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
s = s*10 + (*z - '0');
z+=incr, nDigits++;
}
/* skip non-significant significand digits
** (increase exponent by d to shift decimal left) */
while( z<zEnd && sqlite4Isdigit(*z) ) z+=incr, nDigits++, d++;
if( z>=zEnd ) goto do_atof_calc;
/* if decimal point is present */
if( *z=='.' ){
z+=incr;
/* copy digits from after decimal to significand
** (decrease exponent by d to shift decimal right) */
while( z<zEnd && sqlite4Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
s = s*10 + (*z - '0');
z+=incr, nDigits++, d--;
}
/* skip non-significant digits */
while( z<zEnd && sqlite4Isdigit(*z) ) z+=incr, nDigits++;
}
if( z>=zEnd ) goto do_atof_calc;
/* if exponent is present */
if( *z=='e' || *z=='E' ){
z+=incr;
eValid = 0;
if( z>=zEnd ) goto do_atof_calc;
/* get sign of exponent */
if( *z=='-' ){
esign = -1;
z+=incr;
}else if( *z=='+' ){
z+=incr;
}
/* copy digits to exponent */
while( z<zEnd && sqlite4Isdigit(*z) ){
e = e<10000 ? (e*10 + (*z - '0')) : 10000;
z+=incr;
eValid = 1;
}
}
/* skip trailing spaces */
if( nDigits && eValid ){
while( z<zEnd && sqlite4Isspace(*z) ) z+=incr;
}
do_atof_calc:
/* adjust exponent by d, and update sign */
e = (e*esign) + d;
if( e<0 ) {
esign = -1;
e *= -1;
} else {
esign = 1;
}
/* if 0 significand */
if( !s ) {
/* In the IEEE 754 standard, zero is signed.
** Add the sign if we've seen at least one digit */
result = (sign<0 && nDigits) ? -(double)0 : (double)0;
} else {
/* attempt to reduce exponent */
if( esign>0 ){
while( s<(LARGEST_INT64/10) && e>0 ) e--,s*=10;
}else{
while( !(s%10) && e>0 ) e--,s/=10;
}
/* adjust the sign of significand */
s = sign<0 ? -s : s;
/* if exponent, scale significand as appropriate
** and store in result. */
if( e ){
double scale = 1.0;
/* attempt to handle extremely small/large numbers better */
if( e>307 && e<342 ){
while( e%308 ) { scale *= 1.0e+1; e -= 1; }
if( esign<0 ){
result = s / scale;
result /= 1.0e+308;
}else{
result = s * scale;
result *= 1.0e+308;
}
}else if( e>=342 ){
if( esign<0 ){
result = 0.0*s;
}else{
result = 1e308*1e308*s; /* Infinity */
}
}else{
/* 1.0e+22 is the largest power of 10 than can be
** represented exactly. */
while( e%22 ) { scale *= 1.0e+1; e -= 1; }
while( e>0 ) { scale *= 1.0e+22; e -= 22; }
if( esign<0 ){
result = s / scale;
}else{
result = s * scale;
}
}
} else {
result = (double)s;
}
}
/* store the result */
*pResult = result;
/* return true if number and no extra non-whitespace chracters after */
return z>=zEnd && nDigits>0 && eValid;
#else
return !sqlite4Atoi64(z, pResult, length, enc);
#endif /* SQLITE_OMIT_FLOATING_POINT */
}
/*
** Compare the 19-character string zNum against the text representation
** value 2^63: 9223372036854775808. Return negative, zero, or positive
** if zNum is less than, equal to, or greater than the string.
** Note that zNum must contain exactly 19 characters.
**
** Unlike memcmp() this routine is guaranteed to return the difference
** in the values of the last digit if the only difference is in the
** last digit. So, for example,
**
** compare2pow63("9223372036854775800", 1)
**
** will return -8.
*/
static int compare2pow63(const char *zNum, int incr){
int c = 0;
int i;
/* 012345678901234567 */
const char *pow63 = "922337203685477580";
for(i=0; c==0 && i<18; i++){
c = (zNum[i*incr]-pow63[i])*10;
}
if( c==0 ){
c = zNum[18*incr] - '8';
testcase( c==(-1) );
testcase( c==0 );
testcase( c==(+1) );
}
return c;
}
/*
** Convert zNum to a 64-bit signed integer.
**
** If the zNum value is representable as a 64-bit twos-complement
** integer, then write that value into *pNum and return 0.
**
** If zNum is exactly 9223372036854665808, return 2. This special
** case is broken out because while 9223372036854665808 cannot be a
** signed 64-bit integer, its negative -9223372036854665808 can be.
**
** If zNum is too big for a 64-bit integer and is not
** 9223372036854665808 then return 1.
**
** length is the number of bytes in the string (bytes, not characters).
** The string is not necessarily zero-terminated. The encoding is
** given by enc.
*/
SQLITE_PRIVATE int sqlite4Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
int incr = (enc==SQLITE_UTF8?1:2);
u64 u = 0;
int neg = 0; /* assume positive */
int i;
int c = 0;
const char *zStart;
const char *zEnd = zNum + length;
if( enc==SQLITE_UTF16BE ) zNum++;
while( zNum<zEnd && sqlite4Isspace(*zNum) ) zNum+=incr;
if( zNum<zEnd ){
if( *zNum=='-' ){
neg = 1;
zNum+=incr;
}else if( *zNum=='+' ){
zNum+=incr;
}
}
zStart = zNum;
while( zNum<zEnd && zNum[0]=='0' ){ zNum+=incr; } /* Skip leading zeros. */
for(i=0; &zNum[i]<zEnd && (c=zNum[i])>='0' && c<='9'; i+=incr){
u = u*10 + c - '0';
}
if( u>LARGEST_INT64 ){
*pNum = SMALLEST_INT64;
}else if( neg ){
*pNum = -(i64)u;
}else{
*pNum = (i64)u;
}
testcase( i==18 );
testcase( i==19 );
testcase( i==20 );
if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum) || i>19*incr ){
/* zNum is empty or contains non-numeric text or is longer
** than 19 digits (thus guaranteeing that it is too large) */
return 1;
}else if( i<19*incr ){
/* Less than 19 digits, so we know that it fits in 64 bits */
assert( u<=LARGEST_INT64 );
return 0;
}else{
/* zNum is a 19-digit numbers. Compare it against 9223372036854775808. */
c = compare2pow63(zNum, incr);
if( c<0 ){
/* zNum is less than 9223372036854775808 so it fits */
assert( u<=LARGEST_INT64 );
return 0;
}else if( c>0 ){
/* zNum is greater than 9223372036854775808 so it overflows */
return 1;
}else{
/* zNum is exactly 9223372036854775808. Fits if negative. The
** special case 2 overflow if positive */
assert( u-1==LARGEST_INT64 );
assert( (*pNum)==SMALLEST_INT64 );
return neg ? 0 : 2;
}
}
}
/*
** If zNum represents an integer that will fit in 32-bits, then set
** *pValue to that integer and return true. Otherwise return false.
**
** Any non-numeric characters that following zNum are ignored.
** This is different from sqlite4Atoi64() which requires the
** input number to be zero-terminated.
*/
SQLITE_PRIVATE int sqlite4GetInt32(const char *zNum, int *pValue){
sqlite_int64 v = 0;
int i, c;
int neg = 0;
if( zNum[0]=='-' ){
neg = 1;
zNum++;
}else if( zNum[0]=='+' ){
zNum++;
}
while( zNum[0]=='0' ) zNum++;
for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){
v = v*10 + c;
}
/* The longest decimal representation of a 32 bit integer is 10 digits:
**
** 1234567890
** 2^31 -> 2147483648
*/
testcase( i==10 );
if( i>10 ){
return 0;
}
testcase( v-neg==2147483647 );
if( v-neg>2147483647 ){
return 0;
}
if( neg ){
v = -v;
}
*pValue = (int)v;
return 1;
}
/*
** Return a 32-bit integer value extracted from a string. If the
** string is not an integer, just return 0.
*/
SQLITE_PRIVATE int sqlite4Atoi(const char *z){
int x = 0;
if( z ) sqlite4GetInt32(z, &x);
return x;
}
/*
** 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
*/
/*
** 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.
*/
SQLITE_PRIVATE int sqlite4PutVarint(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;
}
/*
** This routine is a faster version of sqlite4PutVarint() that only
** works for 32-bit positive integers and which is optimized for
** the common case of small integers. A MACRO version, putVarint32,
** is provided which inlines the single-byte case. All code should use
** the MACRO version as this function assumes the single-byte case has
** already been handled.
*/
SQLITE_PRIVATE int sqlite4PutVarint32(unsigned char *p, u32 v){
#ifndef putVarint32
if( (v & ~0x7f)==0 ){
p[0] = v;
return 1;
}
#endif
if( (v & ~0x3fff)==0 ){
p[0] = (u8)((v>>7) | 0x80);
p[1] = (u8)(v & 0x7f);
return 2;
}
return sqlite4PutVarint(p, v);
}
/*
** Bitmasks used by sqlite4GetVarint(). 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.
*/
SQLITE_PRIVATE u8 sqlite4GetVarint(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;
}
/*
** Read a 32-bit variable-length integer from memory starting at p[0].
** Return the number of bytes read. The value is stored in *v.
**
** If the varint stored in p[0] is larger than can fit in a 32-bit unsigned
** integer, then set *v to 0xffffffff.
**
** A MACRO version, getVarint32, is provided which inlines the
** single-byte case. All code should use the MACRO version as
** this function assumes the single-byte case has already been handled.
*/
SQLITE_PRIVATE u8 sqlite4GetVarint32(const unsigned char *p, u32 *v){
u32 a,b;
/* The 1-byte case. Overwhelmingly the most common. Handled inline
** by the getVarin32() macro */
a = *p;
/* a: p0 (unmasked) */
#ifndef getVarint32
if (!(a&0x80))
{
/* Values between 0 and 127 */
*v = a;
return 1;
}
#endif
/* 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.
*/
#if 1
{
u64 v64;
u8 n;
p -= 2;
n = sqlite4GetVarint(p, &v64);
assert( n>3 && n<=9 );
if( (v64 & SQLITE_MAX_U32)!=v64 ){
*v = 0xffffffff;
}else{
*v = (u32)v64;
}
return n;
}
#else
/* For following code (kept for historical record only) shows an
** unrolling for the 3- and 4-byte varint cases. This code is
** slightly faster, but it is also larger and much harder to test.
*/
p++;
b = b<<14;
b |= *p;
/* b: p1<<14 | p3 (unmasked) */
if (!(b&0x80))
{
/* Values between 2097152 and 268435455 */
b &= (0x7f<<14)|(0x7f);
a &= (0x7f<<14)|(0x7f);
a = a<<7;
*v = a | b;
return 4;
}
p++;
a = a<<14;
a |= *p;
/* a: p0<<28 | p2<<14 | p4 (unmasked) */
if (!(a&0x80))
{
/* Values between 268435456 and 34359738367 */
a &= SLOT_4_2_0;
b &= SLOT_4_2_0;
b = b<<7;
*v = a | b;
return 5;
}
/* We can only reach this point when reading a corrupt database
** file. In that case we are not in any hurry. Use the (relatively
** slow) general-purpose sqlite4GetVarint() routine to extract the
** value. */
{
u64 v64;
u8 n;
p -= 4;
n = sqlite4GetVarint(p, &v64);
assert( n>5 && n<=9 );
*v = (u32)v64;
return n;
}
#endif
}
/*
** Return the number of bytes that will be needed to store the given
** 64-bit integer.
*/
SQLITE_PRIVATE int sqlite4VarintLen(u64 v){
int i = 0;
do{
i++;
v >>= 7;
}while( v!=0 && ALWAYS(i<9) );
return i;
}
/*
** Read or write a four-byte big-endian integer value.
*/
SQLITE_PRIVATE u32 sqlite4Get4byte(const u8 *p){
return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
}
SQLITE_PRIVATE void sqlite4Put4byte(unsigned char *p, u32 v){
p[0] = (u8)(v>>24);
p[1] = (u8)(v>>16);
p[2] = (u8)(v>>8);
p[3] = (u8)v;
}
/*
** Translate a single byte of Hex into an integer.
** This routine only works if h really is a valid hexadecimal
** character: 0..9a..fA..F
*/
SQLITE_PRIVATE u8 sqlite4HexToInt(int h){
assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') );
#ifdef SQLITE_ASCII
h += 9*(1&(h>>6));
#endif
#ifdef SQLITE_EBCDIC
h += 9*(1&~(h>>4));
#endif
return (u8)(h & 0xf);
}
#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC)
/*
** Convert a BLOB literal of the form "x'hhhhhh'" into its binary
** value. Return a pointer to its binary value. Space to hold the
** binary value has been obtained from malloc and must be freed by
** the calling routine.
*/
SQLITE_PRIVATE void *sqlite4HexToBlob(sqlite4 *db, const char *z, int n){
char *zBlob;
int i;
zBlob = (char *)sqlite4DbMallocRaw(db, n/2 + 1);
n--;
if( zBlob ){
for(i=0; i<n; i+=2){
zBlob[i/2] = (sqlite4HexToInt(z[i])<<4) | sqlite4HexToInt(z[i+1]);
}
zBlob[i/2] = 0;
}
return zBlob;
}
#endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC */
/*
** Log an error that is an API call on a connection pointer that should
** not have been used. The "type" of connection pointer is given as the
** argument. The zType is a word like "NULL" or "closed" or "invalid".
*/
static void logBadConnection(const char *zType){
sqlite4_log(0, SQLITE_MISUSE,
"API call with %s database connection pointer",
zType
);
}
/*
** Check to make sure we have a valid db pointer. This test is not
** foolproof but it does provide some measure of protection against
** misuse of the interface such as passing in db pointers that are
** NULL or which have been previously closed. If this routine returns
** 1 it means that the db pointer is valid and 0 if it should not be
** dereferenced for any reason. The calling function should invoke
** SQLITE_MISUSE immediately.
**
** sqlite4SafetyCheckOk() requires that the db pointer be valid for
** use. sqlite4SafetyCheckSickOrOk() allows a db pointer that failed to
** open properly and is not fit for general use but which can be
** used as an argument to sqlite4_errmsg() or sqlite4_close().
*/
SQLITE_PRIVATE int sqlite4SafetyCheckOk(sqlite4 *db){
u32 magic;
if( db==0 ){
logBadConnection("NULL");
return 0;
}
magic = db->magic;
if( magic!=SQLITE_MAGIC_OPEN ){
if( sqlite4SafetyCheckSickOrOk(db) ){
testcase( sqlite4DefaultEnv.xLog!=0 );
logBadConnection("unopened");
}
return 0;
}else{
return 1;
}
}
SQLITE_PRIVATE int sqlite4SafetyCheckSickOrOk(sqlite4 *db){
u32 magic;
magic = db->magic;
if( magic!=SQLITE_MAGIC_SICK &&
magic!=SQLITE_MAGIC_OPEN &&
magic!=SQLITE_MAGIC_BUSY ){
testcase( sqlite4DefaultEnv.xLog!=0 );
logBadConnection("invalid");
return 0;
}else{
return 1;
}
}
/*
** Attempt to add, substract, or multiply the 64-bit signed value iB against
** the other 64-bit signed integer at *pA and store the result in *pA.
** Return 0 on success. Or if the operation would have resulted in an
** overflow, leave *pA unchanged and return 1.
*/
SQLITE_PRIVATE int sqlite4AddInt64(i64 *pA, i64 iB){
i64 iA = *pA;
testcase( iA==0 ); testcase( iA==1 );
testcase( iB==-1 ); testcase( iB==0 );
if( iB>=0 ){
testcase( iA>0 && LARGEST_INT64 - iA == iB );
testcase( iA>0 && LARGEST_INT64 - iA == iB - 1 );
if( iA>0 && LARGEST_INT64 - iA < iB ) return 1;
*pA += iB;
}else{
testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 1 );
testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 2 );
if( iA<0 && -(iA + LARGEST_INT64) > iB + 1 ) return 1;
*pA += iB;
}
return 0;
}
SQLITE_PRIVATE int sqlite4SubInt64(i64 *pA, i64 iB){
testcase( iB==SMALLEST_INT64+1 );
if( iB==SMALLEST_INT64 ){
testcase( (*pA)==(-1) ); testcase( (*pA)==0 );
if( (*pA)>=0 ) return 1;
*pA -= iB;
return 0;
}else{
return sqlite4AddInt64(pA, -iB);
}
}
#define TWOPOWER32 (((i64)1)<<32)
#define TWOPOWER31 (((i64)1)<<31)
SQLITE_PRIVATE int sqlite4MulInt64(i64 *pA, i64 iB){
i64 iA = *pA;
i64 iA1, iA0, iB1, iB0, r;
iA1 = iA/TWOPOWER32;
iA0 = iA % TWOPOWER32;
iB1 = iB/TWOPOWER32;
iB0 = iB % TWOPOWER32;
if( iA1*iB1 != 0 ) return 1;
assert( iA1*iB0==0 || iA0*iB1==0 );
r = iA1*iB0 + iA0*iB1;
testcase( r==(-TWOPOWER31)-1 );
testcase( r==(-TWOPOWER31) );
testcase( r==TWOPOWER31 );
testcase( r==TWOPOWER31-1 );
if( r<(-TWOPOWER31) || r>=TWOPOWER31 ) return 1;
r *= TWOPOWER32;
if( sqlite4AddInt64(&r, iA0*iB0) ) return 1;
*pA = r;
return 0;
}
/*
** Compute the absolute value of a 32-bit signed integer, of possible. Or
** if the integer has a value of -2147483648, return +2147483647
*/
SQLITE_PRIVATE int sqlite4AbsInt32(int x){
if( x>=0 ) return x;
if( x==(int)0x80000000 ) return 0x7fffffff;
return -x;
}
#ifdef SQLITE_ENABLE_8_3_NAMES
/*
** If SQLITE_ENABLE_8_3_NAMES is set at compile-time and if the database
** filename in zBaseFilename is a URI with the "8_3_names=1" parameter and
** if filename in z[] has a suffix (a.k.a. "extension") that is longer than
** three characters, then shorten the suffix on z[] to be the last three
** characters of the original suffix.
**
** If SQLITE_ENABLE_8_3_NAMES is set to 2 at compile-time, then always
** do the suffix shortening regardless of URI parameter.
**
** Examples:
**
** test.db-journal => test.nal
** test.db-wal => test.wal
** test.db-shm => test.shm
** test.db-mj7f3319fa => test.9fa
*/
SQLITE_PRIVATE void sqlite4FileSuffix3(const char *zBaseFilename, char *z){
#if SQLITE_ENABLE_8_3_NAMES<2
if( sqlite4_uri_boolean(zBaseFilename, "8_3_names", 0) )
#endif
{
int i, sz;
sz = sqlite4Strlen30(z);
for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){}
if( z[i]=='.' && ALWAYS(sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4);
}
}
#endif
/************** End of util.c ************************************************/
/************** Begin file varint.c ******************************************/
/*
** 2012 January 17
**
** The authors renounce all claim of copyright to this code and dedicate
** this code to the public domain. In place of 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 routines used to encode or decode variable-length
** integers.
**
** A variable length integer is an encoding of 64-bit unsigned integers
** into between 1 and 9 bytes. The encoding is designed so that small
** (and common) values take much less space that larger values. Additional
** properties:
**
** * The length of the varint can be determined after examining just
** the first byte of the encoding.
**
** * Varints compare in numerical order using memcmp().
**
**************************************************************************
**
** Treat each byte of the encoding as an unsigned integer between 0 and 255.
** Let the bytes of the encoding be called A0, A1, A2, ..., A8.
**
** DECODE
**
** If A0 is between 0 and 240 inclusive, then the result is the value of A0.
**
** If A0 is between 241 and 248 inclusive, then the result is
** 240+256*(A0-241)+A1.
**
** If A0 is 249 then the result is 2288+256*A1+A2.
**
** If A0 is 250 then the result is A1..A3 as a 3-byte big-ending integer.
**
** If A0 is 251 then the result is A1..A4 as a 4-byte big-ending integer.
**
** If A0 is 252 then the result is A1..A5 as a 5-byte big-ending integer.
**
** If A0 is 253 then the result is A1..A6 as a 6-byte big-ending integer.
**
** If A0 is 254 then the result is A1..A7 as a 7-byte big-ending integer.
**
** If A0 is 255 then the result is A1..A8 as a 8-byte big-ending integer.
**
** ENCODE
**
** Let the input value be V.
**
** If V<=240 then output a single by A0 equal to V.
**
** If V<=2287 then output A0 as (V-240)/256 + 241 and A1 as (V-240)%256.
**
** If V<=67823 then output A0 as 249, A1 as (V-2288)/256, and A2
** as (V-2288)%256.
**
** If V<=16777215 then output A0 as 250 and A1 through A3 as a big-endian
** 3-byte integer.
**
** If V<=4294967295 then output A0 as 251 and A1..A4 as a big-ending
** 4-byte integer.
**
** If V<=1099511627775 then output A0 as 252 and A1..A5 as a big-ending
** 5-byte integer.
**
** If V<=281474976710655 then output A0 as 253 and A1..A6 as a big-ending
** 6-byte integer.
**
** If V<=72057594037927935 then output A0 as 254 and A1..A7 as a
** big-ending 7-byte integer.
**
** Otherwise then output A0 as 255 and A1..A8 as a big-ending 8-byte integer.
**
** SUMMARY
**
** Bytes Max Value Digits
** ------- --------- ---------
** 1 240 2.3
** 2 2287 3.3
** 3 67823 4.8
** 4 2**24-1 7.2
** 5 2**32-1 9.6
** 6 2**40-1 12.0
** 7 2**48-1 14.4
** 8 2**56-1 16.8
** 9 2**64-1 19.2
**
*/
/*
** Decode the varint in the first n bytes z[]. Write the integer value
** into *pResult and return the number of bytes in the varint.
**
** If the decode fails because there are not enough bytes in z[] then
** return 0;
*/
SQLITE_PRIVATE int sqlite4GetVarint64(
const unsigned char *z,
int n,
sqlite4_uint64 *pResult
){
unsigned int x;
if( n<1 ) return 0;
if( z[0]<=240 ){
*pResult = z[0];
return 1;
}
if( z[0]<=248 ){
if( n<2 ) return 0;
*pResult = (z[0]-241)*256 + z[1] + 240;
return 2;
}
if( n<z[0]-246 ) return 0;
if( z[0]==249 ){
*pResult = 2288 + 256*z[1] + z[2];
return 3;
}
if( z[0]==250 ){
*pResult = (z[1]<<16) + (z[2]<<8) + z[3];
return 4;
}
x = (z[1]<<24) + (z[2]<<16) + (z[3]<<8) + z[4];
if( z[0]==251 ){
*pResult = x;
return 5;
}
if( z[0]==252 ){
*pResult = (((sqlite4_uint64)x)<<8) + z[5];
return 6;
}
if( z[0]==253 ){
*pResult = (((sqlite4_uint64)x)<<16) + (z[5]<<8) + z[6];
return 7;
}
if( z[0]==254 ){
*pResult = (((sqlite4_uint64)x)<<24) + (z[5]<<16) + (z[6]<<8) + z[7];
return 8;
}
*pResult = (((sqlite4_uint64)x)<<32) +
(0xffffffff & ((z[5]<<24) + (z[6]<<16) + (z[7]<<8) + z[8]));
return 9;
}
/*
** Write a 32-bit unsigned integer as 4 big-endian bytes.
*/
static void varintWrite32(unsigned char *z, unsigned int y){
z[0] = (unsigned char)(y>>24);
z[1] = (unsigned char)(y>>16);
z[2] = (unsigned char)(y>>8);
z[3] = (unsigned char)(y);
}
/*
** Write a varint into z[]. The buffer z[] must be at least 9 characters
** long to accommodate the largest possible varint. Return the number of
** bytes of z[] used.
*/
SQLITE_PRIVATE int sqlite4PutVarint64(unsigned char *z, sqlite4_uint64 x){
unsigned int w, y;
if( x<=240 ){
z[0] = (unsigned char)x;
return 1;
}
if( x<=2287 ){
y = (unsigned int)(x - 240);
z[0] = (unsigned char)(y/256 + 241);
z[1] = (unsigned char)(y%256);
return 2;
}
if( x<=67823 ){
y = (unsigned int)(x - 2288);
z[0] = 249;
z[1] = (unsigned char)(y/256);
z[2] = (unsigned char)(y%256);
return 3;
}
y = (unsigned int)x;
w = (unsigned int)(x>>32);
if( w==0 ){
if( y<=16777215 ){
z[0] = 250;
z[1] = (unsigned char)(y>>16);
z[2] = (unsigned char)(y>>8);
z[3] = (unsigned char)(y);
return 4;
}
z[0] = 251;
varintWrite32(z+1, y);
return 5;
}
if( w<=255 ){
z[0] = 252;
z[1] = (unsigned char)w;
varintWrite32(z+2, y);
return 6;
}
if( w<=32767 ){
z[0] = 253;
z[1] = (unsigned char)(w>>8);
z[2] = (unsigned char)w;
varintWrite32(z+3, y);
return 7;
}
if( w<=16777215 ){
z[0] = 254;
z[1] = (unsigned char)(w>>16);
z[2] = (unsigned char)(w>>8);
z[3] = (unsigned char)w;
varintWrite32(z+4, y);
return 8;
}
z[0] = 255;
varintWrite32(z+1, w);
varintWrite32(z+5, y);
return 9;
}
/*
** Compile this one file with the -DTEST_VARINT option to run the simple
** test case below. The test program generates 10 million random 64-bit
** values, weighted toward smaller numbers, and for each value it encodes
** and then decodes the varint to verify that the same number comes back.
** It also checks to make sure the if x<y then memcmp(varint(x),varint(y))<0.
*/
#ifdef TEST_VARINT
static unsigned int randInt(void){
static unsigned int rx = 1;
static unsigned int ry = 0;
rx = (rx>>1) ^ (-(rx&1) & 0xd0000001);
ry = ry*1103515245 + 12345;
return rx ^ ry;
}
int main(int argc,char **argv){
sqlite4_uint64 x, y, px;
int i, n1, n2, pn;
int nbit;
unsigned char z[20], zp[20];
for(i=0; i<10000000; i++){
x = randInt();
x = (x<<32) + randInt();
nbit = randInt()%65;
if( nbit<64 ){
x &= (((sqlite4_uint64)1)<<nbit)-1;
}
n1 = sqlite4PutVarint64(z, x);
assert( n1>=1 && n1<=9 );
n2 = sqlite4GetVarint64(z, n1, &y);
assert( n1==n2 );
assert( x==y );
n2 = sqlite4GetVarint64(z, n1-1, &y);
assert( n2==0 );
if( i>0 ){
int c = memcmp(z,zp,pn<n1?pn:n1);
if( x<px ){
assert( c<0 );
}else if( x>px ){
assert( c>0 );
}else{
assert( c==0 );
}
}
memcpy(zp, z, n1);
pn = n1;
px = x;
/* printf("%24lld 0x%016llx n=%d ok\n",
(long long int)x, (long long int)x, n1); */
}
printf("%d tests with 0 errors\n", i);
return 0;
}
#endif
/*
** Compile this one file with -DVARINT_TOOL to generate a command-line
** program that converts the integers it finds as arguments into varints
** and then displays the hexadecimal representation of the varint.
*/
#ifdef VARINT_TOOL
int main(int argc, char **argv){
int i, j, n;
sqlite4_uint64 x;
char out[20];
for(i=1; i<argc; i++){
const char *z = argv[i];
x = 0;
while( z[0]>='0' && z[0]<='9' ){
x = x*10 + z[0] - '0';
z++;
}
n = sqlite4PutVarint64(out, x);
printf("%llu = ", (long long unsigned)x);
for(j=0; j<n; j++) printf("%02x", out[j]&0xff);
printf("\n");
}
return 0;
}
#endif
/************** End of varint.c **********************************************/
/************** Begin file hash.c ********************************************/
/*
** 2001 September 22
**
** 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 the implementation of generic hash-tables
** used in SQLite.
*/
/* #include <assert.h> */
/* Turn bulk memory into a hash table object by initializing the
** fields of the Hash structure.
**
** "pNew" is a pointer to the hash table that is to be initialized.
*/
SQLITE_PRIVATE void sqlite4HashInit(sqlite4_env *pEnv, Hash *pNew){
assert( pNew!=0 );
pNew->first = 0;
pNew->count = 0;
pNew->htsize = 0;
pNew->ht = 0;
pNew->pEnv = pEnv;
}
/* Remove all entries from a hash table. Reclaim all memory.
** Call this routine to delete a hash table or to reset a hash table
** to the empty state.
*/
SQLITE_PRIVATE void sqlite4HashClear(Hash *pH){
HashElem *elem; /* For looping over all elements of the table */
assert( pH!=0 );
elem = pH->first;
pH->first = 0;
sqlite4_free(pH->pEnv, pH->ht);
pH->ht = 0;
pH->htsize = 0;
while( elem ){
HashElem *next_elem = elem->next;
sqlite4_free(pH->pEnv, elem);
elem = next_elem;
}
pH->count = 0;
}
/*
** The hashing function.
*/
static unsigned int strHash(const char *z, int nKey){
int h = 0;
assert( nKey>=0 );
while( nKey > 0 ){
h = (h<<3) ^ h ^ sqlite4UpperToLower[(unsigned char)*z++];
nKey--;
}
return h;
}
/* Link pNew element into the hash table pH. If pEntry!=0 then also
** insert pNew into the pEntry hash bucket.
*/
static void insertElement(
Hash *pH, /* The complete hash table */
struct _ht *pEntry, /* The entry into which pNew is inserted */
HashElem *pNew /* The element to be inserted */
){
HashElem *pHead; /* First element already in pEntry */
if( pEntry ){
pHead = pEntry->count ? pEntry->chain : 0;
pEntry->count++;
pEntry->chain = pNew;
}else{
pHead = 0;
}
if( pHead ){
pNew->next = pHead;
pNew->prev = pHead->prev;
if( pHead->prev ){ pHead->prev->next = pNew; }
else { pH->first = pNew; }
pHead->prev = pNew;
}else{
pNew->next = pH->first;
if( pH->first ){ pH->first->prev = pNew; }
pNew->prev = 0;
pH->first = pNew;
}
}
/* Resize the hash table so that it cantains "new_size" buckets.
**
** The hash table might fail to resize if sqlite4_malloc() fails or
** if the new size is the same as the prior size.
** Return TRUE if the resize occurs and false if not.
*/
static int rehash(Hash *pH, unsigned int new_size){
struct _ht *new_ht; /* The new hash table */
HashElem *elem, *next_elem; /* For looping over existing elements */
#if SQLITE_MALLOC_SOFT_LIMIT>0
if( new_size*sizeof(struct _ht)>SQLITE_MALLOC_SOFT_LIMIT ){
new_size = SQLITE_MALLOC_SOFT_LIMIT/sizeof(struct _ht);
}
if( new_size==pH->htsize ) return 0;
#endif
/* The inability to allocates space for a larger hash table is
** a performance hit but it is not a fatal error. So mark the
** allocation as a benign.
*/
sqlite4BeginBenignMalloc(pH->pEnv);
new_ht = (struct _ht *)sqlite4Malloc(pH->pEnv, new_size*sizeof(struct _ht) );
sqlite4EndBenignMalloc(pH->pEnv);
if( new_ht==0 ) return 0;
sqlite4_free(pH->pEnv, pH->ht);
pH->ht = new_ht;
pH->htsize = new_size = sqlite4MallocSize(pH->pEnv, new_ht)/sizeof(struct _ht);
memset(new_ht, 0, new_size*sizeof(struct _ht));
for(elem=pH->first, pH->first=0; elem; elem = next_elem){
unsigned int h = strHash(elem->pKey, elem->nKey) % new_size;
next_elem = elem->next;
insertElement(pH, &new_ht[h], elem);
}
return 1;
}
/* This function (for internal use only) locates an element in an
** hash table that matches the given key. The hash for this key has
** already been computed and is passed as the 4th parameter.
*/
static HashElem *findElementGivenHash(
const Hash *pH, /* The pH to be searched */
const char *pKey, /* The key we are searching for */
int nKey, /* Bytes in key (not counting zero terminator) */
unsigned int h /* The hash for this key. */
){
HashElem *elem; /* Used to loop thru the element list */
int count; /* Number of elements left to test */
if( pH->ht ){
struct _ht *pEntry = &pH->ht[h];
elem = pEntry->chain;
count = pEntry->count;
}else{
elem = pH->first;
count = pH->count;
}
while( count-- && ALWAYS(elem) ){
if( elem->nKey==nKey && sqlite4StrNICmp(elem->pKey,pKey,nKey)==0 ){
return elem;
}
elem = elem->next;
}
return 0;
}
/* Remove a single entry from the hash table given a pointer to that
** element and a hash on the element's key.
*/
static void removeElementGivenHash(
Hash *pH, /* The pH containing "elem" */
HashElem* elem, /* The element to be removed from the pH */
unsigned int h /* Hash value for the element */
){
struct _ht *pEntry;
if( elem->prev ){
elem->prev->next = elem->next;
}else{
pH->first = elem->next;
}
if( elem->next ){
elem->next->prev = elem->prev;
}
if( pH->ht ){
pEntry = &pH->ht[h];
if( pEntry->chain==elem ){
pEntry->chain = elem->next;
}
pEntry->count--;
assert( pEntry->count>=0 );
}
sqlite4_free(pH->pEnv, elem);
pH->count--;
if( pH->count<=0 ){
assert( pH->first==0 );
assert( pH->count==0 );
sqlite4HashClear(pH);
}
}
/* Attempt to locate an element of the hash table pH with a key
** that matches pKey,nKey. Return the data for this element if it is
** found, or NULL if there is no match.
*/
SQLITE_PRIVATE void *sqlite4HashFind(const Hash *pH, const char *pKey, int nKey){
HashElem *elem; /* The element that matches key */
unsigned int h; /* A hash on key */
assert( pH!=0 );
assert( pKey!=0 );
assert( nKey>=0 );
if( pH->ht ){
h = strHash(pKey, nKey) % pH->htsize;
}else{
h = 0;
}
elem = findElementGivenHash(pH, pKey, nKey, h);
return elem ? elem->data : 0;
}
/* Insert an element into the hash table pH. The key is pKey,nKey
** and the data is "data".
**
** If no element exists with a matching key, then a new
** element is created and NULL is returned.
**
** If another element already exists with the same key, then the
** new data replaces the old data and the old data is returned.
** The key is not copied in this instance. If a malloc fails, then
** the new data is returned and the hash table is unchanged.
**
** If the "data" parameter to this function is NULL, then the
** element corresponding to "key" is removed from the hash table.
*/
SQLITE_PRIVATE void *sqlite4HashInsert(Hash *pH, const char *pKey, int nKey, void *data){
unsigned int h; /* the hash of the key modulo hash table size */
HashElem *elem; /* Used to loop thru the element list */
HashElem *new_elem; /* New element added to the pH */
assert( pH!=0 );
assert( pKey!=0 );
assert( nKey>=0 );
if( pH->htsize ){
h = strHash(pKey, nKey) % pH->htsize;
}else{
h = 0;
}
elem = findElementGivenHash(pH,pKey,nKey,h);
if( elem ){
void *old_data = elem->data;
if( data==0 ){
removeElementGivenHash(pH,elem,h);
}else{
elem->data = data;
elem->pKey = pKey;
assert(nKey==elem->nKey);
}
return old_data;
}
if( data==0 ) return 0;
new_elem = (HashElem*)sqlite4Malloc(pH->pEnv, sizeof(HashElem) );
if( new_elem==0 ) return data;
new_elem->pKey = pKey;
new_elem->nKey = nKey;
new_elem->data = data;
pH->count++;
if( pH->count>=10 && pH->count > 2*pH->htsize ){
if( rehash(pH, pH->count*2) ){
assert( pH->htsize>0 );
h = strHash(pKey, nKey) % pH->htsize;
}
}
if( pH->ht ){
insertElement(pH, &pH->ht[h], new_elem);
}else{
insertElement(pH, 0, new_elem);
}
return 0;
}
/************** End of hash.c ************************************************/
/************** Begin file opcodes.c *****************************************/
/* Automatically generated. Do not edit */
/* See the mkopcodec.awk script for details. */
#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
SQLITE_PRIVATE const char *sqlite4OpcodeName(int i){
static const char *const azName[] = { "?",
/* 1 */ "Goto",
/* 2 */ "Gosub",
/* 3 */ "Return",
/* 4 */ "Yield",
/* 5 */ "HaltIfNull",
/* 6 */ "Halt",
/* 7 */ "Integer",
/* 8 */ "Int64",
/* 9 */ "String",
/* 10 */ "Null",
/* 11 */ "Blob",
/* 12 */ "Variable",
/* 13 */ "Move",
/* 14 */ "Copy",
/* 15 */ "SCopy",
/* 16 */ "ResultRow",
/* 17 */ "CollSeq",
/* 18 */ "Function",
/* 19 */ "Not",
/* 20 */ "AddImm",
/* 21 */ "MustBeInt",
/* 22 */ "RealAffinity",
/* 23 */ "Permutation",
/* 24 */ "Compare",
/* 25 */ "Jump",
/* 26 */ "Once",
/* 27 */ "If",
/* 28 */ "IfNot",
/* 29 */ "Column",
/* 30 */ "Affinity",
/* 31 */ "MakeIdxKey",
/* 32 */ "MakeKey",
/* 33 */ "MakeRecord",
/* 34 */ "Count",
/* 35 */ "Savepoint",
/* 36 */ "Transaction",
/* 37 */ "SetCookie",
/* 38 */ "VerifyCookie",
/* 39 */ "OpenRead",
/* 40 */ "OpenWrite",
/* 41 */ "OpenAutoindex",
/* 42 */ "OpenEphemeral",
/* 43 */ "SorterOpen",
/* 44 */ "OpenPseudo",
/* 45 */ "Close",
/* 46 */ "SeekPk",
/* 47 */ "SeekLt",
/* 48 */ "SeekLe",
/* 49 */ "SeekGe",
/* 50 */ "SeekGt",
/* 51 */ "Seek",
/* 52 */ "NotExists",
/* 53 */ "NotFound",
/* 54 */ "Found",
/* 55 */ "IsUnique",
/* 56 */ "Sequence",
/* 57 */ "NewRowid",
/* 58 */ "NewIdxid",
/* 59 */ "Insert",
/* 60 */ "InsertInt",
/* 61 */ "Delete",
/* 62 */ "ResetCount",
/* 63 */ "GrpCompare",
/* 64 */ "SorterData",
/* 65 */ "RowKey",
/* 66 */ "RowData",
/* 67 */ "Or",
/* 68 */ "And",
/* 69 */ "Rowid",
/* 70 */ "NullRow",
/* 71 */ "Last",
/* 72 */ "IsNull",
/* 73 */ "NotNull",
/* 74 */ "Ne",
/* 75 */ "Eq",
/* 76 */ "Gt",
/* 77 */ "Le",
/* 78 */ "Lt",
/* 79 */ "Ge",
/* 80 */ "SorterSort",
/* 81 */ "BitAnd",
/* 82 */ "BitOr",
/* 83 */ "ShiftLeft",
/* 84 */ "ShiftRight",
/* 85 */ "Add",
/* 86 */ "Subtract",
/* 87 */ "Multiply",
/* 88 */ "Divide",
/* 89 */ "Remainder",
/* 90 */ "Concat",
/* 91 */ "Sort",
/* 92 */ "BitNot",
/* 93 */ "String8",
/* 94 */ "Rewind",
/* 95 */ "SorterNext",
/* 96 */ "Prev",
/* 97 */ "Next",
/* 98 */ "SorterInsert",
/* 99 */ "IdxInsert",
/* 100 */ "IdxDelete",
/* 101 */ "IdxRowid",
/* 102 */ "IdxLT",
/* 103 */ "IdxLE",
/* 104 */ "IdxGE",
/* 105 */ "IdxGT",
/* 106 */ "Clear",
/* 107 */ "ParseSchema",
/* 108 */ "LoadAnalysis",
/* 109 */ "DropTable",
/* 110 */ "DropIndex",
/* 111 */ "DropTrigger",
/* 112 */ "RowSetTest",
/* 113 */ "RowSetAdd",
/* 114 */ "RowSetRead",
/* 115 */ "Program",
/* 116 */ "Param",
/* 117 */ "FkCounter",
/* 118 */ "FkIfZero",
/* 119 */ "MemMax",
/* 120 */ "IfPos",
/* 121 */ "IfNeg",
/* 122 */ "IfZero",
/* 123 */ "AggStep",
/* 124 */ "AggFinal",
/* 125 */ "JournalMode",
/* 126 */ "Expire",
/* 127 */ "VBegin",
/* 128 */ "VCreate",
/* 129 */ "Real",
/* 130 */ "VDestroy",
/* 131 */ "VOpen",
/* 132 */ "VFilter",
/* 133 */ "VColumn",
/* 134 */ "VNext",
/* 135 */ "VRename",
/* 136 */ "VUpdate",
/* 137 */ "Trace",
/* 138 */ "Noop",
/* 139 */ "Explain",
/* 140 */ "ToText",
/* 141 */ "ToBlob",
/* 142 */ "ToNumeric",
/* 143 */ "ToInt",
/* 144 */ "ToReal",
};
return azName[i];
}
#endif
/************** End of opcodes.c *********************************************/
/************** Begin file lsm_ckpt.c ****************************************/
/*
** 2011-09-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 code to read and write checkpoints.
**
** A checkpoint represents the database layout at a single point in time.
** It includes a log offset. When an existing database is opened, the
** current state is determined by reading the newest checkpoint and updating
** it with all committed transactions from the log that follow the specified
** offset.
*/
/************** Include lsmInt.h in the middle of lsm_ckpt.c *****************/
/************** Begin file lsmInt.h ******************************************/
/*
** 2011-08-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.
**
*************************************************************************
** Internal structure definitions for the LSM module.
*/
#ifndef _LSM_INT_H
#define _LSM_INT_H
/************** Include lsm.h in the middle of lsmInt.h **********************/
/************** Begin file lsm.h *********************************************/
/*
** 2011-08-10
**
** 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 defines the LSM API.
*/
#ifndef _LSM_H
#define _LSM_H
/* #include <stddef.h> */
#if 0
extern "C" {
#endif
/*
** Opaque handle types.
*/
typedef struct lsm_db lsm_db; /* Database connection handle */
typedef struct lsm_cursor lsm_cursor; /* Database cursor handle */
typedef struct lsm_mutex lsm_mutex; /* Mutex handle */
typedef struct lsm_file lsm_file; /* OS file handle */
/* 64-bit integer type used for file offsets. */
typedef long long int lsm_i64; /* 64-bit signed integer type */
/* Forward reference */
typedef struct lsm_env lsm_env; /* Runtime environment */
/*
** Run-time environment used by LSM
*/
struct lsm_env {
int nByte; /* Size of this structure in bytes */
int iVersion; /* Version number of this structure */
/****** file i/o ***********************************************/
void *pVfsCtx;
int (*xFullpath)(lsm_env*, const char *, char *, int *);
int (*xOpen)(lsm_env*, const char *, lsm_file **);
int (*xRead)(lsm_file *, lsm_i64, void *, int);
int (*xWrite)(lsm_file *, lsm_i64, void *, int);
int (*xTruncate)(lsm_file *, lsm_i64);
int (*xSync)(lsm_file *);
int (*xSectorSize)(lsm_file *);
int (*xRemap)(lsm_file *, lsm_i64, void **, lsm_i64*);
int (*xFileid)(lsm_file *, void *pBuf, int *pnBuf);
int (*xClose)(lsm_file *);
int (*xUnlink)(lsm_env*, const char *);
/****** memory allocation ****************************************/
void *pMemCtx;
void *(*xMalloc)(lsm_env*, int); /* malloc(3) function */
void *(*xRealloc)(lsm_env*, void *, int); /* realloc(3) function */
void (*xFree)(lsm_env*, void *); /* free(3) function */
/****** mutexes ****************************************************/
void *pMutexCtx;
int (*xMutexStatic)(lsm_env*,int,lsm_mutex**); /* Obtain a static mutex */
int (*xMutexNew)(lsm_env*, lsm_mutex**); /* Get a new dynamic mutex */
void (*xMutexDel)(lsm_mutex *); /* Delete an allocated mutex */
void (*xMutexEnter)(lsm_mutex *); /* Grab a mutex */
int (*xMutexTry)(lsm_mutex *); /* Attempt to obtain a mutex */
void (*xMutexLeave)(lsm_mutex *); /* Leave a mutex */
int (*xMutexHeld)(lsm_mutex *); /* Return true if mutex is held */
int (*xMutexNotHeld)(lsm_mutex *); /* Return true if mutex not held */
/* New fields may be added in future releases, in which case the
** iVersion value will increase. */
};
/*
** Values that may be passed as the second argument to xMutexStatic.
*/
#define LSM_MUTEX_GLOBAL 1
#define LSM_MUTEX_HEAP 2
/*
** Return a pointer to the default LSM run-time environment
*/
lsm_env *lsm_default_env(void);
/*
** Error codes.
*/
#define LSM_OK 0
#define LSM_ERROR 1
#define LSM_BUSY 5
#define LSM_NOMEM 7
#define LSM_IOERR 10
#define LSM_CORRUPT 11
#define LSM_FULL 13
#define LSM_CANTOPEN 14
#define LSM_MISUSE 21
/*
** Open and close a connection to a named database.
*/
int lsm_new(lsm_env*, lsm_db **ppDb);
int lsm_open(lsm_db *pDb, const char *zFilename);
int lsm_close(lsm_db *pDb);
/*
** Return a pointer to the environment used by the database connection
** passed as the first argument. Assuming the argument is valid, this
** function always returns a valid environment pointer - it cannot fail.
*/
lsm_env *lsm_get_env(lsm_db *pDb);
/*
** Configure a database connection.
*/
int lsm_config(lsm_db *, int, ...);
/*
** The following values may be passed as the second argument to lsm_config().
**
** LSM_CONFIG_WRITE_BUFFER
** A read/write integer parameter. This value determines the maximum amount
** of space (in bytes) used to accumulate writes in main-memory before
** they are flushed to a level 0 segment.
**
** LSM_CONFIG_PAGE_SIZE
** A read/write integer parameter. This parameter may only be set before
** lsm_open() has been called.
**
** LSM_CONFIG_BLOCK_SIZE
** A read/write integer parameter. This parameter may only be set before
** lsm_open() has been called.
**
** LSM_CONFIG_LOG_SIZE
** A read/write integer parameter.
**
** LSM_CONFIG_SAFETY
** A read/write integer parameter. Valid values are 0, 1 (the default)
** and 2. This parameter determines how robust the database is in the
** face of a system crash (e.g. a power failure or operating system
** crash). As follows:
**
** 0 (off): No robustness. A system crash may corrupt the database.
**
** 1 (normal): Some robustness. A system crash may not corrupt the
** database file, but recently committed transactions may
** be lost following recovery.
**
** 2 (full): Full robustness. A system crash may not corrupt the
** database file. Following recovery the database file
** contains all successfully committed transactions.
**
** LSM_CONFIG_AUTOWORK
** A read/write integer parameter.
**
** TODO: This should configure some kind of threshold for turning on
** auto-work. Right now it is Boolean - 1 for on and 0 for off. Default 1.
**
** LSM_CONFIG_MMAP
** A read/write integer parameter. True to use mmap() to access the
** database file. False otherwise.
**
** LSM_CONFIG_USE_LOG
** A read/write boolean parameter. True (the default) to use the log
** file normally. False otherwise.
*/
#define LSM_CONFIG_WRITE_BUFFER 1
#define LSM_CONFIG_PAGE_SIZE 2
#define LSM_CONFIG_SAFETY 3
#define LSM_CONFIG_BLOCK_SIZE 4
#define LSM_CONFIG_AUTOWORK 5
#define LSM_CONFIG_LOG_SIZE 6
#define LSM_CONFIG_MMAP 7
#define LSM_CONFIG_USE_LOG 8
#define LSM_SAFETY_OFF 0
#define LSM_SAFETY_NORMAL 1
#define LSM_SAFETY_FULL 2
/*
** Invoke the memory allocation functions that belong to environment
** pEnv. Or the system defaults if no memory allocation functions have
** been registered.
*/
void *lsm_malloc(lsm_env*, size_t);
void *lsm_realloc(lsm_env*, void *, size_t);
void lsm_free(lsm_env*, void *);
/*
** Configure a callback to which debugging and other messages should
** be directed. Only useful for debugging lsm.
*/
void lsm_config_log(lsm_db *, void (*)(void *, int, const char *), void *);
/*
** Configure a callback that is invoked if the database connection ever
** writes to the database file.
*/
void lsm_config_work_hook(lsm_db *, void (*)(lsm_db *, void *), void *);
/*
** Query a database connection for operational statistics or data.
*/
int lsm_info(lsm_db *, int, ...);
/*
** The following values may be passed as the second argument to lsm_info().
**
** LSM_INFO_NWRITE
** The third parameter should be of type (int *). The location pointed
** to by the third parameter is set to the number of 4KB pages written to
** the database file during the lifetime of this connection.
**
** LSM_INFO_NREAD
** The third parameter should be of type (int *). The location pointed
** to by the third parameter is set to the number of 4KB pages read from
** the database file during the lifetime of this connection.
**
** LSM_INFO_DB_STRUCTURE
** The third argument should be of type (char **). The location pointed
** to is populated with a pointer to a nul-terminated string containing
** the string representation of a Tcl data-structure reflecting the
** current structure of the database file. Specifically, the current state
** of the worker snapshot. The returned string should be eventually freed
** by the caller using lsm_free().
**
** The returned list contains one element for each level in the database,
** in order from most to least recent. Each element contains a
** single element for each segment comprising the corresponding level,
** starting with the lhs segment, then each of the rhs segments (if any)
** in order from most to least recent.
**
** Each segment element is itself a list of 6 integer values, as follows:
**
** 1. First page of separators array, or 0 if n/a.
** 2. Last page of separators array, or 0 if n/a.
** 3. Root page of separators array, or 0 if n/a.
** 4. First page of main array.
** 5. Last page of main array.
** 6. Total number of pages in main array.
**
** LSM_INFO_ARRAY_STRUCTURE
** There should be two arguments passed following this option (i.e. a
** total of four arguments passed to lsm_info()). The first argument
** should be the page number of the first page in a database array
** (perhaps obtained from an earlier INFO_DB_STRUCTURE call). The second
** trailing argument should be of type (char **). The location pointed
** to is populated with a pointer to a nul-terminated string that must
** be eventually freed using lsm_free() by the caller.
**
** The output string contains the text representation of a Tcl list of
** integers. Each pair of integers represent a range of pages used by
** the identified array. For example, if the array occupies database
** pages 993 to 1024, then pages 2048 to 2777, then the returned string
** will be "993 1024 2048 2777".
**
** If the specified integer argument does not correspond to the first
** page of any database array, LSM_ERROR is returned and the output
** pointer is set to a NULL value.
**
** LSM_INFO_PAGE_ASCII_DUMP
** As with LSM_INFO_ARRAY_STRUCTURE, there should be two arguments passed
** with calls that specify this option - an integer page number and a
** (char **) used to return a nul-terminated string that must be later
** freed using lsm_free(). In this case the output string is populated
** with a human-readable description of the page content.
**
** If the page cannot be decoded, it is not an error. In this case the
** human-readable output message will report the systems failure to
** interpret the page data.
**
** LSM_INFO_PAGE_HEX_DUMP
** This argument is similar to PAGE_ASCII_DUMP, except that keys and
** values are represented using hexadecimal notation instead of ascii.
**
** LSM_INFO_LOG_STRUCTURE
** The third argument should be of type (char **). The location pointed
** to is populated with a pointer to a nul-terminated string containing
** the string representation of a Tcl data-structure. The returned
** string should be eventually freed by the caller using lsm_free().
**
** The Tcl structure returned is a list of six integers that describe
** the current structure of the log file.
*/
#define LSM_INFO_NWRITE 1
#define LSM_INFO_NREAD 2
#define LSM_INFO_DB_STRUCTURE 3
#define LSM_INFO_LOG_STRUCTURE 4
#define LSM_INFO_ARRAY_STRUCTURE 5
#define LSM_INFO_PAGE_ASCII_DUMP 6
#define LSM_INFO_PAGE_HEX_DUMP 7
/*
** Open and close transactions and nested transactions.
**
** lsm_begin():
** Used to open transactions and sub-transactions. A successful call to
** lsm_begin() ensures that there are at least iLevel nested transactions
** open. To open a top-level transaction, pass iLevel==1. To open a
** sub-transaction within the top-level transaction, iLevel==2. Passing
** iLevel==0 is a no-op.
**
** lsm_commit():
** Used to commit transactions and sub-transactions. A successful call
** to lsm_commit() ensures that there are at most iLevel nested
** transactions open. To commit a top-level transaction, pass iLevel==0.
** To commit all sub-transactions inside the main transaction, pass
** iLevel==1.
**
** lsm_rollback():
** Used to roll back transactions and sub-transactions. A successful call
** to lsm_rollback() restores the database to the state it was in when
** the iLevel'th nested sub-transaction (if any) was first opened. And then
** closes transactions to ensure that there are at most iLevel nested
** transactions open.
**
** Passing iLevel==0 rolls back and closes the top-level transaction.
** iLevel==1 also rolls back the top-level transaction, but leaves it
** open. iLevel==2 rolls back the sub-transaction nested directly inside
** the top-level transaction (and leaves it open).
*/
int lsm_begin(lsm_db *pDb, int iLevel);
int lsm_commit(lsm_db *pDb, int iLevel);
int lsm_rollback(lsm_db *pDb, int iLevel);
/*
** Write a new value into the database. If a value with a duplicate key
** already exists it is replaced.
*/
int lsm_write(lsm_db *pDb, void *pKey, int nKey, void *pVal, int nVal);
/*
** Delete a value from the database. No error is returned if the specified
** key value does not exist in the database.
*/
int lsm_delete(lsm_db *pDb, void *pKey, int nKey);
/*
** This function is called by a thread to work on the database structure.
** The actual operations performed by this function depend on the value
** passed as the "flags" parameter:
**
** LSM_WORK_FLUSH:
** Attempt to flush the contents of the in-memory tree to disk.
**
** LSM_WORK_CHECKPOINT:
** Write a checkpoint (if one exists in memory) to the database file.
**
** LSM_WORK_OPTIMIZE:
** This flag is only regcognized if LSM_WORK_MERGE is also set.
*/
int lsm_work(lsm_db *pDb, int flags, int nPage, int *pnWrite);
#define LSM_WORK_FLUSH 0x00000001
#define LSM_WORK_CHECKPOINT 0x00000002
#define LSM_WORK_OPTIMIZE 0x00000004
/*
** Open and close a database cursor.
*/
int lsm_csr_open(lsm_db *pDb, lsm_cursor **ppCsr);
int lsm_csr_close(lsm_cursor *pCsr);
/*
** If the fourth parameter is LSM_SEEK_EQ, LSM_SEEK_GE or LSM_SEEK_LE,
** this function searches the database for an entry with key (pKey/nKey).
** If an error occurs, an LSM error code is returned. Otherwise, LSM_OK.
**
** If no error occurs and the requested key is present in the database, the
** cursor is left pointing to the entry with the specified key. Or, if the
** specified key is not present in the database the state of the cursor
** depends on the value passed as the final parameter, as follows:
**
** LSM_SEEK_EQ:
** The cursor is left at EOF (invalidated). A call to lsm_csr_valid()
** returns non-zero.
**
** LSM_SEEK_LE:
** The cursor is left pointing to the largest key in the database that
** is smaller than (pKey/nKey). If the database contains no keys smaller
** than (pKey/nKey), the cursor is left at EOF.
**
** LSM_SEEK_GE:
** The cursor is left pointing to the smallest key in the database that
** is larger than (pKey/nKey). If the database contains no keys larger
** than (pKey/nKey), the cursor is left at EOF.
**
** If the fourth parameter is LSM_SEEK_LEFAST, this function searches the
** database in a similar manner to LSM_SEEK_LE, with two differences:
**
** 1) Even if a key can be found (the cursor is not left at EOF), the
** lsm_csr_value() function may not be used (attempts to do so return
** LSM_MISUSE).
**
** 2) The key that the cursor is left pointing to may be one that has
** been recently deleted from the database. In this case it is guaranteed
** that the returned key is larger than any key currently in the database
** that is less than or equal to (pKey/nKey).
**
** LSM_SEEK_LEFAST requests are intended to be used to allocate database
** keys.
*/
int lsm_csr_seek(lsm_cursor *pCsr, void *pKey, int nKey, int eSeek);
/*
** Values that may be passed as the fourth argument to lsm_csr_seek().
*/
#define LSM_SEEK_LEFAST -2
#define LSM_SEEK_LE -1
#define LSM_SEEK_EQ 0
#define LSM_SEEK_GE 1
int lsm_csr_first(lsm_cursor *pCsr);
int lsm_csr_last(lsm_cursor *pCsr);
/*
** Advance the specified cursor to the next or previous key in the database.
** Return LSM_OK if successful, or an LSM error code otherwise.
**
** Functions lsm_csr_seek(), lsm_csr_first() and lsm_csr_last() are "seek"
** functions. Whether or not lsm_csr_next and lsm_csr_prev may be called
** successfully also depends on the most recent seek function called on
** the cursor. Specifically:
**
** * At least one seek function must have been called on the cursor.
**
** * To call lsm_csr_next(), the most recent call to a seek function must
** have been either lsm_csr_first() or a call to lsm_csr_seek() specifying
** LSM_SEEK_GE.
**
** * To call lsm_csr_prev(), the most recent call to a seek function must
** have been either lsm_csr_first() or a call to lsm_csr_seek() specifying
** LSM_SEEK_GE.
**
** Otherwise, if the above conditions are not met when lsm_csr_next or
** lsm_csr_prev is called, LSM_MISUSE is returned and the cursor position
** remains unchanged.
*/
int lsm_csr_next(lsm_cursor *pCsr);
int lsm_csr_prev(lsm_cursor *pCsr);
/*
** Retrieve data from a database cursor.
*/
int lsm_csr_valid(lsm_cursor *pCsr);
int lsm_csr_key(lsm_cursor *pCsr, void **ppKey, int *pnKey);
int lsm_csr_value(lsm_cursor *pCsr, void **ppVal, int *pnVal);
#if 0
} /* End of the 'extern "C"' block */
#endif
#endif /* ifndef _LSM_H */
/************** End of lsm.h *************************************************/
/************** Continuing where we left off in lsmInt.h *********************/
/* #include <assert.h> */
/* #include <string.h> */
/* #include <stdarg.h> */
/* #include <stdlib.h> */
/* #include <stdio.h> */
/* #include <ctype.h> */
#include <unistd.h>
#ifdef NDEBUG
# ifdef LSM_DEBUG_EXPENSIVE
# undef LSM_DEBUG_EXPENSIVE
# endif
# ifdef LSM_DEBUG
# undef LSM_DEBUG
# endif
#else
# define LSM_DEBUG
#endif
/*
** Default values for various data structure parameters. These may be
** overridden by calls to lsm_config().
*/
#define LSM_PAGE_SIZE 4096
#define LSM_BLOCK_SIZE (2 * 1024 * 1024)
#define LSM_TREE_BYTES (2 * 1024 * 1024)
#define LSM_ECOLA 4
#define LSM_DEFAULT_LOG_SIZE (128*1024)
/* Places where a NULL needs to be changed to a real lsm_env pointer
** are marked with NEED_ENV */
#define NEED_ENV ((lsm_env*)0)
/* Initial values for log file checksums. These are only used if the
** database file does not contain a valid checkpoint. */
#define LSM_CKSUM0_INIT 42
#define LSM_CKSUM1_INIT 42
typedef struct Database Database;
typedef struct DbLog DbLog;
typedef struct FileSystem FileSystem;
typedef struct Level Level;
typedef struct LogMark LogMark;
typedef struct LogRegion LogRegion;
typedef struct LogWriter LogWriter;
typedef struct LsmString LsmString;
typedef struct Mempool Mempool;
typedef struct MetaPage MetaPage;
typedef struct MultiCursor MultiCursor;
typedef struct Page Page;
typedef struct Segment Segment;
typedef struct SegmentMerger SegmentMerger;
typedef struct Snapshot Snapshot;
typedef struct SortedRun SortedRun;
typedef struct TransMark TransMark;
typedef struct Tree Tree;
typedef struct TreeMark TreeMark;
typedef struct TreeVersion TreeVersion;
typedef struct TreeCursor TreeCursor;
typedef struct Merge Merge;
typedef struct MergeInput MergeInput;
typedef unsigned char u8;
typedef unsigned short int u16;
typedef unsigned int u32;
typedef lsm_i64 i64;
typedef unsigned long long int u64;
/* A page number is an integer. */
typedef int Pgno;
#ifdef LSM_DEBUG
int lsmErrorBkpt(int);
#else
# define lsmErrorBkpt(x) (x)
#endif
#define LSM_IOERR_BKPT lsmErrorBkpt(LSM_IOERR)
#define LSM_NOMEM_BKPT lsmErrorBkpt(LSM_NOMEM)
#define LSM_CORRUPT_BKPT lsmErrorBkpt(LSM_CORRUPT)
#define LSM_MISUSE_BKPT lsmErrorBkpt(LSM_MISUSE)
#define unused_parameter(x) (void)(x)
#define array_size(x) (sizeof(x)/sizeof(x[0]))
/*
** A string that can grow by appending.
*/
struct LsmString {
lsm_env *pEnv; /* Run-time environment */
int n; /* Size of string. -1 indicates error */
int nAlloc; /* Space allocated for z[] */
char *z; /* The string content */
};
/*
** An instance of this structure represents a point in the history of the
** tree structure to roll back to. Refer to comments in tree.c for details.
**
** Pointers pRollback and pRoot both point to structures of type TreeNode.
*/
struct TreeMark {
void *pMpChunk; /* Mempool chunk to roll back to */
int iMpOff; /* Mempool chunk offset to roll back to */
void *pRollback; /* Zero v2 information starting here */
void *pRoot; /* Root node to restore */
int nHeight; /* Height of tree at pRoot */
};
/*
** An instance of this structure represents a point in the database log.
*/
struct LogMark {
i64 iOff; /* Offset into log (see lsm_log.c) */
int nBuf; /* Size of in-memory buffer here */
u8 aBuf[8]; /* Bytes of content in aBuf[] */
u32 cksum0; /* Checksum 0 at offset (iOff-nBuf) */
u32 cksum1; /* Checksum 1 at offset (iOff-nBuf) */
};
struct TransMark {
TreeMark tree;
LogMark log;
};
/*
** A structure that defines the start and end offsets of a region in the
** log file. The size of the region in bytes is (iEnd - iStart), so if
** iEnd==iStart the region is zero bytes in size.
*/
struct LogRegion {
i64 iStart; /* Start of region in log file */
i64 iEnd; /* End of region in log file */
};
struct DbLog {
u32 cksum0; /* Checksum 0 at offset iOff */
u32 cksum1; /* Checksum 1 at offset iOff */
LogRegion aRegion[3]; /* Log file regions (see docs in lsm_log.c) */
LsmString buf; /* Buffer containing data not yet written */
};
/*
** Database handle structure.
*/
struct lsm_db {
/* Database handle configuration */
lsm_env *pEnv; /* runtime environment */
int (*xCmp)(void *, int, void *, int); /* Compare function */
int nTreeLimit; /* Maximum size of in-memory tree in bytes */
int bAutowork; /* True to do auto-work after writing */
int eSafety; /* LSM_SAFETY_OFF, NORMAL or FULL */
int nLogSz; /* Configured by LSM_CONFIG_LOG_SIZE */
int bUseLog; /* Configured by LSM_CONFIG_USE_LOG */
int nDfltPgsz; /* Configured by LSM_CONFIG_PAGE_SIZE */
int nDfltBlksz; /* Configured by LSM_CONFIG_BLOCK_SIZE */
/* Sub-system handles */
FileSystem *pFS; /* On-disk portion of database */
Database *pDatabase; /* Database shared data */
/* Client transaction context */
TreeVersion *pTV; /* In-memory tree snapshot (non-NULL in rt) */
Snapshot *pClient; /* Client snapshot (non-NULL in read trans) */
MultiCursor *pCsr; /* List of all open cursors */
LogWriter *pLogWriter;
int nTransOpen; /* Number of opened write transactions */
int nTransAlloc; /* Allocated size of aTrans[] array */
TransMark *aTrans; /* Array of marks for transaction rollback */
/* Worker context */
Snapshot *pWorker; /* Worker snapshot (or NULL) */
/* Debugging message callback */
void (*xLog)(void *, int, const char *);
void *pLogCtx;
/* Work done notification callback */
void (*xWork)(lsm_db *, void *);
void *pWorkCtx;
};
struct SortedRun {
int iFirst; /* First page of this run */
int iLast; /* Last page of this run */
Pgno iRoot; /* Root page number (if any) */
int nSize; /* Size of this run in pages */
};
struct Segment {
SortedRun run; /* Main array */
SortedRun sep; /* If sep.iFirst!=0, the separators array */
};
/*
** iSplitTopic/pSplitKey/nSplitKey:
** If nRight>0, this buffer contains a copy of the largest key that has
** already been written to the left-hand-side of the level.
*/
struct Level {
Segment lhs; /* Left-hand (main) segment */
int iAge; /* Number of times data has been written */
int nRight; /* Size of apRight[] array */
Segment *aRhs; /* Old segments being merged into this */
int iSplitTopic;
void *pSplitKey; /* Pointer to split-key (if nRight>0) */
int nSplitKey; /* Number of bytes in split-key */
Merge *pMerge; /* Merge operation currently underway */
Level *pNext; /* Next level in tree */
};
/*
** A structure describing an ongoing merge. There is an instance of this
** structure for every Level currently undergoing a merge in the worker
** snapshot.
**
** It is assumed that code that uses an instance of this structure has
** access to the associated Level struct.
**
** bHierReadonly:
** True if the b-tree hierarchy is currently read-only.
**
** aiOutputOff:
** The byte offset to write to next within the last page of the output
** segments main run (aiOutputOff[0]) or separators run (aiOutputOff[1]).
** If either page is read-only, then the associated aiOutputOff[] entry
** is set to a negative value.
*/
struct Merge {
int nInput; /* Number of input runs being merged */
MergeInput *aInput; /* Array nInput entries in size */
int nSkip; /* Number of separators entries to skip */
int aiOutputOff[2]; /* Write offsets on run output pages */
int bHierReadonly; /* True if b-tree heirarchy is read-only */
};
struct MergeInput {
Pgno iPg; /* Page on which next input is stored */
int iCell; /* Cell containing next input to merge */
};
/*
** The first argument to this macro is a pointer to a Segment structure.
** Returns true if the structure instance indicates that the separators
** array is valid.
*/
#define segmentHasSeparators(pSegment) ((pSegment)->sep.iFirst>0)
/*
** Number of integers in the free-list delta.
*/
#define LSM_FREELIST_DELTA_SIZE 3
/*
** Functions from file "lsm_ckpt.c".
*/
int lsmCheckpointRead(lsm_db *);
int lsmCheckpointWrite(lsm_db *);
int lsmCheckpointExport(lsm_db *, int, i64, int, void **, int *);
void lsmChecksumBytes(const u8 *, int, const u32 *, u32 *);
lsm_i64 lsmCheckpointLogOffset(void *pExport);
int lsmCheckpointLevels(lsm_db *, int *, void **, int *);
int lsmCheckpointLoadLevels(lsm_db *pDb, void *pVal, int nVal);
/*
** Functions from file "lsm_tree.c".
*/
int lsmTreeNew(lsm_env *, int (*)(void *, int, void *, int), Tree **ppTree);
int lsmTreeSize(TreeVersion *pTV);
int lsmTreeIsEmpty(Tree *pTree);
int lsmTreeInsert(lsm_db *pDb, void *pKey, int nKey, void *pVal, int nVal);
void lsmTreeRollback(lsm_db *pDb, TreeMark *pMark);
void lsmTreeMark(TreeVersion *pTV, TreeMark *pMark);
int lsmTreeCursorNew(lsm_db *pDb, TreeCursor **);
void lsmTreeCursorDestroy(TreeCursor *);
int lsmTreeCursorSeek(TreeCursor *pCsr, void *pKey, int nKey, int *pRes);
int lsmTreeCursorNext(TreeCursor *pCsr);
int lsmTreeCursorPrev(TreeCursor *pCsr);
int lsmTreeCursorEnd(TreeCursor *pCsr, int bLast);
void lsmTreeCursorReset(TreeCursor *pCsr);
int lsmTreeCursorKey(TreeCursor *pCsr, void **ppKey, int *pnKey);
int lsmTreeCursorValue(TreeCursor *pCsr, void **ppVal, int *pnVal);
int lsmTreeCursorValid(TreeCursor *pCsr);
void lsmTreeCursorSave(TreeCursor *pCsr);
TreeVersion *lsmTreeReadVersion(Tree *);
int lsmTreeWriteVersion(lsm_env *pEnv, Tree *, TreeVersion **);
TreeVersion *lsmTreeRecoverVersion(Tree *);
int lsmTreeIsWriteVersion(TreeVersion *);
int lsmTreeReleaseWriteVersion(lsm_env *, TreeVersion *, int, TreeVersion **);
void lsmTreeReleaseReadVersion(lsm_env *, TreeVersion *);
void lsmTreeRelease(lsm_env *, Tree *);
/*
** Functions from file "mem.c".
*/
int lsmPoolNew(lsm_env *pEnv, Mempool **ppPool);
void lsmPoolDestroy(lsm_env *pEnv, Mempool *pPool);
void *lsmPoolMalloc(lsm_env *pEnv, Mempool *pPool, int nByte);
void *lsmPoolMallocZero(lsm_env *pEnv, Mempool *pPool, int nByte);
int lsmPoolUsed(Mempool *pPool);
void lsmPoolMark(Mempool *pPool, void **, int *);
void lsmPoolRollback(lsm_env *pEnv, Mempool *pPool, void *, int);
void *lsmMalloc(lsm_env*, size_t);
void lsmFree(lsm_env*, void *);
void *lsmRealloc(lsm_env*, void *, size_t);
void *lsmReallocOrFree(lsm_env*, void *, size_t);
void *lsmReallocOrFreeRc(lsm_env *, void *, size_t, int *);
void *lsmMallocZeroRc(lsm_env*, size_t, int *);
void *lsmMallocRc(lsm_env*, size_t, int *);
void *lsmMallocZero(lsm_env *pEnv, size_t);
char *lsmMallocStrdup(lsm_env *pEnv, const char *);
/*
** Functions from file "lsm_mutex.c".
*/
int lsmMutexStatic(lsm_env*, int, lsm_mutex **);
int lsmMutexNew(lsm_env*, lsm_mutex **);
void lsmMutexDel(lsm_env*, lsm_mutex *);
void lsmMutexEnter(lsm_env*, lsm_mutex *);
int lsmMutexTry(lsm_env*, lsm_mutex *);
void lsmMutexLeave(lsm_env*, lsm_mutex *);
#ifndef NDEBUG
int lsmMutexHeld(lsm_env *, lsm_mutex *);
int lsmMutexNotHeld(lsm_env *, lsm_mutex *);
#endif
/**************************************************************************
** Start of functions from "lsm_file.c".
*/
int lsmFsOpen(lsm_db *, const char *);
void lsmFsClose(FileSystem *);
int lsmFsBlockSize(FileSystem *);
void lsmFsSetBlockSize(FileSystem *, int);
int lsmFsPageSize(FileSystem *);
void lsmFsSetPageSize(FileSystem *, int);
int lsmFsFileid(lsm_db *pDb, void **ppId, int *pnId);
/* Creating, populating, gobbling and deleting sorted runs. */
int lsmFsPhantom(FileSystem *, SortedRun *);
void lsmFsPhantomFree(FileSystem *pFS);
void lsmFsGobble(Snapshot *, SortedRun *, Page *);
int lsmFsSortedDelete(FileSystem *, Snapshot *, int, SortedRun *);
int lsmFsSortedFinish(FileSystem *, SortedRun *);
int lsmFsSortedAppend(FileSystem *, Snapshot *, SortedRun *, Page **);
int lsmFsPhantomMaterialize(FileSystem *, Snapshot *, SortedRun *);
/* Functions to retrieve the lsm_env pointer from a FileSystem or Page object */
lsm_env *lsmFsEnv(FileSystem *);
lsm_env *lsmPageEnv(Page *);
int lsmFsSectorSize(FileSystem *);
void lsmSortedSplitkey(lsm_db *, Level *, int *);
int lsmFsSetupAppendList(lsm_db *db);
/* Reading sorted run content. */
int lsmFsDbPageGet(FileSystem *, Pgno, Page **);
int lsmFsDbPageNext(SortedRun *, Page *, int eDir, Page **);
int lsmFsPageWrite(Page *);
u8 *lsmFsPageData(Page *, int *);
int lsmFsPageRelease(Page *);
int lsmFsPagePersist(Page *);
void lsmFsPageRef(Page *);
Pgno lsmFsPageNumber(Page *);
int lsmFsNRead(FileSystem *);
int lsmFsNWrite(FileSystem *);
int lsmFsMetaPageGet(FileSystem *, int, int, MetaPage **);
int lsmFsMetaPageRelease(MetaPage *);
u8 *lsmFsMetaPageData(MetaPage *, int *);
#ifdef LSM_EXPENSIVE_DEBUG
int lsmFsIntegrityCheck(lsm_db *);
#else
# define lsmFsIntegrityCheck(pDb) 1
#endif
int lsmFsPageWritable(Page *);
/* Functions to read, write and sync the log file. */
int lsmFsWriteLog(FileSystem *pFS, i64 iOff, LsmString *pStr);
int lsmFsSyncLog(FileSystem *pFS);
int lsmFsReadLog(FileSystem *pFS, i64 iOff, int nRead, LsmString *pStr);
int lsmFsTruncateLog(FileSystem *pFS, i64 nByte);
int lsmFsCloseAndDeleteLog(FileSystem *pFS);
/* And to sync the db file */
int lsmFsSyncDb(FileSystem *);
/* Used by lsm_info(ARRAY_STRUCTURE) and lsm_config(MMAP) */
int lsmInfoArrayStructure(lsm_db *pDb, Pgno iFirst, char **pzOut);
int lsmConfigMmap(lsm_db *pDb, int *piParam);
/*
** End of functions from "lsm_file.c".
**************************************************************************/
/*
** Functions from file "lsm_sorted.c".
*/
int lsmInfoPageDump(lsm_db *, Pgno, int, char **);
int lsmSortedFlushTree(lsm_db *, int *);
void lsmSortedCleanup(lsm_db *);
int lsmSortedAutoWork(lsm_db *, int nUnit);
void lsmSortedFreeLevel(lsm_env *pEnv, Level *);
int lsmSortedFlushDb(lsm_db *);
int lsmSortedAdvanceAll(lsm_db *pDb);
int lsmSortedLoadMerge(lsm_db *, Level *, u32 *, int *);
int lsmSortedLoadSystem(lsm_db *pDb);
void *lsmSortedSplitKey(Level *pLevel, int *pnByte);
void lsmSortedSaveTreeCursors(lsm_db *);
int lsmMCursorNew(lsm_db *, MultiCursor **);
void lsmMCursorClose(MultiCursor *);
int lsmMCursorSeek(MultiCursor *, void *, int , int);
int lsmMCursorFirst(MultiCursor *);
int lsmMCursorPrev(MultiCursor *);
int lsmMCursorLast(MultiCursor *);
int lsmMCursorValid(MultiCursor *);
int lsmMCursorNext(MultiCursor *);
int lsmMCursorKey(MultiCursor *, void **, int *);
int lsmMCursorValue(MultiCursor *, void **, int *);
int lsmMCursorType(MultiCursor *, int *);
lsm_db *lsmMCursorDb(MultiCursor *);
int lsmSaveCursors(lsm_db *pDb);
int lsmRestoreCursors(lsm_db *pDb);
void lsmSortedDumpStructure(lsm_db *pDb, Snapshot *, int, int, const char *);
void lsmFsDumpBlockmap(lsm_db *, SortedRun *);
void lsmFsDumpBlocklists(lsm_db *);
void lsmPutU32(u8 *, u32);
u32 lsmGetU32(u8 *);
/*
** Functions from "lsm_varint.c".
*/
int lsmVarintPut32(u8 *, int);
int lsmVarintGet32(u8 *, int *);
int lsmVarintPut64(u8 *aData, i64 iVal);
int lsmVarintGet64(const u8 *aData, i64 *piVal);
int lsmVarintLen32(int);
int lsmVarintSize(u8 c);
/*
** Functions from file "main.c".
*/
void lsmLogMessage(lsm_db *, int, const char *, ...);
int lsmFlushToDisk(lsm_db *);
/*
** Functions from file "lsm_log.c".
*/
int lsmLogBegin(lsm_db *pDb, DbLog *pLog);
int lsmLogWrite(lsm_db *, void *, int, void *, int);
int lsmLogCommit(lsm_db *);
void lsmLogEnd(lsm_db *pDb, DbLog *pLog, int bCommit);
void lsmLogTell(lsm_db *, LogMark *);
void lsmLogSeek(lsm_db *, LogMark *);
int lsmLogRecover(lsm_db *);
void lsmLogCheckpoint(lsm_db *, DbLog *pLog, lsm_i64);
int lsmLogStructure(lsm_db *pDb, char **pzVal);
/**************************************************************************
** Functions from file "lsm_shared.c".
*/
int lsmDbDatabaseFind(lsm_db*, const char *);
void lsmDbDatabaseRelease(lsm_db *);
int lsmBeginRecovery(lsm_db *);
int lsmBeginReadTrans(lsm_db *);
int lsmBeginWriteTrans(lsm_db *);
int lsmBeginFlush(lsm_db *);
int lsmFinishRecovery(lsm_db *);
void lsmFinishReadTrans(lsm_db *);
int lsmFinishWriteTrans(lsm_db *, int);
int lsmFinishFlush(lsm_db *, int);
int lsmDbUpdateClient(lsm_db *, int);
int lsmSnapshotFreelist(lsm_db *, int **, int *);
int lsmSnapshotSetFreelist(lsm_db *, int *, int);
void lsmDbSetPagesize(lsm_db *pDb, int nPgsz, int nBlksz);
Snapshot *lsmDbSnapshotClient(lsm_db *);
Snapshot *lsmDbSnapshotWorker(lsm_db *);
Snapshot *lsmDbSnapshotRecover(lsm_db *);
void lsmDbSnapshotRelease(lsm_env *pEnv, Snapshot *);
void lsmSnapshotSetNBlock(Snapshot *, int);
int lsmSnapshotGetNBlock(Snapshot *);
void lsmSnapshotSetCkptid(Snapshot *, i64);
Level *lsmDbSnapshotLevel(Snapshot *);
void lsmDbSnapshotSetLevel(Snapshot *, Level *);
void lsmDbRecoveryComplete(lsm_db *, int);
int lsmBlockAllocate(lsm_db *, int *);
int lsmBlockFree(lsm_db *, int);
int lsmBlockRefree(lsm_db *, int);
void lsmFreelistDeltaBegin(lsm_db *);
void lsmFreelistDeltaEnd(lsm_db *);
void lsmFreelistDelta(lsm_db *, u32 *);
u32 *lsmFreelistDeltaPtr(lsm_db *pDb);
void lsmDatabaseDirty(lsm_db *pDb);
int lsmDatabaseIsDirty(lsm_db *pDb);
DbLog *lsmDatabaseLog(lsm_db *pDb);
Pgno *lsmSharedAppendList(lsm_db *db, int *pnApp);
int lsmSharedAppendListAdd(lsm_db *db, Pgno iPg);
void lsmSharedAppendListRemove(lsm_db *db, int iIdx);
#ifdef LSM_DEBUG
int lsmHoldingClientMutex(lsm_db *pDb);
#endif
/**************************************************************************
** functions in lsm_str.c
*/
void lsmStringInit(LsmString*, lsm_env *pEnv);
int lsmStringExtend(LsmString*, int);
int lsmStringAppend(LsmString*, const char *, int);
void lsmStringVAppendf(LsmString*, const char *zFormat, va_list, va_list);
void lsmStringAppendf(LsmString*, const char *zFormat, ...);
void lsmStringClear(LsmString*);
char *lsmMallocPrintf(lsm_env*, const char*, ...);
int lsmStringBinAppend(LsmString *pStr, const u8 *a, int n);
/*
** Round up a number to the next larger multiple of 8. This is used
** to force 8-byte alignment on 64-bit architectures.
*/
#define ROUND8(x) (((x)+7)&~7)
#define LSM_MIN(x,y) ((x)>(y) ? (y) : (x))
#define LSM_MAX(x,y) ((x)>(y) ? (x) : (y))
#endif
/************** End of lsmInt.h **********************************************/
/************** Continuing where we left off in lsm_ckpt.c *******************/
/*
** CHECKPOINT BLOB FORMAT:
**
** A checkpoint blob is a series of unsigned 32-bit integers stored in
** big-endian byte order. As follows:
**
** Checkpoint header (see the CKPT_HDR_XXX #defines):
**
** 1. The checkpoint id MSW.
** 2. The checkpoint id LSW.
** 3. The number of integer values in the entire checkpoint, including
** the two checksum values.
** 4. The total number of blocks in the database.
** 5. The block size.
** 6. The number of levels.
** 7. The nominal database page size.
**
** Log pointer:
**
** 4 integers. See ckptExportLog() and ckptImportLog().
**
** For each level in the database, a level record. Formatted as follows:
**
** 0. Age of the level.
** 1. The number of right-hand segments (possibly 0),
** 2. Segment record for left-hand segment (6 integers),
** 3. Segment record for each right-hand segment (6 integers),
** 4. If nRight>0, The number of segments involved in the merge,
** 5. Current nSkip value (see Merge structure defn.),
** 6. For each segment in the merge:
** 5a. Page number of next cell to read during merge
** 5b. Cell number of next cell to read during merge
**
** The freelist delta. Currently consists of (this will change):
**
** 1. The size to truncate the free list to after it is loaded.
** 2. First refree block (or 0),
** 3. Second refree block (or 0),
**
** The checksum:
**
** 1. Checksum value 1.
** 2. Checksum value 2.
**
** In the above, a segment record is:
**
** 1. First page of main array,
** 2. Last page of main array,
** 3. Size of main array in pages,
** 4. First page of separators array (or 0),
** 5. Last page of separators array (or 0),
** 6. Root page of separators array (or 0).
*/
/*
** OVERSIZED CHECKPOINT BLOBS:
**
** There are two slots allocated for checkpoints at the start of each
** database file. Each are 4096 bytes in size, so may accommodate
** checkpoints that consist of up to 1024 32-bit integers. Normally,
** this is enough.
**
** However, if a database contains a sufficiently large number of levels,
** a checkpoint may exceed 1024 integers in size. In most circumstances this
** is an undesirable scenario, as a database with so many levels will be
** slow to query. If this does happen, then only the uppermost (more recent)
** levels are stored in the checkpoint blob itself. The remainder are stored
** in an LSM record with the system key "LEVELS". The payload of the entry
** is a series of 32-bit big-endian integers, as follows:
**
** 1. Number of levels (store in the LEVELS record, not total).
** 2. For each level, a "level record" (as desribed above).
**
** There is no checksum in the LEVELS record.
*/
/*
** The argument to this macro must be of type u32. On a little-endian
** architecture, it returns the u32 value that results from interpreting
** the 4 bytes as a big-endian value. On a big-endian architecture, it
** returns the value that would be produced by intepreting the 4 bytes
** of the input value as a little-endian integer.
*/
#define BYTESWAP32(x) ( \
(((x)&0x000000FF)<<24) + (((x)&0x0000FF00)<<8) \
+ (((x)&0x00FF0000)>>8) + (((x)&0xFF000000)>>24) \
)
static const int one = 1;
#define LSM_LITTLE_ENDIAN (*(u8 *)(&one))
/* Total number of 32-bit integers in the checkpoint header. */
#define CKPT_HDRSIZE 7
/* A #define to describe each integer in the checkpoint header. */
#define CKPT_HDR_ID_MSW 0
#define CKPT_HDR_ID_LSW 1
#define CKPT_HDR_NCKPT 2
#define CKPT_HDR_NBLOCK 3
#define CKPT_HDR_BLKSZ 4
#define CKPT_HDR_NLEVEL 5
#define CKPT_HDR_PGSZ 6
/*
** Generate or extend an 8 byte checksum based on the data in array aByte[]
** and the initial values of aIn[0] and aIn[1] (or initial values of 0 and
** 0 if aIn==NULL).
**
** The checksum is written back into aOut[] before returning.
*/
void lsmChecksumBytes(
const u8 *a, /* Content to be checksummed */
int nByte, /* Bytes of content in a[] */
const u32 *aIn, /* Initial checksum value input */
u32 *aOut /* OUT: Final checksum value output */
){
u32 s1, s2;
u32 *aData = (u32 *)a;
u32 *aEnd = (u32 *)&a[nByte & ~0x00000007];
u32 aExtra[2] = {0, 0};
memcpy(aExtra, &a[nByte & ~0x00000007], nByte & 0x00000007);
if( aIn ){
s1 = aIn[0];
s2 = aIn[1];
}else{
s1 = s2 = 0;
}
if( LSM_LITTLE_ENDIAN ){
/* little-endian */
s1 += aExtra[0] + s2;
s2 += aExtra[1] + s1;
while( aData<aEnd ){
s1 += *aData++ + s2;
s2 += *aData++ + s1;
}
}else{
/* big-endian */
s1 += BYTESWAP32(aExtra[0]) + s2;
s2 += BYTESWAP32(aExtra[1]) + s1;
while( aData<aEnd ){
s1 += BYTESWAP32(aData[0]) + s2;
s2 += BYTESWAP32(aData[1]) + s1;
aData += 2;
}
}
aOut[0] = s1;
aOut[1] = s2;
}
typedef struct CkptBuffer CkptBuffer;
struct CkptBuffer {
lsm_env *pEnv;
int nAlloc;
u32 *aCkpt;
};
static void ckptSetValue(CkptBuffer *p, int iIdx, u32 iVal, int *pRc){
if( iIdx>=p->nAlloc ){
int nNew = LSM_MAX(8, iIdx*2);
p->aCkpt = (u32 *)lsmReallocOrFree(p->pEnv, p->aCkpt, nNew*sizeof(u32));
if( !p->aCkpt ){
*pRc = LSM_NOMEM_BKPT;
return;
}
p->nAlloc = nNew;
}
p->aCkpt[iIdx] = iVal;
}
static void ckptChangeEndianness(u32 *a, int n){
if( LSM_LITTLE_ENDIAN ){
int i;
for(i=0; i<n; i++) a[i] = BYTESWAP32(a[i]);
}
}
static void ckptAddChecksum(CkptBuffer *p, int nCkpt, int *pRc){
if( *pRc==LSM_OK ){
u32 aCksum[2] = {0, 0};
ckptChangeEndianness(p->aCkpt, nCkpt);
lsmChecksumBytes((u8 *)p->aCkpt, sizeof(u32)*nCkpt, 0, aCksum);
ckptChangeEndianness(aCksum, 2);
ckptSetValue(p, nCkpt, aCksum[0], pRc);
ckptSetValue(p, nCkpt+1, aCksum[1], pRc);
}
}
/*
** Append a 6-value segment record corresponding to pSeg to the checkpoint
** buffer passed as the third argument.
*/
static void ckptExportSegment(
Segment *pSeg,
CkptBuffer *p,
int *piOut,
int *pRc
){
int iOut = *piOut;
ckptSetValue(p, iOut++, pSeg->run.iFirst, pRc);
ckptSetValue(p, iOut++, pSeg->run.iLast, pRc);
ckptSetValue(p, iOut++, pSeg->run.nSize, pRc);
if( segmentHasSeparators(pSeg) ){
ckptSetValue(p, iOut++, pSeg->sep.iFirst, pRc);
ckptSetValue(p, iOut++, pSeg->sep.iLast, pRc);
ckptSetValue(p, iOut++, pSeg->sep.iRoot, pRc);
}else{
ckptSetValue(p, iOut++, 0, pRc);
ckptSetValue(p, iOut++, 0, pRc);
ckptSetValue(p, iOut++, 0, pRc);
}
*piOut = iOut;
}
static void ckptExportLevel(
Level *pLevel,
CkptBuffer *p,
int *piOut,
int *pRc
){
int iOut = *piOut;
Merge *pMerge;
pMerge = pLevel->pMerge;
ckptSetValue(p, iOut++, pLevel->iAge, pRc);
ckptSetValue(p, iOut++, pLevel->nRight, pRc);
ckptExportSegment(&pLevel->lhs, p, &iOut, pRc);
assert( (pLevel->nRight>0)==(pMerge!=0) );
if( pMerge ){
int i;
for(i=0; i<pLevel->nRight; i++){
ckptExportSegment(&pLevel->aRhs[i], p, &iOut, pRc);
}
assert( pMerge->nInput==pLevel->nRight
|| pMerge->nInput==pLevel->nRight+1
);
ckptSetValue(p, iOut++, pMerge->nInput, pRc);
ckptSetValue(p, iOut++, pMerge->nSkip, pRc);
for(i=0; i<pMerge->nInput; i++){
ckptSetValue(p, iOut++, pMerge->aInput[i].iPg, pRc);
ckptSetValue(p, iOut++, pMerge->aInput[i].iCell, pRc);
}
}
*piOut = iOut;
}
/*
** Write the current log offset into the checkpoint buffer. 4 values.
*/
static void ckptExportLog(DbLog *pLog, CkptBuffer *p, int *piOut, int *pRc){
int iOut = *piOut;
i64 iOff = pLog->aRegion[2].iEnd;
ckptSetValue(p, iOut++, (iOff >> 32) & 0xFFFFFFFF, pRc);
ckptSetValue(p, iOut++, (iOff & 0xFFFFFFFF), pRc);
ckptSetValue(p, iOut++, pLog->cksum0, pRc);
ckptSetValue(p, iOut++, pLog->cksum1, pRc);
*piOut = iOut;
}
/*
** Import a log offset.
*/
static void ckptImportLog(u32 *aIn, int *piIn, DbLog *pLog){
int iIn = *piIn;
/* TODO: Look at this again after updating lsmLogRecover() */
pLog->aRegion[2].iStart = (((i64)aIn[iIn]) << 32) + (i64)aIn[iIn+1];
pLog->cksum0 = aIn[iIn+2];
pLog->cksum1 = aIn[iIn+3];
*piIn = iIn+4;
}
lsm_i64 lsmCheckpointLogOffset(void *pExport){
u8 *aIn = (u8 *)pExport;
u32 i1;
u32 i2;
i1 = lsmGetU32(&aIn[CKPT_HDRSIZE*4]);
i2 = lsmGetU32(&aIn[CKPT_HDRSIZE*4+4]);
return (((i64)i1) << 32) + (i64)i2;
}
int lsmCheckpointExport(
lsm_db *pDb, /* Connection handle */
int nHdrLevel, /* Number of levels to store in checkpoint */
i64 iId, /* Checkpoint id */
int bCksum, /* If true, include checksums */
void **ppCkpt, /* OUT: Buffer containing checkpoint */
int *pnCkpt /* OUT: Size of checkpoint in bytes */
){
int rc = LSM_OK; /* Return Code */
FileSystem *pFS = pDb->pFS; /* File system object */
Snapshot *pSnap = pDb->pWorker; /* Worker snapshot */
u32 nLevel = 0; /* Number of levels in db file */
int iOut = 0; /* Current offset in aCkpt[] */
int i; /* Iterator used for several purposes */
Level *pLevel; /* Level iterator */
u32 aDelta[LSM_FREELIST_DELTA_SIZE];
CkptBuffer ckpt;
memset(&ckpt, 0, sizeof(CkptBuffer));
ckpt.pEnv = pDb->pEnv;
iOut = CKPT_HDRSIZE;
/* Write the current log offset */
ckptExportLog(lsmDatabaseLog(pDb), &ckpt, &iOut, &rc);
/* Export up to nHdrLevel levels. Or, if nHdrLevel==0, export all levels. */
for(pLevel=lsmDbSnapshotLevel(pSnap);
pLevel && (nHdrLevel==0 || nLevel<nHdrLevel);
pLevel=pLevel->pNext
){
ckptExportLevel(pLevel, &ckpt, &iOut, &rc);
nLevel++;
}
/* Write the freelist delta */
lsmFreelistDelta(pDb, aDelta);
for(i=0; i<LSM_FREELIST_DELTA_SIZE; i++){
ckptSetValue(&ckpt, iOut++, aDelta[i], &rc);
}
/* Write the checkpoint header */
assert( iId>=0 );
ckptSetValue(&ckpt, CKPT_HDR_ID_MSW, (u32)(iId>>32), &rc);
ckptSetValue(&ckpt, CKPT_HDR_ID_LSW, (u32)(iId&0xFFFFFFFF), &rc);
ckptSetValue(&ckpt, CKPT_HDR_NCKPT, iOut+2, &rc);
ckptSetValue(&ckpt, CKPT_HDR_NBLOCK, lsmSnapshotGetNBlock(pSnap), &rc);
ckptSetValue(&ckpt, CKPT_HDR_BLKSZ, lsmFsBlockSize(pFS), &rc);
ckptSetValue(&ckpt, CKPT_HDR_NLEVEL, nLevel, &rc);
ckptSetValue(&ckpt, CKPT_HDR_PGSZ, lsmFsPageSize(pFS), &rc);
if( bCksum ){
ckptAddChecksum(&ckpt, iOut, &rc);
}else{
ckptSetValue(&ckpt, iOut, 0, &rc);
ckptSetValue(&ckpt, iOut+1, 0, &rc);
}
iOut += 2;
assert( iOut<=1024 );
*ppCkpt = (void *)ckpt.aCkpt;
if( pnCkpt ) *pnCkpt = sizeof(u32)*iOut;
return rc;
}
/*
** Helper function for ckptImport().
*/
static void ckptNewSegment(
u32 *aIn,
int *piIn,
Segment *pSegment /* Populate this structure */
){
int iIn = *piIn;
assert( pSegment->run.iFirst==0 && pSegment->run.iLast==0 );
assert( pSegment->run.nSize==0 && pSegment->run.iRoot==0 );
assert( pSegment->sep.iFirst==0 && pSegment->sep.iLast==0 );
assert( pSegment->sep.nSize==0 && pSegment->sep.iRoot==0 );
pSegment->run.iFirst = aIn[iIn++];
pSegment->run.iLast = aIn[iIn++];
pSegment->run.nSize = aIn[iIn++];
pSegment->sep.iFirst = aIn[iIn++];
pSegment->sep.iLast = aIn[iIn++];
pSegment->sep.iRoot = aIn[iIn++];
if( pSegment->sep.iFirst ) pSegment->sep.nSize = 1;
*piIn = iIn;
}
static int ckptSetupMerge(lsm_db *pDb, u32 *aInt, int *piIn, Level *pLevel){
Merge *pMerge; /* Allocated Merge object */
int nInput; /* Number of input segments in merge */
int iIn = *piIn; /* Next value to read from aInt[] */
int i; /* Iterator variable */
int nByte; /* Number of bytes to allocate */
/* Allocate the Merge object. If malloc() fails, return LSM_NOMEM. */
nInput = (int)aInt[iIn++];
nByte = sizeof(Merge) + sizeof(MergeInput) * nInput;
pMerge = (Merge *)lsmMallocZero(pDb->pEnv, nByte);
if( !pMerge ) return LSM_NOMEM_BKPT;
pLevel->pMerge = pMerge;
/* Populate the Merge object. */
pMerge->aInput = (MergeInput *)&pMerge[1];
pMerge->nInput = nInput;
pMerge->aiOutputOff[0] = -1;
pMerge->aiOutputOff[1] = -1;
pMerge->nSkip = (int)aInt[iIn++];
pMerge->bHierReadonly = 1;
for(i=0; i<nInput; i++){
pMerge->aInput[i].iPg = (Pgno)aInt[iIn++];
pMerge->aInput[i].iCell = (int)aInt[iIn++];
}
/* Set *piIn and return LSM_OK. */
*piIn = iIn;
return LSM_OK;
}
static int ckptLoadLevels(
lsm_db *pDb,
u32 *aIn,
int *piIn,
int nLevel,
Level **ppLevel
){
int i;
int rc = LSM_OK;
Level *pRet = 0;
Level **ppNext;
int iIn = *piIn;
ppNext = &pRet;
for(i=0; rc==LSM_OK && i<nLevel; i++){
int iRight;
Level *pLevel;
/* Allocate space for the Level structure and Level.apRight[] array */
pLevel = (Level *)lsmMallocZeroRc(pDb->pEnv, sizeof(Level), &rc);
if( rc==LSM_OK ){
pLevel->iAge = aIn[iIn++];
pLevel->nRight = aIn[iIn++];
if( pLevel->nRight ){
int nByte = sizeof(Segment) * pLevel->nRight;
pLevel->aRhs = (Segment *)lsmMallocZeroRc(pDb->pEnv, nByte, &rc);
}
if( rc==LSM_OK ){
*ppNext = pLevel;
ppNext = &pLevel->pNext;
/* Allocate the main segment */
ckptNewSegment(aIn, &iIn, &pLevel->lhs);
/* Allocate each of the right-hand segments, if any */
for(iRight=0; iRight<pLevel->nRight; iRight++){
ckptNewSegment(aIn, &iIn, &pLevel->aRhs[iRight]);
}
/* Set up the Merge object, if required */
if( pLevel->nRight>0 ){
rc = ckptSetupMerge(pDb, aIn, &iIn, pLevel);
}
}
}
}
if( rc!=LSM_OK ){
/* An OOM must have occurred. Free any level structures allocated and
** return the error to the caller. */
lsmSortedFreeLevel(pDb->pEnv, pRet);
pRet = 0;
}
*ppLevel = pRet;
*piIn = iIn;
return rc;
}
static int ckptImport(lsm_db *pDb, void *pCkpt, int nInt, int *pRc){
int ret = 0;
if( *pRc==LSM_OK ){
Snapshot *pSnap = pDb->pWorker;
FileSystem *pFS = pDb->pFS;
u32 cksum[2] = {0, 0};
u32 *aInt = (u32 *)pCkpt;
lsmChecksumBytes((u8 *)aInt, sizeof(u32)*(nInt-2), 0, cksum);
if( LSM_LITTLE_ENDIAN ){
int i;
for(i=0; i<nInt; i++) aInt[i] = BYTESWAP32(aInt[i]);
}
if( aInt[nInt-2]==cksum[0] && aInt[nInt-1]==cksum[1] ){
int i;
int nLevel;
int iIn = CKPT_HDRSIZE;
i64 iId;
u32 *aDelta;
Level *pTopLevel = 0;
/* Read header fields */
iId = ((i64)aInt[CKPT_HDR_ID_MSW] << 32) + (i64)aInt[CKPT_HDR_ID_LSW];
lsmSnapshotSetCkptid(pSnap, iId);
nLevel = (int)aInt[CKPT_HDR_NLEVEL];
lsmSnapshotSetNBlock(pSnap, (int)aInt[CKPT_HDR_NBLOCK]);
lsmDbSetPagesize(pDb,(int)aInt[CKPT_HDR_PGSZ],(int)aInt[CKPT_HDR_BLKSZ]);
/* Import log offset */
ckptImportLog(aInt, &iIn, lsmDatabaseLog(pDb));
/* Import each level. This loop runs once for each db level. */
*pRc = ckptLoadLevels(pDb, aInt, &iIn, nLevel, &pTopLevel);
lsmDbSnapshotSetLevel(pSnap, pTopLevel);
/* Import the freelist delta */
aDelta = lsmFreelistDeltaPtr(pDb);
for(i=0; i<LSM_FREELIST_DELTA_SIZE; i++){
aDelta[i] = aInt[iIn++];
}
ret = 1;
}
assert( *pRc!=LSM_OK || lsmFsIntegrityCheck(pDb) );
}
return ret;
}
int lsmCheckpointLoadLevels(lsm_db *pDb, void *pVal, int nVal){
int rc = LSM_OK;
if( nVal>0 ){
u32 *aIn;
aIn = lsmMallocRc(pDb->pEnv, nVal, &rc);
if( aIn ){
Level *pLevel = 0;
Level *pParent;
int nIn;
int nLevel;
int iIn = 1;
memcpy(aIn, pVal, nVal);
nIn = nVal / sizeof(u32);
ckptChangeEndianness(aIn, nIn);
nLevel = aIn[0];
rc = ckptLoadLevels(pDb, aIn, &iIn, nLevel, &pLevel);
lsmFree(pDb->pEnv, aIn);
assert( rc==LSM_OK || pLevel==0 );
if( rc==LSM_OK ){
pParent = lsmDbSnapshotLevel(pDb->pWorker);
assert( pParent );
while( pParent->pNext ) pParent = pParent->pNext;
pParent->pNext = pLevel;
}
}
}
return rc;
}
/*
** If *pRc is not LSM_OK when this function is called, it is a no-op.
**
** Otherwise, it attempts to read the id and size of the checkpoint stored in
** slot iSlot of the database header. If an error occurs during processing,
** *pRc is set to an error code before returning. The returned value is
** always zero in this case.
**
** Or, if no error occurs, set *pnInt to the total number of integer values
** in the checkpoint and return the checkpoint id.
*/
static i64 ckptReadId(
lsm_db *pDb, /* Connection handle */
int iSlot, /* Slot to read from (1 or 2) */
int *pnInt, /* OUT: Size of slot checkpoint in ints */
int *pRc /* IN/OUT: Error code */
){
i64 iId = 0; /* Checkpoint id (return value) */
assert( iSlot==1 || iSlot==2 );
if( *pRc==LSM_OK ){
MetaPage *pPg; /* Meta page for slot iSlot */
*pRc = lsmFsMetaPageGet(pDb->pFS, 0, iSlot, &pPg);
if( *pRc==LSM_OK ){
u8 *aData = lsmFsMetaPageData(pPg, 0);
iId = (i64)lsmGetU32(&aData[CKPT_HDR_ID_MSW*4]) << 32;
iId += (i64)lsmGetU32(&aData[CKPT_HDR_ID_LSW*4]);
*pnInt = (int)lsmGetU32(&aData[CKPT_HDR_NCKPT*4]);
lsmFsMetaPageRelease(pPg);
}
}
return iId;
}
/*
** Attempt to load the checkpoint from slot iSlot. Return true if the
** attempt is successful.
*/
static int ckptTryRead(
lsm_db *pDb,
int iSlot,
int nCkpt,
int *pRc
){
int ret = 0;
assert( iSlot==1 || iSlot==2 );
if( *pRc==LSM_OK
&& nCkpt>=CKPT_HDRSIZE
&& nCkpt<65536
){
u32 *aCkpt;
aCkpt = (u32 *)lsmMallocZeroRc(pDb->pEnv, sizeof(u32)*nCkpt, pRc);
if( aCkpt ){
int rc = LSM_OK;
int iPg;
int nRem;
u8 *aRem;
/* Read the checkpoint data. */
nRem = sizeof(u32) * nCkpt;
aRem = (u8 *)aCkpt;
iPg = iSlot;
while( rc==LSM_OK && nRem ){
MetaPage *pPg;
rc = lsmFsMetaPageGet(pDb->pFS, 0, iPg, &pPg);
if( rc==LSM_OK ){
int nCopy;
int nData;
u8 *aData = lsmFsMetaPageData(pPg, &nData);
nCopy = LSM_MIN(nRem, nData);
memcpy(aRem, aData, nCopy);
aRem += nCopy;
nRem -= nCopy;
lsmFsMetaPageRelease(pPg);
}
iPg += 2;
}
ret = ckptImport(pDb, aCkpt, nCkpt, &rc);
lsmFree(pDb->pEnv, aCkpt);
*pRc = rc;
}
}
return ret;
}
/*
** Return the data for the LEVELS record.
**
** The size of the checkpoint that can be stored in the database header
** must not exceed 1024 32-bit integers. Normally, it does not. However,
** if it does, part of the checkpoint must be stored in the LSM. This
** routine returns that part.
*/
int lsmCheckpointLevels(
lsm_db *pDb, /* Database handle */
int *pnHdrLevel, /* OUT: Levels to write to db header */
void **paVal, /* OUT: Pointer to LEVELS blob */
int *pnVal /* OUT: Size of LEVELS blob in bytes */
){
int rc = LSM_OK; /* Return code */
const int SEGMENT_SIZE = 6; /* Size of a checkpoint segment record */
Level *p; /* Used to iterate through levels */
int nFree; /* Free integers remaining in db header */
int nHdr = 0; /* Number of levels stored in db header */
int nLevels = 0; /* Number of levels stored in LEVELS */
/* Number of free integers - 1024 less those used by the checkpoint header,
** less the 4 used for the log-pointer, less the 3 used for the
** free-list delta and the 2 used for the checkpoint checksum. */
nFree = 1024 - CKPT_HDRSIZE - 4 - 3 - 2;
/* Each level record not currently undergoing a merge consumes 2 + 6
** integers. Each level that is undergoing a merge consumes 2 + 6 +
** (nRhs * 6) + 1 + 1 + (nMerge * 2), where nRhs is the number of levels
** used as input to the merge and nMerge is the total number of segments
** (same as the number of levels, possibly plus 1 separators array).
**
** The calculation in the following block may overestimate the number
** of integers required by a single level by 2 (as it assumes
** that nMerge==nRhs+1).
*/
for(p=lsmDbSnapshotLevel(pDb->pWorker); p; p=p->pNext){
int nThis; /* Number of integers required by level p */
if( p->pMerge ){
nThis = 2 + (1 + p->nRight) * (2 + SEGMENT_SIZE) + 1 + 1;
}else{
nThis = 2 + SEGMENT_SIZE;
}
if( nFree<nThis ) break;
nFree -= nThis;
nHdr++;
}
if( p ){
int iOut;
CkptBuffer ckpt;
memset(&ckpt, 0, sizeof(CkptBuffer));
ckpt.pEnv = pDb->pEnv;
iOut = 1;
do{
nLevels++;
ckptExportLevel(p, &ckpt, &iOut, &rc);
} while( 0!=(p = p->pNext) );
ckptSetValue(&ckpt, 0, (u32)nLevels, &rc);
ckptChangeEndianness(ckpt.aCkpt, iOut);
*paVal = (void *)ckpt.aCkpt;
*pnVal = iOut * sizeof(u32);
}else{
*pnVal = 0;
*paVal = 0;
}
*pnHdrLevel = nHdr;
return rc;
}
int lsmCheckpointRead(lsm_db *pDb){
int rc = LSM_OK; /* Return Code */
i64 iId1;
i64 iId2;
int nInt1;
int nInt2;
int bLoaded = 0;
iId1 = ckptReadId(pDb, 1, &nInt1, &rc);
iId2 = ckptReadId(pDb, 2, &nInt2, &rc);
if( iId1>=iId2 ){
bLoaded = ckptTryRead(pDb, 1, nInt1, &rc);
if( bLoaded==0 ){
bLoaded = ckptTryRead(pDb, 2, nInt2, &rc);
}
}else{
bLoaded = ckptTryRead(pDb, 2, nInt2, &rc);
if( bLoaded==0 ){
bLoaded = ckptTryRead(pDb, 1, nInt1, &rc);
}
}
return rc;
}
/************** End of lsm_ckpt.c ********************************************/
/************** Begin file lsm_file.c ****************************************/
/*
** 2011-08-26
**
** 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.
**
*************************************************************************
**
** DATABASE FILE FORMAT
**
** The following database file format concepts are used by the code in
** this file to read and write the database file.
**
** Pages:
**
** A database file is divided into pages. The first 8KB of the file consists
** of two 4KB meta-pages. The meta-page size is not configurable. The
** remainder of the file is made up of database pages. The default database
** page size is 4KB. Database pages are aligned to page-size boundaries,
** so if the database page size is larger than 8KB there is a gap between
** the end of the meta pages and the start of the database pages.
**
** Database pages are numbered based on their position in the file. Page N
** begins at byte offset ((N-1)*pgsz). This means that page 1 does not
** exist - since it would always overlap with the meta pages. If the
** page-size is (say) 512 bytes, then the first usable page in the database
** is page 33.
**
** It is assumed that the first two meta pages and the data that follows
** them are located on different disk sectors. So that if a power failure
** while writing to a meta page there is no risk of damage to the other
** meta page or any other part of the database file.
**
** Blocks:
**
** The database file is also divided into blocks. The default block size is
** 2MB. When writing to the database file, an attempt is made to write data
** in contiguous block-sized chunks.
**
** The first and last page on each block are special in that they are 4
** bytes smaller than all other pages. This is because the last four bytes
** of space on the first and last pages of each block are reserved for a
** pointers to other blocks (i.e. a 32-bit block number).
**
** Runs:
**
** A run is a sequence of pages that the upper layer uses to store a
** sorted array of database keys (and accompanying data - values, FC
** pointers and so on). Given a page within a run, it is possible to
** navigate to the next page in the run as follows:
**
** a) if the current page is not the last in a block, the next page
** in the run is located immediately after the current page, OR
**
** b) if the current page is the last page in a block, the next page
** in the run is the first page on the block identified by the
** block pointer stored in the last 4 bytes of the current block.
**
** It is possible to navigate to the previous page in a similar fashion,
** using the block pointer embedded in the last 4 bytes of the first page
** of each block as required.
**
** The upper layer is responsible for identifying by page number the
** first and last page of any run that it needs to navigate - there are
** no "end-of-run" markers stored or identified by this layer. This is
** necessary as clients reading different database snapshots may access
** different subsets of a run.
**
** THE LOG FILE
**
** This file opens and closes the log file. But it does not contain any
** logic related to the log file format. Instead, it exports the following
** functions that are used by the code in lsm_log.c to read and write the
** log file:
**
** lsmFsWriteLog
** lsmFsSyncLog
** lsmFsReadLog
** lsmFsTruncateLog
** lsmFsCloseAndDeleteLog
**
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
/*
** A "phantom" run under construction.
**
** Phantom runs are constructed entirely in memory, then written out to
** disk. This is distinct from normal runs, for which each page is written
** to disk as soon as it is completely populated.
**
** They are used when the in-memory tree is flushed to disk. In this case,
** the main run is written directly to disk and the separators run
** accumulated in memory as a phantom run and flushed to disk after the main
** run is completed. This allows the separators run to immediately follow
** the main run in the file - making the entire flush operation a single
** contiguous write.
**
** Before they are flushed to disk, the pages of phantom runs do not have
** page numbers. This means it is not possible to obtain pointers to them.
** In practice, this means that when creating a separators run, a phantom
** run is used to accumulate and write all leaf pages to disk, then a
** second pass is made to populate and append the b-tree hierarchy pages.
*/
typedef struct PhantomRun PhantomRun;
struct PhantomRun {
SortedRun *pRun; /* Accompanying SortedRun object */
int nPhantom; /* Number of pages in run */
int bRunFinished; /* True if the associated run is finished */
Page *pFirst; /* First page in phantom run */
Page *pLast; /* Current last page in phantom run */
};
/*
** Maximum number of pages allowed to accumulate in memory when constructing
** a phantom run. If this limit is exceeded, the phantom run is flushed to
** disk even if it is not finished.
*/
#define FS_MAX_PHANTOM_PAGES 32
/*
** File-system object. Each database connection allocates a single instance
** of the following structure. It is used for all access to the database and
** log files.
**
** pLruFirst, pLruLast:
** The first and last entries in a doubly-linked list of pages. The
** Page.pLruNext and Page.pLruPrev pointers are used to link the list
** elements together.
**
** In mmap() mode, this list contains all currently allocated pages that
** are carrying pointers into the database file mapping (pMap/nMap). If the
** file has to be unmapped and then remapped (required to grow the mapping
** as the file grows), the Page.aData pointers are updated by iterating
** through the contents of this list.
**
** In non-mmap() mode, this list is an LRU list of cached pages with nRef==0.
*/
struct FileSystem {
lsm_db *pDb; /* Database handle that owns this object */
lsm_env *pEnv; /* Environment pointer */
char *zDb; /* Database file name */
int nMetasize; /* Size of meta pages in bytes */
int nPagesize; /* Database page-size in bytes */
int nBlocksize; /* Database block-size in bytes */
PhantomRun phantom; /* Phantom run currently under construction */
/* r/w file descriptors for both files. */
lsm_file *fdDb; /* Database file */
lsm_file *fdLog; /* Log file */
/* mmap() mode things */
int bUseMmap; /* True to use mmap() to access db file */
void *pMap; /* Current mapping of database file */
i64 nMap; /* Bytes mapped at pMap */
/* Statistics */
int nWrite; /* Total number of pages written */
int nRead; /* Total number of pages read */
/* Page cache parameters for non-mmap() mode */
int nOut; /* Number of outstanding pages */
int nCacheMax; /* Configured cache size (in pages) */
int nCacheAlloc; /* Current cache size (in pages) */
Page *pLruFirst; /* Head of the LRU list */
Page *pLruLast; /* Tail of the LRU list */
int nHash; /* Number of hash slots in hash table */
Page **apHash; /* nHash Hash slots */
};
/*
** Database page handle.
*/
struct Page {
u8 *aData; /* Buffer containing page data */
int iPg; /* Page number */
int nRef; /* Number of outstanding references */
int flags; /* Combination of PAGE_XXX flags */
Page *pHashNext; /* Next page in hash table slot */
Page *pLruNext; /* Next page in LRU list */
Page *pLruPrev; /* Previous page in LRU list */
FileSystem *pFS; /* File system that owns this page */
};
/*
** Meta-data page handle. There are two meta-data pages at the start of
** the database file, each FileSystem.nMetasize bytes in size.
*/
struct MetaPage {
int iPg; /* Either 1 or 2 */
int bWrite; /* Write back to db file on release */
u8 *aData; /* Pointer to buffer */
FileSystem *pFS; /* FileSystem that owns this page */
};
/*
** Values for LsmPage.flags
*/
#define PAGE_DIRTY 0x00000001 /* Set if page is dirty */
#define PAGE_FREE 0x00000002 /* Set if Page.aData requires lsmFree() */
#define PAGE_SHORT 0x00000004 /* Set if page is 4 bytes short */
/*
** Number of pgsz byte pages omitted from the start of block 1. The start
** of block 1 contains two 4096 byte meta pages (8192 bytes in total).
*/
#define BLOCK1_HDR_SIZE(pgsz) LSM_MAX(1, 8192/(pgsz))
/*
** Return true if the SortedRun passed as the second argument is a phantom
** run currently being constructed by FileSystem object pFS.
*/
#define isPhantom(pFS, pSorted) ((pSorted) && (pFS)->phantom.pRun==(pSorted))
/*
** Wrappers around the VFS methods of the lsm_env object:
**
** lsmEnvOpen()
** lsmEnvRead()
** lsmEnvWrite()
** lsmEnvSync()
** lsmEnvSectorSize()
** lsmEnvClose()
** lsmEnvTruncate()
** lsmEnvUnlink()
** lsmEnvRemap()
*/
static int lsmEnvOpen(lsm_env *pEnv, const char *zFile, lsm_file **ppNew){
return pEnv->xOpen(pEnv, zFile, ppNew);
}
static int lsmEnvRead(
lsm_env *pEnv,
lsm_file *pFile,
lsm_i64 iOff,
void *pRead,
int nRead
){
return pEnv->xRead(pFile, iOff, pRead, nRead);
}
static int lsmEnvWrite(
lsm_env *pEnv,
lsm_file *pFile,
lsm_i64 iOff,
void *pWrite,
int nWrite
){
return pEnv->xWrite(pFile, iOff, pWrite, nWrite);
}
static int lsmEnvSync(lsm_env *pEnv, lsm_file *pFile){
return pEnv->xSync(pFile);
}
static int lsmEnvSectorSize(lsm_env *pEnv, lsm_file *pFile){
return pEnv->xSectorSize(pFile);
}
static int lsmEnvClose(lsm_env *pEnv, lsm_file *pFile){
return pEnv->xClose(pFile);
}
static int lsmEnvTruncate(lsm_env *pEnv, lsm_file *pFile, lsm_i64 nByte){
return pEnv->xTruncate(pFile, nByte);
}
static int lsmEnvUnlink(lsm_env *pEnv, const char *zDel){
return pEnv->xUnlink(pEnv, zDel);
}
static int lsmEnvRemap(
lsm_env *pEnv,
lsm_file *pFile,
i64 szMin,
void **ppMap,
i64 *pszMap
){
return pEnv->xRemap(pFile, szMin, ppMap, pszMap);
}
/*
** Write the contents of string buffer pStr into the log file, starting at
** offset iOff.
*/
int lsmFsWriteLog(FileSystem *pFS, i64 iOff, LsmString *pStr){
return lsmEnvWrite(pFS->pEnv, pFS->fdLog, iOff, pStr->z, pStr->n);
}
/*
** fsync() the log file.
*/
int lsmFsSyncLog(FileSystem *pFS){
return lsmEnvSync(pFS->pEnv, pFS->fdLog);
}
/*
** Read nRead bytes of data starting at offset iOff of the log file. Store
** the results in string buffer pStr.
*/
int lsmFsReadLog(FileSystem *pFS, i64 iOff, int nRead, LsmString *pStr){
int rc; /* Return code */
rc = lsmStringExtend(pStr, nRead);
if( rc==LSM_OK ){
rc = lsmEnvRead(pFS->pEnv, pFS->fdLog, iOff, &pStr->z[pStr->n], nRead);
pStr->n += nRead;
}
return rc;
}
/*
** Truncate the log file to nByte bytes in size.
*/
int lsmFsTruncateLog(FileSystem *pFS, i64 nByte){
if( pFS->fdLog==0 ) return LSM_OK;
return lsmEnvTruncate(pFS->pEnv, pFS->fdLog, nByte);
}
/*
** Close the log file. Then delete it from the file-system. This function
** is called during database shutdown only.
*/
int lsmFsCloseAndDeleteLog(FileSystem *pFS){
if( pFS->fdLog ){
char *zDel = lsmMallocPrintf(pFS->pEnv, "%s-log", pFS->zDb);
if( zDel ){
lsmEnvClose(pFS->pEnv, pFS->fdLog );
lsmEnvUnlink(pFS->pEnv, zDel);
lsmFree(pFS->pEnv, zDel);
pFS->fdLog = 0;
}
}
return LSM_OK;
}
/*
** Given that there are currently nHash slots in the hash table, return
** the hash key for file iFile, page iPg.
*/
static int fsHashKey(int nHash, int iPg){
return (iPg % nHash);
}
/*
** This is a helper function for lsmFsOpen(). It opens a single file on
** disk (either the database or log file).
*/
static lsm_file *fsOpenFile(
FileSystem *pFS, /* File system object */
int bLog, /* True for log, false for db */
int *pRc /* IN/OUT: Error code */
){
lsm_file *pFile = 0;
if( *pRc==LSM_OK ){
char *zName;
zName = lsmMallocPrintf(pFS->pEnv, "%s%s", pFS->zDb, (bLog ? "-log" : ""));
if( !zName ){
*pRc = LSM_NOMEM;
}else{
*pRc = lsmEnvOpen(pFS->pEnv, zName, &pFile);
}
lsmFree(pFS->pEnv, zName);
}
return pFile;
}
/*
** Open a connection to a database stored within the file-system (the
** "system of files").
*/
int lsmFsOpen(lsm_db *pDb, const char *zDb){
FileSystem *pFS;
int rc = LSM_OK;
assert( pDb->pFS==0 );
assert( pDb->pWorker==0 && pDb->pClient==0 );
pFS = (FileSystem *)lsmMallocZeroRc(pDb->pEnv, sizeof(FileSystem), &rc);
if( pFS ){
pFS->nPagesize = LSM_PAGE_SIZE;
pFS->nBlocksize = LSM_BLOCK_SIZE;
pFS->nMetasize = 4 * 1024;
pFS->pDb = pDb;
pFS->pEnv = pDb->pEnv;
/* Make a copy of the database name. */
pFS->zDb = lsmMallocStrdup(pDb->pEnv, zDb);
if( pFS->zDb==0 ) rc = LSM_NOMEM;
/* Allocate the hash-table here. At some point, it should be changed
** so that it can grow dynamicly. */
pFS->nCacheMax = 2048;
pFS->nHash = 4096;
pFS->apHash = lsmMallocZeroRc(pDb->pEnv, sizeof(Page *) * pFS->nHash, &rc);
/* Open the files */
pFS->fdDb = fsOpenFile(pFS, 0, &rc);
pFS->fdLog = fsOpenFile(pFS, 1, &rc);
if( rc!=LSM_OK ){
lsmFsClose(pFS);
pFS = 0;
}
}
pDb->pFS = pFS;
return rc;
}
/*
** Close and destroy a FileSystem object.
*/
void lsmFsClose(FileSystem *pFS){
if( pFS ){
Page *pPg;
lsm_env *pEnv = pFS->pEnv;
assert( pFS->nOut==0 );
pPg = pFS->pLruFirst;
while( pPg ){
Page *pNext = pPg->pLruNext;
if( pPg->flags & PAGE_FREE ) lsmFree(pEnv, pPg->aData);
lsmFree(pEnv, pPg);
pPg = pNext;
}
if( pFS->fdDb ) lsmEnvClose(pFS->pEnv, pFS->fdDb );
if( pFS->fdLog ) lsmEnvClose(pFS->pEnv, pFS->fdLog );
lsmFree(pEnv, pFS->zDb);
lsmFree(pEnv, pFS->apHash);
lsmFree(pEnv, pFS);
}
}
/*
** Allocate a buffer and populate it with the output of the xFileid()
** method of the database file handle. If successful, set *ppId to point
** to the buffer and *pnId to the number of bytes in the buffer and return
** LSM_OK. Otherwise, set *ppId and *pnId to zero and return an LSM
** error code.
*/
int lsmFsFileid(lsm_db *pDb, void **ppId, int *pnId){
lsm_env *pEnv = pDb->pEnv;
FileSystem *pFS = pDb->pFS;
int rc;
int nId = 0;
void *pId;
rc = pEnv->xFileid(pFS->fdDb, 0, &nId);
pId = lsmMallocZeroRc(pEnv, nId, &rc);
if( rc==LSM_OK ) rc = pEnv->xFileid(pFS->fdDb, pId, &nId);
if( rc!=LSM_OK ){
lsmFree(pEnv, pId);
pId = 0;
nId = 0;
}
*ppId = pId;
*pnId = nId;
return rc;
}
/*
** Return the nominal page-size used by this file-system. Actual pages
** may be smaller or larger than this value.
*/
int lsmFsPageSize(FileSystem *pFS){
return pFS->nPagesize;
}
/*
** Return the block-size used by this file-system.
*/
int lsmFsBlockSize(FileSystem *pFS){
return pFS->nBlocksize;
}
/*
** Configure the nominal page-size used by this file-system. Actual
** pages may be smaller or larger than this value.
*/
void lsmFsSetPageSize(FileSystem *pFS, int nPgsz){
pFS->nPagesize = nPgsz;
}
/*
** Configure the block-size used by this file-system. Actual pages may be
** smaller or larger than this value.
*/
void lsmFsSetBlockSize(FileSystem *pFS, int nBlocksize){
pFS->nBlocksize = nBlocksize;
}
/*
** Return the page number of the first page on block iBlock. Blocks are
** numbered starting from 1.
*/
static Pgno fsFirstPageOnBlock(FileSystem *pFS, int iBlock){
const int nPagePerBlock = (pFS->nBlocksize / pFS->nPagesize);
int iPg;
if( iBlock==1 ){
iPg = 1 + ((pFS->nMetasize*2 + pFS->nPagesize - 1) / pFS->nPagesize);
}else{
iPg = 1 + (iBlock-1) * nPagePerBlock;
}
return iPg;
}
/*
** Return the page number of the last page on block iBlock. Blocks are
** numbered starting from 1.
*/
static Pgno fsLastPageOnBlock(FileSystem *pFS, int iBlock){
const int nPagePerBlock = (pFS->nBlocksize / pFS->nPagesize);
return iBlock * nPagePerBlock;
}
/*
** Return true if page iPg is the last page on its block.
*/
static int fsIsLast(FileSystem *pFS, Pgno iPg){
const int nPagePerBlock = (pFS->nBlocksize / pFS->nPagesize);
return ( iPg && (iPg % nPagePerBlock)==0 );
}
/*
** Return true if page iPg is the first page on its block.
*/
static int fsIsFirst(FileSystem *pFS, Pgno iPg){
const int nPagePerBlock = (pFS->nBlocksize / pFS->nPagesize);
return (
(iPg % nPagePerBlock)==1
|| (iPg<nPagePerBlock && iPg==fsFirstPageOnBlock(pFS, 1))
);
}
/*
** Given a page reference, return a pointer to the in-memory buffer of the
** pages contents. If parameter pnData is not NULL, set *pnData to the size
** of the buffer in bytes before returning.
*/
u8 *lsmFsPageData(Page *pPage, int *pnData){
if( pnData ){
#ifndef NDEBUG
int bShort = (
fsIsFirst(pPage->pFS, pPage->iPg) || fsIsLast(pPage->pFS, pPage->iPg)
);
assert( bShort==!!(pPage->flags & PAGE_SHORT) );
assert( PAGE_SHORT==4 );
#endif
*pnData = pPage->pFS->nPagesize - (pPage->flags & PAGE_SHORT);
}
return pPage->aData;
}
/*
** Return the page number of a page.
*/
Pgno lsmFsPageNumber(Page *pPage){
return pPage ? pPage->iPg : 0;
}
/*
** Page pPg is currently part of the LRU list belonging to pFS. Remove
** it from the list. pPg->pLruNext and pPg->pLruPrev are cleared by this
** operation.
*/
static void fsPageRemoveFromLru(FileSystem *pFS, Page *pPg){
assert( pPg->pLruNext || pPg==pFS->pLruLast );
assert( pPg->pLruPrev || pPg==pFS->pLruFirst );
if( pPg->pLruNext ){
pPg->pLruNext->pLruPrev = pPg->pLruPrev;
}else{
pFS->pLruLast = pPg->pLruPrev;
}
if( pPg->pLruPrev ){
pPg->pLruPrev->pLruNext = pPg->pLruNext;
}else{
pFS->pLruFirst = pPg->pLruNext;
}
pPg->pLruPrev = 0;
pPg->pLruNext = 0;
}
/*
** Page pPg is not currently part of the LRU list belonging to pFS. Add it.
*/
static void fsPageAddToLru(FileSystem *pFS, Page *pPg){
assert( pPg->pLruNext==0 && pPg->pLruPrev==0 );
pPg->pLruPrev = pFS->pLruLast;
if( pPg->pLruPrev ){
pPg->pLruPrev->pLruNext = pPg;
}else{
pFS->pLruFirst = pPg;
}
pFS->pLruLast = pPg;
}
static void fsPageRemoveFromHash(FileSystem *pFS, Page *pPg){
int iHash;
Page **pp;
iHash = fsHashKey(pFS->nHash, pPg->iPg);
for(pp=&pFS->apHash[iHash]; *pp!=pPg; pp=&(*pp)->pHashNext);
*pp = pPg->pHashNext;
}
static int fsPageBuffer(
FileSystem *pFS,
int bRequireData, /* True to allocate buffer as well */
Page **ppOut
){
int rc = LSM_OK;
Page *pPage = 0;
if( pFS->bUseMmap || pFS->pLruFirst==0 || pFS->nCacheAlloc<pFS->nCacheMax ){
pPage = lsmMallocZero(pFS->pEnv, sizeof(Page));
if( !pPage ){
rc = LSM_NOMEM_BKPT;
}else if( bRequireData ){
pPage->aData = (u8 *)lsmMalloc(pFS->pEnv, pFS->nPagesize);
pPage->flags = PAGE_FREE;
if( !pPage->aData ){
lsmFree(pFS->pEnv, pPage);
rc = LSM_NOMEM_BKPT;
pPage = 0;
}
pFS->nCacheAlloc++;
}else{
fsPageAddToLru(pFS, pPage);
}
}else{
pPage = pFS->pLruFirst;
fsPageRemoveFromLru(pFS, pPage);
fsPageRemoveFromHash(pFS, pPage);
}
assert( pPage==0 || (pPage->flags & PAGE_DIRTY)==0 );
*ppOut = pPage;
return rc;
}
static void fsPageBufferFree(Page *pPg){
if( pPg->flags & PAGE_FREE ){
lsmFree(pPg->pFS->pEnv, pPg->aData);
}
else if( pPg->pFS->bUseMmap ){
fsPageRemoveFromLru(pPg->pFS, pPg);
}
lsmFree(pPg->pFS->pEnv, pPg);
}
int fsPageToBlock(FileSystem *pFS, Pgno iPg){
return 1 + ((iPg-1) / (pFS->nBlocksize / pFS->nPagesize));
}
static void fsGrowMapping(
FileSystem *pFS,
i64 iSz,
int *pRc
){
if( *pRc==LSM_OK && iSz>pFS->nMap ){
Page *pFix;
int rc;
rc = lsmEnvRemap(pFS->pEnv, pFS->fdDb, iSz, &pFS->pMap, &pFS->nMap);
if( rc==LSM_OK ){
u8 *aData = (u8 *)pFS->pMap;
for(pFix=pFS->pLruFirst; pFix; pFix=pFix->pLruNext){
pFix->aData = &aData[pFS->nPagesize * (i64)(pFix->iPg-1)];
}
}
*pRc = rc;
}
}
/*
** Return a handle for a database page.
*/
int fsPageGet(
FileSystem *pFS, /* File-system handle */
Pgno iPg, /* Page id */
int noContent, /* True to not load content from disk */
Page **ppPg /* OUT: New page handle */
){
Page *p;
int iHash;
int rc = LSM_OK;
assert( iPg>=fsFirstPageOnBlock(pFS, 1) );
/* Search the hash-table for the page */
iHash = fsHashKey(pFS->nHash, iPg);
for(p=pFS->apHash[iHash]; p; p=p->pHashNext){
if( p->iPg==iPg) break;
}
if( p==0 ){
/* Set bRequireData to true if a buffer allocated by malloc() is required
** to store the page data (the alternative is to have the Page object
** carry a pointer into the mapped region at FileSystem.pMap). In
** non-mmap mode, this should always be true. In mmap mode, it should
** always be false for readable pages (noContent==0), but may be set
** to either true or false for appended pages (noContent==1). Setting
** it to true in this case causes LSM to do "double-buffered" writes. */
int bRequireData = (pFS->bUseMmap==0);
rc = fsPageBuffer(pFS, bRequireData, &p);
if( rc==LSM_OK ){
p->iPg = iPg;
p->nRef = 0;
p->pFS = pFS;
assert( p->flags==0 || p->flags==PAGE_FREE );
if( fsIsLast(pFS, iPg) || fsIsFirst(pFS, iPg) ) p->flags |= PAGE_SHORT;
if( pFS->bUseMmap && bRequireData==0 ){
i64 iEnd = (i64)iPg * pFS->nPagesize;
fsGrowMapping(pFS, iEnd, &rc);
if( rc==LSM_OK ){
p->aData = &((u8 *)pFS->pMap)[pFS->nPagesize * (i64)(iPg-1)];
}
}else{
#ifdef LSM_DEBUG
memset(p->aData, 0x56, pFS->nPagesize);
#endif
assert( p->pLruNext==0 && p->pLruPrev==0 );
if( noContent==0 ){
int nByte = pFS->nPagesize;
i64 iOff;
iOff = (i64)(iPg-1) * pFS->nPagesize;
rc = lsmEnvRead(pFS->pEnv, pFS->fdDb, iOff, p->aData, nByte);
pFS->nRead++;
}
}
/* If the xRead() call was successful (or not attempted), link the
** page into the page-cache hash-table. Otherwise, if it failed,
** free the buffer. */
if( rc==LSM_OK ){
p->pHashNext = pFS->apHash[iHash];
pFS->apHash[iHash] = p;
}else{
fsPageBufferFree(p);
p = 0;
}
}
}else if( p->nRef==0 && pFS->bUseMmap==0 ){
fsPageRemoveFromLru(pFS, p);
}
assert( (rc==LSM_OK && p) || (rc!=LSM_OK && p==0) );
if( rc==LSM_OK ){
pFS->nOut += (p->nRef==0);
p->nRef++;
}
*ppPg = p;
return rc;
}
static int fsBlockNext(
FileSystem *pFS,
int iBlock,
int *piNext
){
const int nPagePerBlock = (pFS->nBlocksize / pFS->nPagesize);
Page *pLast;
int rc;
rc = fsPageGet(pFS, iBlock*nPagePerBlock, 0, &pLast);
if( rc==LSM_OK ){
*piNext = fsPageToBlock(pFS, lsmGetU32(&pLast->aData[pFS->nPagesize-4]));
lsmFsPageRelease(pLast);
}
return rc;
}
static int fsRunEndsBetween(
SortedRun *pRun,
SortedRun *pIgnore,
int iFirst,
int iLast
){
return (pRun!=pIgnore && (
(pRun->iFirst>=iFirst && pRun->iFirst<=iLast)
|| (pRun->iLast>=iFirst && pRun->iLast<=iLast)
));
}
static int fsLevelEndsBetween(
Level *pLevel,
SortedRun *pIgnore,
int iFirst,
int iLast
){
int i;
if( fsRunEndsBetween(&pLevel->lhs.run, pIgnore, iFirst, iLast)
|| fsRunEndsBetween(&pLevel->lhs.sep, pIgnore, iFirst, iLast)
){
return 1;
}
for(i=0; i<pLevel->nRight; i++){
if( fsRunEndsBetween(&pLevel->aRhs[i].run, pIgnore, iFirst, iLast)
|| fsRunEndsBetween(&pLevel->aRhs[i].sep, pIgnore, iFirst, iLast)
){
return 1;
}
}
return 0;
}
static int fsFreeBlock(
FileSystem *pFS,
Snapshot *pSnapshot,
SortedRun *pIgnore, /* Ignore this run when searching */
int iBlk
){
int rc = LSM_OK; /* Return code */
int iFirst; /* First page on block iBlk */
int iLast; /* Last page on block iBlk */
int i; /* Used to iterate through append points */
Level *pLevel; /* Used to iterate through levels */
Pgno *aAppend;
int nAppend;
iFirst = fsFirstPageOnBlock(pFS, iBlk);
iLast = fsLastPageOnBlock(pFS, iBlk);
/* Check if any other run in the snapshot has a start or end page
** within this block. If there is such a run, return early. */
for(pLevel=lsmDbSnapshotLevel(pSnapshot); pLevel; pLevel=pLevel->pNext){
if( fsLevelEndsBetween(pLevel, pIgnore, iFirst, iLast) ){
return LSM_OK;
}
}
aAppend = lsmSharedAppendList(pFS->pDb, &nAppend);
for(i=0; i<nAppend; i++){
if( aAppend[i]>=iFirst && aAppend[i]<=iLast ){
lsmSharedAppendListRemove(pFS->pDb, i);
break;
}
}
if( rc==LSM_OK ){
rc = lsmBlockFree(pFS->pDb, iBlk);
}
return rc;
}
/*
** Delete or otherwise recycle the blocks currently occupied by run pDel.
*/
int lsmFsSortedDelete(
FileSystem *pFS,
Snapshot *pSnapshot,
int bZero, /* True to zero the SortedRun structure */
SortedRun *pDel
){
if( pDel->iFirst ){
int rc = LSM_OK;
int iBlk;
int iLastBlk;
iBlk = fsPageToBlock(pFS, pDel->iFirst);
iLastBlk = fsPageToBlock(pFS, pDel->iLast);
/* Mark all blocks currently used by this sorted run as free */
while( iBlk && rc==LSM_OK ){
int iNext = 0;
if( iBlk!=iLastBlk ){
rc = fsBlockNext(pFS, iBlk, &iNext);
}else if( bZero==0 && pDel->iLast!=fsLastPageOnBlock(pFS, iLastBlk) ){
break;
}
rc = fsFreeBlock(pFS, pSnapshot, pDel, iBlk);
iBlk = iNext;
}
if( bZero ) memset(pDel, 0, sizeof(SortedRun));
}
return LSM_OK;
}
/*
** The pager reference passed as the only argument must refer to a sorted
** file page (not a log or meta page). This call indicates that the argument
** page is now the first page in its sorted file - all previous pages may
** be considered free.
*/
void lsmFsGobble(
Snapshot *pSnapshot,
SortedRun *pRun,
Page *pPg
){
FileSystem *pFS = pPg->pFS;
if( pPg->iPg!=pRun->iFirst ){
int rc = LSM_OK;
int iBlk = fsPageToBlock(pFS, pRun->iFirst);
int iFirstBlk = fsPageToBlock(pFS, pPg->iPg);
pRun->nSize += (pRun->iFirst - fsFirstPageOnBlock(pFS, iBlk));
pRun->iFirst = pPg->iPg;
while( rc==LSM_OK && iBlk!=iFirstBlk ){
int iNext = 0;
rc = fsBlockNext(pFS, iBlk, &iNext);
if( rc==LSM_OK ) rc = fsFreeBlock(pFS, pSnapshot, 0, iBlk);
pRun->nSize -= (
1 + fsLastPageOnBlock(pFS, iBlk) - fsFirstPageOnBlock(pFS, iBlk)
);
iBlk = iNext;
}
pRun->nSize -= (pRun->iFirst - fsFirstPageOnBlock(pFS, iBlk));
assert( pRun->nSize>0 );
}
}
/*
** The first argument to this function is a valid reference to a database
** file page that is part of a sorted run. If parameter eDir is -1, this
** function attempts to locate and load the previous page in the same run.
** Or, if eDir is +1, it attempts to find the next page in the same run.
** The results of passing an eDir value other than positive or negative one
** are undefined.
**
** If parameter pRun is not NULL then it must point to the run that page
** pPg belongs to. In this case, if pPg is the first or last page of the
** run, and the request is for the previous or next page, respectively,
** *ppNext is set to NULL before returning LSM_OK. If pRun is NULL, then it
** is assumed that the next or previous page, as requested, exists.
**
** If the previous/next page does exist and is successfully loaded, *ppNext
** is set to point to it and LSM_OK is returned. Otherwise, if an error
** occurs, *ppNext is set to NULL and and lsm error code returned.
**
** Page references returned by this function should be released by the
** caller using lsmFsPageRelease().
*/
int lsmFsDbPageNext(SortedRun *pRun, Page *pPg, int eDir, Page **ppNext){
FileSystem *pFS = pPg->pFS;
int iPg = pPg->iPg;
assert( eDir==1 || eDir==-1 );
if( eDir<0 ){
if( pRun && iPg==pRun->iFirst ){
*ppNext = 0;
return LSM_OK;
}else if( fsIsFirst(pFS, iPg) ){
iPg = lsmGetU32(&pPg->aData[pFS->nPagesize-4]);
}else{
iPg--;
}
}else{
if( pRun && iPg==pRun->iLast ){
*ppNext = 0;
return LSM_OK;
}else if( fsIsLast(pFS, iPg) ){
iPg = lsmGetU32(&pPg->aData[pFS->nPagesize-4]);
}else{
iPg++;
}
}
return fsPageGet(pFS, iPg, 0, ppNext);
}
static Pgno findAppendPoint(FileSystem *pFS, int nMin){
Pgno ret = 0;
Pgno *aAppend;
int nAppend;
int i;
aAppend = lsmSharedAppendList(pFS->pDb, &nAppend);
for(i=0; i<nAppend; i++){
Pgno iLastOnBlock;
iLastOnBlock = fsLastPageOnBlock(pFS, fsPageToBlock(pFS, aAppend[i]));
if( (iLastOnBlock - aAppend[i])>=nMin ){
ret = aAppend[i];
lsmSharedAppendListRemove(pFS->pDb, i);
break;
}
}
return ret;
}
static void addAppendPoint(
lsm_db *db,
Pgno iLast,
int *pRc /* IN/OUT: Error code */
){
if( *pRc==LSM_OK && iLast>0 ){
FileSystem *pFS = db->pFS;
Pgno *aPoint;
int nPoint;
int i;
int iBlk;
int bLast;
iBlk = fsPageToBlock(pFS, iLast);
bLast = (iLast==fsLastPageOnBlock(pFS, iBlk));
aPoint = lsmSharedAppendList(db, &nPoint);
for(i=0; i<nPoint; i++){
if( iBlk==fsPageToBlock(pFS, aPoint[i]) ){
if( bLast ){
lsmSharedAppendListRemove(db, i);
}else if( iLast>=aPoint[i] ){
aPoint[i] = iLast+1;
}
return;
}
}
if( bLast==0 ){
*pRc = lsmSharedAppendListAdd(db, iLast+1);
}
}
}
static void subAppendPoint(lsm_db *db, Pgno iFirst){
if( iFirst>0 ){
FileSystem *pFS = db->pFS;
Pgno *aPoint;
int nPoint;
int i;
int iBlk;
iBlk = fsPageToBlock(pFS, iFirst);
aPoint = lsmSharedAppendList(db, &nPoint);
for(i=0; i<nPoint; i++){
if( iBlk==fsPageToBlock(pFS, aPoint[i]) ){
if( iFirst>=aPoint[i] ) lsmSharedAppendListRemove(db, i);
return;
}
}
}
}
int lsmFsSetupAppendList(lsm_db *db){
int rc = LSM_OK;
Level *pLvl;
assert( db->pWorker );
for(pLvl=lsmDbSnapshotLevel(db->pWorker);
rc==LSM_OK && pLvl;
pLvl=pLvl->pNext
){
if( pLvl->nRight==0 ){
addAppendPoint(db, pLvl->lhs.sep.iLast, &rc);
addAppendPoint(db, pLvl->lhs.run.iLast, &rc);
}else{
int i;
for(i=0; i<pLvl->nRight; i++){
addAppendPoint(db, pLvl->aRhs[i].sep.iLast, &rc);
addAppendPoint(db, pLvl->aRhs[i].run.iLast, &rc);
}
}
}
for(pLvl=lsmDbSnapshotLevel(db->pWorker); pLvl; pLvl=pLvl->pNext){
int i;
subAppendPoint(db, pLvl->lhs.sep.iFirst);
subAppendPoint(db, pLvl->lhs.run.iFirst);
for(i=0; i<pLvl->nRight; i++){
subAppendPoint(db, pLvl->aRhs[i].sep.iFirst);
subAppendPoint(db, pLvl->aRhs[i].run.iFirst);
}
}
return rc;
}
int lsmFsPhantom(FileSystem *pFS, SortedRun *pRun){
assert( pFS->phantom.pRun==0 );
pFS->phantom.pRun = pRun;
return LSM_OK;
}
void lsmFsPhantomFree(FileSystem *pFS){
if( pFS->phantom.pRun ){
Page *pPg;
Page *pNext;
for(pPg=pFS->phantom.pFirst; pPg; pPg=pNext){
pNext = pPg->pHashNext;
fsPageBufferFree(pPg);
}
memset(&pFS->phantom, 0, sizeof(PhantomRun));
}
}
int lsmFsPhantomMaterialize(
FileSystem *pFS,
Snapshot *pSnapshot,
SortedRun *p
){
int rc = LSM_OK;
if( isPhantom(pFS, p) ){
PhantomRun *pPhantom = &pFS->phantom;
Page *pPg;
Page *pNext;
int i;
Pgno iFirst = 0;
/* Search for an existing run in the database that this run can be
** appended to. See comments surrounding findAppendPoint() for details. */
iFirst = findAppendPoint(pFS, pPhantom->nPhantom);
/* If the array can not be written into any partially used block,
** allocate a new block. The first page of the materialized run will
** be the second page of the new block (since the first is undersized
** and can not be used). */
if( iFirst==0 ){
int iNew; /* New block */
lsmBlockAllocate(pFS->pDb, &iNew);
iFirst = fsFirstPageOnBlock(pFS, iNew) + 1;
}
p->iFirst = iFirst;
p->iLast = iFirst + pPhantom->nPhantom - 1;
assert( 0==fsIsFirst(pFS, p->iFirst) && 0==fsIsLast(pFS, p->iFirst) );
assert( 0==fsIsFirst(pFS, p->iLast) && 0==fsIsLast(pFS, p->iLast) );
assert( fsPageToBlock(pFS, p->iFirst)==fsPageToBlock(pFS, p->iLast) );
i = iFirst;
for(pPg=pPhantom->pFirst; pPg; pPg=pNext){
int iHash;
pNext = pPg->pHashNext;
pPg->iPg = i++;
pPg->nRef++;
iHash = fsHashKey(pFS->nHash, pPg->iPg);
pPg->pHashNext = pFS->apHash[iHash];
pFS->apHash[iHash] = pPg;
pFS->nOut++;
lsmFsPageRelease(pPg);
}
assert( i==p->iLast+1 );
p->nSize = pPhantom->nPhantom;
memset(&pFS->phantom, 0, sizeof(PhantomRun));
}
return rc;
}
/*
** Append a page to file iFile. Return a reference to it. lsmFsPageWrite()
** has already been called on the returned reference.
*/
int lsmFsSortedAppend(
FileSystem *pFS,
Snapshot *pSnapshot,
SortedRun *p,
Page **ppOut
){
int rc = LSM_OK;
Page *pPg = 0;
*ppOut = 0;
if( isPhantom(pFS, p) ){
const int nPagePerBlock = (pFS->nBlocksize / pFS->nPagesize);
int nLimit = (nPagePerBlock - 2 - (fsFirstPageOnBlock(pFS, 1)-1) );
if( pFS->phantom.nPhantom>=nLimit ){
rc = lsmFsPhantomMaterialize(pFS, pSnapshot, p);
if( rc!=LSM_OK ) return rc;
}
}
if( isPhantom(pFS, p) ){
rc = fsPageBuffer(pFS, 1, &pPg);
if( rc==LSM_OK ){
PhantomRun *pPhantom = &pFS->phantom;
pPg->iPg = 0;
pPg->nRef = 1;
pPg->flags |= PAGE_DIRTY;
pPg->pHashNext = 0;
pPg->pLruNext = 0;
pPg->pLruPrev = 0;
pPg->pFS = pFS;
if( pPhantom->pFirst ){
assert( pPhantom->pLast );
pPhantom->pLast->pHashNext = pPg;
}else{
pPhantom->pFirst = pPg;
}
pPhantom->pLast = pPg;
pPhantom->nPhantom++;
}
}else{
int iApp = 0;
int iNext = 0;
int iPrev = p->iLast;
if( iPrev==0 ){
iApp = findAppendPoint(pFS, 0);
}else if( fsIsLast(pFS, iPrev) ){
Page *pLast = 0;
rc = fsPageGet(pFS, iPrev, 0, &pLast);
if( rc!=LSM_OK ) return rc;
iApp = lsmGetU32(&pLast->aData[pFS->nPagesize-4]);
lsmFsPageRelease(pLast);
}else{
iApp = iPrev + 1;
}
/* If this is the first page allocated, or if the page allocated is the
** last in the block, allocate a new block here. */
if( iApp==0 || fsIsLast(pFS, iApp) ){
int iNew; /* New block number */
lsmBlockAllocate(pFS->pDb, &iNew);
if( iApp==0 ){
iApp = fsFirstPageOnBlock(pFS, iNew);
}else{
iNext = fsFirstPageOnBlock(pFS, iNew);
}
}
/* Grab the new page. */
pPg = 0;
rc = fsPageGet(pFS, iApp, 1, &pPg);
assert( rc==LSM_OK || pPg==0 );
/* If this is the first or last page of a block, fill in the pointer
** value at the end of the new page. */
if( rc==LSM_OK ){
p->nSize++;
p->iLast = iApp;
if( p->iFirst==0 ) p->iFirst = iApp;
pPg->flags |= PAGE_DIRTY;
if( fsIsLast(pFS, iApp) ){
lsmPutU32(&pPg->aData[pFS->nPagesize-4], iNext);
}else
if( fsIsFirst(pFS, iApp) ){
lsmPutU32(&pPg->aData[pFS->nPagesize-4], iPrev);
}
}
}
*ppOut = pPg;
return rc;
}
/*
** Mark the sorted run passed as the second argument as finished.
*/
int lsmFsSortedFinish(FileSystem *pFS, SortedRun *p){
int rc = LSM_OK;
if( p ){
const int nPagePerBlock = (pFS->nBlocksize / pFS->nPagesize);
if( pFS->phantom.pRun ) pFS->phantom.bRunFinished = 1;
/* Check if the last page of this run happens to be the last of a block.
** If it is, then an extra block has already been allocated for this run.
** Shift this extra block back to the free-block list.
**
** Otherwise, add the first free page in the last block used by the run
** to the lAppend list.
*/
if( (p->iLast % nPagePerBlock)==0 ){
Page *pLast;
rc = fsPageGet(pFS, p->iLast, 0, &pLast);
if( rc==LSM_OK ){
int iPg = (int)lsmGetU32(&pLast->aData[pFS->nPagesize-4]);
int iBlk = fsPageToBlock(pFS, iPg);
lsmBlockRefree(pFS->pDb, iBlk);
lsmFsPageRelease(pLast);
}
}else{
rc = lsmSharedAppendListAdd(pFS->pDb, p->iLast+1);
}
}
return rc;
}
/*
** Obtain a reference to page number iPg.
*/
int lsmFsDbPageGet(FileSystem *pFS, int iPg, Page **ppPg){
assert( pFS );
return fsPageGet(pFS, iPg, 0, ppPg);
}
/*
** Return a reference to meta-page iPg. If successful, LSM_OK is returned
** and *ppPg populated with the new page reference. The reference should
** be released by the caller using lsmFsPageRelease().
**
** Otherwise, if an error occurs, *ppPg is set to NULL and an LSM error
** code is returned.
*/
int lsmFsMetaPageGet(
FileSystem *pFS, /* File-system connection */
int bWrite, /* True for write access, false for read */
int iPg, /* Either 1 or 2 */
MetaPage **ppPg /* OUT: Pointer to MetaPage object */
){
int rc = LSM_OK;
MetaPage *pPg;
assert( iPg==1 || iPg==2 );
pPg = lsmMallocZeroRc(pFS->pEnv, sizeof(Page), &rc);
if( pPg ){
i64 iOff = (iPg-1) * pFS->nMetasize;
if( pFS->bUseMmap ){
fsGrowMapping(pFS, 2*pFS->nMetasize, &rc);
pPg->aData = (u8 *)(pFS->pMap) + iOff;
}else{
pPg->aData = lsmMallocRc(pFS->pEnv, pFS->nMetasize, &rc);
if( rc==LSM_OK && bWrite==0 ){
rc = lsmEnvRead(pFS->pEnv, pFS->fdDb, iOff, pPg->aData, pFS->nMetasize);
}
}
if( rc!=LSM_OK ){
if( pFS->bUseMmap==0 ) lsmFree(pFS->pEnv, pPg->aData);
lsmFree(pFS->pEnv, pPg);
pPg = 0;
}else{
pPg->iPg = iPg;
pPg->bWrite = bWrite;
pPg->pFS = pFS;
}
}
*ppPg = pPg;
return rc;
}
/*
** Release a meta-page reference obtained via a call to lsmFsMetaPageGet().
*/
int lsmFsMetaPageRelease(MetaPage *pPg){
int rc = LSM_OK;
if( pPg ){
FileSystem *pFS = pPg->pFS;
if( pFS->bUseMmap==0 ){
if( pPg->bWrite ){
i64 iOff = (pPg->iPg==2 ? pFS->nMetasize : 0);
int nWrite = pFS->nMetasize;
rc = lsmEnvWrite(pFS->pEnv, pFS->fdDb, iOff, pPg->aData, nWrite);
}
lsmFree(pFS->pEnv, pPg->aData);
}
lsmFree(pFS->pEnv, pPg);
}
return rc;
}
/*
** Return a pointer to a buffer containing the data associated with the
** meta-page passed as the first argument. If parameter pnData is not NULL,
** set *pnData to the size of the meta-page in bytes before returning.
*/
u8 *lsmFsMetaPageData(MetaPage *pPg, int *pnData){
if( pnData ) *pnData = pPg->pFS->nMetasize;
return pPg->aData;
}
/*
** Notify the file-system that the page needs to be written back to disk
** when the reference count next drops to zero.
*/
int lsmFsPageWrite(Page *pPg){
pPg->flags |= PAGE_DIRTY;
return LSM_OK;
}
/*
** Return true if page is currently writable.
*/
int lsmFsPageWritable(Page *pPg){
return (pPg->flags & PAGE_DIRTY) ? 1 : 0;
}
/*
** If the page passed as an argument is dirty, update the database file
** (or mapping of the database file) with its current contents and mark
** the page as clean.
**
** Return LSM_OK if the operation is a success, or an LSM error code
** otherwise.
*/
int lsmFsPagePersist(Page *pPg){
int rc = LSM_OK;
if( pPg && (pPg->flags & PAGE_DIRTY) ){
FileSystem *pFS = pPg->pFS;
i64 iOff; /* Offset to write within database file */
iOff = (i64)pFS->nPagesize * (i64)(pPg->iPg-1);
if( pFS->bUseMmap==0 ){
rc = lsmEnvWrite(pFS->pEnv, pFS->fdDb, iOff, pPg->aData,pFS->nPagesize);
}else if( pPg->flags & PAGE_FREE ){
fsGrowMapping(pFS, iOff + pFS->nPagesize, &rc);
if( rc==LSM_OK ){
u8 *aTo = &((u8 *)(pFS->pMap))[iOff];
memcpy(aTo, pPg->aData, pFS->nPagesize);
lsmFree(pFS->pEnv, pPg->aData);
pPg->aData = aTo;
pPg->flags &= ~PAGE_FREE;
fsPageAddToLru(pFS, pPg);
}
}
pPg->flags &= ~PAGE_DIRTY;
pFS->nWrite++;
}
return rc;
}
/*
** Increment the reference count on the page object passed as the first
** argument.
*/
void lsmFsPageRef(Page *pPg){
if( pPg ){
pPg->nRef++;
}
}
/*
** Release a page-reference obtained using fsPageGet().
*/
int lsmFsPageRelease(Page *pPg){
int rc = LSM_OK;
if( pPg ){
assert( pPg->nRef>0 );
pPg->nRef--;
if( pPg->nRef==0 && pPg->iPg!=0 ){
FileSystem *pFS = pPg->pFS;
rc = lsmFsPagePersist(pPg);
pFS->nOut--;
assert( pFS->bUseMmap || pPg->pLruNext==0 );
assert( pFS->bUseMmap || pPg->pLruPrev==0 );
#if 0
fsPageAddToLru(pFS, pPg);
#else
fsPageRemoveFromHash(pFS, pPg);
fsPageBufferFree(pPg);
#endif
}
}
return rc;
}
/*
** Return the total number of pages read from the database file.
*/
int lsmFsNRead(FileSystem *pFS){ return pFS->nRead; }
/*
** Return the total number of pages written to the database file.
*/
int lsmFsNWrite(FileSystem *pFS){ return pFS->nWrite; }
/*
** fsync() the database file.
*/
int lsmFsSyncDb(FileSystem *pFS){
return lsmEnvSync(pFS->pEnv, pFS->fdDb);
}
/*
** Return a copy of the environment pointer used by the file-system object.
*/
lsm_env *lsmFsEnv(FileSystem *pFS) {
return pFS->pEnv;
}
/*
** Return a copy of the environment pointer used by the file-system object
** to which this page belongs.
*/
lsm_env *lsmPageEnv(Page *pPg) {
return pPg->pFS->pEnv;
}
/*
** Return the sector-size as reported by the log file handle.
*/
int lsmFsSectorSize(FileSystem *pFS){
return lsmEnvSectorSize(pFS->pEnv, pFS->fdLog);
}
/*
** This function implements the lsm_config(LSM_CONFIG_MMAP) request. This
** setting may only be modified if there are currently no outstanding page
** references.
*/
int lsmConfigMmap(lsm_db *pDb, int *piParam){
int iNew = *piParam;
FileSystem *pFS = pDb->pFS;
if( pFS->nOut==0 && (iNew==0 || iNew==1) ){
pFS->bUseMmap = iNew;
}
*piParam = pFS->bUseMmap;
return LSM_OK;
}
/*
** Helper function for lsmInfoArrayStructure().
*/
static SortedRun *startsWith(SortedRun *pRun, Pgno iFirst){
return (iFirst==pRun->iFirst) ? pRun : 0;
}
/*
** This function implements the lsm_info(LSM_INFO_ARRAY_STRUCTURE) request.
** If successful, *pzOut is set to point to a nul-terminated string
** containing the array structure and LSM_OK is returned. The caller should
** eventually free the string using lsmFree().
**
** If an error occurs, *pzOut is set to NULL and an LSM error code returned.
*/
int lsmInfoArrayStructure(lsm_db *pDb, Pgno iFirst, char **pzOut){
int rc = LSM_OK;
Snapshot *pWorker; /* Worker snapshot */
Snapshot *pRelease = 0; /* Snapshot to release */
SortedRun *pArray = 0; /* Array to report on */
Level *pLvl; /* Used to iterate through db levels */
*pzOut = 0;
if( iFirst==0 ) return LSM_ERROR;
/* Obtain the worker snapshot */
pWorker = pDb->pWorker;
if( !pWorker ){
pRelease = pWorker = lsmDbSnapshotWorker(pDb);
}
/* Search for the array that starts on page iFirst */
for(pLvl=lsmDbSnapshotLevel(pWorker); pLvl && pArray==0; pLvl=pLvl->pNext){
if( 0==(pArray = startsWith(&pLvl->lhs.sep, iFirst))
&& 0==(pArray = startsWith(&pLvl->lhs.run, iFirst))
){
int i;
for(i=0; i<pLvl->nRight; i++){
if( (pArray = startsWith(&pLvl->aRhs[i].sep, iFirst)) ) break;
if( (pArray = startsWith(&pLvl->aRhs[i].run, iFirst)) ) break;
}
}
}
if( pArray==0 ){
/* Could not find the requested array. This is an error. */
*pzOut = 0;
rc = LSM_ERROR;
}else{
FileSystem *pFS = pDb->pFS;
LsmString str;
int iBlk;
int iLastBlk;
iBlk = fsPageToBlock(pFS, pArray->iFirst);
iLastBlk = fsPageToBlock(pFS, pArray->iLast);
lsmStringInit(&str, pDb->pEnv);
lsmStringAppendf(&str, "%d", pArray->iFirst);
while( iBlk!=iLastBlk ){
lsmStringAppendf(&str, " %d", fsLastPageOnBlock(pFS, iBlk));
fsBlockNext(pFS, iBlk, &iBlk);
lsmStringAppendf(&str, " %d", fsFirstPageOnBlock(pFS, iBlk));
}
lsmStringAppendf(&str, " %d", pArray->iLast);
*pzOut = str.z;
}
lsmDbSnapshotRelease(pDb->pEnv, pRelease);
return rc;
}
void lsmFsDumpBlockmap(lsm_db *pDb, SortedRun *p){
if( p ){
FileSystem *pFS = pDb->pFS;
int iBlk;
int iLastBlk;
char *zMsg = 0;
LsmString zBlk;
lsmStringInit(&zBlk, pDb->pEnv);
iBlk = fsPageToBlock(pFS, p->iFirst);
iLastBlk = fsPageToBlock(pFS, p->iLast);
while( iBlk ){
lsmStringAppendf(&zBlk, " %d", iBlk);
if( iBlk!=iLastBlk ){
fsBlockNext(pFS, iBlk, &iBlk);
}else{
iBlk = 0;
}
}
zMsg = lsmMallocPrintf(pDb->pEnv, "%d..%d: ", p->iFirst, p->iLast);
lsmLogMessage(pDb, LSM_OK, " % -15s %s", zMsg, zBlk.z);
lsmFree(pDb->pEnv, zMsg);
lsmStringClear(&zBlk);
}
}
#ifdef LSM_EXPENSIVE_DEBUG
/*
** Helper function for lsmFsIntegrityCheck()
*/
static void checkBlocks(
FileSystem *pFS,
Segment *pSeg,
int bExtra,
u8 *aUsed
){
if( pSeg ){
int i;
for(i=0; i<2; i++){
SortedRun *p = (i ? pSeg->pRun : pSeg->pSep);
if( p && p->nSize>0 ){
const int nPagePerBlock = (pFS->nBlocksize / pFS->nPagesize);
int iBlk;
int iLastBlk;
iBlk = fsPageToBlock(pFS, p->iFirst);
iLastBlk = fsPageToBlock(pFS, p->iLast);
while( iBlk ){
assert( iBlk<=pFS->nBlock );
/* assert( aUsed[iBlk-1]==0 ); */
aUsed[iBlk-1] = 1;
if( iBlk!=iLastBlk ){
fsBlockNext(pFS, iBlk, &iBlk);
}else{
iBlk = 0;
}
}
if( bExtra && (p->iLast % nPagePerBlock)==0 ){
fsBlockNext(pFS, iLastBlk, &iBlk);
aUsed[iBlk-1] = 1;
}
}
}
}
}
/*
** This function checks that all blocks in the database file are accounted
** for. For each block, exactly one of the following must be true:
**
** + the block is part of a sorted run, or
** + the block is on the lPending list, or
** + the block is on the lFree list
**
** This function also checks that there are no references to blocks with
** out-of-range block numbers.
**
** If no errors are found, non-zero is returned. If an error is found, an
** assert() fails.
*/
int lsmFsIntegrityCheck(lsm_db *pDb){
int nBlock;
int i;
FileSystem *pFS = pDb->pFS;
u8 *aUsed;
Level *pLevel;
nBlock = pFS->nBlock;
aUsed = lsmMallocZero(pDb->pEnv, nBlock);
assert( aUsed );
for(pLevel=pDb->pLevel; pLevel; pLevel=pLevel->pNext){
int i;
checkBlocks(pFS, &pLevel->lhs, (pLevel->pSMerger!=0), aUsed);
for(i=0; i<pLevel->nRight; i++){
checkBlocks(pFS, &pLevel->aRhs[i], 0, aUsed);
}
}
for(i=0; i<pFS->lFree.n; i++){
int iBlk = pFS->lFree.a[i];
assert( aUsed[iBlk-1]==0 );
aUsed[iBlk-1] = 1;
}
for(i=0; i<pFS->lPending.n; i++){
int iBlk = pFS->lPending.a[i];
assert( aUsed[iBlk-1]==0 );
aUsed[iBlk-1] = 1;
}
for(i=0; i<nBlock; i++) assert( aUsed[i]==1 );
lsmFree(pDb->pEnv, aUsed);
return 1;
}
#endif
/************** End of lsm_file.c ********************************************/
/************** Begin file lsm_log.c *****************************************/
/*
** 2011-08-13
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains the implementation of LSM database logging. Logging
** has one purpose in LSM - to make transactions durable.
**
** When data is written to an LSM database, it is initially stored in an
** in-memory tree structure. Since this structure is in volatile memory,
** if a power failure or application crash occurs it may be lost. To
** prevent loss of data in this case, each time a record is written to the
** in-memory tree an equivalent record is appended to the log on disk.
** If a power failure or application crash does occur, data can be recovered
** by reading the log.
**
** A log file consists of the following types of records representing data
** written into the database:
**
** LOG_WRITE: A key-value pair written to the database.
** LOG_DELETE: A delete key issued to the database.
** LOG_COMMIT: A transaction commit.
**
** And the following types of records for ancillary purposes..
**
** LOG_EOF: A record indicating the end of a log file.
** LOG_PAD1: A single byte padding record.
** LOG_PAD2: An N byte padding record (N>1).
** LOG_JUMP: A pointer to another offset within the log file.
**
** Each transaction written to the log contains one or more LOG_WRITE and/or
** LOG_DELETE records, followed by a LOG_COMMIT record. The LOG_COMMIT record
** contains an 8-byte checksum based on all previous data written to the
** log file.
**
** LOG CHECKSUMS & RECOVERY
**
** Checksums are found in two types of log records: LOG_COMMIT and
** LOG_CKSUM records. In order to recover content from a log, a client
** reads each record from the start of the log, calculating a checksum as
** it does. Each time a LOG_COMMIT or LOG_CKSUM is encountered, the
** recovery process verifies that the checksum stored in the log
** matches the calculated checksum. If it does not, the recovery process
** can stop reading the log.
**
** If a recovery process reads records (other than COMMIT or CKSUM)
** consisting of at least LSM_CKSUM_MAXDATA bytes, then the next record in
** the log must be either a LOG_CKSUM or LOG_COMMIT record. If it is
** not, the recovery process also stops reading the log.
**
** To recover the log file, it must be read twice. The first time to
** determine the location of the last valid commit record. And the second
** time to load data into the in-memory tree.
**
** Todo: Surely there is a better way...
**
** LOG WRAPPING
**
** If the log file were never deleted or wrapped, it would be possible to
** read it from start to end each time is required recovery (i.e each time
** the number of database clients changes from 0 to 1). Effectively reading
** the entire history of the database each time. This would quickly become
** inefficient. Additionally, since the log file would grow without bound,
** it wastes storage space.
**
** Instead, part of each checkpoint written into the database file contains
** a log offset (and other information required to read the log starting at
** at this offset) at which to begin recovery. Offset $O.
**
** Once a checkpoint has been written and synced into the database file, it
** is guaranteed that no recovery process will need to read any data before
** offset $O of the log file. It is therefore safe to begin overwriting
** any data that occurs before offset $O.
**
** This implementation separates the log into three regions mapped into
** the log file - regions 0, 1 and 2. During recovery, regions are read
** in ascending order (i.e. 0, then 1, then 2). Each region is zero or
** more bytes in size.
**
** |---1---|..|--0--|.|--2--|....
**
** New records are always appended to the end of region 2.
**
** Initially (when it is empty), all three regions are zero bytes in size.
** Each of them are located at the beginning of the file. As records are
** added to the log, region 2 grows, so that the log consists of a zero
** byte region 1, followed by a zero byte region 0, followed by an N byte
** region 2. After one or more checkpoints have been written to disk,
** the start point of region 2 is moved to $O. For example:
**
** A) ||.........|--2--|....
**
** (both regions 0 and 1 are 0 bytes in size at offset 0).
**
** Eventually, the log wraps around to write new records into the start.
** At this point, region 2 is renamed to region 0. Region 0 is renamed
** to region 2. After appending a few records to the new region 2, the
** log file looks like this:
**
** B) ||--2--|...|--0--|....
**
** (region 1 is still 0 bytes in size, located at offset 0).
**
** Any checkpoints made at this point may reduce the size of region 0.
** However, if they do not, and region 2 expands so that it is about to
** overwrite the start of region 0, then region 2 is renamed to region 1,
** and a new region 2 created at the end of the file following the existing
** region 0.
**
** C) |---1---|..|--0--|.|-2-|
**
** In this state records are appended to region 2 until checkpoints have
** contracted regions 0 AND 1 UNTil they are both zero bytes in size. They
** are then shifted to the start of the log file, leaving the system in
** the equivalent of state A above.
**
** Alternatively, state B may transition directly to state A if the size
** of region 0 is reduced to zero bytes before region 2 threatens to
** encroach upon it.
**
** LOG_PAD1 & LOG_PAD2 RECORDS
**
** PAD1 and PAD2 records may appear in a log file at any point. They allow
** a process writing the log file align the beginning of transactions with
** the beginning of disk sectors, which increases robustness.
**
** RECORD FORMATS:
**
** LOG_EOF: * A single 0x00 byte.
**
** LOG_PAD1: * A single 0x01 byte.
**
** LOG_PAD2: * A single 0x02 byte, followed by
** * The number of unused bytes (N) as a varint,
** * An N byte block of unused space.
**
** LOG_COMMIT: * A single 0x03 byte.
** * An 8-byte checksum.
**
** LOG_JUMP: * A single 0x04 byte.
** * Absolute file offset to jump to, encoded as a varint.
**
** LOG_WRITE: * A single 0x06 or 0x07 byte,
** * The number of bytes in the key, encoded as a varint,
** * The number of bytes in the value, encoded as a varint,
** * If the first byte was 0x07, an 8 byte checksum.
** * The key data,
** * The value data.
**
** LOG_DELETE: * A single 0x08 or 0x09 byte,
** * The number of bytes in the key, encoded as a varint,
** * If the first byte was 0x09, an 8 byte checksum.
** * The key data.
**
** Varints are as described in lsm_varint.c (SQLite 4 format).
**
** CHECKSUMS:
**
** The checksum is calculated using two 32-bit unsigned integers, s0 and
** s1. The initial value for both is 42. It is updated each time a record
** is written into the log file by treating the encoded (binary) record as
** an array of 32-bit little-endian integers. Then, if x[] is the integer
** array, updating the checksum accumulators as follows:
**
** for i from 0 to n-1 step 2:
** s0 += x[i] + s1;
** s1 += x[i+1] + s0;
** endfor
**
** If the record is not an even multiple of 8-bytes in size it is padded
** with zeroes to make it so before the checksum is updated.
**
** The checksum stored in a COMMIT, WRITE or DELETE is based on all bytes
** up to the start of the 8-byte checksum itself, including the COMMIT,
** WRITE or DELETE fields that appear before the checksum in the record.
**
** VARINT FORMAT
**
** See lsm_varint.c.
*/
#ifndef _LSM_INT_H
#endif
/* Log record types */
#define LSM_LOG_EOF 0x00
#define LSM_LOG_PAD1 0x01
#define LSM_LOG_PAD2 0x02
#define LSM_LOG_COMMIT 0x03
#define LSM_LOG_JUMP 0x04
#define LSM_LOG_WRITE 0x06
#define LSM_LOG_WRITE_CKSUM 0x07
#define LSM_LOG_DELETE 0x08
#define LSM_LOG_DELETE_CKSUM 0x09
/* Require a checksum every 32KB. */
#define LSM_CKSUM_MAXDATA (32*1024)
/*
** szSector:
** Commit records must be aligned to end on szSector boundaries. If
** the safety-mode is set to NORMAL or OFF, this value is 1. Otherwise,
** if the safety-mode is set to FULL, it is the size of the file-system
** sectors as reported by lsmFsSectorSize().
*/
struct LogWriter {
u32 cksum0; /* Checksum 0 at offset iOff */
u32 cksum1; /* Checksum 1 at offset iOff */
int iCksumBuf; /* Bytes of buf that have been checksummed */
i64 iOff; /* Offset at start of buffer buf */
LsmString buf; /* Buffer containing data not yet written */
int szSector; /* Sector size for this transaction */
LogRegion jump; /* Avoid writing to this region */
i64 iRegion1End; /* End of first region written by trans */
i64 iRegion2Start; /* Start of second regions written by trans */
};
/*
** Return the result of interpreting the first 4 bytes in buffer aIn as
** a 32-bit unsigned little-endian integer.
*/
static u32 getU32le(u8 *aIn){
return ((u32)aIn[3] << 24)
+ ((u32)aIn[2] << 16)
+ ((u32)aIn[1] << 8)
+ ((u32)aIn[0]);
}
/*
** This function is the same as logCksum(), except that pointer "a" need
** not be aligned to an 8-byte boundary or padded with zero bytes. This
** version is slower, but sometimes more convenient to use.
*/
static void logCksumUnaligned(
char *z, /* Input buffer */
int n, /* Size of input buffer in bytes */
u32 *pCksum0, /* IN/OUT: Checksum value 1 */
u32 *pCksum1 /* IN/OUT: Checksum value 2 */
){
u8 *a = (u8 *)z;
u32 cksum0 = *pCksum0;
u32 cksum1 = *pCksum1;
int nIn = (n/8) * 8;
int i;
assert( n>0 );
for(i=0; i<nIn; i+=8){
cksum0 += getU32le(&a[i]) + cksum1;
cksum1 += getU32le(&a[i+4]) + cksum0;
}
if( nIn!=n ){
u8 aBuf[8] = {0, 0, 0, 0, 0, 0, 0, 0};
assert( (n-nIn)<8 && n>nIn );
memcpy(aBuf, &a[nIn], n-nIn);
cksum0 += getU32le(aBuf) + cksum1;
cksum1 += getU32le(&aBuf[4]) + cksum0;
}
*pCksum0 = cksum0;
*pCksum1 = cksum1;
}
/*
** Update pLog->cksum0 and pLog->cksum1 so that the first nBuf bytes in the
** write buffer (pLog->buf) are included in the checksum.
*/
static void logUpdateCksum(LogWriter *pLog, int nBuf){
assert( (pLog->iCksumBuf % 8)==0 );
assert( pLog->iCksumBuf<=nBuf );
assert( (nBuf % 8)==0 || nBuf==pLog->buf.n );
if( nBuf>pLog->iCksumBuf ){
logCksumUnaligned(
&pLog->buf.z[pLog->iCksumBuf], nBuf-pLog->iCksumBuf,
&pLog->cksum0, &pLog->cksum1
);
}
pLog->iCksumBuf = nBuf;
}
static i64 firstByteOnSector(LogWriter *pLog, i64 iOff){
return (iOff / pLog->szSector) * pLog->szSector;
}
static i64 lastByteOnSector(LogWriter *pLog, i64 iOff){
return firstByteOnSector(pLog, iOff) + pLog->szSector - 1;
}
/*
** This function is called when a write-transaction is first opened. It
** is assumed that the caller is holding the client-mutex when it is
** called.
**
** Before returning, this function allocates the LogWriter object that
** will be used to write to the log file during the write transaction.
** LSM_OK is returned if no error occurs, otherwise an LSM error code.
*/
int lsmLogBegin(lsm_db *pDb, DbLog *pLog){
int rc = LSM_OK;
LogWriter *pNew;
LogRegion *aReg;
assert( lsmHoldingClientMutex(pDb) );
if( pDb->bUseLog==0 ) return LSM_OK;
pNew = lsmMallocZeroRc(pDb->pEnv, sizeof(LogWriter), &rc);
if( pNew ){
lsmStringInit(&pNew->buf, pDb->pEnv);
rc = lsmStringExtend(&pNew->buf, 2);
}
if( rc!=LSM_OK ){
assert( pNew==0 || pNew->buf.z==0 );
lsmFree(pDb->pEnv, pNew);
return rc;
}
/* Set the effective sector-size for this transaction. Sectors are assumed
** to be one byte in size if the safety-mode is OFF or NORMAL, or as
** reported by lsmFsSectorSize if it is FULL. */
if( pDb->eSafety==LSM_SAFETY_FULL ){
pNew->szSector = lsmFsSectorSize(pDb->pFS);
assert( pNew->szSector>0 );
}else{
pNew->szSector = 1;
}
/* There are now three scenarios:
**
** 1) Regions 0 and 1 are both zero bytes in size and region 2 begins
** at a file offset greater than N, where N is the value configured
** by LSM_CONFIG_LOG_SIZE. In this case, wrap around to the start
** and write data into the start of the log file.
**
** 2) Region 1 is zero bytes in size and region 2 occurs earlier in the
** file than region 0. In this case, append data to region 2, but
** remember to jump over region 1 if required.
**
** 3) Region 2 is the last in the file. Append to it.
*/
aReg = &pLog->aRegion[0];
assert( aReg[0].iEnd==0 || aReg[0].iEnd>aReg[0].iStart );
assert( aReg[1].iEnd==0 || aReg[1].iEnd>aReg[1].iStart );
pNew->cksum0 = pLog->cksum0;
pNew->cksum1 = pLog->cksum1;
if( aReg[0].iEnd==0 && aReg[1].iEnd==0 && aReg[2].iStart>=pDb->nLogSz ){
/* Case 1. Wrap around to the start of the file. Write an LSM_LOG_JUMP
** into the log file in this case. Pad it out to 8 bytes using a PAD2
** record so that the checksums can be updated immediately. */
u8 aJump[] = {
LSM_LOG_PAD2, 0x04, 0x00, 0x00, 0x00, 0x00, LSM_LOG_JUMP, 0x00
};
lsmStringBinAppend(&pNew->buf, aJump, sizeof(aJump));
logUpdateCksum(pNew, pNew->buf.n);
rc = lsmFsWriteLog(pDb->pFS, aReg[2].iEnd, &pNew->buf);
pNew->iCksumBuf = pNew->buf.n = 0;
aReg[2].iEnd += 8;
pNew->jump = aReg[0] = aReg[2];
aReg[2].iStart = aReg[2].iEnd = 0;
}else if( aReg[1].iEnd==0 && aReg[2].iEnd<aReg[0].iEnd ){
/* Case 2. */
pNew->iOff = aReg[2].iEnd;
pNew->jump = aReg[0];
}else{
/* Case 3. */
assert( aReg[2].iStart>=aReg[0].iEnd && aReg[2].iStart>=aReg[1].iEnd );
pNew->iOff = aReg[2].iEnd;
}
if( pNew->jump.iStart ){
i64 iRound;
assert( pNew->jump.iStart>pNew->iOff );
iRound = firstByteOnSector(pNew, pNew->jump.iStart);
if( iRound>pNew->iOff ) pNew->jump.iStart = iRound;
pNew->jump.iEnd = lastByteOnSector(pNew, pNew->jump.iEnd);
}
pDb->pLogWriter = pNew;
return rc;
}
/*
** This function is called when a write-transaction is being closed.
** Parameter bCommit is true if the transaction is being committed,
** or false otherwise. The caller must hold the client-mutex to call
** this function.
**
** A call to this function deletes the LogWriter object allocated by
** lsmLogBegin(). If the transaction is being committed, the shared state
** in *pLog is updated before returning.
*/
void lsmLogEnd(lsm_db *pDb, DbLog *pLog, int bCommit){
LogWriter *p;
assert( lsmHoldingClientMutex(pDb) );
if( pDb->bUseLog==0 ) return;
p = pDb->pLogWriter;
if( bCommit ){
pLog->aRegion[2].iEnd = p->iOff;
pLog->cksum0 = p->cksum0;
pLog->cksum1 = p->cksum1;
if( p->iRegion1End ){
/* This happens when the transaction had to jump over some other
** part of the log. */
assert( pLog->aRegion[1].iEnd==0 );
assert( pLog->aRegion[2].iStart<p->iRegion1End );
pLog->aRegion[1].iStart = pLog->aRegion[2].iStart;
pLog->aRegion[1].iEnd = p->iRegion1End;
pLog->aRegion[2].iStart = p->iRegion2Start;
}
}
lsmStringClear(&p->buf);
lsmFree(pDb->pEnv, p);
pDb->pLogWriter = 0;
}
/*
** This function is called after a checkpoint is synced into the database
** file. The checkpoint specifies that the log starts at offset iOff.
** The shared state in *pLog is updated to reflect the fact that space
** in the log file that occurs logically before offset iOff may now
** be reused.
*/
void lsmLogCheckpoint(lsm_db *pDb, DbLog *pLog, lsm_i64 iOff){
int iRegion;
assert( lsmHoldingClientMutex(pDb) );
for(iRegion=0; iRegion<3; iRegion++){
LogRegion *p = &pLog->aRegion[iRegion];
if( iOff>=p->iStart && iOff<=p->iEnd ) break;
p->iStart = 0;
p->iEnd = 0;
}
assert( iRegion<3 );
pLog->aRegion[iRegion].iStart = iOff;
}
static int jumpIfRequired(
lsm_db *pDb,
LogWriter *pLog,
int nReq,
int *pbJump
){
/* Determine if it is necessary to add an LSM_LOG_JUMP to jump over the
** jump region before writing the LSM_LOG_WRITE or DELETE record. This
** is necessary if there is insufficient room between the current offset
** and the jump region to fit the new WRITE/DELETE record and the largest
** possible JUMP record with up to 7 bytes of padding (a total of 17
** bytes). */
if( (pLog->jump.iStart > (pLog->iOff + pLog->buf.n))
&& (pLog->jump.iStart < (pLog->iOff + pLog->buf.n + (nReq + 17)))
){
int rc; /* Return code */
i64 iJump; /* Offset to jump to */
u8 aJump[10]; /* Encoded jump record */
int nJump; /* Valid bytes in aJump[] */
int nPad; /* Bytes of padding required */
/* Serialize the JUMP record */
iJump = pLog->jump.iEnd+1;
aJump[0] = LSM_LOG_JUMP;
nJump = 1 + lsmVarintPut64(&aJump[1], iJump);
/* Adding padding to the contents of the buffer so that it will be a
** multiple of 8 bytes in size after the JUMP record is appended. This
** is not strictly required, it just makes the keeping the running
** checksum up to date in this file a little simpler. */
nPad = (pLog->buf.n + nJump) % 8;
if( nPad ){
u8 aPad[7] = {0,0,0,0,0,0,0};
nPad = 8-nPad;
if( nPad==1 ){
aPad[0] = LSM_LOG_PAD1;
}else{
aPad[0] = LSM_LOG_PAD2;
aPad[1] = (nPad-2);
}
rc = lsmStringBinAppend(&pLog->buf, aPad, nPad);
if( rc!=LSM_OK ) return rc;
}
/* Append the JUMP record to the buffer. Then flush the buffer to disk
** and update the checksums. The next write to the log file (assuming
** there is no transaction rollback) will be to offset iJump (just past
** the jump region). */
rc = lsmStringBinAppend(&pLog->buf, aJump, nJump);
if( rc!=LSM_OK ) return rc;
assert( (pLog->buf.n % 8)==0 );
rc = lsmFsWriteLog(pDb->pFS, pLog->iOff, &pLog->buf);
if( rc!=LSM_OK ) return rc;
logUpdateCksum(pLog, pLog->buf.n);
pLog->iRegion1End = (pLog->iOff + pLog->buf.n);
pLog->iRegion2Start = iJump;
pLog->iOff = iJump;
pLog->iCksumBuf = pLog->buf.n = 0;
if( pbJump ) *pbJump = 1;
}
return LSM_OK;
}
static int logCksumAndFlush(lsm_db *pDb){
int rc; /* Return code */
LogWriter *pLog = pDb->pLogWriter;
/* Calculate the checksum value. Append it to the buffer. */
logUpdateCksum(pLog, pLog->buf.n);
lsmPutU32((u8 *)&pLog->buf.z[pLog->buf.n], pLog->cksum0);
pLog->buf.n += 4;
lsmPutU32((u8 *)&pLog->buf.z[pLog->buf.n], pLog->cksum1);
pLog->buf.n += 4;
/* Write the contents of the buffer to disk. */
rc = lsmFsWriteLog(pDb->pFS, pLog->iOff, &pLog->buf);
pLog->iOff += pLog->buf.n;
pLog->iCksumBuf = pLog->buf.n = 0;
return rc;
}
/*
** Write the contents of the log-buffer to disk. Then write either a CKSUM
** or COMMIT record, depending on the value of parameter eType.
*/
static int logFlush(lsm_db *pDb, int eType){
int rc;
int nReq;
LogWriter *pLog = pDb->pLogWriter;
assert( eType==LSM_LOG_COMMIT );
assert( pLog );
/* Commit record is always 9 bytes in size. */
nReq = 9;
if( eType==LSM_LOG_COMMIT && pLog->szSector>1 ) nReq += pLog->szSector + 17;
rc = jumpIfRequired(pDb, pLog, nReq, 0);
/* If this is a COMMIT, add padding to the log so that the COMMIT record
** is aligned against the end of a disk sector. In other words, add padding
** so that the first byte following the COMMIT record lies on a different
** sector. */
if( eType==LSM_LOG_COMMIT && pLog->szSector>1 ){
int nPad; /* Bytes of padding to add */
/* Determine the value of nPad. */
nPad = ((pLog->iOff + pLog->buf.n + 9) % pLog->szSector);
if( nPad ) nPad = pLog->szSector - nPad;
rc = lsmStringExtend(&pLog->buf, nPad);
if( rc!=LSM_OK ) return rc;
while( nPad ){
if( nPad==1 ){
pLog->buf.z[pLog->buf.n++] = LSM_LOG_PAD1;
nPad = 0;
}else{
int n = LSM_MIN(200, nPad-2);
pLog->buf.z[pLog->buf.n++] = LSM_LOG_PAD2;
pLog->buf.z[pLog->buf.n++] = n;
nPad -= 2;
memset(&pLog->buf.z[pLog->buf.n], 0x2B, n);
pLog->buf.n += n;
nPad -= n;
}
}
}
/* Make sure there is room in the log-buffer to add the CKSUM or COMMIT
** record. Then add the first byte of it. */
rc = lsmStringExtend(&pLog->buf, 9);
if( rc!=LSM_OK ) return rc;
pLog->buf.z[pLog->buf.n++] = eType;
memset(&pLog->buf.z[pLog->buf.n], 0, 8);
rc = logCksumAndFlush(pDb);
/* If this is a commit and synchronous=full, sync the log to disk. */
if( rc==LSM_OK && eType==LSM_LOG_COMMIT && pDb->eSafety==LSM_SAFETY_FULL ){
rc = lsmFsSyncLog(pDb->pFS);
}
return rc;
}
/*
** Append an LSM_LOG_WRITE (if nVal>=0) or LSM_LOG_DELETE (if nVal<0)
** record to the database log.
*/
int lsmLogWrite(
lsm_db *pDb, /* Database handle */
void *pKey, int nKey, /* Database key to write to log */
void *pVal, int nVal /* Database value (or nVal<0) to write */
){
int rc = LSM_OK;
LogWriter *pLog; /* Log object to write to */
int nReq; /* Bytes of space required in log */
int bCksum = 0; /* True to embed a checksum in this record */
if( pDb->bUseLog==0 ) return LSM_OK;
pLog = pDb->pLogWriter;
/* Determine how many bytes of space are required, assuming that a checksum
** will be embedded in this record (even though it may not be). */
nReq = 1 + lsmVarintLen32(nKey) + 8 + nKey;
if( nVal>=0 ) nReq += lsmVarintLen32(nVal) + nVal;
/* Jump over the jump region if required. Set bCksum to true to tell the
** code below to include a checksum in the record if either (a) writing
** this record would mean that more than LSM_CKSUM_MAXDATA bytes of data
** have been written to the log since the last checksum, or (b) the jump
** is taken. */
rc = jumpIfRequired(pDb, pLog, nReq, &bCksum);
if( (pLog->buf.n+nReq) > LSM_CKSUM_MAXDATA ) bCksum = 1;
if( rc==LSM_OK ){
rc = lsmStringExtend(&pLog->buf, nReq);
}
if( rc==LSM_OK ){
u8 *a = (u8 *)&pLog->buf.z[pLog->buf.n];
/* Write the record header - the type byte followed by either 1 (for
** DELETE) or 2 (for WRITE) varints. */
assert( LSM_LOG_WRITE_CKSUM == (LSM_LOG_WRITE | 0x0001) );
assert( LSM_LOG_DELETE_CKSUM == (LSM_LOG_DELETE | 0x0001) );
*(a++) = (nVal>=0 ? LSM_LOG_WRITE : LSM_LOG_DELETE) | (u8)bCksum;
a += lsmVarintPut32(a, nKey);
if( nVal>=0 ) a += lsmVarintPut32(a, nVal);
if( bCksum ){
pLog->buf.n = (a - (u8 *)pLog->buf.z);
rc = logCksumAndFlush(pDb);
a = (u8 *)&pLog->buf.z[pLog->buf.n];
}
memcpy(a, pKey, nKey);
a += nKey;
if( nVal>=0 ){
memcpy(a, pVal, nVal);
a += nVal;
}
pLog->buf.n = a - (u8 *)pLog->buf.z;
assert( pLog->buf.n<=pLog->buf.nAlloc );
}
return rc;
}
/*
** Append an LSM_LOG_COMMIT record to the database log.
*/
int lsmLogCommit(lsm_db *pDb){
if( pDb->bUseLog==0 ) return LSM_OK;
return logFlush(pDb, LSM_LOG_COMMIT);
}
/*
** Store the current offset and other checksum related information in the
** structure *pMark. Later, *pMark can be passed to lsmLogSeek() to "rewind"
** the LogWriter object to the current log file offset. This is used when
** rolling back savepoint transactions.
*/
void lsmLogTell(
lsm_db *pDb, /* Database handle */
LogMark *pMark /* Populate this object with current offset */
){
LogWriter *pLog;
int nCksum;
if( pDb->bUseLog==0 ) return;
pLog = pDb->pLogWriter;
nCksum = pLog->buf.n & 0xFFFFFFF8;
logUpdateCksum(pLog, nCksum);
assert( pLog->iCksumBuf==nCksum );
pMark->nBuf = pLog->buf.n - nCksum;
memcpy(pMark->aBuf, &pLog->buf.z[nCksum], pMark->nBuf);
pMark->iOff = pLog->iOff + pLog->buf.n;
pMark->cksum0 = pLog->cksum0;
pMark->cksum1 = pLog->cksum1;
}
/*
** Seek (rewind) back to the log file offset stored by an ealier call to
** lsmLogTell() in *pMark.
*/
void lsmLogSeek(
lsm_db *pDb, /* Database handle */
LogMark *pMark /* Object containing log offset to seek to */
){
LogWriter *pLog;
if( pDb->bUseLog==0 ) return;
pLog = pDb->pLogWriter;
assert( pMark->iOff<=pLog->iOff+pLog->buf.n );
if( (pMark->iOff & 0xFFFFFFF8)>=pLog->iOff ){
pLog->buf.n = pMark->iOff - pLog->iOff;
pLog->iCksumBuf = (pLog->buf.n & 0xFFFFFFF8);
}else{
pLog->buf.n = pMark->nBuf;
memcpy(pLog->buf.z, pMark->aBuf, pMark->nBuf);
pLog->iCksumBuf = 0;
pLog->iOff = pMark->iOff - pMark->nBuf;
}
pLog->cksum0 = pMark->cksum0;
pLog->cksum1 = pMark->cksum1;
if( pMark->iOff > pLog->iRegion1End ) pLog->iRegion1End = 0;
if( pMark->iOff > pLog->iRegion2Start ) pLog->iRegion2Start = 0;
}
/*
** TODO: Thread safety of this function?
*/
int lsmLogStructure(lsm_db *pDb, char **pzVal){
DbLog *pLog = lsmDatabaseLog(pDb);
*pzVal = lsmMallocPrintf(pDb->pEnv,
"%d %d %d %d %d %d",
(int)pLog->aRegion[0].iStart, (int)pLog->aRegion[0].iEnd,
(int)pLog->aRegion[1].iStart, (int)pLog->aRegion[1].iEnd,
(int)pLog->aRegion[2].iStart, (int)pLog->aRegion[2].iEnd
);
return (*pzVal ? LSM_OK : LSM_NOMEM_BKPT);
}
/*************************************************************************
** Begin code for log recovery.
*/
typedef struct LogReader LogReader;
struct LogReader {
FileSystem *pFS; /* File system to read from */
i64 iOff; /* File offset at end of buf content */
int iBuf; /* Current read offset in buf */
LsmString buf; /* Buffer containing file content */
int iCksumBuf; /* Offset in buf corresponding to cksum[01] */
u32 cksum0; /* Checksum 0 at offset iCksumBuf */
u32 cksum1; /* Checksum 1 at offset iCksumBuf */
};
static void logReaderBlob(
LogReader *p, /* Log reader object */
LsmString *pBuf, /* Dynamic storage, if required */
int nBlob, /* Number of bytes to read */
u8 **ppBlob, /* OUT: Pointer to blob read */
int *pRc /* IN/OUT: Error code */
){
static const int LOG_READ_SIZE = 512;
int rc = *pRc; /* Return code */
int nReq = nBlob; /* Bytes required */
while( rc==LSM_OK && nReq>0 ){
int nAvail; /* Bytes of data available in p->buf */
if( p->buf.n==p->iBuf ){
int nCksum; /* Total bytes requiring checksum */
int nCarry = 0; /* Total bytes requiring checksum */
nCksum = p->iBuf - p->iCksumBuf;
if( nCksum>0 ){
nCarry = nCksum % 8;
nCksum = ((nCksum / 8) * 8);
if( nCksum>0 ){
logCksumUnaligned(
&p->buf.z[p->iCksumBuf], nCksum, &p->cksum0, &p->cksum1
);
}
}
if( nCarry>0 ) memcpy(p->buf.z, &p->buf.z[p->iBuf-nCarry], nCarry);
p->buf.n = nCarry;
p->iBuf = nCarry;
rc = lsmFsReadLog(p->pFS, p->iOff, LOG_READ_SIZE, &p->buf);
if( rc!=LSM_OK ) break;
p->iCksumBuf = 0;
p->iOff += LOG_READ_SIZE;
}
nAvail = p->buf.n - p->iBuf;
if( ppBlob && nReq==nBlob && nBlob<=nAvail ){
*ppBlob = (u8 *)&p->buf.z[p->iBuf];
p->iBuf += nBlob;
nReq = 0;
}else{
int nCopy = LSM_MIN(nAvail, nReq);
if( nBlob==nReq ){
if( ppBlob ) *ppBlob = (u8 *)pBuf->z;
pBuf->n = 0;
}
rc = lsmStringBinAppend(pBuf, (u8 *)&p->buf.z[p->iBuf], nCopy);
nReq -= nCopy;
p->iBuf += nCopy;
}
}
*pRc = rc;
}
static void logReaderVarint(
LogReader *p,
LsmString *pBuf,
int *piVal, /* OUT: Value read from log */
int *pRc /* IN/OUT: Error code */
){
if( *pRc==LSM_OK ){
u8 *aVarint;
if( p->buf.n==p->iBuf ){
logReaderBlob(p, 0, 10, &aVarint, pRc);
if( LSM_OK==*pRc ) p->iBuf -= (10 - lsmVarintGet32(aVarint, piVal));
}else{
logReaderBlob(p, pBuf, lsmVarintSize(p->buf.z[p->iBuf]), &aVarint, pRc);
if( LSM_OK==*pRc ) lsmVarintGet32(aVarint, piVal);
}
}
}
static void logReaderByte(LogReader *p, u8 *pByte, int *pRc){
u8 *pPtr = 0;
logReaderBlob(p, 0, 1, &pPtr, pRc);
if( pPtr ) *pByte = *pPtr;
}
static void logReaderCksum(LogReader *p, LsmString *pBuf, int *pbEof, int *pRc){
if( *pRc==LSM_OK ){
u8 *pPtr = 0;
u32 cksum0, cksum1;
int nCksum = p->iBuf - p->iCksumBuf;
/* Update in-memory (expected) checksums */
assert( nCksum>=0 );
logCksumUnaligned(&p->buf.z[p->iCksumBuf], nCksum, &p->cksum0, &p->cksum1);
p->iCksumBuf = p->iBuf + 8;
logReaderBlob(p, pBuf, 8, &pPtr, pRc);
/* Read the checksums from the log file. Set *pbEof if they do not match. */
if( pPtr ){
cksum0 = lsmGetU32(pPtr);
cksum1 = lsmGetU32(&pPtr[4]);
*pbEof = (cksum0!=p->cksum0 || cksum1!=p->cksum1);
p->iCksumBuf = p->iBuf;
}
}
}
static void logReaderInit(
lsm_db *pDb, /* Database handle */
DbLog *pLog, /* Log object associated with pDb */
int bInitBuf, /* True if p->buf is uninitialized */
LogReader *p /* Initialize this LogReader object */
){
p->pFS = pDb->pFS;
p->iOff = pLog->aRegion[2].iStart;
p->cksum0 = pLog->cksum0;
p->cksum1 = pLog->cksum1;
if( bInitBuf ){ lsmStringInit(&p->buf, pDb->pEnv); }
p->buf.n = 0;
p->iCksumBuf = 0;
p->iBuf = 0;
}
/*
** This function is called after reading the header of a LOG_DELETE or
** LOG_WRITE record. Parameter nByte is the total size of the key and
** value that follow the header just read. Return true if the size and
** position of the record indicate that it should contain a checksum.
*/
static int logRequireCksum(LogReader *p, int nByte){
return ((p->iBuf + nByte - p->iCksumBuf) > LSM_CKSUM_MAXDATA);
}
/*
** Recover the contents of the log file.
*/
int lsmLogRecover(lsm_db *pDb){
LsmString buf1; /* Key buffer */
LsmString buf2; /* Value buffer */
LogReader reader; /* Log reader object */
int rc; /* Return code */
int nCommit = 0; /* Number of transactions to recover */
int iPass;
int nJump = 0; /* Number of LSM_LOG_JUMP records in pass 0 */
DbLog *pLog;
rc = lsmBeginRecovery(pDb);
if( rc!=LSM_OK ) return rc;
pLog = lsmDatabaseLog(pDb);
logReaderInit(pDb, pLog, 1, &reader);
lsmStringInit(&buf1, pDb->pEnv);
lsmStringInit(&buf2, pDb->pEnv);
/* The outer for() loop runs at most twice. The first iteration is to
** count the number of committed transactions in the log. The second
** iterates through those transactions and updates the in-memory tree
** structure with their contents. */
for(iPass=0; iPass<2 && rc==LSM_OK; iPass++){
int bEof = 0;
while( rc==LSM_OK && !bEof ){
u8 eType = 0;
logReaderByte(&reader, &eType, &rc);
switch( eType ){
case LSM_LOG_PAD1:
break;
case LSM_LOG_PAD2: {
int nPad;
logReaderVarint(&reader, &buf1, &nPad, &rc);
logReaderBlob(&reader, &buf1, nPad, 0, &rc);
break;
}
case LSM_LOG_WRITE:
case LSM_LOG_WRITE_CKSUM: {
int nKey;
int nVal;
u8 *aVal;
logReaderVarint(&reader, &buf1, &nKey, &rc);
logReaderVarint(&reader, &buf2, &nVal, &rc);
if( eType==LSM_LOG_WRITE_CKSUM ){
logReaderCksum(&reader, &buf1, &bEof, &rc);
}else{
bEof = logRequireCksum(&reader, nKey+nVal);
}
if( bEof ) break;
logReaderBlob(&reader, &buf1, nKey, 0, &rc);
logReaderBlob(&reader, &buf2, nVal, &aVal, &rc);
if( iPass==1 && rc==LSM_OK ){
rc = lsmTreeInsert(pDb, (u8 *)buf1.z, nKey, aVal, nVal);
}
break;
}
case LSM_LOG_DELETE:
case LSM_LOG_DELETE_CKSUM: {
int nKey; u8 *aKey;
logReaderVarint(&reader, &buf1, &nKey, &rc);
if( eType==LSM_LOG_DELETE_CKSUM ){
logReaderCksum(&reader, &buf1, &bEof, &rc);
}else{
bEof = logRequireCksum(&reader, nKey);
}
if( bEof ) break;
logReaderBlob(&reader, &buf1, nKey, &aKey, &rc);
if( iPass==1 && rc==LSM_OK ){
rc = lsmTreeInsert(pDb, aKey, nKey, NULL, -1);
}
break;
}
case LSM_LOG_COMMIT:
logReaderCksum(&reader, &buf1, &bEof, &rc);
if( bEof==0 ){
nCommit++;
assert( nCommit>0 || iPass==1 );
if( nCommit==0 ) bEof = 1;
}
break;
case LSM_LOG_JUMP: {
int iOff = 0;
logReaderVarint(&reader, &buf1, &iOff, &rc);
if( rc==LSM_OK ){
if( iPass==1 ){
if( pLog->aRegion[2].iStart==0 ){
assert( pLog->aRegion[1].iStart==0 );
pLog->aRegion[1].iEnd = reader.iOff;
}else{
assert( pLog->aRegion[0].iStart==0 );
pLog->aRegion[0].iStart = pLog->aRegion[2].iStart;
pLog->aRegion[0].iEnd = reader.iOff - reader.buf.n+reader.iBuf;
}
pLog->aRegion[2].iStart = iOff;
}else{
if( (nJump++)==2 ){
bEof = 1;
}
}
reader.iOff = iOff;
reader.buf.n = reader.iBuf;
}
break;
}
default:
/* Including LSM_LOG_EOF */
bEof = 1;
break;
}
}
if( rc==LSM_OK && iPass==0 ){
if( nCommit==0 ){
if( pLog->aRegion[2].iStart==0 ){
iPass = 1;
}else{
pLog->aRegion[2].iStart = 0;
iPass = -1;
}
}
logReaderInit(pDb, pLog, 0, &reader);
nCommit = nCommit * -1;
}
}
/* Initialize DbLog object */
if( rc==LSM_OK ){
pLog->aRegion[2].iEnd = reader.iOff - reader.buf.n + reader.iBuf;
pLog->cksum0 = reader.cksum0;
pLog->cksum1 = reader.cksum1;
}
if( rc==LSM_OK ){
rc = lsmFinishRecovery(pDb);
}else{
lsmFinishRecovery(pDb);
}
lsmStringClear(&buf1);
lsmStringClear(&buf2);
lsmStringClear(&reader.buf);
return rc;
}
/************** End of lsm_log.c *********************************************/
/************** Begin file lsm_main.c ****************************************/
/*
** 2011-08-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.
**
*************************************************************************
**
** The main interface to the LSM module.
*/
#ifdef LSM_DEBUG
/*
** This function returns a copy of its only argument.
**
** When the library is built with LSM_DEBUG defined, this function is called
** whenever an error code is generated (not propagated - generated). So
** if the library is mysteriously returning (say) LSM_IOERR, a breakpoint
** may be set in this function to determine why.
*/
int lsmErrorBkpt(int rc){
/* Set breakpoint here! */
return rc;
}
/*
** This function contains various assert() statements that test that the
** lsm_db structure passed as an argument is internally consistent.
*/
static void assert_db_state(lsm_db *pDb){
/* If there is at least one cursor or a write transaction open, the database
** handle must be holding a pointer to a client snapshot. And the reverse
** - if there are no open cursors and no write transactions then there must
** not be a client snapshot. */
assert( (pDb->pCsr!=0 || pDb->nTransOpen>0)==(pDb->pClient!=0) );
/* If there is a write transaction open according to pDb->nTransOpen, then
** the connection must be holding the read/write TreeVersion. */
assert( pDb->nTransOpen>=0 );
assert( pDb->nTransOpen==0 || lsmTreeIsWriteVersion(pDb->pTV) );
}
#else
# define assert_db_state(x)
#endif
/*
** The default key-compare function.
*/
static int xCmp(void *p1, int n1, void *p2, int n2){
int res;
res = memcmp(p1, p2, LSM_MIN(n1, n2));
if( res==0 ) res = (n1-n2);
return res;
}
/*
** Allocate a new db handle.
*/
int lsm_new(lsm_env *pEnv, lsm_db **ppDb){
lsm_db *pDb;
/* If the user did not provide an environment, use the default. */
if( pEnv==0 ) pEnv = lsm_default_env();
assert( pEnv );
/* Allocate the new database handle */
*ppDb = pDb = (lsm_db *)lsmMallocZero(pEnv, sizeof(lsm_db));
if( pDb==0 ) return LSM_NOMEM_BKPT;
/* Initialize the new object */
pDb->pEnv = pEnv;
pDb->nTreeLimit = LSM_TREE_BYTES;
pDb->bAutowork = 1;
pDb->eSafety = LSM_SAFETY_NORMAL;
pDb->xCmp = xCmp;
pDb->nLogSz = LSM_DEFAULT_LOG_SIZE;
pDb->nDfltPgsz = LSM_PAGE_SIZE;
pDb->nDfltBlksz = LSM_BLOCK_SIZE;
pDb->bUseLog = 1;
return LSM_OK;
}
lsm_env *lsm_get_env(lsm_db *pDb){
assert( pDb->pEnv );
return pDb->pEnv;
}
/*
** Release snapshot handle *ppSnap. Then set *ppSnap to zero. This
** is useful for doing (say):
**
** dbReleaseSnapshot(pDb->pEnv, &pDb->pWorker);
*/
static void dbReleaseSnapshot(lsm_env *pEnv, Snapshot **ppSnap){
lsmDbSnapshotRelease(pEnv, *ppSnap);
*ppSnap = 0;
}
/*
** If database handle pDb is currently holding a client snapshot, but does
** not have any open cursors or write transactions, release it.
*/
static void dbReleaseClientSnapshot(lsm_db *pDb){
if( pDb->nTransOpen==0 && pDb->pCsr==0 ){
lsmFinishReadTrans(pDb);
}
}
static void dbWorkerStart(lsm_db *pDb){
assert( pDb->pWorker==0 );
pDb->pWorker = lsmDbSnapshotWorker(pDb);
}
static void dbWorkerDone(lsm_db *pDb){
assert( pDb->pWorker );
dbReleaseSnapshot(pDb->pEnv, &pDb->pWorker);
}
static int dbAutoWork(lsm_db *pDb, int nUnit){
int rc = LSM_OK; /* Return code */
assert( pDb->pWorker==0 );
assert( pDb->bAutowork );
assert( nUnit>0 );
/* If one is required, run a checkpoint. */
rc = lsmCheckpointWrite(pDb);
dbWorkerStart(pDb);
rc = lsmSortedAutoWork(pDb, nUnit);
dbWorkerDone(pDb);
return rc;
}
/*
** If required, run the recovery procedure to initialize the database.
** Return LSM_OK if successful or an error code otherwise.
*/
static int dbRecoverIfRequired(lsm_db *pDb){
int rc = LSM_OK;
assert( pDb->pWorker==0 && pDb->pClient==0 );
/* The following call returns NULL if recovery is not required. */
pDb->pWorker = lsmDbSnapshotRecover(pDb);
if( pDb->pWorker ){
/* Read the database structure */
rc = lsmCheckpointRead(pDb);
/* Read the free block list and any level records stored in the LSM. */
if( rc==LSM_OK ){
rc = lsmSortedLoadSystem(pDb);
}
/* Set up the initial append list */
if( rc==LSM_OK ){
rc = lsmFsSetupAppendList(pDb);
}
/* Populate the in-memory tree by reading the log file. */
if( rc==LSM_OK ){
rc = lsmLogRecover(pDb);
}
/* Set the "recovery done" flag */
if( rc==LSM_OK ){
lsmDbRecoveryComplete(pDb, 1);
}
/* Set up the initial client snapshot. */
if( rc==LSM_OK ){
rc = lsmDbUpdateClient(pDb, 0);
}
dbReleaseSnapshot(pDb->pEnv, &pDb->pWorker);
}
return rc;
}
static int getFullpathname(
lsm_env *pEnv,
const char *zRel,
char **pzAbs
){
int nAlloc = 0;
char *zAlloc = 0;
int nReq = 0;
int rc;
do{
nAlloc = nReq;
rc = pEnv->xFullpath(pEnv, zRel, zAlloc, &nReq);
if( nReq>nAlloc ){
zAlloc = lsmReallocOrFreeRc(pEnv, zAlloc, nReq, &rc);
}
}while( nReq>nAlloc && rc==LSM_OK );
if( rc!=LSM_OK ){
lsmFree(pEnv, zAlloc);
zAlloc = 0;
}
*pzAbs = zAlloc;
return rc;
}
/*
** Open a new connection to database zFilename.
*/
int lsm_open(lsm_db *pDb, const char *zFilename){
int rc;
if( pDb->pDatabase ){
rc = LSM_MISUSE;
}else{
char *zFull;
/* Translate the possibly relative pathname supplied by the user into
** an absolute pathname. This is required because the supplied path
** is used (either directly or with "-log" appended to it) for more
** than one purpose - to open both the database and log files, and
** perhaps to unlink the log file during disconnection. An absolute
** path is required to ensure that the correct files are operated
** on even if the application changes the cwd. */
rc = getFullpathname(pDb->pEnv, zFilename, &zFull);
assert( rc==LSM_OK || zFull==0 );
/* Open the database file */
if( rc==LSM_OK ){
rc = lsmFsOpen(pDb, zFull);
}
/* Open the shared data handle. */
if( rc==LSM_OK ){
rc = lsmDbDatabaseFind(pDb, zFilename);
}
if( rc==LSM_OK ){
rc = dbRecoverIfRequired(pDb);
}
lsmFree(pDb->pEnv, zFull);
}
return rc;
}
/*
** This function flushes the contents of the in-memory tree to disk. It
** returns LSM_OK if successful, or an error code otherwise.
*/
int lsmFlushToDisk(lsm_db *pDb){
int rc = LSM_OK; /* Return code */
int nHdrLevel;
/* Must not hold the worker snapshot when this is called. */
assert( pDb->pWorker==0 );
dbWorkerStart(pDb);
/* Save the position of each open cursor belonging to pDb. */
rc = lsmSaveCursors(pDb);
/* Write the contents of the in-memory tree into the database file and
** update the worker snapshot accordingly. Then flush the contents of
** the db file to disk too. No calls to fsync() are made here - just
** write(). */
if( rc==LSM_OK ) rc = lsmSortedFlushTree(pDb, &nHdrLevel);
if( rc==LSM_OK ) rc = lsmSortedFlushDb(pDb);
/* Create a new client snapshot - one that uses the new runs created above. */
if( rc==LSM_OK ) rc = lsmDbUpdateClient(pDb, nHdrLevel);
/* Restore the position of any open cursors */
rc = lsmRestoreCursors(pDb);
#if 0
if( rc==LSM_OK ) lsmSortedDumpStructure(pDb, pDb->pWorker, 0, 0, "flush");
#endif
dbWorkerDone(pDb);
return rc;
}
int lsm_close(lsm_db *pDb){
int rc = LSM_OK;
if( pDb ){
assert_db_state(pDb);
if( pDb->pCsr || pDb->nTransOpen ){
rc = LSM_MISUSE_BKPT;
}else{
assert( pDb->pWorker==0 && pDb->pTV==0 );
lsmDbDatabaseRelease(pDb);
lsmFsClose(pDb->pFS);
lsmFree(pDb->pEnv, pDb->aTrans);
lsmFree(pDb->pEnv, pDb);
}
}
return rc;
}
int lsm_config(lsm_db *pDb, int eParam, ...){
int rc = LSM_OK;
va_list ap;
va_start(ap, eParam);
switch( eParam ){
case LSM_CONFIG_WRITE_BUFFER: {
int *piVal = va_arg(ap, int *);
if( *piVal>0 ){
pDb->nTreeLimit = *piVal;
}
*piVal = pDb->nTreeLimit;
break;
}
case LSM_CONFIG_AUTOWORK: {
int *piVal = va_arg(ap, int *);
if( *piVal>=0 ){
pDb->bAutowork = *piVal;
}
*piVal = pDb->bAutowork;
break;
}
case LSM_CONFIG_LOG_SIZE: {
int *piVal = va_arg(ap, int *);
if( *piVal>0 ){
pDb->nLogSz = *piVal;
}
*piVal = pDb->nLogSz;
break;
}
case LSM_CONFIG_PAGE_SIZE: {
int *piVal = va_arg(ap, int *);
if( pDb->pDatabase ){
/* If lsm_open() has been called, this is a read-only parameter.
** Set the output variable to the page-size according to the
** FileSystem object. */
*piVal = lsmFsPageSize(pDb->pFS);
}else{
if( *piVal>=256 && *piVal<=65536 && ((*piVal-1) & *piVal)==0 ){
pDb->nDfltPgsz = *piVal;
}else{
*piVal = pDb->nDfltPgsz;
}
}
break;
}
case LSM_CONFIG_BLOCK_SIZE: {
int *piVal = va_arg(ap, int *);
if( pDb->pDatabase ){
/* If lsm_open() has been called, this is a read-only parameter.
** Set the output variable to the page-size according to the
** FileSystem object. */
*piVal = lsmFsBlockSize(pDb->pFS);
}else{
if( *piVal>=65536 && ((*piVal-1) & *piVal)==0 ){
pDb->nDfltBlksz = *piVal;
}else{
*piVal = pDb->nDfltBlksz;
}
}
break;
}
case LSM_CONFIG_SAFETY: {
int *piVal = va_arg(ap, int *);
if( *piVal>=0 && *piVal<=2 ){
pDb->eSafety = *piVal;
}
*piVal = pDb->eSafety;
break;
}
case LSM_CONFIG_MMAP: {
int *piVal = va_arg(ap, int *);
rc = lsmConfigMmap(pDb, piVal);
break;
}
case LSM_CONFIG_USE_LOG: {
int *piVal = va_arg(ap, int *);
if( pDb->nTransOpen==0 && (*piVal==0 || *piVal==1) ){
pDb->bUseLog = *piVal;
}
*piVal = pDb->bUseLog;
break;
}
default:
rc = LSM_MISUSE;
break;
}
va_end(ap);
return rc;
}
void lsmAppendSegmentList(LsmString *pStr, char *zPre, Segment *pSeg){
lsmStringAppendf(pStr, "%s{%d %d %d %d %d %d}", zPre,
pSeg->sep.iFirst, pSeg->sep.iLast, pSeg->sep.iRoot,
pSeg->run.iFirst, pSeg->run.iLast, pSeg->run.nSize
);
}
int lsmStructList(
lsm_db *pDb, /* Database handle */
char **pzOut /* OUT: Nul-terminated string (tcl list) */
){
Level *pTopLevel = 0; /* Top level of snapshot to report on */
int rc = LSM_OK;
Level *p;
LsmString s;
Snapshot *pWorker; /* Worker snapshot */
Snapshot *pRelease = 0; /* Snapshot to release */
/* Obtain the worker snapshot */
pWorker = pDb->pWorker;
if( !pWorker ){
pRelease = pWorker = lsmDbSnapshotWorker(pDb);
}
/* Format the contents of the snapshot as text */
pTopLevel = lsmDbSnapshotLevel(pWorker);
lsmStringInit(&s, pDb->pEnv);
for(p=pTopLevel; rc==LSM_OK && p; p=p->pNext){
int i;
lsmStringAppendf(&s, "%s{", (s.n ? " " : ""));
lsmAppendSegmentList(&s, "", &p->lhs);
for(i=0; rc==LSM_OK && i<p->nRight; i++){
lsmAppendSegmentList(&s, " ", &p->aRhs[i]);
}
lsmStringAppend(&s, "}", 1);
}
rc = s.n>=0 ? LSM_OK : LSM_NOMEM;
/* Release the snapshot and return */
lsmDbSnapshotRelease(pDb->pEnv, pRelease);
*pzOut = s.z;
return rc;
}
int lsm_info(lsm_db *pDb, int eParam, ...){
int rc = LSM_OK;
va_list ap;
va_start(ap, eParam);
switch( eParam ){
case LSM_INFO_NWRITE: {
int *piVal = va_arg(ap, int *);
*piVal = lsmFsNWrite(pDb->pFS);
break;
}
case LSM_INFO_NREAD: {
int *piVal = va_arg(ap, int *);
*piVal = lsmFsNRead(pDb->pFS);
break;
}
case LSM_INFO_DB_STRUCTURE: {
char **pzVal = va_arg(ap, char **);
rc = lsmStructList(pDb, pzVal);
break;
}
case LSM_INFO_ARRAY_STRUCTURE: {
Pgno pgno = va_arg(ap, Pgno);
char **pzVal = va_arg(ap, char **);
rc = lsmInfoArrayStructure(pDb, pgno, pzVal);
break;
}
case LSM_INFO_PAGE_HEX_DUMP:
case LSM_INFO_PAGE_ASCII_DUMP: {
Pgno pgno = va_arg(ap, Pgno);
char **pzVal = va_arg(ap, char **);
rc = lsmInfoPageDump(pDb, pgno, (eParam==LSM_INFO_PAGE_HEX_DUMP), pzVal);
break;
}
case LSM_INFO_LOG_STRUCTURE: {
char **pzVal = va_arg(ap, char **);
rc = lsmLogStructure(pDb, pzVal);
break;
}
default:
rc = LSM_MISUSE;
break;
}
va_end(ap);
return rc;
}
/*
** Write a new value into the database.
*/
int lsm_write(lsm_db *pDb, void *pKey, int nKey, void *pVal, int nVal){
int rc = LSM_OK; /* Return code */
int bCommit = 0; /* True to commit before returning */
if( pDb->nTransOpen==0 ){
bCommit = 1;
rc = lsm_begin(pDb, 1);
}
if( rc==LSM_OK ){
assert( pDb->pTV && lsmTreeIsWriteVersion(pDb->pTV) );
rc = lsmLogWrite(pDb, pKey, nKey, pVal, nVal);
}
lsmSortedSaveTreeCursors(pDb);
if( rc==LSM_OK ){
int pgsz = lsmFsPageSize(pDb->pFS);
int nQuant = 32 * pgsz;
int nBefore;
int nAfter;
int nDiff;
if( nQuant>pDb->nTreeLimit ){
nQuant = pDb->nTreeLimit;
}
nBefore = lsmTreeSize(pDb->pTV);
rc = lsmTreeInsert(pDb, pKey, nKey, pVal, nVal);
nAfter = lsmTreeSize(pDb->pTV);
nDiff = (nAfter/nQuant) - (nBefore/nQuant);
if( rc==LSM_OK && pDb->bAutowork && nDiff!=0 ){
rc = dbAutoWork(pDb, nDiff*nQuant / pgsz);
}
}
/* If a transaction was opened at the start of this function, commit it.
** Or, if an error has occurred, roll it back.
*/
if( bCommit ){
if( rc==LSM_OK ){
rc = lsm_commit(pDb, 0);
}else{
lsm_rollback(pDb, 0);
}
}
return rc;
}
/*
** Delete a value from the database.
*/
int lsm_delete(lsm_db *pDb, void *pKey, int nKey){
return lsm_write(pDb, pKey, nKey, 0, -1);
}
/*
** Open a new cursor handle.
**
** If there are currently no other open cursor handles, and no open write
** transaction, open a read transaction here.
*/
int lsm_csr_open(lsm_db *pDb, lsm_cursor **ppCsr){
int rc; /* Return code */
MultiCursor *pCsr = 0; /* New cursor object */
/* Open a read transaction if one is not already open. */
assert_db_state(pDb);
rc = lsmBeginReadTrans(pDb);
/* Allocate the multi-cursor. */
if( rc==LSM_OK ) rc = lsmMCursorNew(pDb, &pCsr);
/* If an error has occured, set the output to NULL and delete any partially
** allocated cursor. If this means there are no open cursors, release the
** client snapshot. */
if( rc!=LSM_OK ){
lsmMCursorClose(pCsr);
dbReleaseClientSnapshot(pDb);
}
assert_db_state(pDb);
*ppCsr = (lsm_cursor *)pCsr;
return rc;
}
/*
** Close a cursor opened using lsm_csr_open().
*/
int lsm_csr_close(lsm_cursor *p){
if( p ){
lsm_db *pDb = lsmMCursorDb((MultiCursor *)p);
assert_db_state(pDb);
lsmMCursorClose((MultiCursor *)p);
dbReleaseClientSnapshot(pDb);
assert_db_state(pDb);
}
return LSM_OK;
}
/*
** Attempt to seek the cursor to the database entry specified by pKey/nKey.
** If an error occurs (e.g. an OOM or IO error), return an LSM error code.
** Otherwise, return LSM_OK.
*/
int lsm_csr_seek(lsm_cursor *pCsr, void *pKey, int nKey, int eSeek){
return lsmMCursorSeek((MultiCursor *)pCsr, pKey, nKey, eSeek);
}
int lsm_csr_next(lsm_cursor *pCsr){
return lsmMCursorNext((MultiCursor *)pCsr);
}
int lsm_csr_prev(lsm_cursor *pCsr){
return lsmMCursorPrev((MultiCursor *)pCsr);
}
int lsm_csr_first(lsm_cursor *pCsr){
return lsmMCursorFirst((MultiCursor *)pCsr);
}
int lsm_csr_last(lsm_cursor *pCsr){
return lsmMCursorLast((MultiCursor *)pCsr);
}
int lsm_csr_valid(lsm_cursor *pCsr){
return lsmMCursorValid((MultiCursor *)pCsr);
}
int lsm_csr_key(lsm_cursor *pCsr, void **ppKey, int *pnKey){
return lsmMCursorKey((MultiCursor *)pCsr, ppKey, pnKey);
}
int lsm_csr_value(lsm_cursor *pCsr, void **ppVal, int *pnVal){
return lsmMCursorValue((MultiCursor *)pCsr, ppVal, pnVal);
}
void lsm_config_log(
lsm_db *pDb,
void (*xLog)(void *, int, const char *),
void *pCtx
){
pDb->xLog = xLog;
pDb->pLogCtx = pCtx;
}
void lsm_config_work_hook(
lsm_db *pDb,
void (*xWork)(lsm_db *, void *),
void *pCtx
){
pDb->xWork = xWork;
pDb->pWorkCtx = pCtx;
}
void lsmLogMessage(lsm_db *pDb, int rc, const char *zFormat, ...){
if( pDb->xLog ){
LsmString s;
va_list ap, ap2;
lsmStringInit(&s, pDb->pEnv);
va_start(ap, zFormat);
va_start(ap2, zFormat);
lsmStringVAppendf(&s, zFormat, ap, ap2);
va_end(ap);
va_end(ap2);
pDb->xLog(pDb->pLogCtx, rc, s.z);
lsmStringClear(&s);
}
}
int lsm_begin(lsm_db *pDb, int iLevel){
int rc = LSM_OK;
assert_db_state( pDb );
/* A value less than zero means open one more transaction. */
if( iLevel<0 ) iLevel = pDb->nTransOpen + 1;
if( iLevel>pDb->nTransOpen ){
int i;
/* Extend the pDb->aTrans[] array if required. */
if( rc==LSM_OK && pDb->nTransAlloc<iLevel ){
TransMark *aNew; /* New allocation */
int nByte = sizeof(TransMark) * (iLevel+1);
aNew = (TransMark *)lsmRealloc(pDb->pEnv, pDb->aTrans, nByte);
if( !aNew ){
rc = LSM_NOMEM;
}else{
nByte = sizeof(TransMark) * (iLevel+1 - pDb->nTransAlloc);
memset(&aNew[pDb->nTransAlloc], 0, nByte);
pDb->nTransAlloc = iLevel+1;
pDb->aTrans = aNew;
}
}
if( rc==LSM_OK && pDb->nTransOpen==0 ){
rc = lsmBeginWriteTrans(pDb);
}
if( rc==LSM_OK ){
for(i=pDb->nTransOpen; i<iLevel; i++){
lsmTreeMark(pDb->pTV, &pDb->aTrans[i].tree);
lsmLogTell(pDb, &pDb->aTrans[i].log);
}
pDb->nTransOpen = iLevel;
}
}
return rc;
}
int lsm_commit(lsm_db *pDb, int iLevel){
int rc = LSM_OK;
assert_db_state( pDb );
/* A value less than zero means close the innermost nested transaction. */
if( iLevel<0 ) iLevel = LSM_MAX(0, pDb->nTransOpen - 1);
if( iLevel<pDb->nTransOpen ){
if( iLevel==0 ){
/* Commit the transaction to disk. */
if( pDb->pTV && lsmTreeSize(pDb->pTV)>pDb->nTreeLimit ){
rc = lsmFlushToDisk(pDb);
}
if( rc==LSM_OK ) rc = lsmLogCommit(pDb);
if( rc==LSM_OK && pDb->eSafety==LSM_SAFETY_FULL ){
rc = lsmFsSyncLog(pDb->pFS);
}
lsmFinishWriteTrans(pDb, (rc==LSM_OK));
}
pDb->nTransOpen = iLevel;
}
dbReleaseClientSnapshot(pDb);
return rc;
}
int lsm_rollback(lsm_db *pDb, int iLevel){
int rc = LSM_OK;
assert_db_state( pDb );
if( pDb->nTransOpen ){
/* A value less than zero means close the innermost nested transaction. */
if( iLevel<0 ) iLevel = LSM_MAX(0, pDb->nTransOpen - 1);
if( iLevel<=pDb->nTransOpen ){
TransMark *pMark = &pDb->aTrans[(iLevel==0 ? 0 : iLevel-1)];
lsmTreeRollback(pDb, &pMark->tree);
if( iLevel ) lsmLogSeek(pDb, &pMark->log);
pDb->nTransOpen = iLevel;
}
if( pDb->nTransOpen==0 ){
lsmFinishWriteTrans(pDb, 0);
}
dbReleaseClientSnapshot(pDb);
}
return rc;
}
/************** End of lsm_main.c ********************************************/
/************** Begin file lsm_mem.c *****************************************/
/*
** 2011-08-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.
**
*************************************************************************
**
** Helper routines for memory allocation.
*/
/* Default allocation size. */
#define CHUNKSIZE 16*1024
typedef struct Chunk Chunk;
struct Chunk {
int iOff; /* Offset of free space within pSpace */
u8 *aData; /* Pointer to space for user allocations */
int nData; /* Size of buffer aData, in bytes */
Chunk *pNext;
};
struct Mempool {
Chunk *pFirst; /* First in list of chunks */
Chunk *pLast; /* Last in list of chunks */
int nUsed; /* Total number of bytes allocated */
};
/*
** The following routines are called internally by LSM sub-routines. In
** this case a valid environment pointer must be supplied.
*/
void *lsmMalloc(lsm_env *pEnv, size_t N){
assert( pEnv );
return pEnv->xMalloc(pEnv, N);
}
void lsmFree(lsm_env *pEnv, void *p){
assert( pEnv );
pEnv->xFree(pEnv, p);
}
void *lsmRealloc(lsm_env *pEnv, void *p, size_t N){
assert( pEnv );
return pEnv->xRealloc(pEnv, p, N);
}
/*
** Core memory allocation routines for LSM.
*/
void *lsm_malloc(lsm_env *pEnv, size_t N){
return lsmMalloc(pEnv ? pEnv : lsm_default_env(), N);
}
void lsm_free(lsm_env *pEnv, void *p){
lsmFree(pEnv ? pEnv : lsm_default_env(), p);
}
void *lsm_realloc(lsm_env *pEnv, void *p, size_t N){
return lsmRealloc(pEnv ? pEnv : lsm_default_env(), p, N);
}
void *lsmMallocZero(lsm_env *pEnv, size_t N){
void *pRet;
assert( pEnv );
pRet = lsmMalloc(pEnv, N);
if( pRet ) memset(pRet, 0, N);
return pRet;
}
void *lsmMallocRc(lsm_env *pEnv, size_t N, int *pRc){
void *pRet = 0;
if( *pRc==LSM_OK ){
pRet = lsmMalloc(pEnv, N);
if( pRet==0 ){
*pRc = LSM_NOMEM_BKPT;
}
}
return pRet;
}
void *lsmMallocZeroRc(lsm_env *pEnv, size_t N, int *pRc){
void *pRet = 0;
if( *pRc==LSM_OK ){
pRet = lsmMallocZero(pEnv, N);
if( pRet==0 ){
*pRc = LSM_NOMEM_BKPT;
}
}
return pRet;
}
void *lsmReallocOrFree(lsm_env *pEnv, void *p, size_t N){
void *pNew;
pNew = lsm_realloc(pEnv, p, N);
if( !pNew ) lsm_free(pEnv, p);
return pNew;
}
void *lsmReallocOrFreeRc(lsm_env *pEnv, void *p, size_t N, int *pRc){
void *pRet = 0;
if( *pRc ){
lsmFree(pEnv, p);
}else{
pRet = lsmReallocOrFree(pEnv, p, N);
if( !pRet ) *pRc = LSM_NOMEM_BKPT;
}
return pRet;
}
char *lsmMallocStrdup(lsm_env *pEnv, const char *zIn){
int nByte;
char *zRet;
nByte = strlen(zIn);
zRet = lsmMalloc(pEnv, nByte+1);
if( zRet ){
memcpy(zRet, zIn, nByte+1);
}
return zRet;
}
/*
** Allocate a new Chunk structure (using lsmMalloc()).
*/
static Chunk * poolChunkNew(lsm_env *pEnv, int nMin){
Chunk *pChunk;
int nAlloc = LSM_MAX(CHUNKSIZE, nMin + sizeof(Chunk));
pChunk = (Chunk *)lsmMalloc(pEnv, nAlloc);
if( pChunk ){
pChunk->pNext = 0;
pChunk->iOff = 0;
pChunk->aData = (u8 *)&pChunk[1];
pChunk->nData = nAlloc - sizeof(Chunk);
}
return pChunk;
}
/*
** Allocate sz bytes from chunk pChunk.
*/
static u8 *poolChunkAlloc(Chunk *pChunk, int sz){
u8 *pRet; /* Pointer value to return */
assert( sz<=(pChunk->nData - pChunk->iOff) );
pRet = &pChunk->aData[pChunk->iOff];
pChunk->iOff += sz;
return pRet;
}
int lsmPoolNew(lsm_env *pEnv, Mempool **ppPool){
int rc = LSM_NOMEM;
Mempool *pPool = 0;
Chunk *pChunk;
pChunk = poolChunkNew(pEnv, sizeof(Mempool));
if( pChunk ){
pPool = (Mempool *)poolChunkAlloc(pChunk, sizeof(Mempool));
pPool->pFirst = pChunk;
pPool->pLast = pChunk;
pPool->nUsed = 0;
rc = LSM_OK;
}
*ppPool = pPool;
return rc;
}
void lsmPoolDestroy(lsm_env *pEnv, Mempool *pPool){
if( pPool ){
Chunk *pChunk = pPool->pFirst;
while( pChunk ){
Chunk *pFree = pChunk;
pChunk = pChunk->pNext;
lsmFree(pEnv, pFree);
}
}
}
void *lsmPoolMalloc(lsm_env *pEnv, Mempool *pPool, int nByte){
u8 *pRet = 0;
Chunk *pLast = pPool->pLast;
nByte = ROUND8(nByte);
if( nByte > (pLast->nData - pLast->iOff) ){
Chunk *pNew = poolChunkNew(pEnv, nByte);
if( pNew ){
pLast->pNext = pNew;
pPool->pLast = pNew;
pLast = pNew;
}
}
if( pLast ){
pRet = poolChunkAlloc(pLast, nByte);
pPool->nUsed += nByte;
}
return (void *)pRet;
}
void *lsmPoolMallocZero(lsm_env *pEnv, Mempool *pPool, int nByte){
void *pRet = lsmPoolMalloc(pEnv, pPool, nByte);
if( pRet ) memset(pRet, 0, nByte);
return pRet;
}
/*
** Return the amount of memory currently allocated from this pool.
*/
int lsmPoolUsed(Mempool *pPool){
return pPool->nUsed;
}
void lsmPoolMark(Mempool *pPool, void **ppChunk, int *piOff){
*ppChunk = (void *)pPool->pLast;
*piOff = pPool->pLast->iOff;
}
void lsmPoolRollback(lsm_env *pEnv, Mempool *pPool, void *pChunk, int iOff){
Chunk *pLast = (Chunk *)pChunk;
Chunk *p;
Chunk *pNext;
#ifdef LSM_EXPENSIVE_DEBUG
/* Check that pLast is actually in the list of chunks */
for(p=pPool->pFirst; p!=pLast; p=p->pNext);
#endif
pPool->nUsed -= (pLast->iOff - iOff);
for(p=pLast->pNext; p; p=pNext){
pPool->nUsed -= p->iOff;
pNext = p->pNext;
lsmFree(pEnv, p);
}
pLast->pNext = 0;
pLast->iOff = iOff;
pPool->pLast = pLast;
}
/************** End of lsm_mem.c *********************************************/
/************** Begin file lsm_mutex.c ***************************************/
/*
** 2012-01-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.
**
*************************************************************************
**
** Mutex functions for LSM.
*/
/*
** Allocate a new mutex.
*/
int lsmMutexNew(lsm_env *pEnv, lsm_mutex **ppNew){
return pEnv->xMutexNew(pEnv, ppNew);
}
/*
** Return a handle for one of the static mutexes.
*/
int lsmMutexStatic(lsm_env *pEnv, int iMutex, lsm_mutex **ppStatic){
return pEnv->xMutexStatic(pEnv, iMutex, ppStatic);
}
/*
** Free a mutex allocated by lsmMutexNew().
*/
void lsmMutexDel(lsm_env *pEnv, lsm_mutex *pMutex){
if( pMutex ) pEnv->xMutexDel(pMutex);
}
/*
** Enter a mutex.
*/
void lsmMutexEnter(lsm_env *pEnv, lsm_mutex *pMutex){
pEnv->xMutexEnter(pMutex);
}
/*
** Attempt to enter a mutex, but do not block. If successful, return zero.
** Otherwise, if the mutex is already held by some other thread and is not
** entered, return non zero.
**
** Each successful call to this function must be matched by a call to
** lsmMutexLeave().
*/
int lsmMutexTry(lsm_env *pEnv, lsm_mutex *pMutex){
return pEnv->xMutexTry(pMutex);
}
/*
** Leave a mutex.
*/
void lsmMutexLeave(lsm_env *pEnv, lsm_mutex *pMutex){
pEnv->xMutexLeave(pMutex);
}
#ifndef NDEBUG
/*
** Return non-zero if the mutex passed as the second argument is held
** by the calling thread, or zero otherwise. If the implementation is not
** able to tell if the mutex is held by the caller, it should return
** non-zero.
**
** This function is only used as part of assert() statements.
*/
int lsmMutexHeld(lsm_env *pEnv, lsm_mutex *pMutex){
return pEnv->xMutexHeld ? pEnv->xMutexHeld(pMutex) : 1;
}
/*
** Return non-zero if the mutex passed as the second argument is not
** held by the calling thread, or zero otherwise. If the implementation
** is not able to tell if the mutex is held by the caller, it should
** return non-zero.
**
** This function is only used as part of assert() statements.
*/
int lsmMutexNotHeld(lsm_env *pEnv, lsm_mutex *pMutex){
return pEnv->xMutexNotHeld ? pEnv->xMutexNotHeld(pMutex) : 1;
}
#endif
/************** End of lsm_mutex.c *******************************************/
/************** Begin file lsm_shared.c **************************************/
/*
** 2012-01-23
**
** 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.
**
*************************************************************************
**
** Utilities used to help multiple LSM clients to coexist within the
** same process space.
*/
typedef struct Freelist Freelist;
typedef struct AppendList AppendList;
typedef struct FreelistEntry FreelistEntry;
/*
** TODO: Find homes for these miscellaneous notes.
**
** FREE-LIST DELTA FORMAT
**
** The free-list delta consists of three integers:
**
** 1. The number of elements to remove from the start of the free-list.
** 2. If non-zero, a refreed block to append to the free-list.
** 3. Same as (2).
**
** SNAPSHOT ID MANIPULATIONS
**
** When the database is initialized the worker snapshot id is set to the
** value read from the checkpoint. Or, if there is no valid checkpoint,
** to a non-zero default value (e.g. 1).
**
** The client snapshot is then initialized as a copy of the worker. The
** client snapshot id is a copy of the worker snapshot id (as read from
** the checkpoint). The worker snapshot id is then incremented.
**
*/
/*
** Global data. All global variables used by code in this file are grouped
** into the following structure instance.
**
** pDatabase:
** Linked list of all Database objects allocated within this process.
** This list may not be traversed without holding the global mutex (see
** functions enterGlobalMutex() and leaveGlobalMutex()).
*/
static struct SharedData {
Database *pDatabase; /* Linked list of all Database objects */
} gShared;
/*
** An instance of the following structure stores the current database free
** block list. The free list is a list of blocks that are not currently
** used by the worker snapshot. Assocated with each block in the list is the
** snapshot id of the most recent snapshot that did actually use the block.
*/
struct Freelist {
FreelistEntry *aEntry; /* Free list entries */
int nEntry; /* Number of valid slots in aEntry[] */
int nAlloc; /* Allocated size of aEntry[] */
};
struct FreelistEntry {
int iBlk; /* Block number */
i64 iId; /* Largest snapshot id to use this block */
};
struct AppendList {
Pgno *aPoint;
int nPoint;
int nAlloc;
};
/*
** A snapshot of a database. A snapshot contains all the information required
** to read or write a database file on disk. See the description of struct
** Database below for futher details.
**
** pExport/nExport:
** pExport points to a buffer containing the serialized (checkpoint)
** image of the snapshot. The serialized image is nExport bytes in size.
*/
struct Snapshot {
Database *pDatabase; /* Database this snapshot belongs to */
Level *pLevel; /* Pointer to level 0 of snapshot (or NULL) */
i64 iId; /* Snapshot id */
Pgno iLogPg; /* Log file page to start recovery from */
u32 iSalt1; /* Log file salt value 1 */
u32 iSalt2; /* Log file salt value 2 */
u32 aDelta[LSM_FREELIST_DELTA_SIZE];
/* Used by client snapshots only */
int nRef; /* Number of references to this structure */
void *pExport; /* Serialized snapshot image */
int nExport; /* Size of pExport in bytes */
/* Used by client snapshots only */
Snapshot *pSnapshotNext;
/* TODO: Below this point should be moved from Snapshot to Database. */
/* The following are populated and used by worker snapshots only */
int nBlock; /* Number of blocks tracked by this ss */
Freelist freelist; /* Database free-list */
int bRecordDelta; /* True when recording freelist delta */
};
#define LSM_INITIAL_LOGPG 1
#define LSM_INITIAL_SNAPSHOT_ID 11
#define LSM_INITIAL_SALT1 0x6c736d21
#define LSM_INITIAL_SALT2 0x78743121
/*
** Database structure. There is one such structure for each distinct
** database accessed by this process. They are stored in the singly linked
** list starting at global variable gShared.pDatabase. Database objects are
** reference counted. Once the number of connections to the associated
** database drops to zero, they are removed from the linked list and deleted.
**
** The primary purpose of the Database structure is to manage Snapshots. A
** snapshot contains the information required to read a database - exactly
** where each array is stored, and where new arrays can be written. A
** database has one worker snapshot and any number of client snapshots.
**
** WORKER SNAPSHOT
**
** When a connection is first made to a database and the Database object
** created, the worker snapshot is initialized to the most recently
** checkpointed database state (based on the values in the db header).
** Any time the database file is written to, either to flush the contents
** of an in-memory tree or to merge existing segments, the worker snapshot
** is updated to reflect the modifications.
**
** The worker snapshot is protected by the worker mutex. The worker mutex
** must be obtained before a connection begins to modify the database
** file. After the db file is written, the worker snapshot is updated and
** the worker mutex released.
**
** CLIENT SNAPSHOTS
**
** Client snapshots are used by database clients (readers). When a
** transaction is opened, the client requests a pointer to a read-only
** client snapshot. It is relinquished when the transaction ends. Client
** snapshots are reference counted objects.
**
** When a database is first loaded, the client snapshot is a copy of
** the worker snapshot. Each time the worker snapshot is checkpointed,
** the client snapshot is updated with the new checkpointed contents.
**
** THE FREE-BLOCK LIST
**
** Each Database structure maintains a list of free blocks - the "free-list".
** There is an entry in the free-list for each block in the database file
** that is not used in any way by the worker snapshot.
**
** Associated with each free block in the free-list is a snapshot id.
** This is the id of the earliest snapshot that does not require the
** contents of the block. The block may therefore be reused only after:
**
** (a) a snapshot with an id equal to or greater than the id associated
** with the block has been checkpointed into the db header, and
**
** (b) all existing database clients are using a snapshot with an id
** equal to or greater than the id stored in the free-list entry.
**
** MULTI-THREADING ISSUES
**
** Each Database structure carries with it two mutexes - the client
** mutex and the worker mutex. In a multi-process version of LSM, these
** will be replaced by some other robust locking mechanism.
**
** TODO - this description.
*/
struct Database {
#if 0
lsm_env *pEnv; /* Environment handle */
#endif
char *zName; /* Canonical path to database file */
void *pId; /* Database id (file inode) */
int nId; /* Size of pId in bytes */
Tree *pTree; /* Current in-memory tree structure */
DbLog log; /* Database log state object */
int nPgsz; /* Nominal database page size */
int nBlksz; /* Database block size */
Snapshot *pClient; /* Client (reader) snapshot */
Snapshot worker; /* Worker (writer) snapshot */
AppendList append; /* List of appendable points */
lsm_mutex *pWorkerMutex; /* Protects the worker snapshot */
lsm_mutex *pClientMutex; /* Protects pClient */
int bDirty; /* True if worker has been modified */
int bRecovered; /* True if db does not require recovery */
int bCheckpointer; /* True if there exists a checkpointer */
int bWriter; /* True if there exists a writer */
i64 iCheckpointId; /* Largest snapshot id stored in db file */
/* Protected by the global mutex (enterGlobalMutex/leaveGlobalMutex): */
int nDbRef; /* Number of associated lsm_db handles */
Database *pDbNext; /* Next Database structure in global list */
};
/*
** Macro that evaluates to true if the snapshot passed as the only argument
** is a worker snapshot.
*/
#define isWorker(pSnap) ((pSnap)==(&(pSnap)->pDatabase->worker))
/*
** Functions to enter and leave the global mutex. This mutex is used
** to protect the global linked-list headed at
*/
static int enterGlobalMutex(lsm_env *pEnv){
lsm_mutex *p;
int rc = lsmMutexStatic(pEnv, LSM_MUTEX_GLOBAL, &p);
if( rc==LSM_OK ) lsmMutexEnter(pEnv, p);
return rc;
}
static void leaveGlobalMutex(lsm_env *pEnv){
lsm_mutex *p;
lsmMutexStatic(pEnv, LSM_MUTEX_GLOBAL, &p);
lsmMutexLeave(pEnv, p);
}
#ifdef LSM_DEBUG
static int holdingGlobalMutex(lsm_env *pEnv){
lsm_mutex *p;
lsmMutexStatic(pEnv, LSM_MUTEX_GLOBAL, &p);
return lsmMutexHeld(pEnv, p);
}
static void assertNotInFreelist(Freelist *p, int iBlk){
int i;
for(i=0; i<p->nEntry; i++){
assert( p->aEntry[i].iBlk!=iBlk );
}
}
static void assertMustbeWorker(lsm_db *pDb){
assert( pDb->pWorker );
assert( lsmMutexHeld(pDb->pEnv, pDb->pDatabase->pWorkerMutex) );
}
static void assertSnapshotListOk(Database *p){
Snapshot *pIter;
i64 iPrev = 0;
for(pIter=p->pClient; pIter; pIter=pIter->pSnapshotNext){
assert( pIter==p->pClient || pIter->iId<iPrev );
iPrev = pIter->iId;
}
}
#else
# define assertNotInFreelist(x,y)
# define assertMustbeWorker(x)
# define assertSnapshotListOk(x)
#endif
Pgno *lsmSharedAppendList(lsm_db *db, int *pnApp){
Database *p = db->pDatabase;
assert( db->pWorker );
*pnApp = p->append.nPoint;
return p->append.aPoint;
}
int lsmSharedAppendListAdd(lsm_db *db, Pgno iPg){
AppendList *pList;
assert( db->pWorker );
pList = &db->pDatabase->append;
assert( pList->nAlloc>=pList->nPoint );
if( pList->nAlloc<=pList->nPoint ){
int nNew = pList->nAlloc+8;
Pgno *aNew = (Pgno *)lsmRealloc(db->pEnv, pList->aPoint, sizeof(Pgno)*nNew);
if( aNew==0 ) return LSM_NOMEM_BKPT;
pList->aPoint = aNew;
pList->nAlloc = nNew;
}
pList->aPoint[pList->nPoint++] = iPg;
return LSM_OK;
}
void lsmSharedAppendListRemove(lsm_db *db, int iIdx){
AppendList *pList;
int i;
assert( db->pWorker );
pList = &db->pDatabase->append;
assert( pList->nPoint>iIdx );
for(i=iIdx+1; i<pList->nPoint;i++){
pList->aPoint[i-1] = pList->aPoint[i];
}
pList->nPoint--;
}
/*
** Append an entry to the free-list.
*/
static int flAppendEntry(lsm_env *pEnv, Freelist *p, int iBlk, i64 iId){
/* Assert that this is not an attempt to insert a duplicate block number */
assertNotInFreelist(p, iBlk);
/* Extend the space allocated for the freelist, if required */
assert( p->nAlloc>=p->nEntry );
if( p->nAlloc==p->nEntry ){
int nNew;
FreelistEntry *aNew;
nNew = (p->nAlloc==0 ? 4 : p->nAlloc*2);
aNew = (FreelistEntry *)lsmRealloc(pEnv, p->aEntry,
sizeof(FreelistEntry)*nNew);
if( !aNew ) return LSM_NOMEM_BKPT;
p->nAlloc = nNew;
p->aEntry = aNew;
}
/* Append the new entry to the freelist */
p->aEntry[p->nEntry].iBlk = iBlk;
p->aEntry[p->nEntry].iId = iId;
p->nEntry++;
return LSM_OK;
}
/*
** Remove the first entry of the free-list.
*/
static void flRemoveEntry0(Freelist *p){
int nNew = p->nEntry - 1;
assert( nNew>=0 );
memmove(&p->aEntry[0], &p->aEntry[1], sizeof(FreelistEntry) * nNew);
p->nEntry = nNew;
}
/*
** This function frees all resources held by the Database structure passed
** as the only argument.
*/
static void freeDatabase(lsm_env *pEnv, Database *p){
if( p ){
/* Free the mutexes */
lsmMutexDel(pEnv, p->pClientMutex);
lsmMutexDel(pEnv, p->pWorkerMutex);
/* Free the log buffer. */
lsmStringClear(&p->log.buf);
/* Free the memory allocated for the Database struct itself */
lsmFree(pEnv, p);
}
}
/*
** Return a reference to the shared Database handle for the database
** identified by canonical path zName. If this is the first connection to
** the named database, a new Database object is allocated. Otherwise, a
** pointer to an existing object is returned.
**
** If successful, *ppDatabase is set to point to the shared Database
** structure and LSM_OK returned. Otherwise, *ppDatabase is set to NULL
** and and LSM error code returned.
**
** Each successful call to this function should be (eventually) matched
** by a call to lsmDbDatabaseRelease().
*/
int lsmDbDatabaseFind(
lsm_db *pDb, /* Database handle */
const char *zName /* Path to db file */
){
lsm_env *pEnv = pDb->pEnv;
int rc; /* Return code */
Database *p = 0; /* Pointer returned via *ppDatabase */
int nId = 0;
void *pId = 0;
assert( pDb->pDatabase==0 );
rc = lsmFsFileid(pDb, &pId, &nId);
if( rc!=LSM_OK ) return rc;
rc = enterGlobalMutex(pEnv);
if( rc==LSM_OK ){
/* Search the global list for an existing object. TODO: Need something
** better than the strcmp() below to figure out if a given Database
** object represents the requested file. */
for(p=gShared.pDatabase; p; p=p->pDbNext){
if( nId==p->nId && 0==memcmp(pId, p->pId, nId) ) break;
}
/* If no suitable Database object was found, allocate a new one. */
if( p==0 ){
int nName = strlen(zName);
p = (Database *)lsmMallocZeroRc(pEnv, sizeof(Database)+nId+nName+1, &rc);
/* Initialize the log handle */
if( rc==LSM_OK ){
p->log.cksum0 = LSM_CKSUM0_INIT;
p->log.cksum1 = LSM_CKSUM1_INIT;
lsmStringInit(&p->log.buf, pEnv);
}
/* Allocate the two mutexes */
if( rc==LSM_OK ) rc = lsmMutexNew(pEnv, &p->pWorkerMutex);
if( rc==LSM_OK ) rc = lsmMutexNew(pEnv, &p->pClientMutex);
/* If no error has occurred, fill in other fields and link the new
** Database structure into the global list starting at
** gShared.pDatabase. Otherwise, if an error has occurred, free any
** resources allocated and return without linking anything new into
** the gShared.pDatabase list. */
if( rc==LSM_OK ){
p->zName = (char *)&p[1];
memcpy((void *)p->zName, zName, nName+1);
p->pId = (void *)&p->zName[nName+1];
memcpy(p->pId, pId, nId);
p->nId = nId;
p->worker.pDatabase = p;
p->pDbNext = gShared.pDatabase;
gShared.pDatabase = p;
p->worker.iLogPg = LSM_INITIAL_LOGPG;
p->worker.iId = LSM_INITIAL_SNAPSHOT_ID;
p->worker.iSalt1 = LSM_INITIAL_SALT1;
p->worker.iSalt2 = LSM_INITIAL_SALT2;
p->nPgsz = pDb->nDfltPgsz;
p->nBlksz = pDb->nDfltBlksz;
}else{
freeDatabase(pEnv, p);
p = 0;
}
}
if( p ) p->nDbRef++;
leaveGlobalMutex(pEnv);
}
lsmFree(pEnv, pId);
pDb->pDatabase = p;
return rc;
}
static void freeClientSnapshot(lsm_env *pEnv, Snapshot *p){
Level *pLevel;
assert( p->nRef==0 );
for(pLevel=p->pLevel; pLevel; pLevel=pLevel->pNext){
lsmFree(pEnv, pLevel->pSplitKey);
}
lsmFree(pEnv, p->pExport);
lsmFree(pEnv, p);
}
/*
** Release a reference to a Database object obtained from lsmDbDatabaseFind().
** There should be exactly one call to this function for each successful
** call to Find().
*/
void lsmDbDatabaseRelease(lsm_db *pDb){
Database *p = pDb->pDatabase;
if( p ){
enterGlobalMutex(pDb->pEnv);
p->nDbRef--;
if( p->nDbRef==0 ){
int rc = LSM_OK;
Database **pp;
/* Remove the Database structure from the linked list. */
for(pp=&gShared.pDatabase; *pp!=p; pp=&((*pp)->pDbNext));
*pp = p->pDbNext;
/* Flush the in-memory tree, if required. If there is data to flush,
** this will create a new client snapshot in Database.pClient. The
** checkpoint (serialization) of this snapshot may be written to disk
** by the following block. */
if( p->bDirty || 0==lsmTreeIsEmpty(p->pTree) ){
rc = lsmFlushToDisk(pDb);
}
/* Write a checkpoint, also if required */
if( rc==LSM_OK && p->pClient ){
rc = lsmCheckpointWrite(pDb);
}
/* If the checkpoint was written successfully, delete the log file */
if( rc==LSM_OK && pDb->pFS ){
lsmFsCloseAndDeleteLog(pDb->pFS);
}
/* Free the in-memory tree object */
lsmTreeRelease(pDb->pEnv, p->pTree);
/* Free the contents of the worker snapshot */
lsmSortedFreeLevel(pDb->pEnv, p->worker.pLevel);
lsmFree(pDb->pEnv, p->worker.freelist.aEntry);
lsmFree(pDb->pEnv, p->append.aPoint);
/* Free the client snapshot */
if( p->pClient ){
assert( p->pClient->nRef==1 );
p->pClient->nRef = 0;
freeClientSnapshot(pDb->pEnv, p->pClient);
}
freeDatabase(pDb->pEnv, p);
}
leaveGlobalMutex(pDb->pEnv);
}
}
Level *lsmDbSnapshotLevel(Snapshot *pSnapshot){
return pSnapshot->pLevel;
}
void lsmDbSnapshotSetLevel(Snapshot *pSnap, Level *pLevel){
assert( isWorker(pSnap) );
pSnap->pLevel = pLevel;
}
void lsmDatabaseDirty(lsm_db *pDb){
Database *p = pDb->pDatabase;
assert( lsmMutexHeld(pDb->pEnv, p->pWorkerMutex) );
if( p->bDirty==0 ){
p->worker.iId++;
p->bDirty = 1;
}
}
int lsmDatabaseIsDirty(lsm_db *pDb){
Database *p = pDb->pDatabase;
assert( lsmMutexHeld(pDb->pEnv, p->pWorkerMutex) );
return p->bDirty;
}
/*
** Get/set methods for the snapshot block-count. These should only be
** used with worker snapshots.
*/
void lsmSnapshotSetNBlock(Snapshot *pSnap, int nNew){
assert( isWorker(pSnap) );
pSnap->nBlock = nNew;
}
int lsmSnapshotGetNBlock(Snapshot *pSnap){
assert( isWorker(pSnap) );
return pSnap->nBlock;
}
void lsmSnapshotSetCkptid(Snapshot *pSnap, i64 iNew){
assert( isWorker(pSnap) );
pSnap->iId = iNew;
}
/*
** Return a pointer to the client snapshot object. Each successful call
** to lsmDbSnapshotClient() must be matched by an lsmDbSnapshotRelease()
** call.
*/
#if 0
Snapshot *lsmDbSnapshotClient(lsm_db *pDb){
Database *p = pDb->pDatabase;
Snapshot *pRet;
lsmMutexEnter(pDb->pEnv, p->pClientMutex);
pRet = p->pClient;
pRet->nRef++;
lsmMutexLeave(pDb->pEnv, p->pClientMutex);
return pRet;
}
#endif
/*
** Return a pointer to the worker snapshot. This call grabs the worker
** mutex. It is released when the pointer to the worker snapshot is passed
** to lsmDbSnapshotRelease().
*/
Snapshot *lsmDbSnapshotWorker(lsm_db *pDb){
Database *p = pDb->pDatabase;
lsmMutexEnter(pDb->pEnv, p->pWorkerMutex);
return &p->worker;
}
Snapshot *lsmDbSnapshotRecover(lsm_db *pDb){
Database *p = pDb->pDatabase;
Snapshot *pRet = 0;
lsmMutexEnter(pDb->pEnv, p->pWorkerMutex);
if( p->bRecovered ){
lsmFsSetPageSize(pDb->pFS, p->nPgsz);
lsmFsSetBlockSize(pDb->pFS, p->nBlksz);
lsmMutexLeave(pDb->pEnv, p->pWorkerMutex);
}else{
pRet = &p->worker;
}
return pRet;
}
/*
** Set (bVal==1) or clear (bVal==0) the "recovery done" flag.
**
** TODO: Should this be combined with BeginRecovery()/FinishRecovery()?
*/
void lsmDbRecoveryComplete(lsm_db *pDb, int bVal){
Database *p = pDb->pDatabase;
assert( bVal==1 || bVal==0 );
assert( lsmMutexHeld(pDb->pEnv, p->pWorkerMutex) );
assert( p->pTree );
p->bRecovered = bVal;
p->iCheckpointId = p->worker.iId;
lsmFsSetPageSize(pDb->pFS, p->nPgsz);
lsmFsSetBlockSize(pDb->pFS, p->nBlksz);
}
void lsmDbSetPagesize(lsm_db *pDb, int nPgsz, int nBlksz){
Database *p = pDb->pDatabase;
assert( lsmMutexHeld(pDb->pEnv, p->pWorkerMutex) && p->bRecovered==0 );
p->nPgsz = nPgsz;
p->nBlksz = nBlksz;
lsmFsSetPageSize(pDb->pFS, p->nPgsz);
lsmFsSetBlockSize(pDb->pFS, p->nBlksz);
}
static void snapshotDecrRefcnt(lsm_env *pEnv, Snapshot *pSnap){
Database *p = pSnap->pDatabase;
assertSnapshotListOk(p);
pSnap->nRef--;
assert( pSnap->nRef>=0 );
if( pSnap->nRef==0 ){
Snapshot *pIter = p->pClient;
assert( pSnap!=pIter );
while( pIter->pSnapshotNext!=pSnap ) pIter = pIter->pSnapshotNext;
pIter->pSnapshotNext = pSnap->pSnapshotNext;
freeClientSnapshot(pEnv, pSnap);
assertSnapshotListOk(p);
}
}
/*
** Release a snapshot reference obtained by calling lsmDbSnapshotWorker()
** or lsmDbSnapshotClient().
*/
void lsmDbSnapshotRelease(lsm_env *pEnv, Snapshot *pSnap){
if( pSnap ){
Database *p = pSnap->pDatabase;
/* If this call is to release a pointer to the worker snapshot, relinquish
** the worker mutex.
**
** If pSnap is a client snapshot, decrement the reference count. When the
** reference count reaches zero, free the snapshot object. The decrement
** and (nRef==0) test are protected by the database client mutex.
*/
if( isWorker(pSnap) ){
lsmMutexLeave(pEnv, p->pWorkerMutex);
}else{
lsmMutexEnter(pEnv, p->pClientMutex);
snapshotDecrRefcnt(pEnv, pSnap);
lsmMutexLeave(pEnv, p->pClientMutex);
}
}
}
/*
** Create a new client snapshot based on the current contents of the worker
** snapshot. The connection must be the worker to call this function.
*/
int lsmDbUpdateClient(lsm_db *pDb, int nHdrLevel){
Database *p = pDb->pDatabase; /* Database handle */
Snapshot *pOld; /* Old client snapshot object */
Snapshot *pNew; /* New client snapshot object */
int nByte; /* Memory required for new client snapshot */
int rc = LSM_OK; /* Memory required for new client snapshot */
int nLevel = 0; /* Number of levels in worker snapshot */
int nRight = 0; /* Total number of rhs in worker */
int nKeySpace = 0; /* Total size of split keys */
Level *pLevel; /* Used to iterate through worker levels */
Level **ppLink; /* Used to link levels together */
u8 *pAvail; /* Used to divide up allocation */
/* Must be the worker to call this. */
assertMustbeWorker(pDb);
/* Allocate space for the client snapshot and all levels. */
for(pLevel=p->worker.pLevel; pLevel; pLevel=pLevel->pNext){
nLevel++;
nRight += pLevel->nRight;
}
nByte = sizeof(Snapshot)
+ nLevel * sizeof(Level)
+ nRight * sizeof(Segment)
+ nKeySpace;
pNew = (Snapshot *)lsmMallocZero(pDb->pEnv, nByte);
if( !pNew ) return LSM_NOMEM_BKPT;
pNew->pDatabase = p;
pNew->iId = p->worker.iId;
pNew->iLogPg = p->worker.iLogPg;
pNew->iSalt1 = p->worker.iSalt1;
pNew->iSalt2 = p->worker.iSalt2;
/* Copy the linked-list of Level structures */
pAvail = (u8 *)&pNew[1];
ppLink = &pNew->pLevel;
for(pLevel=p->worker.pLevel; pLevel && rc==LSM_OK; pLevel=pLevel->pNext){
Level *p;
p = (Level *)pAvail;
memcpy(p, pLevel, sizeof(Level));
pAvail += sizeof(Level);
if( p->nRight ){
p->aRhs = (Segment *)pAvail;
memcpy(p->aRhs, pLevel->aRhs, sizeof(Segment) * p->nRight);
pAvail += (sizeof(Segment) * p->nRight);
lsmSortedSplitkey(pDb, p, &rc);
}
/* This needs to come after any call to lsmSortedSplitkey(). Splitkey()
** uses data within the Merge object to set p->pSplitKey and co. */
p->pMerge = 0;
*ppLink = p;
ppLink = &p->pNext;
}
/* Create the serialized version of the new client snapshot. */
if( p->bDirty && rc==LSM_OK ){
assert( nHdrLevel>0 || p->worker.pLevel==0 );
rc = lsmCheckpointExport(
pDb, nHdrLevel, pNew->iId, 1, &pNew->pExport, &pNew->nExport
);
}
if( rc==LSM_OK ){
/* Initialize the new snapshot ref-count to 1 */
pNew->nRef = 1;
lsmDbSnapshotRelease(pDb->pEnv, pDb->pClient);
/* Install the new client snapshot and release the old. */
lsmMutexEnter(pDb->pEnv, p->pClientMutex);
assertSnapshotListOk(p);
pOld = p->pClient;
pNew->pSnapshotNext = pOld;
p->pClient = pNew;
assertSnapshotListOk(p);
if( pDb->pClient ){
assert( pDb->pClient==pOld );
pDb->pClient = p->pClient;
p->pClient->nRef++;
}
lsmMutexLeave(pDb->pEnv, p->pClientMutex);
lsmDbSnapshotRelease(pDb->pEnv, pOld);
p->bDirty = 0;
/* Upgrade the user connection to the new client snapshot */
}else{
/* An error has occurred. Delete the allocated object. */
freeClientSnapshot(pDb->pEnv, pNew);
}
return rc;
}
/*
** Allocate a new database file block to write data to, either by extending
** the database file or by recycling a free-list entry. The worker snapshot
** must be held in order to call this function.
**
** If successful, *piBlk is set to the block number allocated and LSM_OK is
** returned. Otherwise, *piBlk is zeroed and an lsm error code returned.
*/
int lsmBlockAllocate(lsm_db *pDb, int *piBlk){
Database *p = pDb->pDatabase;
Snapshot *pWorker; /* Worker snapshot */
Freelist *pFree; /* Database free list */
int iRet = 0; /* Block number of allocated block */
pWorker = pDb->pWorker;
pFree = &pWorker->freelist;
if( pFree->nEntry>0 ){
/* The first block on the free list was freed as part of the work done
** to create the snapshot with id iFree. So, we can reuse this block if
** snapshot iFree or later has been checkpointed and all currently
** active clients are reading from snapshot iFree or later.
*/
Snapshot *pIter;
i64 iFree = pFree->aEntry[0].iId;
i64 iInUse;
/* Both Database.iCheckpointId and the Database.pClient list are
** protected by the client mutex. So grab it here before determining
** the id of the oldest snapshot still potentially in use. */
lsmMutexEnter(pDb->pEnv, p->pClientMutex);
assertSnapshotListOk(p);
for(pIter=p->pClient; pIter->pSnapshotNext; pIter=pIter->pSnapshotNext);
iInUse = LSM_MIN(pIter->iId, p->iCheckpointId);
lsmMutexLeave(pDb->pEnv, p->pClientMutex);
if( iFree<=iInUse ){
iRet = pFree->aEntry[0].iBlk;
flRemoveEntry0(pFree);
assert( iRet!=0 );
if( pWorker->bRecordDelta ){
pWorker->aDelta[0]++;
}
}
}
/* If no block was allocated from the free-list, allocate one at the
** end of the file. */
if( iRet==0 ){
pWorker->nBlock++;
iRet = pWorker->nBlock;
}
*piBlk = iRet;
return LSM_OK;
}
/*
** Free a database block. The worker snapshot must be held in order to call
** this function.
**
** If successful, LSM_OK is returned. Otherwise, an lsm error code (e.g.
** LSM_NOMEM).
*/
int lsmBlockFree(lsm_db *pDb, int iBlk){
Snapshot *pWorker = pDb->pWorker;
int rc = LSM_OK;
assertMustbeWorker(pDb);
assert( pWorker->bRecordDelta==0 );
assert( pDb->pDatabase->bDirty );
rc = flAppendEntry(pDb->pEnv, &pWorker->freelist, iBlk, pWorker->iId);
return rc;
}
/*
** Refree a database block. The worker snapshot must be held in order to call
** this function.
**
** Refreeing is required when a block is allocated using lsmBlockAllocate()
** but then not used. This function is used to push the block back onto
** the freelist. Refreeing a block is different from freeing is, as a refreed
** block may be reused immediately. Whereas a freed block can not be reused
** until (at least) after the next checkpoint.
*/
int lsmBlockRefree(lsm_db *pDb, int iBlk){
int rc = LSM_OK; /* Return code */
Snapshot *pWorker = pDb->pWorker;
if( iBlk==pWorker->nBlock ){
pWorker->nBlock--;
}else if( pWorker->bRecordDelta ){
assert( pWorker->aDelta[2]==0 );
pWorker->aDelta[1 + (pWorker->aDelta[1]!=0)] = iBlk;
}else{
rc = flAppendEntry(pDb->pEnv, &pWorker->freelist, iBlk, 0);
}
return rc;
}
void lsmFreelistDeltaBegin(lsm_db *pDb){
Snapshot *pWorker = pDb->pWorker;
assert( pWorker->bRecordDelta==0 );
memset(pWorker->aDelta, 0, sizeof(pWorker->aDelta));
pWorker->bRecordDelta = 1;
}
void lsmFreelistDeltaEnd(lsm_db *pDb){
Snapshot *pWorker = pDb->pWorker;
pWorker->bRecordDelta = 0;
}
void lsmFreelistDelta(
lsm_db *pDb, /* Database handle */
u32 *aDeltaOut /* OUT: Copy free-list delta here */
){
Snapshot *pWorker = pDb->pWorker;
assert( sizeof(pWorker->aDelta)==(sizeof(u32)*LSM_FREELIST_DELTA_SIZE) );
memcpy(aDeltaOut, pWorker->aDelta, sizeof(pWorker->aDelta));
}
u32 *lsmFreelistDeltaPtr(lsm_db *pDb){
return pDb->pWorker->aDelta;
}
/*
** Return the current contents of the free-list as a list of integers.
*/
int lsmSnapshotFreelist(lsm_db *pDb, int **paFree, int *pnFree){
int rc = LSM_OK; /* Return Code */
int *aFree = 0; /* Integer array to return via *paFree */
int nFree; /* Value to return via *pnFree */
Freelist *p; /* Database free list object */
Snapshot *pSnap = pDb->pWorker;
assert( isWorker(pSnap) );
p = &pSnap->freelist;
nFree = p->nEntry;
if( nFree && paFree ){
aFree = lsmMallocRc(pDb->pEnv, sizeof(int) * nFree, &rc);
if( aFree ){
int i;
for(i=0; i<nFree; i++){
aFree[i] = p->aEntry[i].iBlk;
}
}
}
*pnFree = nFree;
*paFree = aFree;
return rc;
}
int lsmSnapshotSetFreelist(lsm_db *pDb, int *aElem, int nElem){
lsm_env *pEnv = pDb->pEnv;
int rc = LSM_OK; /* Return code */
int i; /* Iterator variable */
int nIgnore; /* Number of entries to ignore */
int iRefree1; /* A refreed block (or 0) */
int iRefree2; /* A refreed block (or 0) */
Freelist *pFree; /* Database free-list */
Snapshot *pSnap = pDb->pWorker;
assert( isWorker(pSnap) );
nIgnore = pSnap->aDelta[0];
iRefree1 = pSnap->aDelta[1];
iRefree2 = pSnap->aDelta[2];
pFree = &pSnap->freelist;
for(i=nIgnore; rc==LSM_OK && i<nElem; i++){
rc = flAppendEntry(pEnv, pFree, aElem[i], 0);
}
if( rc==LSM_OK && iRefree1!=0 ) rc = flAppendEntry(pEnv, pFree, iRefree1, 0);
if( rc==LSM_OK && iRefree2!=0 ) rc = flAppendEntry(pEnv, pFree, iRefree2, 0);
return rc;
}
/*
** If required, store a new database checkpoint.
**
** The worker mutex must not be held when this is called. This is because
** this function may indirectly call fsync(). And the worker mutex should
** not be held that long (in case it is required by a client flushing an
** in-memory tree to disk).
*/
int lsmCheckpointWrite(lsm_db *pDb){
Snapshot *pSnap; /* Snapshot to checkpoint */
Database *p = pDb->pDatabase;
int rc = LSM_OK; /* Return Code */
assert( pDb->pWorker==0 );
/* Try to obtain the checkpointer lock, then check if the a checkpoint
** is actually required. If successful, and one is, set stack variable
** pSnap to point to the client snapshot to checkpoint.
*/
lsmMutexEnter(pDb->pEnv, p->pClientMutex);
pSnap = p->pClient;
if( p->bCheckpointer==0 && pSnap->iId>p->iCheckpointId ){
p->bCheckpointer = 1;
pSnap->nRef++;
}else{
pSnap = 0;
}
lsmMutexLeave(pDb->pEnv, p->pClientMutex);
/* Attempt to grab the checkpoint mutex. If the attempt fails, this
** function becomes a no-op. Some other thread is already running
** a checkpoint (or at least checking if one is required). */
if( pSnap ){
FileSystem *pFS = pDb->pFS; /* File system object */
int iPg = 1; /* TODO */
MetaPage *pPg = 0; /* Page to write to */
int doSync; /* True to sync the db */
/* If the safety mode is "off", omit calls to xSync(). */
doSync = (pDb->eSafety!=LSM_SAFETY_OFF);
/* Sync the db. To make sure all runs referred to by the checkpoint
** are safely on disk. If we do not do this and a power failure occurs
** just after the checkpoint is written into the db header, the
** database could be corrupted following recovery. */
if( doSync ) rc = lsmFsSyncDb(pFS);
/* Fetch a reference to the meta-page to write the checkpoint to. */
if( rc==LSM_OK ) rc = lsmFsMetaPageGet(pFS, 1, iPg, &pPg);
/* Unless an error has occurred, copy the checkpoint blob into the
** meta-page, then release the reference to it (which will flush the
** checkpoint into the file). */
if( rc!=LSM_OK ){
lsmFsMetaPageRelease(pPg);
}else{
u8 *aData; /* Page buffer */
int nData; /* Size of buffer aData[] */
aData = lsmFsMetaPageData(pPg, &nData);
assert( pSnap->nExport<=nData );
memcpy(aData, pSnap->pExport, pSnap->nExport);
rc = lsmFsMetaPageRelease(pPg);
pPg = 0;
}
/* Sync the db file again. To make sure that the checkpoint just
** written is on the disk. */
if( rc==LSM_OK && doSync ) rc = lsmFsSyncDb(pFS);
/* This is where space on disk is reclaimed. Now that the checkpoint
** has been written to the database and synced, part of the database
** log (the part containing the data just synced to disk) is no longer
** required and so the space that it was taking up on disk can be
** reused.
**
** It is also possible that database file blocks may be made available
** for reuse here. A database file block is free if it is not used by
** the most recently checkpointed snapshot, or by a snapshot that is
** in use by any existing database client. And "the most recently
** checkpointed snapshot" has just changed.
*/
lsmMutexEnter(pDb->pEnv, p->pClientMutex);
if( rc==LSM_OK ){
lsmLogCheckpoint(pDb, &p->log, lsmCheckpointLogOffset(pSnap->pExport));
p->iCheckpointId = pSnap->iId;
}
p->bCheckpointer = 0;
snapshotDecrRefcnt(pDb->pEnv, pSnap);
lsmMutexLeave(pDb->pEnv, p->pClientMutex);
}
return rc;
}
/*
** This function is called when a connection is about to run log file
** recovery (read the contents of the log file from disk and create a new
** in memory tree from it). This happens when the very first connection
** starts up and connects to the database.
**
** This sets the connections tree-version handle to one suitable to insert
** the read data into.
**
** Once recovery is complete (regardless of whether or not it is successful),
** lsmFinishRecovery() must be called to release resources locked by
** this function.
*/
int lsmBeginRecovery(lsm_db *pDb){
int rc; /* Return code */
Database *p = pDb->pDatabase; /* Shared data handle */
assert( p && p->pTree==0 );
assert( pDb->pWorker );
assert( pDb->pClient==0 );
assert( pDb->pTV==0 );
assert( lsmMutexHeld(pDb->pEnv, pDb->pDatabase->pWorkerMutex) );
rc = lsmTreeNew(pDb->pEnv, pDb->xCmp, &p->pTree);
if( rc==LSM_OK ){
assert( pDb->pTV==0 );
rc = lsmTreeWriteVersion(pDb->pEnv, p->pTree, &pDb->pTV);
}
return rc;
}
/*
** Called when recovery is finished.
*/
int lsmFinishRecovery(lsm_db *pDb){
int rc;
assert( pDb->pWorker );
assert( pDb->pClient==0 );
assert( lsmMutexHeld(pDb->pEnv, pDb->pDatabase->pWorkerMutex) );
rc = lsmTreeReleaseWriteVersion(pDb->pEnv, pDb->pTV, 1, 0);
pDb->pTV = 0;
return rc;
}
/*
** Begin a read transaction. This function is a no-op if the connection
** passed as the only argument already has an open read transaction.
*/
int lsmBeginReadTrans(lsm_db *pDb){
int rc = LSM_OK; /* Return code */
/* No reason a worker connection should be opening a read-transaction. */
assert( pDb->pWorker==0 );
if( pDb->pClient==0 ){
Database *p = pDb->pDatabase;
lsmMutexEnter(pDb->pEnv, p->pClientMutex);
assert( pDb->pCsr==0 && pDb->nTransOpen==0 );
/* If there is no in-memory tree structure, allocate one now */
if( p->pTree==0 ){
rc = lsmTreeNew(pDb->pEnv, pDb->xCmp, &p->pTree);
}
if( rc==LSM_OK ){
/* Set the connections client database file snapshot */
p->pClient->nRef++;
pDb->pClient = p->pClient;
/* Set the connections tree-version handle */
assert( pDb->pTV==0 );
pDb->pTV = lsmTreeReadVersion(p->pTree);
assert( pDb->pTV!=0 );
}
lsmMutexLeave(pDb->pEnv, p->pClientMutex);
}
return rc;
}
/*
** Close the currently open read transaction.
*/
void lsmFinishReadTrans(lsm_db *pDb){
Snapshot *pClient = pDb->pClient;
/* Worker connections should not be closing read transactions. And
** read transactions should only be closed after all cursors and write
** transactions have been closed. */
assert( pDb->pWorker==0 );
assert( pDb->pCsr==0 && pDb->nTransOpen==0 );
if( pClient ){
Database *p = pDb->pDatabase;
lsmDbSnapshotRelease(pDb->pEnv, pDb->pClient);
pDb->pClient = 0;
/* Release the in-memory tree version */
lsmMutexEnter(pDb->pEnv, p->pClientMutex);
lsmTreeReleaseReadVersion(pDb->pEnv, pDb->pTV);
pDb->pTV = 0;
lsmMutexLeave(pDb->pEnv, p->pClientMutex);
}
}
/*
** Open a write transaction.
*/
int lsmBeginWriteTrans(lsm_db *pDb){
int rc = LSM_OK; /* Return code */
Database *p = pDb->pDatabase; /* Shared database object */
lsmMutexEnter(pDb->pEnv, p->pClientMutex);
assert( p->pTree );
assert( (pDb->pTV==0)==(pDb->pClient==0) );
/* There are two reasons the attempt to open a write transaction may fail:
**
** 1. There is already a writer.
** 2. Connection pDb already has an open read transaction, and the read
** snapshot is not the most recent version of the database.
**
** If condition 1 is true, then the Database.bWriter flag is set. If the
** second is true, then the call to lsmTreeWriteVersion() returns NULL.
*/
if( p->bWriter ){
rc = LSM_BUSY;
}else{
rc = lsmTreeWriteVersion(pDb->pEnv, p->pTree, &pDb->pTV);
}
if( rc==LSM_OK ){
rc = lsmLogBegin(pDb, &p->log);
if( rc!=LSM_OK ){
/* If the call to lsmLogBegin() failed, relinquish the read/write
** TreeVersion handle obtained above. The attempt to open a transaction
** has failed. */
TreeVersion *pWrite = pDb->pTV;
TreeVersion **ppRestore = (pDb->pClient ? &pDb->pTV : 0);
pDb->pTV = 0;
lsmTreeReleaseWriteVersion(pDb->pEnv, pWrite, 0, ppRestore);
}else if( pDb->pClient==0 ){
/* Otherwise, if the lsmLogBegin() attempt was successful and the
** client did not have a read transaction open when this function
** was called, lsm_db.pClient will still be NULL. In this case, grab
** a reference to the lastest checkpointed snapshot now. */
p->pClient->nRef++;
pDb->pClient = p->pClient;
}
}
if( rc==LSM_OK ){
p->bWriter = 1;
}
lsmMutexLeave(pDb->pEnv, p->pClientMutex);
return rc;
}
/*
** End the current write transaction. The connection is left with an open
** read transaction. It is an error to call this if there is no open write
** transaction.
**
** If the transaction was committed, then a commit record has already been
** written into the log file when this function is called. Or, if the
** transaction was rolled back, both the log file and in-memory tree
** structure have already been restored. In either case, this function
** merely releases locks and other resources held by the write-transaction.
**
** LSM_OK is returned if successful, or an LSM error code otherwise.
*/
int lsmFinishWriteTrans(lsm_db *pDb, int bCommit){
Database *p = pDb->pDatabase;
lsmMutexEnter(pDb->pEnv, p->pClientMutex);
assert( pDb->pTV && lsmTreeIsWriteVersion(pDb->pTV) );
assert( p->bWriter );
p->bWriter = 0;
lsmTreeReleaseWriteVersion(pDb->pEnv, pDb->pTV, bCommit, &pDb->pTV);
lsmLogEnd(pDb, &p->log, bCommit);
lsmMutexLeave(pDb->pEnv, p->pClientMutex);
return LSM_OK;
}
/*
** This function is called at the beginning of a flush operation (i.e. when
** flushing the contents of the in-memory tree to a segment on disk).
**
** The caller must already be the worker connection.
**
** Also, the caller must have an open write transaction or be in the process
** of shutting down the (shared) database connection. This means we don't
** have to worry about any other connection modifying the in-memory tree
** structure while it is being flushed (although some other clients may be
** reading from it).
*/
int lsmBeginFlush(lsm_db *pDb){
assert( pDb->pWorker );
assert( (pDb->pDatabase->bWriter && lsmTreeIsWriteVersion(pDb->pTV))
|| (pDb->pTV==0 && holdingGlobalMutex(pDb->pEnv))
);
if( pDb->pTV==0 ){
pDb->pTV = lsmTreeRecoverVersion(pDb->pDatabase->pTree);
}
return LSM_OK;
}
/*
** This is called to indicate that a "flush-tree" operation has finished.
** If the second argument is true, a new in-memory tree is allocated to
** hold subsequent writes.
*/
int lsmFinishFlush(lsm_db *pDb, int bEmpty){
Database *p = pDb->pDatabase;
int rc = LSM_OK;
assert( pDb->pWorker );
assert( pDb->pTV && (p->nDbRef==0 || lsmTreeIsWriteVersion(pDb->pTV)) );
lsmMutexEnter(pDb->pEnv, p->pClientMutex);
if( bEmpty ){
if( p->bWriter ){
lsmTreeReleaseWriteVersion(pDb->pEnv, pDb->pTV, 1, 0);
}
pDb->pTV = 0;
lsmTreeRelease(pDb->pEnv, p->pTree);
if( p->nDbRef>0 ){
rc = lsmTreeNew(pDb->pEnv, pDb->xCmp, &p->pTree);
}else{
/* This is the case if the Database object is being deleted */
p->pTree = 0;
}
}
if( p->bWriter ){
assert( pDb->pClient );
if( 0==pDb->pTV ) rc = lsmTreeWriteVersion(pDb->pEnv, p->pTree, &pDb->pTV);
}else{
pDb->pTV = 0;
}
lsmMutexLeave(pDb->pEnv, p->pClientMutex);
return rc;
}
/*
** Return a pointer to the DbLog object associated with connection pDb.
** Allocate and initialize it if necessary.
*/
DbLog *lsmDatabaseLog(lsm_db *pDb){
Database *p = pDb->pDatabase;
return &p->log;
}
/*
** Return non-zero if the caller is holding the client mutex.
*/
#ifdef LSM_DEBUG
int lsmHoldingClientMutex(lsm_db *pDb){
return lsmMutexHeld(pDb->pEnv, pDb->pDatabase->pClientMutex);
}
#endif
/************** End of lsm_shared.c ******************************************/
/************** Begin file lsm_sorted.c **************************************/
/*
** 2011-08-14
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** SORTED FILE FORMAT:
**
** A sorted file is divided into pages. The page-size is not stored anywhere
** within the sorted file itself - it must be known in advance in order to
** read the file. The maximum allowed page-size is 64KB.
**
** PAGE FORMAT:
**
** The maximum page size is 65536 bytes.
**
** Since all records are equal to or larger than 2 bytes in size, and
** some space within the page is consumed by the page footer, there must
** be less than 2^15 records on each page.
**
** Each page ends with a footer that describes the pages contents. This
** footer serves as similar purpose to the page header in an SQLite database.
** A footer is used instead of a header because it makes it easier to
** populate a new page based on a sorted list of key/value pairs.
**
** The footer consists of the following values (starting at the end of
** the page and continuing backwards towards the start). All values are
** stored as unsigned big-endian integers.
**
** * Number of records on page (2 bytes).
** * Flags field (2 bytes).
** * Left-hand pointer value (4 bytes).
** * The starting offset of each record (2 bytes per record).
**
** Records may span pages. Unless it happens to be an exact fit, the part
** of the final record that starts on page X that does not fit on page X
** is stored at the start of page (X+1). This means there may be pages where
** (N==0). And on most pages the first record that starts on the page will
** not start at byte offset 0. For example:
**
** aaaaa bbbbb ccc <footer> cc eeeee fffff g <footer> gggg....
**
** RECORD FORMAT:
**
** Each record in a sorted file is either a WRITE, a DELETE, or a
** SEPARATOR.
**
** The first byte of the record indicates the type, as follows:
**
** SORTED_SEPARATOR: 0x01
** SORTED_WRITE: 0x02
** SORTED_DELETE: 0x03
**
** If the sorted file contains pointers, then immediately following the
** type byte is a pointer to the smallest key in the next file that is larger
** than the key in the current record. The pointer is encoded as a varint.
** When added to the 32-bit page number stored in the footer, it is the
** page number of the page that contains the smallest key in the next sorted
** file that is larger than this key.
**
** Next is the number of bytes in the key, encoded as a varint.
**
** If the record is a SORTED_WRITE, the number of bytes in the value, as
** a varint, is next.
**
** Finally, the blob of data containing the key, and for SORTED_WRITE
** records, the value as well.
**
** SEPARATOR ARRAYS:
**
** Each time a sorted run that spans more than one page is constructed, a
** separators array is also constructed. A separators array contains normal
** pages and b-tree pages. Both types of pages use the same format (as
** above).
**
** The normal pages in the separators array contain a SORTED_SEPARATOR
** record with a copy of the first key on each page of the main array
** except the leftmost. If a main array page contains no keys, then there
** is no corresponding entry in the separators array.
*/
#ifndef _LSM_INT_H
#endif
/*
** Record types for user data.
*/
#define SORTED_SEPARATOR 0x01
#define SORTED_WRITE 0x02
#define SORTED_DELETE 0x03
#define SORTED_SYSTEM_DATA 0x10
/*
** Record types for system data (e.g. free-block list, secondary storage
** management entries). These are the same as the user types with the
** most-significant bit set.
*/
#define SORTED_SYSTEM_SEPARATOR (SORTED_SYSTEM_DATA | SORTED_SEPARATOR)
#define SORTED_SYSTEM_WRITE (SORTED_SYSTEM_DATA | SORTED_WRITE)
#define SORTED_SYSTEM_DELETE (SORTED_SYSTEM_DATA | SORTED_DELETE)
/*
** Macros to help decode record types.
*/
#define rtTopic(eType) ((eType) & 0xF0)
#define rtIsDelete(eType) (((eType) & 0x0F)==SORTED_DELETE)
#define rtIsSeparator(eType) (((eType) & 0x0F)==SORTED_SEPARATOR)
#define rtIsWrite(eType) (((eType) & 0x0F)==SORTED_WRITE)
/*
** The following macros are used to access a page footer.
*/
#define SEGMENT_NRECORD_OFFSET(pgsz) ((pgsz) - 2)
#define SEGMENT_FLAGS_OFFSET(pgsz) ((pgsz) - 2 - 2)
#define SEGMENT_POINTER_OFFSET(pgsz) ((pgsz) - 2 - 2 - 4)
#define SEGMENT_CELLPTR_OFFSET(pgsz, iCell) ((pgsz) - 2 - 2 - 4 - 2 - (iCell)*2)
#define SEGMENT_EOF(pgsz, nEntry) SEGMENT_CELLPTR_OFFSET(pgsz, nEntry)
#define SEGMENT_BTREE_FLAG 0x0001
#define PGFTR_SKIP_NEXT_FLAG 0x0002
#define PGFTR_SKIP_THIS_FLAG 0x0004
typedef struct LevelCursor LevelCursor;
typedef struct SegmentPtr SegmentPtr;
typedef struct Blob Blob;
struct Blob {
lsm_env *pEnv;
void *pData;
int nData;
int nAlloc;
};
/*
** A SegmentPtr object may be used for one of two purposes:
**
** * To iterate and/or seek within a single Segment (the combination of a
** main run and an optional sorted run).
**
** * To iterate through the separators array of a segment.
*/
struct SegmentPtr {
Segment *pSeg; /* Segment to access */
SortedRun *pRun; /* Points to either pSeg->run or pSeg->sep */
/* Current page. See segmentPtrLoadPage(). */
Page *pPg; /* Current page */
u16 flags; /* Copy of page flags field */
int nCell; /* Number of cells on pPg */
int iPtr; /* Base cascade pointer */
/* Current cell. See segmentPtrLoadCell() */
int iCell; /* Current record within page pPg */
int eType; /* Type of current record */
int iPgPtr; /* Cascade pointer offset */
void *pKey; int nKey; /* Key associated with current record */
void *pVal; int nVal; /* Current record value (eType==WRITE only) */
/* Blobs used to allocate buffers for pKey and pVal as required */
Blob blob1;
Blob blob2;
};
/*
** A cursor used to search or iterate within a single sorted file.
** LevelCursor structures are only used within this file. The rest of the
** system uses MultiCursor objects to search and iterate within the merge
** of a TreeCursor and zero or more LevelCursor objects.
**
** Instances of this structure are manipulated using the following static
** functions. Similar to the
**
** levelCursorInit()
** segmentCursorSeek()
** segmentCursorAdvance()
** segmentCursorEnd()
**
** segmentCursorKey()
** segmentCursorValue()
** segmentCursorValid()
*/
struct LevelCursor {
FileSystem *pFS; /* File system to read from */
int (*xCmp)(void *, int, void *, int); /* Compare function */
int bIgnoreSeparators; /* True to ignore SORTED_SEPARATOR records */
int bIgnoreSystem; /* True to ignore records for topic!=0 */
int iCurrentPtr; /* Current entry in aPtr[] */
int nPtr; /* Size of aPtr[] array */
SegmentPtr *aPtr; /* Array of segment pointers */
Level *pLevel; /* Pointer to Level object (if nPtr>1) */
};
/*
** A cursor used for merged searches or iterations through up to one
** Tree structure and any number of sorted files.
**
** lsmMCursorNew()
** lsmMCursorSeek()
** lsmMCursorNext()
** lsmMCursorPrev()
** lsmMCursorFirst()
** lsmMCursorLast()
** lsmMCursorKey()
** lsmMCursorValue()
** lsmMCursorValid()
*/
struct MultiCursor {
lsm_db *pDb; /* Connection that owns this cursor */
MultiCursor *pNext; /* Next cursor owned by connection pDb */
int flags; /* Mask of CURSOR_XXX flags */
int (*xCmp)(void *, int, void *, int); /* Compare function */
int eType; /* Cache of current key type */
Blob key; /* Cache of current key (or NULL) */
TreeCursor *pTreeCsr; /* Single tree cursor */
int nSegCsr; /* Size of aSegCsr[] array */
LevelCursor *aSegCsr; /* Array of cursors open on sorted files */
int nTree;
int *aTree;
int *pnHdrLevel;
void *pSystemVal;
Snapshot *pSnap;
};
/*
** CURSOR_IGNORE_DELETE
** If set, this cursor will not visit SORTED_DELETE keys.
**
** CURSOR_NEW_SYSTEM
** If set, then after all user data from the in-memory tree and any other
** cursors has been visited, the cursor visits the live (uncommitted)
** versions of the two system keys: FREELIST AND LEVELS. This is used when
** flushing the in-memory tree to disk - the new free-list and levels record
** are flushed along with it.
**
** CURSOR_AT_FREELIST
** This flag is set when sub-cursor CURSOR_DATA_SYSTEM is actually
** pointing at a free list.
**
** CURSOR_AT_LEVELS
** This flag is set when sub-cursor CURSOR_DATA_SYSTEM is actually
** pointing at a free list.
**
** CURSOR_IGNORE_SYSTEM
** If set, this cursor ignores system keys.
**
** CURSOR_NEXT_OK
** Set if it is Ok to call lsm_csr_next().
**
** CURSOR_PREV_OK
** Set if it is Ok to call lsm_csr_prev().
*/
#define CURSOR_IGNORE_DELETE 0x00000001
#define CURSOR_NEW_SYSTEM 0x00000002
#define CURSOR_AT_FREELIST 0x00000004
#define CURSOR_AT_LEVELS 0x00000008
#define CURSOR_IGNORE_SYSTEM 0x00000010
#define CURSOR_NEXT_OK 0x00000020
#define CURSOR_PREV_OK 0x00000040
typedef struct MergeWorker MergeWorker;
struct MergeWorker {
lsm_db *pDb; /* Database handle */
Level *pLevel; /* Worker snapshot Level being merged */
MultiCursor *pCsr; /* Cursor to read new segment contents from */
int bFlush; /* True if this is an in-memory tree flush */
Page **apHier; /* Separators array b-tree internal nodes */
int nHier; /* Number of entries in apHier[] */
Page *apPage[2]; /* Current output pages (0 is main run) */
int nWork; /* Number of calls to mergeWorkerNextPage() */
};
#ifdef LSM_DEBUG_EXPENSIVE
static void assertAllPointersOk(int rc, lsm_db *pDb);
static void assertAllBtreesOk(int rc, lsm_db *);
#else
# define assertAllPointersOk(y, z)
# define assertAllBtreesOk(y, z)
#endif
/*
** Write nVal as a 16-bit unsigned big-endian integer into buffer aOut.
*/
void lsmPutU16(u8 *aOut, u16 nVal){
aOut[0] = (u8)((nVal>>8) & 0xFF);
aOut[1] = (u8)(nVal & 0xFF);
}
void lsmPutU32(u8 *aOut, u32 nVal){
aOut[0] = (u8)((nVal>>24) & 0xFF);
aOut[1] = (u8)((nVal>>16) & 0xFF);
aOut[2] = (u8)((nVal>> 8) & 0xFF);
aOut[3] = (u8)((nVal ) & 0xFF);
}
int lsmGetU16(u8 *aOut){
return (aOut[0] << 8) + aOut[1];
}
u32 lsmGetU32(u8 *aOut){
return ((u32)aOut[0] << 24)
+ ((u32)aOut[1] << 16)
+ ((u32)aOut[2] << 8)
+ ((u32)aOut[3]);
}
static int sortedBlobGrow(lsm_env *pEnv, Blob *pBlob, int nData){
assert( pBlob->pEnv==pEnv || (pBlob->pEnv==0 && pBlob->pData==0) );
if( pBlob->nAlloc<nData ){
pBlob->pData = lsmReallocOrFree(pEnv, pBlob->pData, nData);
if( !pBlob->pData ) return LSM_NOMEM;
pBlob->nAlloc = nData;
pBlob->pEnv = pEnv;
}
return LSM_OK;
}
static int sortedBlobSet(lsm_env *pEnv, Blob *pBlob, void *pData, int nData){
if( sortedBlobGrow(pEnv, pBlob, nData) ) return LSM_NOMEM;
memcpy(pBlob->pData, pData, nData);
pBlob->nData = nData;
return LSM_OK;
}
#if 0
static int sortedBlobCopy(Blob *pDest, Blob *pSrc){
return sortedBlobSet(pDest, pSrc->pData, pSrc->nData);
}
#endif
static void sortedBlobFree(Blob *pBlob){
assert( pBlob->pEnv || pBlob->pData==0 );
if( pBlob->pData ) lsmFree(pBlob->pEnv, pBlob->pData);
memset(pBlob, 0, sizeof(Blob));
}
static int pageGetNRec(u8 *aData, int nData){
return (int)lsmGetU16(&aData[SEGMENT_NRECORD_OFFSET(nData)]);
}
static int pageGetPtr(u8 *aData, int nData){
return (int)lsmGetU32(&aData[SEGMENT_POINTER_OFFSET(nData)]);
}
static int pageGetFlags(u8 *aData, int nData){
return (int)lsmGetU16(&aData[SEGMENT_FLAGS_OFFSET(nData)]);
}
static u8 *pageGetCell(u8 *aData, int nData, int iCell){
return &aData[lsmGetU16(&aData[SEGMENT_CELLPTR_OFFSET(nData, iCell)])];
}
/*
** Return the decoded (possibly relative) pointer value stored in cell
** iCell from page aData/nData.
*/
static int pageGetRecordPtr(u8 *aData, int nData, int iCell){
int iRet; /* Return value */
u8 *aCell; /* Pointer to cell iCell */
aCell = pageGetCell(aData, nData, iCell);
lsmVarintGet32(&aCell[1], &iRet);
return iRet;
}
static void segmentPtrSetPage(SegmentPtr *pPtr, Page *pNext){
lsmFsPageRelease(pPtr->pPg);
if( pNext ){
int nData;
u8 *aData = lsmFsPageData(pNext, &nData);
pPtr->nCell = pageGetNRec(aData, nData);
pPtr->flags = pageGetFlags(aData, nData);
pPtr->iPtr = pageGetPtr(aData, nData);
}
pPtr->pPg = pNext;
}
/*
** Load a new page into the SegmentPtr object pPtr.
*/
static int segmentPtrLoadPage(
FileSystem *pFS,
SegmentPtr *pPtr, /* Load page into this SegmentPtr object */
int iNew /* Page number of new page */
){
Page *pPg = 0; /* The new page */
int rc; /* Return Code */
assert( pPtr->pSeg==0
|| pPtr->pRun==&pPtr->pSeg->run
|| pPtr->pRun==&pPtr->pSeg->sep
);
rc = lsmFsDbPageGet(pFS, iNew, &pPg);
assert( rc==LSM_OK || pPg==0 );
segmentPtrSetPage(pPtr, pPg);
return rc;
}
static int segmentPtrNextPage(
SegmentPtr *pPtr, /* Load page into this SegmentPtr object */
int eDir /* +1 for next(), -1 for prev() */
){
Page *pNext; /* New page to load */
int rc; /* Return code */
assert( eDir==1 || eDir==-1 );
assert( pPtr->pPg );
assert( (pPtr->pSeg==0 && eDir>0)
|| pPtr->pRun==&pPtr->pSeg->run
|| pPtr->pRun==&pPtr->pSeg->sep
);
rc = lsmFsDbPageNext(pPtr->pRun, pPtr->pPg, eDir, &pNext);
assert( rc==LSM_OK || pNext==0 );
segmentPtrSetPage(pPtr, pNext);
return rc;
}
static int sortedReadData(
Page *pPg,
int iOff,
int nByte,
void **ppData,
Blob *pBlob
){
int rc = LSM_OK;
int iEnd;
int nData;
int nCell;
u8 *aData;
aData = lsmFsPageData(pPg, &nData);
nCell = lsmGetU16(&aData[SEGMENT_NRECORD_OFFSET(nData)]);
iEnd = SEGMENT_EOF(nData, nCell);
assert( iEnd>0 && iEnd<nData );
if( iOff+nByte<=iEnd ){
*ppData = (void *)&aData[iOff];
}else{
int nRem = nByte;
int i = iOff;
u8 *aDest;
/* Make sure the blob is big enough to store the value being loaded. */
rc = sortedBlobGrow(lsmPageEnv(pPg), pBlob, nByte);
if( rc!=LSM_OK ) return rc;
pBlob->nData = nByte;
aDest = (u8 *)pBlob->pData;
*ppData = pBlob->pData;
/* Increment the pointer pages ref-count. */
lsmFsPageRef(pPg);
while( rc==LSM_OK ){
Page *pNext;
int flags;
/* Copy data from pPg into the output buffer. */
int nCopy = LSM_MIN(nRem, iEnd-i);
if( nCopy>0 ){
memcpy(&aDest[nByte-nRem], &aData[i], nCopy);
nRem -= nCopy;
i += nCopy;
assert( nRem==0 || i==iEnd );
}
assert( nRem>=0 );
if( nRem==0 ) break;
i -= iEnd;
/* Grab the next page in the segment */
do {
rc = lsmFsDbPageNext(0, pPg, 1, &pNext);
if( rc==LSM_OK && pNext==0 ){
rc = LSM_CORRUPT_BKPT;
}
if( rc ) break;
lsmFsPageRelease(pPg);
pPg = pNext;
aData = lsmFsPageData(pPg, &nData);
flags = lsmGetU16(&aData[SEGMENT_FLAGS_OFFSET(nData)]);
}while( flags&SEGMENT_BTREE_FLAG );
iEnd = SEGMENT_EOF(nData, lsmGetU16(&aData[nData-2]));
assert( iEnd>0 && iEnd<nData );
}
lsmFsPageRelease(pPg);
}
return rc;
}
static int segmentPtrReadData(
SegmentPtr *pPtr,
int iOff,
int nByte,
void **ppData,
Blob *pBlob
){
return sortedReadData(pPtr->pPg, iOff, nByte, ppData, pBlob);
}
static u8 *pageGetKey(
Page *pPg, /* Page to read from */
int iCell, /* Index of cell on page to read */
int *piTopic, /* OUT: Topic associated with this key */
int *pnKey, /* OUT: Size of key in bytes */
Blob *pBlob /* If required, use this for dynamic memory */
){
u8 *pKey;
int nDummy;
int eType;
u8 *aData;
int nData;
aData = lsmFsPageData(pPg, &nData);
assert( !(pageGetFlags(aData, nData) & SEGMENT_BTREE_FLAG) );
pKey = pageGetCell(aData, nData, iCell);
eType = *pKey++;
pKey += lsmVarintGet32(pKey, &nDummy);
pKey += lsmVarintGet32(pKey, pnKey);
if( rtIsWrite(eType) ){
pKey += lsmVarintGet32(pKey, &nDummy);
}
*piTopic = rtTopic(eType);
sortedReadData(pPg, pKey-aData, *pnKey, (void **)&pKey, pBlob);
return pKey;
}
static int pageGetKeyCopy(
lsm_env *pEnv, /* Environment handle */
Page *pPg, /* Page to read from */
int iCell, /* Index of cell on page to read */
int *piTopic, /* OUT: Topic associated with this key */
Blob *pBlob /* If required, use this for dynamic memory */
){
int rc = LSM_OK;
int nKey;
u8 *aKey;
aKey = pageGetKey(pPg, iCell, piTopic, &nKey, pBlob);
assert( (void *)aKey!=pBlob->pData || nKey==pBlob->nData );
if( (void *)aKey!=pBlob->pData ){
rc = sortedBlobSet(pEnv, pBlob, aKey, nKey);
}
return rc;
}
static int segmentPtrLoadCell(
SegmentPtr *pPtr, /* Load page into this SegmentPtr object */
int iNew /* Cell number of new cell */
){
int rc = LSM_OK;
if( pPtr->pPg ){
u8 *aData; /* Pointer to page data buffer */
int iOff; /* Offset in aData[] to read from */
int nPgsz; /* Size of page (aData[]) in bytes */
assert( iNew<pPtr->nCell );
pPtr->iCell = iNew;
aData = lsmFsPageData(pPtr->pPg, &nPgsz);
iOff = lsmGetU16(&aData[SEGMENT_CELLPTR_OFFSET(nPgsz, pPtr->iCell)]);
pPtr->eType = aData[iOff];
iOff++;
iOff += lsmVarintGet32(&aData[iOff], &pPtr->iPgPtr);
iOff += lsmVarintGet32(&aData[iOff], &pPtr->nKey);
if( rtIsWrite(pPtr->eType) ){
iOff += lsmVarintGet32(&aData[iOff], &pPtr->nVal);
}
rc = segmentPtrReadData(
pPtr, iOff, pPtr->nKey, &pPtr->pKey, &pPtr->blob1
);
if( rc==LSM_OK && rtIsWrite(pPtr->eType) ){
rc = segmentPtrReadData(
pPtr, iOff+pPtr->nKey, pPtr->nVal, &pPtr->pVal, &pPtr->blob2
);
}
}
return rc;
}
static int sortedKeyCompare(
int (*xCmp)(void *, int, void *, int),
int iLhsTopic, void *pLhsKey, int nLhsKey,
int iRhsTopic, void *pRhsKey, int nRhsKey
){
int res = iLhsTopic - iRhsTopic;
if( res==0 ){
res = xCmp(pLhsKey, nLhsKey, pRhsKey, nRhsKey);
}
return res;
}
void lsmSortedSplitkey(lsm_db *pDb, Level *pLevel, int *pRc){
lsm_env *pEnv = pDb->pEnv; /* Environment handle */
int rc = *pRc;
int i;
Merge *pMerge = pLevel->pMerge;
for(i=0; rc==LSM_OK && i<pLevel->nRight; i++){
Page *pPg = 0;
int iTopic;
Blob blob = {0, 0, 0, 0};
SortedRun *pRun = &pLevel->aRhs[i].run;
assert( pRun->iFirst!=0 );
rc = lsmFsDbPageGet(pDb->pFS, pMerge->aInput[i].iPg, &pPg);
if( rc==LSM_OK ){
rc = pageGetKeyCopy(pEnv, pPg, pMerge->aInput[i].iCell, &iTopic, &blob);
}
if( rc==LSM_OK ){
int res = -1;
if( pLevel->pSplitKey ){
res = sortedKeyCompare(pDb->xCmp,
iTopic, blob.pData, blob.nData,
pLevel->iSplitTopic, pLevel->pSplitKey, pLevel->nSplitKey
);
}
if( res<0 ){
lsmFree(pEnv, pLevel->pSplitKey);
pLevel->iSplitTopic = iTopic;
pLevel->pSplitKey = blob.pData;
pLevel->nSplitKey = blob.nData;
}else{
lsmFree(pEnv, blob.pData);
}
}
lsmFsPageRelease(pPg);
}
*pRc = rc;
}
/*
** Initialize a LevelCursor structure. The caller is responsible for
** allocating the memory that the structure itself occupies.
*/
static int levelCursorInit(
lsm_db *pDb,
Level *pLevel,
int (*xCmp)(void *, int, void *, int),
LevelCursor *pCsr /* Cursor structure to initialize */
){
int rc = LSM_OK;
int nPtr = 1 + pLevel->nRight;
memset(pCsr, 0, sizeof(LevelCursor));
pCsr->pFS = pDb->pFS;
pCsr->bIgnoreSeparators = 1;
pCsr->xCmp = xCmp;
pCsr->pLevel = pLevel;
pCsr->aPtr = (SegmentPtr*)lsmMallocZeroRc(pDb->pEnv,
sizeof(SegmentPtr)*nPtr, &rc
);
if( rc==LSM_OK ){
int i;
pCsr->aPtr[0].pSeg = &pLevel->lhs;
pCsr->nPtr = nPtr;
for(i=0; i<pLevel->nRight; i++){
pCsr->aPtr[i+1].pSeg = &pLevel->aRhs[i];
}
for(i=0; i<pCsr->nPtr; i++){
pCsr->aPtr[i].pRun = &pCsr->aPtr[i].pSeg->run;
}
}
return rc;
}
static int levelCursorInitRun(
lsm_db *pDb,
SortedRun *pRun,
int (*xCmp)(void *, int, void *, int),
LevelCursor *pCsr /* Cursor structure to initialize */
){
int rc = LSM_OK;
memset(pCsr, 0, sizeof(LevelCursor));
pCsr->pFS = pDb->pFS;
pCsr->bIgnoreSeparators = 1;
pCsr->xCmp = xCmp;
pCsr->nPtr = 1;
pCsr->aPtr = (SegmentPtr*)lsmMallocZeroRc(pDb->pEnv,
sizeof(SegmentPtr)*pCsr->nPtr, &rc
);
if( rc==LSM_OK ){
pCsr->aPtr[0].pRun = pRun;
}
return rc;
}
static void segmentPtrReset(SegmentPtr *pPtr){
lsmFsPageRelease(pPtr->pPg);
pPtr->pPg = 0;
pPtr->nCell = 0;
pPtr->pKey = 0;
pPtr->nKey = 0;
pPtr->pVal = 0;
pPtr->nVal = 0;
pPtr->eType = 0;
pPtr->iCell = 0;
sortedBlobFree(&pPtr->blob1);
sortedBlobFree(&pPtr->blob2);
}
static void segmentCursorReset(LevelCursor *pCsr){
int i;
for(i=0; i<pCsr->nPtr; i++){
segmentPtrReset(&pCsr->aPtr[i]);
}
}
/*
** Close the cursor. Release all associated resources. The memory occupied
** by the LevelCursor structure itself is not released. It is assumed to
** be managed by the caller.
*/
static void segmentCursorClose(lsm_env *pEnv, LevelCursor *pCsr){
segmentCursorReset(pCsr);
lsmFree(pEnv, pCsr->aPtr);
memset(pCsr, 0, sizeof(LevelCursor));
}
static int segmentPtrAdvance(
LevelCursor *pCsr,
SegmentPtr *pPtr,
int bReverse
){
int eDir = (bReverse ? -1 : 1);
do {
int rc;
int iCell; /* Number of new cell in page */
iCell = pPtr->iCell + eDir;
assert( pPtr->pPg );
assert( iCell<=pPtr->nCell && iCell>=-1 );
if( iCell>=pPtr->nCell || iCell<0 ){
do {
rc = segmentPtrNextPage(pPtr, eDir);
}while( rc==LSM_OK
&& pPtr->pPg
&& (pPtr->nCell==0 || (pPtr->flags & SEGMENT_BTREE_FLAG) )
);
if( rc!=LSM_OK ) return rc;
iCell = bReverse ? (pPtr->nCell-1) : 0;
}
rc = segmentPtrLoadCell(pPtr, iCell);
if( rc!=LSM_OK ) return rc;
}while( pCsr && pPtr->pPg && (
(pCsr->bIgnoreSeparators && rtIsSeparator(pPtr->eType))
|| (pCsr->bIgnoreSystem && rtTopic(pPtr->eType)!=0)
));
return LSM_OK;
}
static void segmentPtrEndPage(
FileSystem *pFS,
SegmentPtr *pPtr,
int bLast,
int *pRc
){
if( *pRc==LSM_OK ){
Page *pNew = 0;
Pgno iPg = (bLast ? pPtr->pRun->iLast : pPtr->pRun->iFirst);
*pRc = lsmFsDbPageGet(pFS, iPg, &pNew);
segmentPtrSetPage(pPtr, pNew);
}
}
/*
** Try to move the segment pointer passed as the second argument so that it
** points at either the first (bLast==0) or last (bLast==1) cell in the valid
** region of the segment defined by pPtr->iFirst and pPtr->iLast.
**
** Return LSM_OK if successful or an lsm error code if something goes
** wrong (IO error, OOM etc.).
*/
static void segmentPtrEnd(
LevelCursor *pCsr, /* Cursor that owns this segment-pointer */
SegmentPtr *pPtr, /* Segment pointer to reposition */
int bLast, /* True for last, false for first */
int *pRc /* IN/OUT error code */
){
if( *pRc==LSM_OK ){
int rc = LSM_OK;
segmentPtrEndPage(pCsr->pFS, pPtr, bLast, &rc);
while( rc==LSM_OK && pPtr->pPg && pPtr->nCell==0 ){
rc = segmentPtrNextPage(pPtr, (bLast ? -1 : 1));
}
if( rc==LSM_OK && pPtr->pPg ){
rc = segmentPtrLoadCell(pPtr, bLast ? (pPtr->nCell-1) : 0);
}
if( rc==LSM_OK && pPtr->pPg && (
(pCsr->bIgnoreSeparators && rtIsSeparator(pPtr->eType))
|| (pCsr->bIgnoreSystem && rtTopic(pPtr->eType)!=0)
)){
rc = segmentPtrAdvance(pCsr, pPtr, bLast);
}
*pRc = rc;
}
}
static void segmentPtrKey(SegmentPtr *pPtr, void **ppKey, int *pnKey){
assert( pPtr->pPg );
*ppKey = pPtr->pKey;
*pnKey = pPtr->nKey;
}
static void segmentCursorKey(LevelCursor *pCsr, void **ppKey, int *pnKey){
segmentPtrKey(&pCsr->aPtr[pCsr->iCurrentPtr], ppKey, pnKey);
}
static void segmentCursorValue(LevelCursor *pCsr, void **ppVal, int *pnVal){
SegmentPtr *pPtr = &pCsr->aPtr[pCsr->iCurrentPtr];
assert( pPtr->pPg );
*ppVal = pPtr->pVal;
*pnVal = pPtr->nVal;
}
static void segmentCursorType(LevelCursor *pCsr, int *peType){
SegmentPtr *pPtr = &pCsr->aPtr[pCsr->iCurrentPtr];
assert( pPtr->pPg );
*peType = pPtr->eType;
}
static int segmentCursorValid(LevelCursor *pCsr){
SegmentPtr *pPtr = &pCsr->aPtr[pCsr->iCurrentPtr];
return (pPtr->pPg!=0);
}
#ifdef LSM_DEBUG
static char *keyToString(lsm_env *pEnv, void *pKey, int nKey){
int i;
u8 *aKey = (u8 *)pKey;
char *zRet = (char *)lsmMalloc(pEnv, nKey+1);
for(i=0; i<nKey; i++){
zRet[i] = (char)(isalnum(aKey[i]) ? aKey[i] : '.');
}
zRet[nKey] = '\0';
return zRet;
}
/*
** Check that the page that pPtr currently has loaded is the correct page
** to search for key (pKey/nKey). If it is, return 1. Otherwise, an assert
** fails and this function does not return.
*/
static int assertKeyLocation(
LevelCursor *pCsr,
SegmentPtr *pPtr,
void *pKey, int nKey
){
lsm_env *pEnv = lsmFsEnv(pCsr->pFS);
Blob blob = {0, 0, 0};
int eDir;
int iTopic = 0; /* TODO: Fix me */
for(eDir=-1; eDir<=1; eDir+=2){
Page *pTest = pPtr->pPg;
lsmFsPageRef(pTest);
while( pTest ){
Page *pNext;
int rc = lsmFsDbPageNext(pPtr->pRun, pTest, eDir, &pNext);
lsmFsPageRelease(pTest);
pTest = pNext;
assert( rc==LSM_OK );
if( pTest ){
int nData;
u8 *aData = lsmFsPageData(pTest, &nData);
int nCell = pageGetNRec(aData, nData);
int flags = pageGetFlags(aData, nData);
if( nCell && 0==(flags&SEGMENT_BTREE_FLAG) ){
int nPgKey;
int iPgTopic;
u8 *pPgKey;
int res;
int iCell;
iCell = ((eDir < 0) ? (nCell-1) : 0);
pPgKey = pageGetKey(pTest, iCell, &iPgTopic, &nPgKey, &blob);
res = iTopic - iPgTopic;
if( res==0 ) res = pCsr->xCmp(pKey, nKey, pPgKey, nPgKey);
if( (eDir==1 && res>0) || (eDir==-1 && res<0) ){
/* Taking this branch means something has gone wrong. */
char *zMsg = lsmMallocPrintf(pEnv, "Key \"%s\" is not on page %d",
keyToString(pEnv, pKey, nKey), lsmFsPageNumber(pPtr->pPg)
);
fprintf(stderr, "%s\n", zMsg);
assert( !"assertKeyLocation() failed" );
}
lsmFsPageRelease(pTest);
pTest = 0;
}
}
}
}
sortedBlobFree(&blob);
return 1;
}
#endif
int segmentPtrSeek(
LevelCursor *pCsr, /* Cursor context */
SegmentPtr *pPtr, /* Pointer to seek */
void *pKey, int nKey, /* Key to seek to */
int eSeek, /* Search bias - see above */
int *piPtr /* OUT: FC pointer */
){
int res; /* Result of comparison operation */
int rc = LSM_OK;
int iMin;
int iMax;
int iPtrOut = 0;
const int iTopic = 0;
/* If the OVERSIZED flag is set, then there is no pointer in the
** upper level to the next page in the segment that contains at least
** one key. So compare the largest key on the current page with the
** key being sought (pKey/nKey). If (pKey/nKey) is larger, advance
** to the next page in the segment that contains at least one key.
*/
while( rc==LSM_OK && (pPtr->flags & PGFTR_SKIP_NEXT_FLAG) ){
u8 *pLastKey;
int nLastKey;
int iLastTopic;
int res; /* Result of comparison */
Page *pNext;
/* Load the last key on the current page. */
pLastKey = pageGetKey(
pPtr->pPg, pPtr->nCell-1, &iLastTopic, &nLastKey, &pPtr->blob1
);
/* If the loaded key is >= than (pKey/nKey), break out of the loop.
** If (pKey/nKey) is present in this array, it must be on the current
** page. */
res = iLastTopic - iTopic;
if( res==0 ) res = pCsr->xCmp(pLastKey, nLastKey, pKey, nKey);
if( res>=0 ) break;
/* Advance to the next page that contains at least one key. */
do {
rc = lsmFsDbPageNext(pPtr->pRun, pPtr->pPg, 1, &pNext);
if( pNext==0 ) break;
assert( rc==LSM_OK );
segmentPtrSetPage(pPtr, pNext);
}while( (pPtr->nCell==0 || (pPtr->flags & SEGMENT_BTREE_FLAG)) );
if( pNext==0 ) break;
/* This should probably be an LSM_CORRUPT error. */
assert( rc!=LSM_OK || (pPtr->flags & PGFTR_SKIP_THIS_FLAG) );
}
iPtrOut = pPtr->iPtr;
/* Assert that this page is the right page of this segment for the key
** that we are searching for. Do this by loading page (iPg-1) and testing
** that pKey/nKey is greater than all keys on that page, and then by
** loading (iPg+1) and testing that pKey/nKey is smaller than all
** the keys it houses. */
#if 0
assert( assertKeyLocation(pCsr, pPtr, pKey, nKey) );
#endif
assert( pPtr->nCell>0
|| pPtr->pRun->nSize==1
|| lsmFsPageNumber(pPtr->pPg)==pPtr->pRun->iLast
);
if( pPtr->nCell==0 ){
segmentPtrReset(pPtr);
}else{
iMin = 0;
iMax = pPtr->nCell-1;
while( 1 ){
int iTry = (iMin+iMax)/2;
void *pKeyT; int nKeyT; /* Key for cell iTry */
int iTopicT;
assert( iTry<iMax || iMin==iMax );
rc = segmentPtrLoadCell(pPtr, iTry);
if( rc!=LSM_OK ) break;
segmentPtrKey(pPtr, &pKeyT, &nKeyT);
iTopicT = rtTopic(pPtr->eType);
res = iTopicT - iTopic;
if( res==0 ) res = pCsr->xCmp(pKeyT, nKeyT, pKey, nKey);
if( res<=0 ){
iPtrOut = pPtr->iPtr + pPtr->iPgPtr;
}
if( res==0 || iMin==iMax ){
break;
}else if( res>0 ){
iMax = LSM_MAX(iTry-1, iMin);
}else{
iMin = iTry+1;
}
}
if( rc==LSM_OK ){
assert( res==0 || (iMin==iMax && iMin>=0 && iMin<pPtr->nCell) );
if( res ){
rc = segmentPtrLoadCell(pPtr, iMin);
}
if( rc==LSM_OK ){
switch( eSeek ){
case LSM_SEEK_EQ:
if( res!=0 || rtIsSeparator(pPtr->eType) ) segmentPtrReset(pPtr);
break;
case LSM_SEEK_LE:
if( res>0 ) rc = segmentPtrAdvance(pCsr, pPtr, 1);
break;
case LSM_SEEK_GE:
if( res<0 ) rc = segmentPtrAdvance(pCsr, pPtr, 0);
break;
}
}
}
if( rc==LSM_OK && pPtr->pPg && (
(pCsr->bIgnoreSeparators && rtIsSeparator(pPtr->eType))
|| (pCsr->bIgnoreSystem && rtTopic(pPtr->eType)!=0)
)){
rc = segmentPtrAdvance(pCsr, pPtr, eSeek==LSM_SEEK_LE);
}
}
*piPtr = iPtrOut;
return rc;
}
/*
** Helper function for segmentCursorSetCurrent(). See its header comment
** for details.
*/
static int segmentCursorPtrCmp(
LevelCursor *pCsr, /* Cursor context */
int bLargest, /* True to identify the larger key */
SegmentPtr *pLeft,
SegmentPtr *pRight
){
int iRet;
if( pLeft->pPg==0 ){
iRet = 1;
}else if( pRight->pPg==0 ){
iRet = 0;
}else{
int res = pCsr->xCmp(pLeft->pKey, pLeft->nKey, pRight->pKey, pRight->nKey);
if( res==0 || (res<0 && bLargest==0) || (res>0 && bLargest) ){
iRet = 0;
}else{
iRet = 1;
}
}
return iRet;
}
static void segmentCursorSetCurrent(LevelCursor *pCsr, int bLargest){
int iBest;
int i;
iBest = 0;
for(i=1; i<pCsr->nPtr; i++){
int res = segmentCursorPtrCmp(
pCsr, bLargest, &pCsr->aPtr[iBest], &pCsr->aPtr[i]
);
if( res ) iBest = i;
}
pCsr->iCurrentPtr = iBest;
}
static int seekInSeparators(
LevelCursor *pCsr,
SegmentPtr *pPtr, /* Segment to seek within */
void *pKey, int nKey, /* Key to seek to */
int *piPtr /* OUT: FC pointer */
){
int rc;
int iPg;
Blob blob = {0, 0, 0};
int iTopic = 0; /* TODO: Fix me */
SortedRun *pSep = &pPtr->pSeg->sep;
iPg = pSep->iRoot;
do {
Page *pPg;
rc = lsmFsDbPageGet(pCsr->pFS, iPg, &pPg);
if( rc==LSM_OK ){
u8 *aData; /* Buffer containing page data */
int nData; /* Size of aData[] in bytes */
int iMin;
int iMax;
int nRec;
int flags;
aData = lsmFsPageData(pPg, &nData);
flags = pageGetFlags(aData, nData);
if( (flags & SEGMENT_BTREE_FLAG)==0 ){
lsmFsPageRelease(pPg);
break;
}
iPg = pageGetPtr(aData, nData);
nRec = pageGetNRec(aData, nData);
iMin = 0;
iMax = nRec-1;
while( iMax>=iMin ){
Page *pRef = 0;
int iTry = (iMin+iMax)/2;
void *pKeyT; int nKeyT; /* Key for cell iTry */
int iTopicT; /* Topic for key pKeyT/nKeyT */
int iPtr; /* Pointer associated with cell iTry */
u8 *aCell; /* Pointer to cell iTry */
int res; /* (pKey - pKeyT) */
int eType;
aCell = pageGetCell(aData, nData, iTry);
eType = *aCell++;
aCell += lsmVarintGet32(aCell, &iPtr);
if( eType==0 ){
/* If eType==0, then this b-tree cell does not contain a key.
** Instead, it is a reference to another cell in the same separators
** array that does contain a key. */
Pgno iRef;
aCell += lsmVarintGet32(aCell, &iRef);
rc = lsmFsDbPageGet(pCsr->pFS, iRef, &pRef);
if( rc!=LSM_OK ) break;
pKeyT = pageGetKey(pRef, 0, &iTopicT, &nKeyT, &blob);
}else{
aCell += lsmVarintGet32(aCell, &nKeyT);
pKeyT = (void *)aCell;
iTopicT = rtTopic(eType);
}
res = iTopic - iTopicT;
if( res==0 ) res = pCsr->xCmp(pKey, nKey, pKeyT, nKeyT);
if( res<0 ){
iPg = iPtr;
iMax = iTry-1;
}else{
iMin = iTry+1;
}
lsmFsPageRelease(pRef);
}
lsmFsPageRelease(pPg);
}
}while( rc==LSM_OK );
if( rc==LSM_OK ){
assert( pPtr->pRun==&pPtr->pSeg->run );
pPtr->pRun = pSep;
rc = segmentPtrLoadPage(pCsr->pFS, pPtr, iPg);
if( rc==LSM_OK ){
rc = segmentPtrSeek(pCsr, pPtr, pKey, nKey, 0, piPtr);
}
pPtr->pRun = &pPtr->pSeg->run;
}
sortedBlobFree(&blob);
return rc;
}
static int seekInSegment(
LevelCursor *pCsr,
SegmentPtr *pPtr,
void *pKey, int nKey,
int iPg, /* Page to search */
int eSeek, /* Search bias - see above */
int *piPtr /* OUT: FC pointer */
){
int iPtr = iPg;
int rc = LSM_OK;
assert( pPtr->pRun==&pPtr->pSeg->run );
if( segmentHasSeparators(pPtr->pSeg) ){
rc = seekInSeparators(pCsr, pPtr, pKey, nKey, &iPtr);
}else if( iPtr==0 ){
iPtr = pPtr->pSeg->run.iFirst;
}
if( rc==LSM_OK ){
rc = segmentPtrLoadPage(pCsr->pFS, pPtr, iPtr);
}
if( rc==LSM_OK ){
rc = segmentPtrSeek(pCsr, pPtr, pKey, nKey, eSeek, piPtr);
}
return rc;
}
/*
** Seek the cursor.
*/
static int segmentCursorSeek(
LevelCursor *pCsr, /* Sorted cursor object to seek */
void *pKey, int nKey, /* Key to seek to */
int iPg, /* Page to search */
int eSeek, /* Search bias - see above */
int *piPtr /* OUT: FC pointer */
){
int rc = LSM_OK;
int iOut = 0; /* Pointer to return to caller */
int res = -1; /* Result of xCmp(pKey, split) */
if( pCsr->nPtr>1 ){
Level *pLevel = pCsr->pLevel;
assert( pLevel );
res = 0 - pLevel->iSplitTopic;
if( res==0 ){
res = pCsr->xCmp(pKey, nKey, pLevel->pSplitKey, pLevel->nSplitKey);
}
}
if( res<0 ){
int iPtr = 0;
if( pCsr->nPtr==1 ) iPtr = iPg;
rc = seekInSegment(pCsr, &pCsr->aPtr[0], pKey, nKey, iPtr, eSeek, &iOut);
if( rc==LSM_OK
&& pCsr->nPtr>1
&& eSeek==LSM_SEEK_GE
&& pCsr->aPtr[0].pPg==0
){
res = 0;
}
}
if( res>=0 ){
int iPtr = iPg;
int i;
for(i=1; rc==LSM_OK && i<pCsr->nPtr; i++){
iOut = 0;
rc = seekInSegment(pCsr, &pCsr->aPtr[i], pKey, nKey, iPtr, eSeek, &iOut);
iPtr = iOut;
}
if( eSeek==LSM_SEEK_LE ){
segmentPtrEnd(pCsr, &pCsr->aPtr[0], 1, &rc);
}
}
segmentCursorSetCurrent(pCsr, eSeek==LSM_SEEK_LE);
*piPtr = iOut;
return rc;
}
/*
** Advance the cursor forwards (bReverse==0) or backwards (bReverse!=0).
*/
static int segmentCursorAdvance(LevelCursor *pCsr, int bReverse){
int rc;
int iCurrent = pCsr->iCurrentPtr;
SegmentPtr *pCurrent;
pCurrent = &pCsr->aPtr[iCurrent];
rc = segmentPtrAdvance(pCsr, pCurrent, bReverse);
/* If bReverse is true and the segment pointer just moved is on the rhs
** of the level, check if the key it now points to is smaller than the
** split-key. If so, set the segment to EOF.
**
** The danger here is that if the current key is smaller than the
** split-key then there may have existed a delete key on a page that
** has already been gobbled.
*/
if( rc==LSM_OK && bReverse && iCurrent>0 && pCurrent->pPg ){
Level *p = pCsr->pLevel;
int res = sortedKeyCompare(pCsr->xCmp,
rtTopic(pCurrent->eType), pCurrent->pKey, pCurrent->nKey,
p->iSplitTopic, p->pSplitKey, p->nSplitKey
);
if( res<0 ){
segmentPtrReset(pCurrent);
}
}
segmentCursorSetCurrent(pCsr, bReverse);
if( segmentCursorValid(pCsr)==0
&& bReverse==0
&& iCurrent==0
&& pCsr->nPtr>1
&& pCsr->aPtr[1].pPg==0
){
Level *p = pCsr->pLevel;
int i;
for(i=1; i<pCsr->nPtr; i++){
SegmentPtr *pPtr = &pCsr->aPtr[i];
segmentPtrEnd(pCsr, pPtr, 0, &rc);
/* If the segment-pointer now points to a key that is smaller than
** the split-key, advance it until it does not. Again, the danger
** is that if the current key is smaller than the split-key then
** there may have existed a delete key on a page that has already
** been gobbled.
**
** TODO: This might end up taking a long time. Is there some other
** way? Apart from searching the entire tree for pSplitkey to set
** this levels segment-pointers?
*/
while( pPtr->pPg ){
int res = sortedKeyCompare(pCsr->xCmp,
rtTopic(pPtr->eType), pPtr->pKey, pPtr->nKey,
p->iSplitTopic, p->pSplitKey, p->nSplitKey
);
if( res>=0 ) break;
segmentPtrAdvance(pCsr, pPtr, 0);
}
}
segmentCursorSetCurrent(pCsr, bReverse);
}
return rc;
}
/*
** Move the cursor to point to either the first element (if bLast==0), or
** the last element (if bLast!=0) in the sorted file.
*/
static int segmentCursorEnd(LevelCursor *pCsr, int bLast){
int rc = LSM_OK;
segmentPtrEnd(pCsr, &pCsr->aPtr[0], bLast, &rc);
if( bLast || pCsr->aPtr[0].pPg==0 ){
int i;
for(i=1; i<pCsr->nPtr; i++){
segmentPtrEnd(pCsr, &pCsr->aPtr[i], bLast, &rc);
}
}
segmentCursorSetCurrent(pCsr, bLast);
return rc;
}
static void mcursorFreeComponents(MultiCursor *pCsr){
int i;
lsm_env *pEnv = pCsr->pDb->pEnv;
/* Close the tree cursor, if any. */
lsmTreeCursorDestroy(pCsr->pTreeCsr);
/* Close the sorted file cursors */
for(i=0; i<pCsr->nSegCsr; i++){
segmentCursorClose(pEnv, &pCsr->aSegCsr[i]);
}
/* Free allocations */
lsmFree(pEnv, pCsr->aSegCsr);
lsmFree(pEnv, pCsr->aTree);
lsmFree(pEnv, pCsr->pSystemVal);
/* Zero fields */
pCsr->nSegCsr = 0;
pCsr->aSegCsr = 0;
pCsr->nTree = 0;
pCsr->aTree = 0;
pCsr->pSystemVal = 0;
pCsr->pSnap = 0;
pCsr->pTreeCsr = 0;
}
void lsmMCursorClose(MultiCursor *pCsr){
if( pCsr ){
lsm_db *pDb = pCsr->pDb;
MultiCursor **pp; /* Iterator variable */
/* The cursor may or may not be currently part of the linked list
** starting at lsm_db.pCsr. If it is, extract it. */
for(pp=&pDb->pCsr; *pp; pp=&((*pp)->pNext)){
if( *pp==pCsr ){
*pp = pCsr->pNext;
break;
}
}
/* Free the allocation used to cache the current key, if any. */
sortedBlobFree(&pCsr->key);
/* Free the component cursors */
mcursorFreeComponents(pCsr);
/* Free the cursor structure itself */
lsmFree(pDb->pEnv, pCsr);
}
}
#define MULTICURSOR_ADDLEVEL_ALL 1
#define MULTICURSOR_ADDLEVEL_RHS 2
#define MULTICURSOR_ADDLEVEL_LHS_SEP 3
#define MULTICURSOR_ADDLEVEL_RHS_SEP 4
/*
** Add segments belonging to level pLevel to the multi-cursor pCsr. The
** third argument must be one of the following:
**
** MULTICURSOR_ADDLEVEL_ALL
** Add all segments in the level to the cursor.
**
** MULTICURSOR_ADDLEVEL_RHS
** Add only the rhs segments in the level to the cursor.
**
** MULTICURSOR_ADDLEVEL_LHS_SEP
** Add only the lhs segment. And iterate through its separators array,
** not the main run array.
**
** MULTICURSOR_ADDLEVEL_RHS_SEP
** Add only the first segment from the rhs. And iterate through its
** separators array, not the main run array.
**
** RHS and SEP are only used by cursors created to use as data sources when
** creating new segments (either when flushing the in-memory tree to disk or
** when merging existing runs).
*/
int multiCursorAddLevel(
MultiCursor *pCsr, /* Multi-cursor to add segment to */
Level *pLevel, /* Level to add to multi-cursor merge */
int eMode /* A MULTICURSOR_ADDLEVEL_*** constant */
){
int rc = LSM_OK;
int i;
int nAdd = (eMode==MULTICURSOR_ADDLEVEL_RHS ? pLevel->nRight : 1);
assert( eMode==MULTICURSOR_ADDLEVEL_ALL
|| eMode==MULTICURSOR_ADDLEVEL_RHS
|| eMode==MULTICURSOR_ADDLEVEL_LHS_SEP
);
for(i=0; i<nAdd; i++){
LevelCursor *pNew;
lsm_db *pDb = pCsr->pDb;
/* Grow the pCsr->aSegCsr array if required */
if( 0==(pCsr->nSegCsr % 16) ){
int nByte;
LevelCursor *aNew;
nByte = sizeof(LevelCursor) * (pCsr->nSegCsr+16);
aNew = (LevelCursor *)lsmRealloc(pDb->pEnv, pCsr->aSegCsr, nByte);
if( aNew==0 ) return LSM_NOMEM_BKPT;
memset(&aNew[pCsr->nSegCsr], 0, sizeof(LevelCursor)*16);
pCsr->aSegCsr = aNew;
}
pNew = &pCsr->aSegCsr[pCsr->nSegCsr];
switch( eMode ){
case MULTICURSOR_ADDLEVEL_ALL:
rc = levelCursorInit(pDb, pLevel, pCsr->xCmp, pNew);
break;
case MULTICURSOR_ADDLEVEL_RHS:
rc = levelCursorInitRun(pDb, &pLevel->aRhs[i].run, pCsr->xCmp, pNew);
break;
case MULTICURSOR_ADDLEVEL_LHS_SEP:
rc = levelCursorInitRun(pDb, &pLevel->lhs.sep, pCsr->xCmp, pNew);
break;
}
if( pCsr->flags & CURSOR_IGNORE_SYSTEM ){
pNew->bIgnoreSystem = 1;
}
if( rc==LSM_OK ) pCsr->nSegCsr++;
}
return rc;
}
static int multiCursorNew(
lsm_db *pDb, /* Database handle */
Snapshot *pSnap, /* Snapshot to use for this cursor */
int useTree, /* If true, search the in-memory tree */
int bUserOnly, /* If true, ignore all system data */
MultiCursor **ppCsr /* OUT: Allocated cursor */
){
int rc = LSM_OK; /* Return Code */
MultiCursor *pCsr = *ppCsr; /* Allocated multi-cursor */
if( pCsr==0 ){
pCsr = (MultiCursor *)lsmMallocZeroRc(pDb->pEnv, sizeof(MultiCursor), &rc);
}
if( rc==LSM_OK ){
if( useTree ){
assert( pDb->pTV );
rc = lsmTreeCursorNew(pDb, &pCsr->pTreeCsr);
}
pCsr->pDb = pDb;
pCsr->pSnap = pSnap;
pCsr->xCmp = pDb->xCmp;
if( bUserOnly ){
pCsr->flags |= CURSOR_IGNORE_SYSTEM;
}
}
if( rc!=LSM_OK ){
lsmMCursorClose(pCsr);
pCsr = 0;
}
*ppCsr = pCsr;
return rc;
}
static void multiCursorReadSeparators(MultiCursor *pCsr){
if( pCsr->nSegCsr>0 ){
pCsr->aSegCsr[pCsr->nSegCsr-1].bIgnoreSeparators = 0;
}
}
/*
** Have this cursor skip over SORTED_DELETE entries.
*/
static void multiCursorIgnoreDelete(MultiCursor *pCsr){
if( pCsr ) pCsr->flags |= CURSOR_IGNORE_DELETE;
}
/*
** If the free-block list is not empty, then have this cursor visit a key
** with (a) the system bit set, and (b) the key "F" and (c) a value blob
** containing the entire serialized free-block list.
*/
static void multiCursorVisitFreelist(MultiCursor *pCsr){
assert( pCsr );
pCsr->flags |= CURSOR_NEW_SYSTEM;
}
/*
** Allocate a new cursor to read the database (the in-memory tree and all
** levels). If successful, set *ppCsr to point to the new cursor object
** and return SQLITE_OK. Otherwise, set *ppCsr to NULL and return an
** lsm error code.
**
** If parameter bSystem is true, this is a system cursor. In that case
** the behaviour of this function is modified as follows:
**
** * the worker snapshot is used instead of the client snapshot, and
** * the in-memory tree is ignored.
*/
static int multiCursorAllocate(
lsm_db *pDb, /* Database handle */
int bSystem, /* True for a system cursor */
MultiCursor **ppCsr /* OUT: Allocated cursor */
){
int rc = LSM_OK; /* Return Code */
MultiCursor *pCsr = *ppCsr; /* Allocated multi-cursor */
Level *p; /* Level iterator */
Snapshot *pSnap; /* Snapshot to use for cursor */
pSnap = (bSystem ? pDb->pWorker : pDb->pClient);
assert( pSnap );
rc = multiCursorNew(pDb, pSnap, !bSystem, !bSystem, &pCsr);
multiCursorIgnoreDelete(pCsr);
for(p=lsmDbSnapshotLevel(pSnap); p && rc==LSM_OK; p=p->pNext){
rc = multiCursorAddLevel(pCsr, p, MULTICURSOR_ADDLEVEL_ALL);
}
if( rc!=LSM_OK ){
lsmMCursorClose(pCsr);
pCsr = 0;
}
*ppCsr = pCsr;
return rc;
}
/*
** Allocate and return a new database cursor.
*/
int lsmMCursorNew(
lsm_db *pDb, /* Database handle */
MultiCursor **ppCsr /* OUT: Allocated cursor */
){
MultiCursor *pCsr = 0;
int rc;
rc = multiCursorAllocate(pDb, 0, &pCsr);
if( rc==LSM_OK ){
pCsr->pNext = pDb->pCsr;
pDb->pCsr = pCsr;
}
assert( (rc==LSM_OK)==(pCsr!=0) );
*ppCsr = pCsr;
return rc;
}
#define CURSOR_DATA_TREE 0
#define CURSOR_DATA_SYSTEM 1
#define CURSOR_DATA_SEGMENT 2
static void multiCursorGetKey(
MultiCursor *pCsr,
int iKey,
int *peType, /* OUT: Key type (SORTED_WRITE etc.) */
void **ppKey, /* OUT: Pointer to buffer containing key */
int *pnKey /* OUT: Size of *ppKey in bytes */
){
int nKey = 0;
void *pKey = 0;
int eType = 0;
switch( iKey ){
case CURSOR_DATA_TREE:
if( lsmTreeCursorValid(pCsr->pTreeCsr) ){
int nVal;
void *pVal;
lsmTreeCursorKey(pCsr->pTreeCsr, &pKey, &nKey);
lsmTreeCursorValue(pCsr->pTreeCsr, &pVal, &nVal);
eType = (nVal<0) ? SORTED_DELETE : SORTED_WRITE;
}
break;
case CURSOR_DATA_SYSTEM:
if( pCsr->flags & CURSOR_AT_FREELIST ){
pKey = (void *)"FREELIST";
nKey = 8;
eType = SORTED_SYSTEM_WRITE;
}
else if( pCsr->flags & CURSOR_AT_LEVELS ){
pKey = (void *)"LEVELS";
nKey = 6;
eType = SORTED_SYSTEM_WRITE;
}
break;
default: {
int iSeg = iKey - CURSOR_DATA_SEGMENT;
if( iSeg<pCsr->nSegCsr && segmentCursorValid(&pCsr->aSegCsr[iSeg]) ){
segmentCursorKey(&pCsr->aSegCsr[iSeg], &pKey, &nKey);
segmentCursorType(&pCsr->aSegCsr[iSeg], &eType);
}
break;
}
}
if( peType ) *peType = eType;
if( pnKey ) *pnKey = nKey;
if( ppKey ) *ppKey = pKey;
}
static int multiCursorGetVal(
MultiCursor *pCsr,
int iVal,
void **ppVal,
int *pnVal
){
int rc = LSM_OK;
if( iVal==CURSOR_DATA_TREE ){
if( lsmTreeCursorValid(pCsr->pTreeCsr) ){
lsmTreeCursorValue(pCsr->pTreeCsr, ppVal, pnVal);
}else{
*ppVal = 0;
*pnVal = 0;
}
}else if( iVal==CURSOR_DATA_SYSTEM ){
if( pCsr->flags & CURSOR_AT_FREELIST ){
int *aVal;
int nVal;
assert( pCsr->pSystemVal==0 );
rc = lsmSnapshotFreelist(pCsr->pDb, &aVal, &nVal);
pCsr->pSystemVal = *ppVal = (void *)aVal;
*pnVal = sizeof(int) * nVal;
lsmFreelistDeltaBegin(pCsr->pDb);
}else if( pCsr->flags & CURSOR_AT_LEVELS ){
lsmFree(pCsr->pDb->pEnv, pCsr->pSystemVal);
lsmCheckpointLevels(pCsr->pDb, pCsr->pnHdrLevel, ppVal, pnVal);
pCsr->pSystemVal = *ppVal;
}else{
*ppVal = 0;
*pnVal = 0;
}
}else if( iVal-CURSOR_DATA_SEGMENT<pCsr->nSegCsr
&& segmentCursorValid(&pCsr->aSegCsr[iVal-CURSOR_DATA_SEGMENT])
){
segmentCursorValue(&pCsr->aSegCsr[iVal-CURSOR_DATA_SEGMENT], ppVal, pnVal);
}else{
*ppVal = 0;
*pnVal = 0;
}
return rc;
}
int lsmSortedLoadSystem(lsm_db *pDb){
MultiCursor *pCsr = 0; /* Cursor used to retreive free-list */
int rc; /* Return Code */
assert( pDb->pWorker );
rc = multiCursorAllocate(pDb, 1, &pCsr);
if( rc==LSM_OK ){
void *pVal; int nVal; /* Value read from database */
rc = lsmMCursorLast(pCsr);
if( rc==LSM_OK
&& pCsr->eType==SORTED_SYSTEM_WRITE
&& pCsr->key.nData==6
&& 0==memcmp(pCsr->key.pData, "LEVELS", 6)
){
rc = lsmMCursorValue(pCsr, &pVal, &nVal);
if( rc==LSM_OK ){
rc = lsmCheckpointLoadLevels(pDb, pVal, nVal);
}
if( rc==LSM_OK ){
rc = lsmMCursorPrev(pCsr);
}
}
if( rc==LSM_OK
&& pCsr->eType==SORTED_SYSTEM_WRITE
&& pCsr->key.nData==8
&& 0==memcmp(pCsr->key.pData, "FREELIST", 8)
){
rc = lsmMCursorValue(pCsr, &pVal, &nVal);
if( rc==LSM_OK ){
int n32 = nVal / sizeof(u32);
rc = lsmSnapshotSetFreelist(pDb, (int *)pVal, n32);
}
}
lsmMCursorClose(pCsr);
}
return rc;
}
static void multiCursorDoCompare(MultiCursor *pCsr, int iOut, int bReverse){
int i1;
int i2;
int iRes;
void *pKey1; int nKey1; int eType1;
void *pKey2; int nKey2; int eType2;
int mul = (bReverse ? -1 : 1);
assert( pCsr->aTree && iOut<pCsr->nTree );
if( iOut>=(pCsr->nTree/2) ){
i1 = (iOut - pCsr->nTree/2) * 2;
i2 = i1 + 1;
}else{
i1 = pCsr->aTree[iOut*2];
i2 = pCsr->aTree[iOut*2+1];
}
multiCursorGetKey(pCsr, i1, &eType1, &pKey1, &nKey1);
multiCursorGetKey(pCsr, i2, &eType2, &pKey2, &nKey2);
if( pKey1==0 ){
iRes = i2;
}else if( pKey2==0 ){
iRes = i1;
}else{
int res;
res = (rtTopic(eType1) - rtTopic(eType2));
if( res==0 ){
res = pCsr->xCmp(pKey1, nKey1, pKey2, nKey2);
}
res = res * mul;
if( res==0 ){
iRes = (rtIsSeparator(eType1) ? i2 : i1);
}else if( res<0 ){
iRes = i1;
}else{
iRes = i2;
}
}
pCsr->aTree[iOut] = iRes;
}
static int multiCursorAllocTree(MultiCursor *pCsr){
int rc = LSM_OK;
if( pCsr->aTree==0 ){
int nByte; /* Bytes of space to allocate */
pCsr->nTree = 2;
while( pCsr->nTree<(CURSOR_DATA_SEGMENT+pCsr->nSegCsr) ){
pCsr->nTree = pCsr->nTree*2;
}
nByte = sizeof(int)*pCsr->nTree*2;
pCsr->aTree = (int *)lsmMallocZeroRc(pCsr->pDb->pEnv, nByte, &rc);
}
return rc;
}
static void multiCursorCacheKey(MultiCursor *pCsr, int *pRc){
if( *pRc==LSM_OK ){
void *pKey;
int nKey;
multiCursorGetKey(pCsr, pCsr->aTree[1], &pCsr->eType, &pKey, &nKey);
*pRc = sortedBlobSet(pCsr->pDb->pEnv, &pCsr->key, pKey, nKey);
}
}
static int multiCursorEnd(MultiCursor *pCsr, int bLast){
int rc = LSM_OK;
int i;
pCsr->flags &= ~(CURSOR_NEXT_OK | CURSOR_PREV_OK);
if( pCsr->pTreeCsr ){
rc = lsmTreeCursorEnd(pCsr->pTreeCsr, bLast);
}
if( pCsr->flags & CURSOR_NEW_SYSTEM ){
assert( bLast==0 );
pCsr->flags |= CURSOR_AT_FREELIST;
}
for(i=0; rc==LSM_OK && i<pCsr->nSegCsr; i++){
rc = segmentCursorEnd(&pCsr->aSegCsr[i], bLast);
}
if( rc==LSM_OK ){
rc = multiCursorAllocTree(pCsr);
}
if( rc==LSM_OK ){
for(i=pCsr->nTree-1; i>0; i--){
multiCursorDoCompare(pCsr, i, bLast);
}
pCsr->flags |= (bLast ? CURSOR_PREV_OK : CURSOR_NEXT_OK);
}
multiCursorCacheKey(pCsr, &rc);
if( rc==LSM_OK
&& (pCsr->flags & CURSOR_IGNORE_DELETE)
&& rtIsDelete(pCsr->eType)
){
if( bLast ){
rc = lsmMCursorPrev(pCsr);
}else{
rc = lsmMCursorNext(pCsr);
}
}
return rc;
}
int mcursorSave(MultiCursor *pCsr){
int rc = LSM_OK;
if( pCsr->aTree ){
if( pCsr->aTree[1]==CURSOR_DATA_TREE ){
multiCursorCacheKey(pCsr, &rc);
}
mcursorFreeComponents(pCsr);
}
return rc;
}
int mcursorRestore(lsm_db *pDb, MultiCursor *pCsr){
int rc;
rc = multiCursorAllocate(pDb, 0, &pCsr);
if( rc==LSM_OK && pCsr->key.pData ){
rc = lsmMCursorSeek(pCsr, pCsr->key.pData, pCsr->key.nData, +1);
}
return rc;
}
int lsmSaveCursors(lsm_db *pDb){
int rc = LSM_OK;
MultiCursor *pCsr;
for(pCsr=pDb->pCsr; rc==LSM_OK && pCsr; pCsr=pCsr->pNext){
rc = mcursorSave(pCsr);
}
return rc;
}
int lsmRestoreCursors(lsm_db *pDb){
int rc = LSM_OK;
MultiCursor *pCsr;
for(pCsr=pDb->pCsr; rc==LSM_OK && pCsr; pCsr=pCsr->pNext){
rc = mcursorRestore(pDb, pCsr);
}
return rc;
}
int lsmMCursorFirst(MultiCursor *pCsr){
return multiCursorEnd(pCsr, 0);
}
int lsmMCursorLast(MultiCursor *pCsr){
return multiCursorEnd(pCsr, 1);
}
lsm_db *lsmMCursorDb(MultiCursor *pCsr){
return pCsr->pDb;
}
void lsmMCursorReset(MultiCursor *pCsr){
int i;
lsmTreeCursorReset(pCsr->pTreeCsr);
for(i=0; i<pCsr->nSegCsr; i++){
segmentCursorReset(&pCsr->aSegCsr[i]);
}
pCsr->key.nData = 0;
}
/*
** Seek the cursor.
*/
int lsmMCursorSeek(MultiCursor *pCsr, void *pKey, int nKey, int eSeek){
int eESeek = eSeek; /* Effective eSeek parameter */
int rc = LSM_OK;
int i;
int res;
int iPtr = 0;
if( eESeek==LSM_SEEK_LEFAST ) eESeek = LSM_SEEK_LE;
assert( eESeek==LSM_SEEK_EQ || eESeek==LSM_SEEK_LE || eESeek==LSM_SEEK_GE );
assert( (pCsr->flags & CURSOR_NEW_SYSTEM)==0 );
assert( (pCsr->flags & CURSOR_AT_FREELIST)==0 );
assert( (pCsr->flags & CURSOR_AT_LEVELS)==0 );
pCsr->flags &= ~(CURSOR_NEXT_OK | CURSOR_PREV_OK);
lsmTreeCursorSeek(pCsr->pTreeCsr, pKey, nKey, &res);
switch( eESeek ){
case LSM_SEEK_EQ:
if( res!=0 ){
lsmTreeCursorReset(pCsr->pTreeCsr);
}
break;
case LSM_SEEK_GE:
if( res<0 && lsmTreeCursorValid(pCsr->pTreeCsr) ){
lsmTreeCursorNext(pCsr->pTreeCsr);
}
break;
default:
if( res>0 ){
assert( lsmTreeCursorValid(pCsr->pTreeCsr) );
lsmTreeCursorPrev(pCsr->pTreeCsr);
}
break;
}
for(i=0; rc==LSM_OK && i<pCsr->nSegCsr; i++){
rc = segmentCursorSeek(&pCsr->aSegCsr[i], pKey, nKey, iPtr, eESeek, &iPtr);
}
if( rc==LSM_OK ){
rc = multiCursorAllocTree(pCsr);
}
if( rc==LSM_OK ){
for(i=pCsr->nTree-1; i>0; i--){
multiCursorDoCompare(pCsr, i, eESeek==LSM_SEEK_LE);
}
if( eSeek==LSM_SEEK_GE ) pCsr->flags |= CURSOR_NEXT_OK;
if( eSeek==LSM_SEEK_LE ) pCsr->flags |= CURSOR_PREV_OK;
}
multiCursorCacheKey(pCsr, &rc);
if( rc==LSM_OK
&& eSeek!=LSM_SEEK_LEFAST
&& (pCsr->flags & CURSOR_IGNORE_DELETE)
&& rtIsDelete(pCsr->eType)
){
switch( eESeek ){
case LSM_SEEK_EQ:
lsmMCursorReset(pCsr);
break;
case LSM_SEEK_GE:
rc = lsmMCursorNext(pCsr);
break;
default:
rc = lsmMCursorPrev(pCsr);
break;
}
}
return rc;
}
int lsmMCursorValid(MultiCursor *pCsr){
int res = 0;
if( pCsr->aTree ){
int iKey = pCsr->aTree[1];
if( iKey==CURSOR_DATA_TREE ){
res = lsmTreeCursorValid(pCsr->pTreeCsr);
}else{
void *pKey;
multiCursorGetKey(pCsr, iKey, 0, &pKey, 0);
res = pKey!=0;
}
}
return res;
}
static int mcursorAdvanceOk(
MultiCursor *pCsr,
int bReverse,
int *pRc
){
void *pNew; /* Pointer to buffer containing new key */
int nNew; /* Size of buffer pNew in bytes */
int eNewType; /* Type of new record */
if( *pRc ) return 1;
/* Check the current key value. If it is not greater than (if bReverse==0)
** or less than (if bReverse!=0) the key currently cached in pCsr->key,
** then the cursor has not yet been successfully advanced.
*/
multiCursorGetKey(pCsr, pCsr->aTree[1], &eNewType, &pNew, &nNew);
if( pNew ){
int res = rtTopic(eNewType) - rtTopic(pCsr->eType);
if( res==0 ){
res = pCsr->xCmp(pNew, nNew, pCsr->key.pData, pCsr->key.nData);
}
if( (bReverse==0 && res<=0) || (bReverse!=0 && res>=0) ){
return 0;
}
}
multiCursorCacheKey(pCsr, pRc);
assert( pCsr->eType==eNewType );
if( *pRc==LSM_OK
&& (pCsr->flags & CURSOR_IGNORE_DELETE)
&& rtIsDelete(eNewType)
){
/* If this cursor is configured to skip deleted keys, and the current
** cursor points to a SORTED_DELETE entry, then the cursor has not been
** successfully advanced. */
return 0;
}
return 1;
}
static int multiCursorAdvance(MultiCursor *pCsr, int bReverse){
int rc = LSM_OK; /* Return Code */
if( lsmMCursorValid(pCsr) ){
do {
int iKey = pCsr->aTree[1];
if( iKey==CURSOR_DATA_TREE ){
if( bReverse ){
rc = lsmTreeCursorPrev(pCsr->pTreeCsr);
}else{
rc = lsmTreeCursorNext(pCsr->pTreeCsr);
}
}else if( iKey==CURSOR_DATA_SYSTEM ){
assert( pCsr->flags & (CURSOR_AT_FREELIST | CURSOR_AT_LEVELS) );
assert( pCsr->flags & CURSOR_NEW_SYSTEM );
assert( bReverse==0 );
if( pCsr->flags & CURSOR_AT_FREELIST ){
pCsr->flags &= ~CURSOR_AT_FREELIST;
pCsr->flags |= CURSOR_AT_LEVELS;
}else{
pCsr->flags &= ~CURSOR_AT_LEVELS;
}
}else{
LevelCursor *pLevel = &pCsr->aSegCsr[iKey-CURSOR_DATA_SEGMENT];
rc = segmentCursorAdvance(pLevel, bReverse);
}
if( rc==LSM_OK ){
int i;
for(i=(iKey+pCsr->nTree)/2; i>0; i=i/2){
multiCursorDoCompare(pCsr, i, bReverse);
}
}
}while( mcursorAdvanceOk(pCsr, bReverse, &rc)==0 );
}
return rc;
}
int lsmMCursorNext(MultiCursor *pCsr){
if( (pCsr->flags & CURSOR_NEXT_OK)==0 ) return LSM_MISUSE_BKPT;
return multiCursorAdvance(pCsr, 0);
}
int lsmMCursorPrev(MultiCursor *pCsr){
if( (pCsr->flags & CURSOR_PREV_OK)==0 ) return LSM_MISUSE_BKPT;
return multiCursorAdvance(pCsr, 1);
}
int lsmMCursorKey(MultiCursor *pCsr, void **ppKey, int *pnKey){
if( pCsr->aTree[1]==CURSOR_DATA_TREE ){
lsmTreeCursorKey(pCsr->pTreeCsr, ppKey, pnKey);
}else{
int nKey;
#ifndef NDEBUG
void *pKey;
int eType;
multiCursorGetKey(pCsr, pCsr->aTree[1], &eType, &pKey, &nKey);
assert( eType==pCsr->eType );
assert( nKey==pCsr->key.nData );
assert( memcmp(pKey, pCsr->key.pData, nKey)==0 );
#endif
nKey = pCsr->key.nData;
if( nKey==0 ){
*ppKey = 0;
}else{
*ppKey = pCsr->key.pData;
}
*pnKey = nKey;
}
return LSM_OK;
}
int lsmMCursorValue(MultiCursor *pCsr, void **ppVal, int *pnVal){
assert( pCsr->aTree );
assert( rtIsDelete(pCsr->eType)==0 || !(pCsr->flags & CURSOR_IGNORE_DELETE) );
return multiCursorGetVal(pCsr, pCsr->aTree[1], ppVal, pnVal);
}
int lsmMCursorType(MultiCursor *pCsr, int *peType){
assert( pCsr->aTree );
multiCursorGetKey(pCsr, pCsr->aTree[1], peType, 0, 0);
return LSM_OK;
}
/*
** Buffer aData[], size nData, is assumed to contain a valid b-tree
** hierarchy page image. Return the offset in aData[] of the next free
** byte in the data area (where a new cell may be written if there is
** space).
*/
static int mergeWorkerPageOffset(u8 *aData, int nData){
int nRec;
int iOff;
int nKey;
int eType;
nRec = lsmGetU16(&aData[SEGMENT_NRECORD_OFFSET(nData)]);
iOff = lsmGetU16(&aData[SEGMENT_CELLPTR_OFFSET(nData, nRec-1)]);
eType = aData[iOff++];
assert( eType==0
|| eType==SORTED_SEPARATOR
|| eType==SORTED_SYSTEM_SEPARATOR
);
iOff += lsmVarintGet32(&aData[iOff], &nKey);
iOff += lsmVarintGet32(&aData[iOff], &nKey);
return iOff + (eType ? nKey : 0);
}
/*
** Following a checkpoint operation, database pages that are part of the
** checkpointed state of the LSM are deemed read-only. This includes the
** right-most page of the b-tree hierarchy of any separators array under
** construction, and all pages between it and the b-tree root, inclusive.
** This is a problem, as when further pages are appended to the separators
** array, entries must be added to the indicated b-tree hierarchy pages.
**
** This function copies all such b-tree pages to new locations, so that
** they can be modified as required.
**
** The complication is that not all database pages are the same size - due
** to the way the file.c module works some (the first and last in each block)
** are 4 bytes smaller than the others.
*/
static int mergeWorkerMoveHierarchy(MergeWorker *pMW){
SortedRun *pSep; /* Separators run being modified */
lsm_db *pDb = pMW->pDb; /* Database handle */
int rc = LSM_OK; /* Return code */
int i;
int iRight = 0;
int nHier = pMW->nHier;
Page **apHier = pMW->apHier;
assert( nHier>0 && pMW->pLevel->pMerge->bHierReadonly );
pSep = &pMW->pLevel->lhs.sep;
for(i=0; rc==LSM_OK && i<nHier; i++){
Page *pNew = 0;
rc = lsmFsSortedAppend(pDb->pFS, pDb->pWorker, pSep, &pNew);
assert( rc==LSM_OK );
if( rc==LSM_OK ){
u8 *a1; int n1;
u8 *a2; int n2;
a1 = lsmFsPageData(pNew, &n1);
a2 = lsmFsPageData(apHier[i], &n2);
assert( n1==n2 || n1+4==n2 || n2+4==n1 );
if( n1>=n2 ){
/* If n1 (size of the new page) is equal to or greater than n2 (the
** size of the old page), then copy the data into the new page. If
** n1==n2, this could be done with a single memcpy(). However,
** since sometimes n1>n2, the page content and footer must be copied
** separately. */
int nEntry = pageGetNRec(a2, n2);
int iEof1 = SEGMENT_EOF(n1, nEntry);
int iEof2 = SEGMENT_EOF(n2, nEntry);
memcpy(a1, a2, iEof2);
memcpy(&a1[iEof1], &a2[iEof2], n2 - iEof2);
if( iRight ) lsmPutU32(&a1[SEGMENT_POINTER_OFFSET(n1)], iRight);
lsmFsPageRelease(apHier[i]);
apHier[i] = pNew;
iRight = lsmFsPageNumber(pNew);
}else{
lsmPutU16(&a1[SEGMENT_FLAGS_OFFSET(n1)], SEGMENT_BTREE_FLAG);
lsmPutU16(&a1[SEGMENT_NRECORD_OFFSET(n1)], 0);
lsmPutU32(&a1[SEGMENT_POINTER_OFFSET(n1)], 0);
i = i - 1;
lsmFsPageRelease(pNew);
}
}
}
#ifdef LSM_DEBUG
if( rc==LSM_OK ){
for(i=0; i<nHier; i++) assert( lsmFsPageWritable(pMW->apHier[i]) );
}
#endif
if( rc==LSM_OK ){
pMW->pLevel->pMerge->bHierReadonly = 0;
}
return rc;
}
/*
** Allocate and populate the MergeWorker.apHier[] array.
*/
static int mergeWorkerLoadHierarchy(MergeWorker *pMW){
int rc = LSM_OK;
SortedRun *pSep = &pMW->pLevel->lhs.sep;
if( pMW->apHier==0 && pSep->iRoot!=0 ){
int bHierReadonly = pMW->pLevel->pMerge->bHierReadonly;
FileSystem *pFS = pMW->pDb->pFS;
lsm_env *pEnv = pMW->pDb->pEnv;
Page **apHier = 0;
int nHier = 0;
int iPg = pSep->iRoot;
do {
Page *pPg = 0;
u8 *aData;
int nData;
int flags;
rc = lsmFsDbPageGet(pFS, iPg, &pPg);
if( rc!=LSM_OK ) break;
aData = lsmFsPageData(pPg, &nData);
flags = pageGetFlags(aData, nData);
if( flags&SEGMENT_BTREE_FLAG ){
Page **apNew = (Page **)lsmRealloc(
pEnv, apHier, sizeof(Page *)*(nHier+1)
);
if( apNew==0 ){
rc = LSM_NOMEM_BKPT;
break;
}
if( bHierReadonly==0 ) lsmFsPageWrite(pPg);
apHier = apNew;
memmove(&apHier[1], &apHier[0], sizeof(Page *) * nHier);
nHier++;
apHier[0] = pPg;
iPg = pageGetPtr(aData, nData);
}else{
lsmFsPageRelease(pPg);
break;
}
}while( 1 );
if( rc==LSM_OK ){
pMW->nHier = nHier;
pMW->apHier = apHier;
}else{
int i;
for(i=0; i<nHier; i++){
lsmFsPageRelease(apHier[i]);
}
lsmFree(pEnv, apHier);
}
}
return rc;
}
/*
** Push the key passed through the pKey/nKey arguments into the b-tree
** hierarchy. The associated pointer value is iPtr.
**
** B-tree pages use almost the same format as regular pages. The
** differences are:
**
** 1. The record format is (usually, see below) as follows:
**
** + Type byte (always SORTED_SEPARATOR or SORTED_SYSTEM_SEPARATOR),
** + Absolute pointer value (varint),
** + Number of bytes in key (varint),
** + Blob containing key data.
**
** 2. All pointer values are stored as absolute values (not offsets
** relative to the footer pointer value).
**
** 3. Each pointer that is part of a record points to a page that
** contains keys smaller than the records key (note: not "equal to or
** smaller than - smaller than").
**
** 4. The pointer in the page footer of a b-tree page points to a page
** that contains keys equal to or larger than the largest key on the
** b-tree page.
**
** The reason for having the page footer pointer point to the right-child
** (instead of the left) is that doing things this way makes the
** segWriterMoveHierarchy() operation less complicated (since the pointers
** that need to be updated are all stored as fixed-size integers within the
** page footer, not varints in page records).
**
** Records may not span b-tree pages. If this function is called to add a
** record larger than (page-size / 4) bytes, then a pointer to the separators
** array page that contains the main record is added to the b-tree instead.
** In this case the record format is:
**
** + 0x00 byte (1 byte)
** + Absolute pointer value (varint),
** + Absolute page number of page containing key (varint).
**
** See function seekInSeparators() for the code that traverses b-tree pages.
*/
static int mergeWorkerPushHierarchy(
MergeWorker *pMW, /* Merge worker object */
Pgno iKeyPg, /* Page that will contain pKey/nKey */
int iTopic, /* Topic value for this key */
void *pKey, /* Pointer to key buffer */
int nKey /* Size of pKey buffer in bytes */
){
lsm_db *pDb = pMW->pDb; /* Database handle */
int rc; /* Return Code */
int iLevel; /* Level of b-tree hierachy to write to */
int nData; /* Size of aData[] in bytes */
u8 *aData; /* Page data for level iLevel */
int iOff; /* Offset on b-tree page to write record to */
int nRec; /* Initial number of records on b-tree page */
Pgno iPtr; /* Pointer value to accompany pKey/nKey */
int bIndirect; /* True to use an indirect record */
/* If there exists a b-tree hierarchy and it is not loaded into
** memory, load it now. */
rc = mergeWorkerLoadHierarchy(pMW);
/* TODO: What the heck does this do? */
if( pMW->nHier ){
aData = lsmFsPageData(pMW->apHier[0], &nData);
iPtr = lsmGetU32(&aData[SEGMENT_POINTER_OFFSET(nData)]);
}else{
iPtr = pMW->pLevel->lhs.sep.iFirst;
}
if( pMW->nHier && pMW->pLevel->pMerge->bHierReadonly ){
rc = mergeWorkerMoveHierarchy(pMW);
if( rc!=LSM_OK ) goto push_hierarchy_out;
}
/* Determine if the indirect format should be used. */
bIndirect = (nKey*4 > lsmFsPageSize(pMW->pDb->pFS));
/* The MergeWorker.apHier[] array contains the right-most leaf of the b-tree
** hierarchy, the root node, and all nodes that lie on the path between.
** apHier[0] is the right-most leaf and apHier[pMW->nHier-1] is the current
** root page.
**
** This loop searches for a node with enough space to store the key on,
** starting with the leaf and iterating up towards the root. When the loop
** exits, the key may be written to apHier[iLevel].
*/
for(iLevel=0; iLevel<=pMW->nHier; iLevel++){
int nByte; /* Number of free bytes required */
int iRight; /* Right hand pointer from aData[]/nData */
if( iLevel==pMW->nHier ){
/* Extend the array and allocate a new root page. */
Page **aNew;
aNew = (Page **)lsmRealloc(
pMW->pDb->pEnv, pMW->apHier, sizeof(Page *)*(pMW->nHier+1)
);
if( !aNew ){
rc = LSM_NOMEM_BKPT;
goto push_hierarchy_out;
}
pMW->apHier = aNew;
}else{
int nFree;
/* If the key will fit on this page, break out of the loop. */
assert( lsmFsPageWritable(pMW->apHier[iLevel]) );
aData = lsmFsPageData(pMW->apHier[iLevel], &nData);
iRight = lsmGetU32(&aData[SEGMENT_POINTER_OFFSET(nData)]);
if( bIndirect ){
nByte = 2 + 1 + lsmVarintLen32(iRight) + lsmVarintLen32(iKeyPg);
}else{
nByte = 2 + 1 + lsmVarintLen32(iRight) + lsmVarintLen32(nKey) + nKey;
}
nRec = pageGetNRec(aData, nData);
nFree = SEGMENT_EOF(nData, nRec) - mergeWorkerPageOffset(aData, nData);
if( nByte<=nFree ) break;
/* Otherwise, it is full. Release it. */
iPtr = lsmFsPageNumber(pMW->apHier[iLevel]);
rc = lsmFsPageRelease(pMW->apHier[iLevel]);
}
/* Allocate a new page for apHier[iLevel]. */
pMW->apHier[iLevel] = 0;
if( rc==LSM_OK ){
rc = lsmFsSortedAppend(
pDb->pFS, pDb->pWorker, &pMW->pLevel->lhs.sep, &pMW->apHier[iLevel]
);
}
if( rc!=LSM_OK ) goto push_hierarchy_out;
aData = lsmFsPageData(pMW->apHier[iLevel], &nData);
memset(aData, 0, nData);
lsmPutU16(&aData[SEGMENT_FLAGS_OFFSET(nData)], SEGMENT_BTREE_FLAG);
lsmPutU16(&aData[SEGMENT_NRECORD_OFFSET(nData)], 0);
if( iLevel>0 ){
iRight = lsmFsPageNumber(pMW->apHier[iLevel-1]);
lsmPutU32(&aData[SEGMENT_POINTER_OFFSET(nData)], iRight);
}
if( iLevel==pMW->nHier ){
pMW->nHier++;
break;
}
}
/* Write the key into page apHier[iLevel]. */
aData = lsmFsPageData(pMW->apHier[iLevel], &nData);
iOff = mergeWorkerPageOffset(aData, nData);
nRec = pageGetNRec(aData, nData);
lsmPutU16(&aData[SEGMENT_CELLPTR_OFFSET(nData, nRec)], iOff);
lsmPutU16(&aData[SEGMENT_NRECORD_OFFSET(nData)], nRec+1);
if( bIndirect ){
aData[iOff++] = 0x00;
iOff += lsmVarintPut32(&aData[iOff], iPtr);
iOff += lsmVarintPut32(&aData[iOff], iKeyPg);
}else{
aData[iOff++] = (u8)(iTopic | SORTED_SEPARATOR);
iOff += lsmVarintPut32(&aData[iOff], iPtr);
iOff += lsmVarintPut32(&aData[iOff], nKey);
memcpy(&aData[iOff], pKey, nKey);
}
if( iLevel>0 ){
int iRight = lsmFsPageNumber(pMW->apHier[iLevel-1]);
lsmPutU32(&aData[SEGMENT_POINTER_OFFSET(nData)], iRight);
}
/* Write the right-hand pointer of the right-most leaf page of the
** b-tree heirarchy. */
aData = lsmFsPageData(pMW->apHier[0], &nData);
lsmPutU32(&aData[SEGMENT_POINTER_OFFSET(nData)], iKeyPg);
/* Ensure that the SortedRun.iRoot field is correct. */
pMW->pLevel->lhs.sep.iRoot = lsmFsPageNumber(pMW->apHier[pMW->nHier-1]);
push_hierarchy_out:
return rc;
}
/*
** The merge-worker object passed as the first argument to this function
** was used for an in-memory tree flush. If one was required, the separators
** array has been assembled in-memory (as a "phantom"). In this case it
** consists of leaf nodes only, there are no b-tree nodes. This function
** materializes the phantom run (writes it into the db file) and appends
** any required b-tree nodes.
*/
static int mergeWorkerBuildHierarchy(MergeWorker *pMW){
int rc = LSM_OK;
assert( pMW->bFlush );
assert( pMW->pLevel->lhs.sep.iRoot==0 );
if( pMW->apPage[1] ){
SortedRun *pRun; /* Separators run to materialize */
lsm_db *db = pMW->pDb;
Blob blob = {0, 0, 0};
Page *pPg;
int iLast;
/* Write the leaf pages into the file. They now have page numbers,
** which can be used as pointers in the b-tree hierarchy. */
pRun = &pMW->pLevel->lhs.sep;
rc = lsmFsPhantomMaterialize(db->pFS, db->pWorker, pRun);
if( rc==LSM_OK ){
rc = lsmFsDbPageGet(db->pFS, pRun->iFirst, &pPg);
}
iLast = pRun->iLast;
while( rc==LSM_OK && lsmFsPageNumber(pPg)!=iLast ){
Page *pNext = 0;
rc = lsmFsDbPageNext(pRun, pPg, 1, &pNext);
lsmFsPageRelease(pPg);
pPg = pNext;
if( rc==LSM_OK ){
u8 *aData;
int nData;
aData = lsmFsPageData(pPg, &nData);
if( pageGetNRec(aData, nData)>0 ){
u8 *pKey;
int nKey;
int iTopic;
Pgno iPg = lsmFsPageNumber(pPg);
pKey = pageGetKey(pPg, 0, &iTopic, &nKey, &blob);
rc = mergeWorkerPushHierarchy(pMW, iPg, iTopic, pKey, nKey);
}
}
}
if( pMW->nHier>0 ){
Page *pRoot = pMW->apHier[pMW->nHier-1];
pRun->iRoot = lsmFsPageNumber(pRoot);
}else{
pRun->iRoot = pRun->iFirst;
}
lsmFsPageRelease(pPg);
sortedBlobFree(&blob);
}
return rc;
}
static int keyszToSkip(FileSystem *pFS, int nKey){
int nPgsz; /* Nominal database page size */
nPgsz = lsmFsPageSize(pFS);
return LSM_MIN(((nKey * 4) / nPgsz), 3);
}
/*
** Advance to the next page of an output run being populated by merge-worker
** pMW. If bSep is true, the separators run output is advanced by one page.
** Otherwise, the main run.
**
** The footer of the new page is initialized to indicate that it contains
** zero records. The flags field is cleared. The page footer pointer field
** is set to iFPtr.
**
** If successful, LSM_OK is returned. Otherwise, an error code.
*/
static int mergeWorkerNextPage(
MergeWorker *pMW, /* Merge worker object to append page to */
int bSep, /* True to append to the separators array */
int iFPtr /* Pointer value for footer of new page */
){
int rc = LSM_OK; /* Return code */
Page *pNext = 0; /* New page appended to run */
lsm_db *pDb = pMW->pDb; /* Database handle */
SortedRun *pRun; /* Run to append to */
assert( bSep==0 || bSep==1 );
pRun = (bSep ? &pMW->pLevel->lhs.sep : &pMW->pLevel->lhs.run);
rc = lsmFsSortedAppend(pDb->pFS, pDb->pWorker, pRun, &pNext);
assert( rc!=LSM_OK || bSep || pRun->iFirst>0 );
if( rc==LSM_OK ){
u8 *aData; /* Data buffer belonging to page pNext */
int nData; /* Size of aData[] in bytes */
lsmFsPageRelease(pMW->apPage[bSep]);
pMW->apPage[bSep] = pNext;
pMW->pLevel->pMerge->aiOutputOff[bSep] = 0;
aData = lsmFsPageData(pNext, &nData);
lsmPutU16(&aData[SEGMENT_NRECORD_OFFSET(nData)], 0);
lsmPutU16(&aData[SEGMENT_FLAGS_OFFSET(nData)], 0);
lsmPutU32(&aData[SEGMENT_POINTER_OFFSET(nData)], iFPtr);
if( bSep==0 ) pMW->nWork++;
}
return rc;
}
/*
** Write a blob of data into an output segment being populated by a
** merge-worker object. If argument bSep is true, write into the separators
** array. Otherwise, the main array.
**
** This function is used to write the blobs of data for keys and values.
*/
static int mergeWorkerData(
MergeWorker *pMW, /* Merge worker object */
int bSep, /* True to write to separators run */
int iFPtr, /* Footer ptr for new pages */
u8 *aWrite, /* Write data from this buffer */
int nWrite /* Size of aWrite[] in bytes */
){
int rc = LSM_OK; /* Return code */
int nRem = nWrite; /* Number of bytes still to write */
while( nRem>0 ){
Merge *pMerge = pMW->pLevel->pMerge;
int nCopy; /* Number of bytes to copy */
u8 *aData; /* Pointer to buffer of current output page */
int nData; /* Size of aData[] in bytes */
int nRec; /* Number of records on current output page */
int iOff; /* Offset in aData[] to write to */
assert( lsmFsPageWritable(pMW->apPage[bSep]) );
aData = lsmFsPageData(pMW->apPage[bSep], &nData);
nRec = pageGetNRec(aData, nData);
iOff = pMerge->aiOutputOff[bSep];
nCopy = LSM_MIN(nRem, SEGMENT_EOF(nData, nRec) - iOff);
memcpy(&aData[iOff], &aWrite[nWrite-nRem], nCopy);
nRem -= nCopy;
if( nRem>0 ){
rc = mergeWorkerNextPage(pMW, bSep, iFPtr);
}else{
pMerge->aiOutputOff[bSep] = iOff + nCopy;
}
}
return rc;
}
static int mergeWorkerWrite(
MergeWorker *pMW, /* Merge worker object to write into */
int bSep, /* True to write to separators array */
int eType, /* One of SORTED_SEPARATOR, WRITE or DELETE */
void *pKey, int nKey, /* Key value */
void *pVal, int nVal, /* Accompanying value, if any */
int iPtr, /* Absolute value of page pointer, or 0 */
int *piPtrOut /* OUT: Pointer to write to separators */
){
int rc = LSM_OK; /* Return code */
Merge *pMerge; /* Persistent part of level merge state */
int nHdr; /* Space required for this record header */
Page *pPg; /* Page to write to */
u8 *aData; /* Data buffer for page pWriter->pPage */
int nData; /* Size of buffer aData[] in bytes */
int nRec; /* Number of records on page pPg */
int iFPtr; /* Value of pointer in footer of pPg */
int iRPtr; /* Value of pointer written into record */
int iOff; /* Current write offset within page pPg */
SortedRun *pRun; /* Run being written to */
int flags = 0; /* If != 0, flags value for page footer */
assert( bSep==0 || bSep==1 );
assert( bSep==0 || rtIsSeparator(eType) );
pMerge = pMW->pLevel->pMerge;
pRun = (bSep ? &pMW->pLevel->lhs.sep : &pMW->pLevel->lhs.run);
pPg = pMW->apPage[bSep];
aData = lsmFsPageData(pPg, &nData);
nRec = pageGetNRec(aData, nData);
iFPtr = pageGetPtr(aData, nData);
/* If iPtr is 0, set it to the same value as the absolute pointer
** stored as part of the previous record. */
if( iPtr==0 ){
iPtr = iFPtr;
if( nRec ) iPtr += pageGetRecordPtr(aData, nData, nRec-1);
}
/* Calculate the relative pointer value to write to this record */
iRPtr = iPtr - iFPtr;
/* assert( iRPtr>=0 ); */
/* Figure out how much space is required by the new record. The space
** required is divided into two sections: the header and the body. The
** header consists of the intial varint fields. The body are the blobs
** of data that correspond to the key and value data. The entire header
** must be stored on the page. The body may overflow onto the next and
** subsequent pages.
**
** The header space is:
**
** 1) record type - 1 byte.
** 2) Page-pointer-offset - 1 varint
** 3) Key size - 1 varint
** 4) Value size - 1 varint (SORTED_WRITE only)
*/
nHdr = 1 + lsmVarintLen32(iRPtr) + lsmVarintLen32(nKey);
if( rtIsWrite(eType) ) nHdr += lsmVarintLen32(nVal);
/* If the entire header will not fit on page pPg, or if page pPg is
** marked read-only, advance to the next page of the output run. */
iOff = pMerge->aiOutputOff[bSep];
if( iOff<0 || iOff+nHdr > SEGMENT_EOF(nData, nRec+1) ){
iFPtr = iFPtr + (nRec ? pageGetRecordPtr(aData, nData, nRec-1) : 0);
iRPtr = iPtr - iFPtr;
iOff = 0;
nRec = 0;
rc = mergeWorkerNextPage(pMW, bSep, iFPtr);
pPg = pMW->apPage[bSep];
aData = lsmFsPageData(pPg, &nData);
}
/* If this record header will be the first on the page, and the page is
** not the very first in the entire run, special actions may need to be
** taken:
**
** * If currently writing the main run, *piPtrOut should be set to
** the current page number. The caller will add a key to the separators
** array that points to the current page.
**
** * If currently writing the separators array, push a copy of the key
** into the b-tree hierarchy.
*/
if( rc==LSM_OK && nRec==0 && pRun->iFirst!=pRun->iLast ){
assert( pMerge->nSkip>=0 );
if( bSep ){
if( pMW->bFlush==0 ){
Pgno iPg = lsmFsPageNumber(pPg);
rc = mergeWorkerPushHierarchy(pMW, iPg, rtTopic(eType), pKey, nKey);
}
}else{
if( pMerge->nSkip ){
pMerge->nSkip--;
flags = PGFTR_SKIP_THIS_FLAG;
}else{
*piPtrOut = lsmFsPageNumber(pPg);
pMerge->nSkip = keyszToSkip(pMW->pDb->pFS, nKey);
}
if( pMerge->nSkip ) flags |= PGFTR_SKIP_NEXT_FLAG;
}
}
/* Update the output segment */
if( rc==LSM_OK ){
/* Update the page footer. */
lsmPutU16(&aData[SEGMENT_NRECORD_OFFSET(nData)], nRec+1);
lsmPutU16(&aData[SEGMENT_CELLPTR_OFFSET(nData, nRec)], iOff);
if( flags ) lsmPutU16(&aData[SEGMENT_FLAGS_OFFSET(nData)], flags);
/* Write the entry header into the current page. */
aData[iOff++] = eType; /* 1 */
iOff += lsmVarintPut32(&aData[iOff], iRPtr); /* 2 */
iOff += lsmVarintPut32(&aData[iOff], nKey); /* 3 */
if( rtIsWrite(eType) ) iOff += lsmVarintPut32(&aData[iOff], nVal); /* 4 */
pMerge->aiOutputOff[bSep] = iOff;
/* Write the key and data into the segment. */
assert( iFPtr==pageGetPtr(aData, nData) );
rc = mergeWorkerData(pMW, bSep, iFPtr+iRPtr, pKey, nKey);
if( rc==LSM_OK && rtIsWrite(eType) ){
rc = mergeWorkerData(pMW, bSep, iFPtr+iRPtr, pVal, nVal);
}
}
return rc;
}
static int multiCursorSetupTree(MultiCursor *pCsr, int bRev){
int rc;
assert( pCsr->aTree==0 );
rc = multiCursorAllocTree(pCsr);
if( rc==LSM_OK ){
int i;
for(i=pCsr->nTree-1; i>0; i--){
multiCursorDoCompare(pCsr, i, bRev);
}
}
multiCursorCacheKey(pCsr, &rc);
return rc;
}
/*
** Free all resources allocated by mergeWorkerInit().
*/
static void mergeWorkerShutdown(MergeWorker *pMW){
int i; /* Iterator variable */
MultiCursor *pCsr = pMW->pCsr;
/* Unless the merge has finished, save the cursor position in the
** Merge.aInput[] array. See function mergeWorkerInit() for the
** code to restore a cursor position based on aInput[]. */
if( pCsr ){
Merge *pMerge = pMW->pLevel->pMerge;
/* pMerge->nInput==0 indicates that this is a FlushTree() operation. */
assert( pMerge->nInput==0 || pMW->pLevel->nRight>0 );
assert( pMerge->nInput==0 || pMerge->nInput==pCsr->nSegCsr );
for(i=0; i<pMerge->nInput; i++){
SegmentPtr *pPtr = &pCsr->aSegCsr[i].aPtr[0];
if( pPtr->pPg ){
pMerge->aInput[i].iPg = lsmFsPageNumber(pPtr->pPg);
pMerge->aInput[i].iCell = pPtr->iCell;
}else{
pMerge->aInput[i].iPg = 0;
pMerge->aInput[i].iCell = 0;
}
}
}
lsmMCursorClose(pCsr);
lsmFsPageRelease(pMW->apPage[0]);
lsmFsPageRelease(pMW->apPage[1]);
for(i=0; i<pMW->nHier; i++){
lsmFsPageRelease(pMW->apHier[i]);
}
lsmFree(pMW->pDb->pEnv, pMW->apHier);
pMW->pCsr = 0;
pMW->apHier = 0;
pMW->nHier = 0;
pMW->apPage[0] = 0;
pMW->apPage[1] = 0;
}
static int mergeWorkerFirstPage(MergeWorker *pMW){
int rc; /* Return code */
SortedRun *pRun; /* Run containing sep. keys to merge in */
Page *pPg = 0; /* First page of run pRun */
assert( pMW->apPage[0]==0 );
pRun = pMW->pCsr->aSegCsr[pMW->pCsr->nSegCsr-1].aPtr[0].pRun;
rc = lsmFsDbPageGet(pMW->pDb->pFS, pRun->iFirst, &pPg);
if( rc==LSM_OK ){
u8 *aData; /* Buffer for page pPg */
int nData; /* Size of aData[] in bytes */
int iFPtr; /* Pointer value read from footer of pPg */
aData = lsmFsPageData(pPg, &nData);
iFPtr = pageGetPtr(aData, nData);
lsmFsPageRelease(pPg);
rc = mergeWorkerNextPage(pMW, 0, iFPtr);
}
return rc;
}
static int mergeWorkerStep(MergeWorker *pMW){
lsm_db *pDb = pMW->pDb; /* Database handle */
MultiCursor *pCsr; /* Cursor to read input data from */
int rc; /* Return code */
int eType; /* SORTED_SEPARATOR, WRITE or DELETE */
void *pKey; int nKey; /* Key */
void *pVal; int nVal; /* Value */
Segment *pSeg; /* Output segment */
int iPtr = 0;
pCsr = pMW->pCsr;
pSeg = &pMW->pLevel->lhs;
/* Pull the next record out of the source cursor. */
lsmMCursorKey(pCsr, &pKey, &nKey);
rc = lsmMCursorValue(pCsr, &pVal, &nVal);
eType = pCsr->eType;
if( rc!=LSM_OK ) return rc;
/* Figure out if the output record may have a different pointer value
** than the previous. This is the case if the current key is identical to
** a key that appears in the lowest level run being merged. If so, set
** iPtr to the absolute pointer value. If not, leave iPtr set to zero,
** indicating that the output pointer value should be a copy of the pointer
** value written with the previous key. */
if( pCsr->nSegCsr ){
LevelCursor *pPtrs = &pCsr->aSegCsr[pCsr->nSegCsr-1];
if( segmentCursorValid(pPtrs)
&& 0==pDb->xCmp(pPtrs->aPtr[0].pKey, pPtrs->aPtr[0].nKey, pKey, nKey)
){
iPtr = pPtrs->aPtr[0].iPtr+pPtrs->aPtr[0].iPgPtr;
}
}
/* If this is a separator key and we know that the output pointer has not
** changed, there is no point in writing an output record. Otherwise,
** proceed. */
if( rtIsSeparator(eType)==0 || iPtr!=0 ){
int iSPtr = 0; /* Separators require a pointer here */
if( pMW->apPage[0]==0 ){
rc = mergeWorkerFirstPage(pMW);
}
/* Write the record into the main run. */
if( rc==LSM_OK ){
rc = mergeWorkerWrite(pMW, 0, eType, pKey, nKey, pVal, nVal, iPtr,&iSPtr);
}
/* If the call to mergeWorkerWrite() above started a new page, then
** add a SORTED_SEPARATOR key to the separators run. */
if( rc==LSM_OK && iSPtr ){
/* If the separators array has not been started, start it now. */
if( pMW->apPage[1]==0 ){
assert( pSeg->run.iFirst!=0 );
rc = mergeWorkerNextPage(pMW, 1, pSeg->run.iFirst);
if( !pMW->bFlush ) pSeg->sep.iRoot = pSeg->sep.iFirst;
}
if( rc==LSM_OK ){
int eSType; /* Type of record for separators array */
/* Figure out how many (if any) keys to skip from this point. */
assert( pMW->apPage[1] && (pSeg->sep.iFirst || pMW->bFlush) );
pMW->pLevel->pMerge->nSkip = keyszToSkip(pDb->pFS, nKey);
/* Write the key into the separators array. */
eSType = rtTopic(eType) | SORTED_SEPARATOR;
rc = mergeWorkerWrite(pMW, 1, eSType, pKey, nKey, 0, 0, iSPtr, 0);
}
}
}
/* Advance the cursor to the next input record (assuming one exists). */
assert( lsmMCursorValid(pMW->pCsr) );
if( rc==LSM_OK ) rc = lsmMCursorNext(pMW->pCsr);
/* If the cursor is at EOF, the merge is finished. Release all page
** references currently held by the merge worker and inform the
** FileSystem object that no further pages will be appended to either
** the main or separators array.
*/
if( rc==LSM_OK && !lsmMCursorValid(pMW->pCsr) ){
if( pSeg->run.iFirst ){
rc = lsmFsSortedFinish(pDb->pFS, &pSeg->run);
}
if( rc==LSM_OK && pMW->bFlush ){
rc = mergeWorkerBuildHierarchy(pMW);
}
if( rc==LSM_OK && pSeg->sep.iFirst ){
rc = lsmFsSortedFinish(pDb->pFS, &pSeg->sep);
}
mergeWorkerShutdown(pMW);
}
return rc;
}
static int mergeWorkerDone(MergeWorker *pMW){
return pMW->pCsr==0 || !lsmMCursorValid(pMW->pCsr);
}
static void sortedFreeLevel(lsm_env *pEnv, Level *p){
if( p ){
lsmFree(pEnv, p->pMerge);
lsmFree(pEnv, p->aRhs);
lsmFree(pEnv, p);
}
}
static void sortedInvokeWorkHook(lsm_db *pDb){
if( pDb->xWork ){
pDb->xWork(pDb, pDb->pWorkCtx);
}
}
int lsmSortedNewToplevel(
lsm_db *pDb, /* Connection handle */
int *pnHdrLevel /* OUT: Number of levels not stored in LSM */
){
int rc = LSM_OK; /* Return Code */
MultiCursor *pCsr = 0;
Level *pNext = 0; /* The current top level */
Level *pNew; /* The new level itself */
SortedRun *pDel = 0;
int iLeftPtr = 0;
/* Allocate the new level structure to write to. */
pNext = lsmDbSnapshotLevel(pDb->pWorker);
pNew = (Level *)lsmMallocZeroRc(pDb->pEnv, sizeof(Level), &rc);
/* Create a cursor to gather the data required by the new segment. The new
** segment contains everything in the tree and pointers to the next segment
** in the database (if any). */
if( rc==LSM_OK ){
pNew->pNext = pNext;
lsmDbSnapshotSetLevel(pDb->pWorker, pNew);
rc = multiCursorNew(pDb, pDb->pWorker, (pDb->pTV!=0), 0, &pCsr);
if( rc==LSM_OK ){
if( pNext ){
assert( pNext->pMerge==0 || pNext->nRight>0 );
if( pNext->pMerge==0 ){
if( segmentHasSeparators(&pNext->lhs) ){
rc = multiCursorAddLevel(pCsr, pNext, MULTICURSOR_ADDLEVEL_LHS_SEP);
/* This call moves any blocks occupied by separators array pDel
** to the pending list. We do this here, even though pDel will be
** read while building the new level, so that the blocks will be
** included in the "FREELIST" entry visited by the cursor (and
** written into the new top level). */
if( rc==LSM_OK ){
pDel = &pNext->lhs.sep;
rc = lsmFsSortedDelete(pDb->pFS, pDb->pWorker, 0, pDel);
}
}
iLeftPtr = pNext->lhs.run.iFirst;
}
}else{
/* The new level will be the only level in the LSM. There is no reason
** to write out delete keys in this case. */
multiCursorIgnoreDelete(pCsr);
}
}
if( rc==LSM_OK ){
multiCursorVisitFreelist(pCsr);
multiCursorReadSeparators(pCsr);
pCsr->pnHdrLevel = pnHdrLevel;
}
}
if( rc!=LSM_OK ){
lsmMCursorClose(pCsr);
}else{
Merge merge; /* Merge object used to create new level */
MergeWorker mergeworker; /* MergeWorker object for the same purpose */
memset(&merge, 0, sizeof(Merge));
memset(&mergeworker, 0, sizeof(MergeWorker));
pNew->pMerge = &merge;
mergeworker.pDb = pDb;
mergeworker.pLevel = pNew;
mergeworker.pCsr = pCsr;
/* Mark the separators array for the new level as a "phantom". */
mergeworker.bFlush = 1;
lsmFsPhantom(pDb->pFS, &pNew->lhs.sep);
/* Allocate the first page of the output segment. */
rc = mergeWorkerNextPage(&mergeworker, 0, iLeftPtr);
/* Do the work to create the new merged segment on disk */
if( rc==LSM_OK ) rc = lsmMCursorFirst(pCsr);
while( rc==LSM_OK && mergeWorkerDone(&mergeworker)==0 ){
rc = mergeWorkerStep(&mergeworker);
}
lsmFsPhantomFree(pDb->pFS);
mergeWorkerShutdown(&mergeworker);
pNew->pMerge = 0;
}
lsmFreelistDeltaEnd(pDb);
/* Link the new level into the top of the tree. Delete the separators
** array (if any) that was merged into the new level. */
if( rc==LSM_OK ){
if( pDel ){
/* lsmFsSortedDelete() has already been called on pDel. So all
** that is required here is to zero it (so that it is not used by
** future LSM searches). */
memset(pDel, 0, sizeof(SortedRun));
}
}else{
lsmDbSnapshotSetLevel(pDb->pWorker, pNext);
sortedFreeLevel(pDb->pEnv, pNew);
}
if( rc==LSM_OK ){
sortedInvokeWorkHook(pDb);
}
return rc;
}
/*
** Flush the contents of the in-memory tree to a new segment on disk.
** At present, this may occur in two scenarios:
**
** 1. When a transaction has just been committed (by connection pDb),
** and the in-memory tree has exceeded the size threshold, or
**
** 2. If the in-memory tree is not empty and the last connection to
** the database (pDb) is being closed.
**
** In both cases, the connection hold a worker snapshot reference. In
** the first, the connection also holds the in-memory tree write-version.
** In the second, no in-memory tree version reference is held at all.
*/
int lsmSortedFlushTree(
lsm_db *pDb, /* Connection handle */
int *pnHdrLevel /* OUT: Number of levels not stored in LSM */
){
int rc;
assert( pDb->pWorker );
assert( pDb->pTV==0 || lsmTreeIsWriteVersion(pDb->pTV) );
rc = lsmBeginFlush(pDb);
/* If there is nothing to do, return early. */
if( lsmTreeSize(pDb->pTV)==0 && lsmDatabaseIsDirty(pDb)==0 ){
lsmFinishFlush(pDb, 0);
return LSM_OK;
}
lsmDatabaseDirty(pDb);
if( rc==LSM_OK ){
lsmSortedNewToplevel(pDb, pnHdrLevel);
}
#if 0
lsmSortedDumpStructure(pDb, pDb->pWorker, 0, 0, "tree flush");
#endif
assertAllBtreesOk(rc, pDb);
assertAllPointersOk(rc, pDb);
assert( rc!=LSM_OK || lsmFsIntegrityCheck(pDb) );
lsmFinishFlush(pDb, rc==LSM_OK);
return rc;
}
/*
** The nMerge levels in the LSM beginning with pLevel consist of a
** left-hand-side segment only. Replace these levels with a single new
** level consisting of a new empty segment on the left-hand-side and the
** nMerge segments from the replaced levels on the right-hand-side.
**
** Also, allocate and populate a Merge object and set Level.pMerge to
** point to it.
*/
static int sortedMergeSetup(
lsm_db *pDb, /* Database handle */
Level *pLevel, /* First level to merge */
int nMerge, /* Merge this many levels together */
Level **ppNew /* New, merged, level */
){
int rc = LSM_OK; /* Return Code */
Level *pNew; /* New Level object */
int bUseNext = 0; /* True to link in next separators */
Merge *pMerge; /* New Merge object */
int nByte; /* Bytes of space allocated at pMerge */
/* Allocate the new Level object */
pNew = (Level *)lsmMallocZeroRc(pDb->pEnv, sizeof(Level), &rc);
if( pNew ){
pNew->aRhs = (Segment *)lsmMallocZeroRc(pDb->pEnv,
nMerge * sizeof(Segment), &rc);
}
/* Populate the new Level object */
if( rc==LSM_OK ){
Level *pNext = 0; /* Level following pNew */
int i;
Level *pTopLevel;
Level *p = pLevel;
Level **pp;
pNew->nRight = nMerge;
pNew->iAge = pLevel->iAge+1;
for(i=0; i<nMerge; i++){
pNext = p->pNext;
pNew->aRhs[i] = p->lhs;
lsmFree(pDb->pEnv, p);
p = pNext;
}
/* Replace the old levels with the new. */
pTopLevel = lsmDbSnapshotLevel(pDb->pWorker);
pNew->pNext = p;
for(pp=&pTopLevel; *pp!=pLevel; pp=&((*pp)->pNext));
*pp = pNew;
lsmDbSnapshotSetLevel(pDb->pWorker, pTopLevel);
/* Determine whether or not the next separators will be linked in */
if( pNext && pNext->pMerge==0 && segmentHasSeparators(&pNext->lhs) ){
bUseNext = 1;
}
}
/* Allocate the merge object */
nByte = sizeof(Merge) + sizeof(MergeInput) * (nMerge + bUseNext);
pMerge = (Merge *)lsmMallocZeroRc(pDb->pEnv, nByte, &rc);
if( pMerge ){
pMerge->aInput = (MergeInput *)&pMerge[1];
pMerge->nInput = nMerge + bUseNext;
pNew->pMerge = pMerge;
}
*ppNew = pNew;
return rc;
}
static int mergeWorkerLoadOutputPage(MergeWorker *pMW, int bSep){
int rc = LSM_OK; /* Return code */
SortedRun *pRun; /* Run to load page from */
Level *pLevel;
pLevel = pMW->pLevel;
pRun = (bSep ? &pLevel->lhs.sep : &pLevel->lhs.run);
if( pRun->iLast ){
Page *pPg;
rc = lsmFsDbPageGet(pMW->pDb->pFS, pRun->iLast, &pPg);
while( rc==LSM_OK ){
Page *pNext;
u8 *aData;
int nData;
aData = lsmFsPageData(pPg, &nData);
if( (pageGetFlags(aData, nData) & SEGMENT_BTREE_FLAG)==0 ) break;
rc = lsmFsDbPageNext(pRun, pPg, -1, &pNext);
lsmFsPageRelease(pPg);
pPg = pNext;
}
if( rc==LSM_OK ){
pMW->apPage[bSep] = pPg;
if( pLevel->pMerge->aiOutputOff[bSep]>=0 ) rc = lsmFsPageWrite(pPg);
}
}
return rc;
}
static int mergeWorkerInit(
lsm_db *pDb, /* Db connection to do merge work */
Level *pLevel, /* Level to work on merging */
MergeWorker *pMW /* Object to initialize */
){
int rc; /* Return code */
Merge *pMerge = pLevel->pMerge; /* Persistent part of merge state */
MultiCursor *pCsr = 0; /* Cursor opened for pMW */
assert( pDb->pWorker );
assert( pLevel->pMerge );
assert( pLevel->nRight>0 );
memset(pMW, 0, sizeof(MergeWorker));
pMW->pDb = pDb;
pMW->pLevel = pLevel;
/* Create a multi-cursor to read the data to write to the new
** segment. The new segment contains:
**
** 1. Records from LHS of each of the nMerge levels being merged.
** 2. Separators from either the last level being merged, or the
** separators attached to the LHS of the following level, or neither.
**
** If the new level is the lowest (oldest) in the db, discard any
** delete keys. Key annihilation.
*/
rc = multiCursorNew(pDb, pDb->pWorker, 0, 0, &pCsr);
if( rc==LSM_OK ){
rc = multiCursorAddLevel(pCsr, pLevel, MULTICURSOR_ADDLEVEL_RHS);
}
if( rc==LSM_OK && pLevel->pNext ){
if( pMerge->nInput > pLevel->nRight ){
Level *pNext = pLevel->pNext;
rc = multiCursorAddLevel(pCsr, pNext, MULTICURSOR_ADDLEVEL_LHS_SEP);
}
multiCursorReadSeparators(pCsr);
}else{
multiCursorIgnoreDelete(pCsr);
}
assert( pMerge->nInput==pCsr->nSegCsr );
pMW->pCsr = pCsr;
/* Load each of the output pages into memory. */
if( rc==LSM_OK ) rc = mergeWorkerLoadOutputPage(pMW, 0);
if( rc==LSM_OK ) rc = mergeWorkerLoadOutputPage(pMW, 1);
/* Position the cursor. */
if( rc==LSM_OK ){
if( pMW->apPage[0]==0 ){
/* The output array is still empty. So position the cursor at the very
** start of the input. */
rc = multiCursorEnd(pCsr, 0);
}else{
/* The output array is non-empty. Position the cursor based on the
** page/cell data saved in the Merge.aInput[] array. */
int i;
for(i=0; rc==LSM_OK && i<pCsr->nSegCsr; i++){
MergeInput *pInput = &pMerge->aInput[i];
if( pInput->iPg ){
SegmentPtr *pPtr;
assert( pCsr->aSegCsr[i].nPtr==1 );
assert( pCsr->aSegCsr[i].aPtr[0].pPg==0 );
pPtr = &pCsr->aSegCsr[i].aPtr[0];
rc = segmentPtrLoadPage(pDb->pFS, pPtr, pInput->iPg);
if( rc==LSM_OK && pPtr->nCell>0 ){
rc = segmentPtrLoadCell(pPtr, pInput->iCell);
}
}
}
if( rc==LSM_OK ){
rc = multiCursorSetupTree(pCsr, 0);
}
}
pCsr->flags |= CURSOR_NEXT_OK;
}
return rc;
}
int sortedWork(lsm_db *pDb, int nWork, int bOptimize, int *pnWrite){
int rc = LSM_OK; /* Return Code */
int nRemaining = nWork; /* Units of work to do before returning */
Snapshot *pWorker = pDb->pWorker;
assert( lsmFsIntegrityCheck(pDb) );
assert( pWorker );
assertAllPointersOk(rc, pDb);
if( lsmDbSnapshotLevel(pWorker)==0 ) return LSM_OK;
lsmDatabaseDirty(pDb);
while( nRemaining>0 ){
Level *pLevel;
Level *pTopLevel = lsmDbSnapshotLevel(pWorker);
/* Find the longest contiguous run of levels not currently undergoing a
** merge with the same age in the structure. Or the level being merged
** with the largest number of right-hand segments. Work on it. */
Level *pBest = 0;
int nBest = 4;
Level *pThis = 0;
int nThis = 0;
for(pLevel = pTopLevel; pLevel; pLevel=pLevel->pNext){
if( pLevel->nRight==0 && pThis && pLevel->iAge==pThis->iAge ){
nThis++;
}else{
if( nThis>=nBest ){
pBest = pThis;
nBest = nThis;
}
if( pLevel->nRight ){
if( pLevel->nRight>=nBest ){
nBest = pLevel->nRight;
pBest = pLevel;
nThis = 0;
pThis = 0;
}
}else{
pThis = pLevel;
nThis = 1;
}
}
}
if( nThis>nBest ){
assert( pThis );
pBest = pThis;
nBest = nThis;
}
if( pBest==0 && bOptimize && pTopLevel->pNext ){
pBest = pTopLevel;
nBest = 2;
}
if( pBest ){
if( pBest->nRight==0 ){
rc = sortedMergeSetup(pDb, pBest, nBest, &pLevel);
}else{
pLevel = pBest;
}
}
if( pLevel==0 ){
/* Could not find any work to do. Finished. */
break;
}else{
MergeWorker mergeworker; /* State used to work on the level merge */
rc = mergeWorkerInit(pDb, pLevel, &mergeworker);
assert( mergeworker.nWork==0 );
while( rc==LSM_OK
&& 0==mergeWorkerDone(&mergeworker)
&& mergeworker.nWork<nRemaining
){
rc = mergeWorkerStep(&mergeworker);
}
nRemaining -= mergeworker.nWork;
/* Check if the merge operation is completely finished. If so, the
** Merge object and the right-hand-side of the level can be deleted.
**
** Otherwise, gobble up (declare eligible for recycling) any pages
** from rhs segments for which the content has been completely merged
** into the lhs of the level.
*/
if( rc==LSM_OK ){
if( mergeWorkerDone(&mergeworker)==0 ){
int iGobble = mergeworker.pCsr->aTree[1] - CURSOR_DATA_SEGMENT;
if( iGobble<pLevel->nRight ){
SegmentPtr *pGobble = &mergeworker.pCsr->aSegCsr[iGobble].aPtr[0];
if( (pGobble->flags & PGFTR_SKIP_THIS_FLAG)==0 ){
lsmFsGobble(pWorker, pGobble->pRun, pGobble->pPg);
}
}
}else if( pLevel->lhs.run.iFirst==0 ){
/* If the new level is completely empty, remove it from the
** database snapshot. This can only happen if all input keys were
** annihilated. Since keys are only annihilated if the new level
** is the last in the linked list (contains the most ancient of
** database content), this guarantees that pLevel->pNext==0. */
Level *pTop; /* Top level of worker snapshot */
Level **pp; /* Read/write iterator for Level.pNext list */
assert( pLevel->pNext==0 );
assert( segmentHasSeparators(&pLevel->lhs)==0 );
/* Remove the level from the worker snapshot. */
pTop = lsmDbSnapshotLevel(pWorker);
for(pp=&pTop; *pp!=pLevel; pp=&((*pp)->pNext));
*pp = pLevel->pNext;
lsmDbSnapshotSetLevel(pWorker, pTop);
/* Free the Level structure. */
lsmFsSortedDelete(pDb->pFS, pWorker, 1, &pLevel->lhs.run);
sortedFreeLevel(pDb->pEnv, pLevel);
}else{
int i;
/* Free the separators of the next level, if required. */
if( pLevel->pMerge->nInput > pLevel->nRight ){
assert( pLevel->pNext );
assert( segmentHasSeparators(&pLevel->pNext->lhs) );
lsmFsSortedDelete(pDb->pFS, pWorker, 1, &pLevel->pNext->lhs.sep);
}
/* Free the right-hand-side of pLevel */
for(i=0; i<pLevel->nRight; i++){
lsmFsSortedDelete(pDb->pFS, pWorker, 1, &pLevel->aRhs[i].run);
lsmFsSortedDelete(pDb->pFS, pWorker, 1, &pLevel->aRhs[i].sep);
}
lsmFree(pDb->pEnv, pLevel->aRhs);
pLevel->nRight = 0;
pLevel->aRhs = 0;
/* Free the Merge object */
lsmFree(pDb->pEnv, pLevel->pMerge);
pLevel->pMerge = 0;
}
}
/* Clean up the MergeWorker object initialized above. If no error
** has occurred, invoke the work-hook to inform the application that
** the database structure has changed. */
mergeWorkerShutdown(&mergeworker);
if( rc==LSM_OK ) sortedInvokeWorkHook(pDb);
#if 0
lsmSortedDumpStructure(pDb, pDb->pWorker, 0, 0, "work");
#endif
}
}
if( pnWrite ){
*pnWrite = (nWork - nRemaining);
}
assertAllBtreesOk(rc, pDb);
assertAllPointersOk(rc, pDb);
assert( rc!=LSM_OK || lsmFsIntegrityCheck(pDb) );
return rc;
}
typedef struct Metric Metric;
struct Metric {
double fAvgHeight;
int nTotalSz;
int nMinSz;
};
#if 0
static void sortedMeasureDb(lsm_db *pDb, Metric *p){
Level *pLevel; /* Used to iterate through levels */
assert( pDb->pWorker );
double fHeight = 0.0;
int nTotalSz = 0;
int nMinSz = 0;
for(pLevel=lsmDbSnapshotLevel(pDb->pWorker); pLevel; pLevel=pLevel->pNext){
const int nLhsSz = pLevel->lhs.run.nSize;
int nRhsSz = 0;
int nSz;
int i;
for(i=0; i<pLevel->nRight; i++){
nRhsSz += pLevel->aRhs[i].run.nSize;
}
nSz = nRhsSz + nLhsSz;
fHeight += (double)nLhsSz/nSz + (double)nRhsSz/nSz * pLevel->nRight;
nTotalSz += nSz;
if( nMinSz==0 || nMinSz>nSz ) nMinSz = nSz;
}
if( nMinSz ){
printf("avg-height=%.2f log2(min/total)=%.2f totalsz=%d minsz=%d\n",
fHeight,
log((double)nTotalSz / nMinSz) / log(2),
nTotalSz,
nMinSz
);
}
}
#endif
/*
** This function is called once for each page worth of data is written to
** the in-memory tree. It calls sortedWork() to do roughly enough work
** to prevent the height of the tree from growing indefinitely, even if
** there are no other calls to sortedWork().
*/
int lsmSortedAutoWork(lsm_db *pDb, int nUnit){
int rc; /* Return code */
int nRemaining; /* Units of work to do before returning */
int nDepth; /* Current height of tree (longest path) */
Level *pLevel; /* Used to iterate through levels */
assert( lsmFsIntegrityCheck(pDb) );
assert( pDb->pWorker );
/* Determine how many units of work to do before returning. One unit of
** work is achieved by writing one page (~4KB) of merged data. */
nRemaining = nDepth = 0;
for(pLevel=lsmDbSnapshotLevel(pDb->pWorker); pLevel; pLevel=pLevel->pNext){
/* nDepth += LSM_MAX(1, pLevel->nRight); */
nDepth += 1;
/* nDepth += pLevel->nRight; */
}
nRemaining = nUnit * nDepth;
rc = sortedWork(pDb, nRemaining, 0, 0);
return rc;
}
/*
** Perform work to merge database segments together.
*/
int lsm_work(lsm_db *pDb, int flags, int nPage, int *pnWrite){
int rc = LSM_OK; /* Return code */
/* This function may not be called if pDb has an open read or write
** transaction. Return LSM_MISUSE if an application attempts this.
*/
if( pDb->nTransOpen || pDb->pCsr ) return LSM_MISUSE_BKPT;
assert( pDb->pTV==0 );
if( (flags & LSM_WORK_FLUSH) ){
rc = lsmBeginWriteTrans(pDb);
if( rc==LSM_OK ){
rc = lsmFlushToDisk(pDb);
lsmFinishWriteTrans(pDb, 0);
lsmFinishReadTrans(pDb);
}
}
if( rc==LSM_OK && nPage>0 ){
int bOptimize = ((flags & LSM_WORK_OPTIMIZE) ? 1 : 0);
int nWrite = 0;
pDb->pWorker = lsmDbSnapshotWorker(pDb);
rc = sortedWork(pDb, nPage, bOptimize, &nWrite);
if( nWrite && (flags & LSM_WORK_CHECKPOINT) ){
int nHdrLevel = 0;
if( rc==LSM_OK ) rc = lsmSortedFlushDb(pDb);
if( rc==LSM_OK ) rc = lsmSortedNewToplevel(pDb, &nHdrLevel);
if( rc==LSM_OK ) rc = lsmDbUpdateClient(pDb, nHdrLevel);
}
lsmDbSnapshotRelease(pDb->pEnv, pDb->pWorker);
pDb->pWorker = 0;
if( pnWrite ) *pnWrite = nWrite;
}else if( pnWrite ){
*pnWrite = 0;
}
/* If the LSM_WORK_CHECKPOINT flag is specified and one is available,
** write a checkpoint out to disk. */
if( rc==LSM_OK && (flags & LSM_WORK_CHECKPOINT) ){
rc = lsmCheckpointWrite(pDb);
}
return rc;
}
/*
** Return a string representation of the segment passed as the only argument.
** Space for the returned string is allocated using lsmMalloc(), and should
** be freed by the caller using lsmFree().
*/
static char *segToString(lsm_env *pEnv, SortedRun *pRun, int nMin){
int nSize = pRun->nSize;
Pgno iRoot = pRun->iRoot;
Pgno iFirst = pRun->iFirst;
Pgno iLast = pRun->iLast;
char *z;
char *z1;
char *z2;
int nPad;
z1 = lsmMallocPrintf(pEnv, "%d.%d", iFirst, iLast);
if( iRoot ){
z2 = lsmMallocPrintf(pEnv, "root=%d", iRoot);
}else{
z2 = lsmMallocPrintf(pEnv, "size=%d", nSize);
}
nPad = nMin - 2 - strlen(z1) - 1 - strlen(z2);
nPad = LSM_MAX(0, nPad);
if( iRoot ){
z = lsmMallocPrintf(pEnv, "/%s %*s%s\\", z1, nPad, "", z2);
}else{
z = lsmMallocPrintf(pEnv, "|%s %*s%s|", z1, nPad, "", z2);
}
lsmFree(pEnv, z1);
lsmFree(pEnv, z2);
return z;
}
static int fileToString(
lsm_env *pEnv, /* For xMalloc() */
char *aBuf,
int nBuf,
int nMin,
SortedRun *pRun
){
int i = 0;
char *zSeg;
zSeg = segToString(pEnv, pRun, nMin);
i += sqlite4_snprintf(&aBuf[i], nBuf-i, "%s", zSeg);
lsmFree(pEnv, zSeg);
return i;
}
void sortedDumpPage(lsm_db *pDb, SortedRun *pRun, Page *pPg, int bVals){
Blob blob = {0, 0, 0}; /* Blob used for keys */
LsmString s;
int i;
int nRec;
int iPtr;
int flags;
u8 *aData;
int nData;
aData = lsmFsPageData(pPg, &nData);
nRec = pageGetNRec(aData, nData);
iPtr = pageGetPtr(aData, nData);
flags = pageGetFlags(aData, nData);
lsmStringInit(&s, pDb->pEnv);
lsmStringAppendf(&s,"nCell=%d iPtr=%d flags=%d {", nRec, iPtr, flags);
if( flags&SEGMENT_BTREE_FLAG ) iPtr = 0;
for(i=0; i<nRec; i++){
Page *pRef = 0; /* Pointer to page iRef */
int iChar;
u8 *aKey; int nKey = 0; /* Key */
u8 *aVal; int nVal = 0; /* Value */
int iTopic;
u8 *aCell;
int iPgPtr;
int eType;
aCell = pageGetCell(aData, nData, i);
eType = *aCell++;
assert( (flags & SEGMENT_BTREE_FLAG) || eType!=0 );
aCell += lsmVarintGet32(aCell, &iPgPtr);
if( eType==0 ){
Pgno iRef; /* Page number of referenced page */
aCell += lsmVarintGet32(aCell, &iRef);
lsmFsDbPageGet(pDb->pFS, iRef, &pRef);
aKey = pageGetKey(pRef, 0, &iTopic, &nKey, &blob);
}else{
aCell += lsmVarintGet32(aCell, &nKey);
if( rtIsWrite(eType) ) aCell += lsmVarintGet32(aCell, &nVal);
sortedReadData(pPg, (aCell-aData), nKey+nVal, (void **)&aKey, &blob);
aVal = &aKey[nKey];
iTopic = eType;
}
lsmStringAppendf(&s, "%s%2X:", (i==0?"":" "), iTopic);
for(iChar=0; iChar<nKey; iChar++){
lsmStringAppendf(&s, "%c", isalnum(aKey[iChar]) ? aKey[iChar] : '.');
}
if( nVal>0 && bVals ){
lsmStringAppendf(&s, "##");
for(iChar=0; iChar<nVal; iChar++){
lsmStringAppendf(&s, "%c", isalnum(aVal[iChar]) ? aVal[iChar] : '.');
}
}
lsmStringAppendf(&s, " %d", iPgPtr+iPtr);
lsmFsPageRelease(pRef);
}
lsmStringAppend(&s, "}", 1);
lsmLogMessage(pDb, LSM_OK, " Page %d: %s", lsmFsPageNumber(pPg), s.z);
lsmStringClear(&s);
sortedBlobFree(&blob);
}
static void infoCellDump(
lsm_db *pDb,
Page *pPg,
int iCell,
int *peType,
int *piPgPtr,
u8 **paKey, int *pnKey,
u8 **paVal, int *pnVal,
Blob *pBlob
){
u8 *aData; int nData; /* Page data */
u8 *aKey; int nKey = 0; /* Key */
u8 *aVal; int nVal = 0; /* Value */
int eType;
int iPgPtr;
Page *pRef = 0; /* Pointer to page iRef */
u8 *aCell;
aData = lsmFsPageData(pPg, &nData);
aCell = pageGetCell(aData, nData, iCell);
eType = *aCell++;
aCell += lsmVarintGet32(aCell, &iPgPtr);
if( eType==0 ){
int dummy;
Pgno iRef; /* Page number of referenced page */
aCell += lsmVarintGet32(aCell, &iRef);
lsmFsDbPageGet(pDb->pFS, iRef, &pRef);
pageGetKeyCopy(pDb->pEnv, pRef, 0, &dummy, pBlob);
aKey = (u8 *)pBlob->pData;
nKey = pBlob->nData;
lsmFsPageRelease(pRef);
}else{
aCell += lsmVarintGet32(aCell, &nKey);
if( rtIsWrite(eType) ) aCell += lsmVarintGet32(aCell, &nVal);
sortedReadData(pPg, (aCell-aData), nKey+nVal, (void **)&aKey, pBlob);
aVal = &aKey[nKey];
}
if( peType ) *peType = eType;
if( piPgPtr ) *piPgPtr = iPgPtr;
if( paKey ) *paKey = aKey;
if( paVal ) *paVal = aVal;
if( pnKey ) *pnKey = nKey;
if( pnVal ) *pnVal = nVal;
}
static int infoAppendBlob(LsmString *pStr, int bHex, u8 *z, int n){
int iChar;
for(iChar=0; iChar<n; iChar++){
if( bHex ){
lsmStringAppendf(pStr, "%02X", z[iChar]);
}else{
lsmStringAppendf(pStr, "%c", isalnum(z[iChar]) ?z[iChar] : '.');
}
}
return LSM_OK;
}
int lsmInfoPageDump(lsm_db *pDb, Pgno iPg, int bHex, char **pzOut){
int rc = LSM_OK; /* Return code */
Snapshot *pWorker; /* Worker snapshot */
Snapshot *pRelease = 0; /* Snapshot to release */
Page *pPg = 0; /* Handle for page iPg */
*pzOut = 0;
if( iPg==0 ) return LSM_ERROR;
/* Obtain the worker snapshot */
pWorker = pDb->pWorker;
if( !pWorker ){
pRelease = pWorker = lsmDbSnapshotWorker(pDb);
}
rc = lsmFsDbPageGet(pDb->pFS, iPg, &pPg);
if( rc==LSM_OK ){
Blob blob = {0, 0, 0, 0};
int nKeyWidth = 0;
LsmString str;
int nRec;
int iPtr;
int flags;
int iCell;
u8 *aData; int nData; /* Page data and size thereof */
aData = lsmFsPageData(pPg, &nData);
nRec = pageGetNRec(aData, nData);
iPtr = pageGetPtr(aData, nData);
flags = pageGetFlags(aData, nData);
lsmStringInit(&str, pDb->pEnv);
lsmStringAppendf(&str, "Page : %d\n", iPg);
lsmStringAppendf(&str, "nRec : %d\n", nRec);
lsmStringAppendf(&str, "iPtr : %d\n", iPtr);
lsmStringAppendf(&str, "flags: %04x\n", flags);
lsmStringAppendf(&str, "\n");
for(iCell=0; iCell<nRec; iCell++){
int nKey;
infoCellDump(pDb, pPg, iCell, 0, 0, 0, &nKey, 0, 0, &blob);
if( nKey>nKeyWidth ) nKeyWidth = nKey;
}
if( bHex ) nKeyWidth = nKeyWidth * 2;
for(iCell=0; iCell<nRec; iCell++){
u8 *aKey; int nKey = 0; /* Key */
u8 *aVal; int nVal = 0; /* Value */
int iPgPtr;
int eType;
char cType = '?';
Pgno iAbsPtr;
infoCellDump(pDb, pPg, iCell, &eType, &iPgPtr,
&aKey, &nKey, &aVal, &nVal, &blob
);
iAbsPtr = iPgPtr + ((flags & SEGMENT_BTREE_FLAG) ? 0 : iPtr);
if( rtIsDelete(eType) ) cType = 'D';
if( rtIsWrite(eType) ) cType = 'W';
if( rtIsSeparator(eType) ) cType = 'S';
lsmStringAppendf(&str, "%c %d (%s) ",
cType, iAbsPtr, (rtTopic(eType) ? "sys" : "usr")
);
infoAppendBlob(&str, bHex, aKey, nKey);
lsmStringAppendf(&str, "%*s", nKeyWidth - (nKey*(1+bHex)), "");
if( nVal>0 ){
lsmStringAppendf(&str, " ");
infoAppendBlob(&str, bHex, aVal, nVal);
}
lsmStringAppendf(&str, "\n");
}
*pzOut = str.z;
sortedBlobFree(&blob);
lsmFsPageRelease(pPg);
}
lsmDbSnapshotRelease(pDb->pEnv, pRelease);
return rc;
}
void sortedDumpSegment(lsm_db *pDb, SortedRun *pRun, int bVals){
assert( pDb->xLog );
if( pRun ){
char *zSeg;
Page *pPg;
zSeg = segToString(pDb->pEnv, pRun, 0);
lsmLogMessage(pDb, LSM_OK, "Segment: %s", zSeg);
lsmFree(pDb->pEnv, zSeg);
lsmFsDbPageGet(pDb->pFS, pRun->iFirst, &pPg);
while( pPg ){
Page *pNext;
sortedDumpPage(pDb, pRun, pPg, bVals);
lsmFsDbPageNext(pRun, pPg, 1, &pNext);
lsmFsPageRelease(pPg);
pPg = pNext;
}
}
}
/*
** Invoke the log callback zero or more times with messages that describe
** the current database structure.
*/
void lsmSortedDumpStructure(
lsm_db *pDb, /* Database handle (used for xLog callback) */
Snapshot *pSnap, /* Snapshot to dump */
int bKeys, /* Output the keys from each segment */
int bVals, /* Output the values from each segment */
const char *zWhy /* Caption to print near top of dump */
){
Snapshot *pDump = pSnap;
Level *pTopLevel;
if( pDump==0 ){
assert( pDb->pWorker==0 );
pDump = lsmDbSnapshotWorker(pDb);
}
pTopLevel = lsmDbSnapshotLevel(pDump);
if( pDb->xLog && pTopLevel ){
Level *pLevel;
int iLevel = 0;
lsmLogMessage(pDb, LSM_OK, "Database structure (%s)", zWhy);
for(pLevel=pTopLevel; pLevel; pLevel=pLevel->pNext){
char zLeft[1024];
char zRight[1024];
int i = 0;
SortedRun *aLeft[24];
SortedRun *aRight[24];
int nLeft = 0;
int nRight = 0;
Segment *pSeg = &pLevel->lhs;
if( segmentHasSeparators(pSeg) ){
aLeft[nLeft++] = &pSeg->sep;
}
aLeft[nLeft++] = &pSeg->run;
for(i=0; i<pLevel->nRight; i++){
if( segmentHasSeparators(&pLevel->aRhs[i]) ){
aRight[nRight++] = &pLevel->aRhs[i].sep;
}
aRight[nRight++] = &pLevel->aRhs[i].run;
}
for(i=0; i<nLeft || i<nRight; i++){
int iPad = 0;
char zLevel[32];
zLeft[0] = '\0';
zRight[0] = '\0';
if( i<nLeft ){
fileToString(pDb->pEnv, zLeft, sizeof(zLeft), 28, aLeft[i]);
}
if( i<nRight ){
fileToString(pDb->pEnv, zRight, sizeof(zRight), 28, aRight[i]);
}
if( i==0 ){
sqlite4_snprintf(zLevel, sizeof(zLevel), "L%d:", iLevel);
}else{
zLevel[0] = '\0';
}
if( nRight==0 ){
iPad = 28 - (strlen(zLeft)/2) ;
}
lsmLogMessage(pDb, LSM_OK, "% 7s % *s% -35s %s",
zLevel, iPad, "", zLeft, zRight
);
}
iLevel++;
}
#if 0
lsmLogMessage(pDb, LSM_OK, "Block map", zWhy);
for(pLevel=pDb->pLevel; pLevel; pLevel=pLevel->pNext){
int iRhs;
lsmFsDumpBlockmap(pDb, pLevel->lhs.pSep);
lsmFsDumpBlockmap(pDb, pLevel->lhs.pRun);
for(iRhs=0; iRhs<pLevel->nRight; iRhs++){
lsmFsDumpBlockmap(pDb, pLevel->aRhs[iRhs].pSep);
lsmFsDumpBlockmap(pDb, pLevel->aRhs[iRhs].pRun);
}
}
lsmFsDumpBlocklists(pDb);
#endif
if( bKeys ){
for(pLevel=pTopLevel; pLevel; pLevel=pLevel->pNext){
int i;
sortedDumpSegment(pDb, &pLevel->lhs.sep, 0);
sortedDumpSegment(pDb, &pLevel->lhs.run, bVals);
for(i=0; i<pLevel->nRight; i++){
if( pLevel->aRhs[i].sep.iFirst>0 ){
sortedDumpSegment(pDb, &pLevel->aRhs[i].sep, 0);
}
sortedDumpSegment(pDb, &pLevel->aRhs[i].run, bVals);
}
}
}
}
if( pSnap==0 ){
lsmDbSnapshotRelease(pDb->pEnv, pDump);
}
}
void lsmSortedFreeLevel(lsm_env *pEnv, Level *pLevel){
Level *pNext;
Level *p;
for(p=pLevel; p; p=pNext){
pNext = p->pNext;
sortedFreeLevel(pEnv, p);
}
}
int lsmSortedFlushDb(lsm_db *pDb){
int rc = LSM_OK;
Level *p;
assert( pDb->pWorker );
for(p=lsmDbSnapshotLevel(pDb->pWorker); p && rc==LSM_OK; p=p->pNext){
Merge *pMerge = p->pMerge;
if( pMerge ){
pMerge->aiOutputOff[0] = -1;
pMerge->aiOutputOff[1] = -1;
pMerge->bHierReadonly = 1;
}
}
return LSM_OK;
}
void lsmSortedSaveTreeCursors(lsm_db *pDb){
MultiCursor *pCsr;
for(pCsr=pDb->pCsr; pCsr; pCsr=pCsr->pNext){
lsmTreeCursorSave(pCsr->pTreeCsr);
}
}
#ifdef LSM_DEBUG_EXPENSIVE
/*
** Argument iPg is a page number within a separators run. Assert() that for
** each key K on on the page, (pKey1 >= K > pKey2) is true.
**
** Also, if page iPg is a BTREE page, call this function recursively to
** check that the keys on each child page fall into the expected range.
*/
static void assertBtreeRanges(
lsm_db *pDb,
SortedRun *pRun,
Pgno iPg, /* Database page to load */
void *pKey1, int nKey1, /* All keys must be >= than this */
void *pKey2, int nKey2 /* And < than this */
){
Blob blob = {0, 0, 0};
u8 *aData;
int nData;
Page *pPg;
int rc;
int i;
int nRec;
int flags;
int iPrevTopic = 0; /* Previous topic value */
u8 *aPrev = 0; /* Buffer pointing to previous key */
int nPrev = 0; /* Size of aPrev[] in bytes */
rc = lsmFsDbPageGet(pDb->pFS, iPg, &pPg);
assert( rc==LSM_OK );
aData = lsmFsPageData(pPg, &nData);
nRec = pageGetNRec(aData, nData);
flags = pageGetFlags(aData, nData);
for(i=0; i<nRec; i++){
u8 *aKey;
int nKey;
int iTopic;
int iPtr;
if( flags & SEGMENT_BTREE_FLAG ){
aKey = pageGetCell(aData, nData, i);
aKey += lsmVarintGet32(aKey, &iPtr);
aKey += lsmVarintGet32(aKey, &nKey);
}else{
aKey = pageGetKey(pPg, i, &iTopic, &nKey, &blob);
}
assert( pKey1==0 || pDb->xCmp(aKey, nKey, pKey1, nKey1)>=0 );
assert( pKey2==0 || pDb->xCmp(aKey, nKey, pKey2, nKey2)<0 );
if( flags&SEGMENT_BTREE_FLAG ){
assertBtreeRanges(pDb, pRun, iPtr, aPrev, nPrev, aKey, nKey);
}
aPrev = aKey;
nPrev = nKey;
}
if( flags&SEGMENT_BTREE_FLAG ){
int iRight = pageGetPtr(aData, nData);
assertBtreeRanges(pDb, pRun, iRight, aPrev, nPrev, 0, 0);
}
lsmFsPageRelease(pPg);
sortedBlobFree(&blob);
}
/*
** Check that the array pOne contains the required pointers to pTwo.
** Array pTwo must be a main array. pOne may be either a separators array
** or another main array.
**
** If an error is encountered, *pzErr is set to point to a buffer containing
** a nul-terminated error message and this function returns immediately. The
** caller should eventually call lsmFree(*pzErr) to free the allocated
** error message buffer.
*/
static void assertPointersOk(
lsm_db *pDb, /* Database handle */
SortedRun *pOne, /* Run containing pointers */
SortedRun *pTwo, /* Run containing pointer targets */
int bRhs, /* True if pTwo may have been Gobble()d */
char **pzErr
){
int rc = LSM_OK; /* Error code */
SegmentPtr ptr1; /* Iterates through pOne */
SegmentPtr ptr2; /* Iterates through pTwo */
Pgno iPrev;
assert( pOne && pTwo );
memset(&ptr1, 0, sizeof(ptr1));
memset(&ptr2, 0, sizeof(ptr1));
ptr1.pRun = pOne;
ptr2.pRun = pTwo;
segmentPtrEndPage(pDb->pFS, &ptr1, 0, &rc);
segmentPtrEndPage(pDb->pFS, &ptr2, 0, &rc);
/* Check that the footer pointer of the first page of pOne points to
** the first page of pTwo. */
iPrev = pTwo->iFirst;
if( ptr1.iPtr!=iPrev && !bRhs ){
assert( 0 );
}
if( rc==LSM_OK && ptr1.nCell>0 ){
rc = segmentPtrLoadCell(&ptr1, 0);
}
while( rc==LSM_OK && ptr2.pPg ){
Pgno iThis;
/* Advance to the next page of segment pTwo that contains at least
** one cell. Break out of the loop if the iterator reaches EOF. */
do{
rc = segmentPtrNextPage(&ptr2, 1);
assert( rc==LSM_OK );
}while( rc==LSM_OK && ptr2.pPg && ptr2.nCell==0 );
if( rc!=LSM_OK || ptr2.pPg==0 ) break;
iThis = lsmFsPageNumber(ptr2.pPg);
if( (ptr2.flags & PGFTR_SKIP_THIS_FLAG)==0 ){
/* Load the first cell in the array pTwo page. */
rc = segmentPtrLoadCell(&ptr2, 0);
/* Iterate forwards through pOne, searching for a key that matches the
** key ptr2.pKey/nKey. This key should have a pointer to the page that
** ptr2 currently points to. */
while( rc==LSM_OK ){
int res = rtTopic(ptr1.eType) - rtTopic(ptr2.eType);
if( res==0 ){
res = pDb->xCmp(ptr1.pKey, ptr1.nKey, ptr2.pKey, ptr2.nKey);
}
if( res<0 ){
assert( bRhs || ptr1.iPtr+ptr1.iPgPtr==iPrev );
}else if( res>0 ){
assert( 0 );
}else{
assert( ptr1.iPtr+ptr1.iPgPtr==iThis );
iPrev = lsmFsPageNumber(ptr2.pPg);
break;
}
rc = segmentPtrAdvance(0, &ptr1, 0);
if( ptr1.pPg==0 ){
assert( 0 );
}
}
}
}
segmentPtrReset(&ptr1);
segmentPtrReset(&ptr2);
}
static int countBtreeKeys(FileSystem *pFS, SortedRun *pRun, Pgno iPg){
#if 0
int rc;
Page *pPg;
u8 *aData;
int nData;
int flags;
int nRet;
rc = lsmFsDbPageGet(pFs, iPg, &pPg);
assert( rc==LSM_OK );
aData = lsmFsPageData(pPg, &nData);
flags = pageGetFlags(aData, nData);
if( flags & SEGMENT_BTREE_FLAG ){
Pgno iRight;
int nRec;
int i;
iRight = pageGetPtr(aData, nData);
nRec = pageGetNRec(aData, nData);
nRet = nRec;
nRet += countBtreeKeys(pFS, pRun, iRight);
for(i=0; i<nRec; i++){
Pgno iPtr;
u8 *aCell = pageGetCell(aData, nData, i);
aCell += lsmVarintGet32(aCell, &iPtr);
if( iPtr==0 ){
lsmVarintGet32(aCell, &iPtr);
}
nRet += countBtreeKeys(pFS, pRun, iPtr);
}
}else{
nRet = 0;
}
lsmFsPageRelease(pPg);
return nRet;
#endif
return 0;
}
static void assertBtreeSize(FileSystem *pFS, SortedRun *pRun, Pgno iRoot){
#if 0
int nRun = 0;
int nKey = 0;
int rc;
Page *pPg;
rc = lsmFsDbPageGet(pFS, pRun->iFirst, &pPg);
assert( rc==LSM_OK );
while( pPg ){
Page *pNext = 0;
u8 *aData;
int nData;
int flags;
int nRec;
aData = lsmFsPageData(pPg, &nData);
flags = pageGetFlags(aData, nData);
nRec = pageGetNRec(aData, nData);
if( (flags & SEGMENT_BTREE_FLAG)==0 && nRec ){
nRun++;
}
rc = lsmFsDbPageNext(pPg, 1, &pNext);
assert( rc==LSM_OK );
lsmFsPageRelease(pPg);
pPg = pNext;
}
nKey = countBtreeKeys(pFS, pRun, iRoot);
assert( nRun==1+nKey );
#endif
}
static void assertAllBtreesOk(int rc, lsm_db *pDb){
#if 0
if( rc==LSM_OK ){
Level *p;
for(p=pDb->pLevel; p; p=p->pNext){
SortedRun *pSep = p->lhs.pSep;
Pgno iRoot = pSep->iRoot;
if( pSep && iRoot ){
assertBtreeRanges(pDb, pSep, iRoot, 0, 0, 0, 0);
assertBtreeSize(pDb->pFS, pSep, iRoot);
}
}
}
#endif
}
/*
** This function is only useful for debugging.
*/
static void assertAllPointersOk(int rc, lsm_db *pDb){
assert( rc!=LSM_OK || pDb->pWorker );
if( rc==LSM_OK ){
Level *p;
for(p=lsmDbSnapshotLevel(pDb->pWorker); p; p=p->pNext){
int i;
if( segmentHasSeparators(&p->lhs) ){
assertPointersOk(pDb, &p->lhs.sep, &p->lhs.run, 0, 0);
}
for(i=0; i<p->nRight; i++){
if( segmentHasSeparators(&p->aRhs[i]) ){
assertPointersOk(pDb, &p->aRhs[i].sep, &p->aRhs[i].run, 1, 0);
}
}
}
}
}
#endif /* ifdef LSM_DEBUG_EXPENSIVE */
/************** End of lsm_sorted.c ******************************************/
/************** Begin file lsm_str.c *****************************************/
/*
** 2012-04-27
**
** 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.
**
*************************************************************************
**
** Dynamic string functions.
*/
/*
** Turn bulk and uninitialized memory into an LsmString object
*/
void lsmStringInit(LsmString *pStr, lsm_env *pEnv){
memset(pStr, 0, sizeof(pStr[0]));
pStr->pEnv = pEnv;
}
/*
** Increase the memory allocated for holding the string. Realloc as needed.
**
** If a memory allocation error occurs, set pStr->n to -1 and free the existing
** allocation. If a prior memory allocation has occurred, this routine is a
** no-op.
*/
int lsmStringExtend(LsmString *pStr, int nNew){
assert( nNew>0 );
if( pStr->n<0 ) return LSM_NOMEM;
if( pStr->n + nNew >= pStr->nAlloc ){
int nAlloc = pStr->n + nNew + 100;
char *zNew = lsmRealloc(pStr->pEnv, pStr->z, nAlloc);
if( zNew==0 ){
lsmFree(pStr->pEnv, pStr->z);
nAlloc = 0;
pStr->n = -1;
pStr->z = 0;
}else{
pStr->nAlloc = nAlloc;
pStr->z = zNew;
}
}
return (pStr->z ? LSM_OK : LSM_NOMEM_BKPT);
}
/*
** Clear an LsmString object, releasing any allocated memory that it holds.
** This also clears the error indication (if any).
*/
void lsmStringClear(LsmString *pStr){
lsmFree(pStr->pEnv, pStr->z);
lsmStringInit(pStr, pStr->pEnv);
}
/*
** Append N bytes of text to the end of an LsmString object. If
** N is negative, append the entire string.
**
** If the string is in an error state, this routine is a no-op.
*/
int lsmStringAppend(LsmString *pStr, const char *z, int N){
int rc;
if( N<0 ) N = (int)strlen(z);
rc = lsmStringExtend(pStr, N+1);
if( pStr->nAlloc ){
memcpy(pStr->z+pStr->n, z, N+1);
pStr->n += N;
}
return rc;
}
int lsmStringBinAppend(LsmString *pStr, const u8 *a, int n){
int rc;
rc = lsmStringExtend(pStr, n);
if( pStr->nAlloc ){
memcpy(pStr->z+pStr->n, a, n);
pStr->n += n;
}
return rc;
}
/*
** Append printf-formatted content to an LsmString.
*/
void lsmStringVAppendf(
LsmString *pStr,
const char *zFormat,
va_list ap1,
va_list ap2
){
int nWrite;
int nAvail;
nAvail = pStr->nAlloc - pStr->n;
nWrite = vsnprintf(pStr->z + pStr->n, nAvail, zFormat, ap1);
if( nWrite>=nAvail ){
lsmStringExtend(pStr, nWrite+1);
if( pStr->nAlloc==0 ) return;
nWrite = vsnprintf(pStr->z + pStr->n, nWrite+1, zFormat, ap2);
}
pStr->n += nWrite;
pStr->z[pStr->n] = 0;
}
void lsmStringAppendf(LsmString *pStr, const char *zFormat, ...){
va_list ap, ap2;
va_start(ap, zFormat);
va_start(ap2, zFormat);
lsmStringVAppendf(pStr, zFormat, ap, ap2);
va_end(ap);
va_end(ap2);
}
/*
** Write into memory obtained from lsm_malloc().
*/
char *lsmMallocPrintf(lsm_env *pEnv, const char *zFormat, ...){
LsmString s;
va_list ap, ap2;
lsmStringInit(&s, pEnv);
va_start(ap, zFormat);
va_start(ap2, zFormat);
lsmStringVAppendf(&s, zFormat, ap, ap2);
va_end(ap);
va_end(ap2);
if( s.n<0 ) return 0;
return (char *)lsmReallocOrFree(pEnv, s.z, s.n+1);
}
/************** End of lsm_str.c *********************************************/
/************** Begin file lsm_tree.c ****************************************/
/*
** 2011-08-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 the implementation of an in-memory tree structure.
**
** Technically the tree is a B-tree of order 4 (in the Knuth sense - each
** node may have up to 4 children). Keys are stored within B-tree nodes by
** reference. This may be slightly slower than a conventional red-black
** tree, but it is simpler. It is also an easier structure to modify to
** create a version that supports nested transaction rollback.
**
** This tree does not currently support a delete operation. One is not
** required. When LSM deletes a key from a database, it inserts a DELETE
** marker into the data structure. As a result, although the value associated
** with a key stored in the in-memory tree structure may be modified, no
** keys are ever removed.
*/
/*
** MVCC NOTES
**
** The in-memory tree structure supports SQLite-style MVCC. This means
** that while one client is writing to the tree structure, other clients
** may still be querying an older snapshot of the tree.
**
** One way to implement this is to use an append-only b-tree. In this
** case instead of modifying nodes in-place, a copy of the node is made
** and the required modifications made to the copy. The parent of the
** node is then modified (to update the pointer so that it points to
** the new copy), which causes a copy of the parent to be made, and so on.
** This means that each time the tree is written to a new root node is
** created. A snapshot is identified by the root node that it uses.
**
** The problem with the above is that each time the tree is written to,
** a copy of the node structure modified and all of its ancestor nodes
** is made. This may prove excessive with large tree structures.
**
** To reduce this overhead, the data structure used for a tree node is
** designed so that it may be edited in place exactly once without
** affecting existing users. In other words, the node structure is capable
** of storing two separate versions of the node at the same time.
** When a node is to be edited, if the node structure already contains
** two versions, a copy is made as in the append-only approach. Or, if
** it only contains a single version, it may be edited in place.
**
** This reduces the overhead so that, roughly, one new node structure
** must be allocated for each write (on top of those allocations that
** would have been required by a non-MVCC tree). Logic: Assume that at
** any time, 50% of nodes in the tree already contain 2 versions. When
** a new entry is written to a node, there is a 50% chance that a copy
** of the node will be required. And a 25% chance that a copy of its
** parent is required. And so on.
**
** ROLLBACK
**
** The in-memory tree also supports transaction and sub-transaction
** rollback. In order to rollback to point in time X, the following is
** necessary:
**
** 1. All memory allocated since X must be freed, and
** 2. All "v2" data adding to nodes that existed at X should be zeroed.
** 3. The root node must be restored to its X value.
**
** The Mempool object used to allocate memory for the tree supports
** operation (1) - see the lsmPoolMark() and lsmPoolRevert() functions.
**
** To support (2), all nodes that have v2 data are part of a singly linked
** list, sorted by the age of the v2 data (nodes that have had data added
** most recently are at the end of the list). So to zero all v2 data added
** since X, the linked list is traversed from the first node added following
** X onwards.
**
*/
#ifndef _LSM_INT_H
#endif
/* #include <string.h> */
#define MAX_DEPTH 32
typedef struct TreeKey TreeKey;
typedef struct TreeNode TreeNode;
typedef struct TreeLeaf TreeLeaf;
typedef struct NodeVersion NodeVersion;
/*
** Container for a key-value pair.
*/
struct TreeKey {
void *pKey; /* Pointer to key */
void *pValue; /* Pointer to value. May be NULL. */
int nKey; /* Size of pKey in bytes */
int nValue; /* Size of pValue. Or negative. */
};
/*
** A single tree node. A node structure may contain up to 3 key/value
** pairs. Internal (non-leaf) nodes have up to 4 children.
**
** TODO: Update the format of this to be more compact. Get it working
** first though...
*/
struct TreeNode {
TreeKey *apKey[3]; /* Array of pointers to key-value pairs */
/* The following fields are present for interior nodes only, not leaves. */
TreeNode *apChild[4]; /* Array of pointers to child nodes */
int iV2; /* Version number of v2 */
u8 iV2Ptr; /* apChild[] entry replaced by pV2Ptr */
TreeNode *pV2Ptr; /* Substitute pointer */
TreeNode *pNext; /* Next in interior node rollback list */
};
struct TreeLeaf {
TreeKey *apKey[3]; /* Array of pointers to key-value pairs */
};
/*
** A handle used by a client to access a Tree structure.
*/
struct TreeVersion {
Tree *pTree; /* The tree structure to which this belongs */
int nRef; /* Number of pointers to this */
TreeNode *pRoot; /* Pointer to root of tree structure */
int nHeight; /* Current height of tree pRoot */
int iVersion; /* Current version */
};
#define WORKING_VERSION (1<<30)
/*
** A tree structure.
**
** iVersion:
** When the tree is first created, this is set to 1. Thereafter it is
** incremented each time lsmTreeMark() is called. The tree must be
** destroyed (i.e. flushed to disk) before it wraps around (todo!).
**
** When v2 data is written to a tree-node, the iV2 field of the node
** is set to the current value of Tree.iVersion.
**
** nRef:
** Number of references to this tree structure. When it is first created,
** (in lsmTreeNew()) nRef is set to 1. There after the ref-count may be
** incremented and decremented using treeIncrRefcount() and
** DecrRefcount(). When the ref-count of a tree structure reaches zero
** it is freed.
**
** xCmp:
** Pointer to the compare function. This is a copy of some pDb->xCmp.
**
*/
struct Tree {
int nTreeRef; /* Current number of pointers to this */
Mempool *pPool; /* Memory pool to allocate from */
int (*xCmp)(void *, int, void *, int); /* Compare function */
TreeVersion *pCommit; /* Committed version of tree (for readers) */
TreeVersion *pWorking; /* Working verson (for writers) */
#if 0
TreeVersion tvWorking; /* Working verson (for writers) */
#endif
TreeNode *pRbFirst;
TreeNode *pRbLast;
};
/*
** The pointer passed as the first argument points to an interior node,
** not a leaf. This function returns the value of the iCell'th child
** sub-tree of the node.
*/
static TreeNode *getChildPtr(TreeNode *p, int iVersion, int iCell){
if( p->iV2 && p->iV2<=iVersion && iCell==p->iV2Ptr ) return p->pV2Ptr;
return p->apChild[iCell];
}
/*
** Cursor for searching a tree structure.
**
** If a cursor does not point to any element (a.k.a. EOF), then the
** TreeCursor.iNode variable is set to a negative value. Otherwise, the
** cursor currently points to key aiCell[iNode] on node apTreeNode[iNode].
**
** Entries in the apTreeNode[] and aiCell[] arrays contain the node and
** index of the TreeNode.apChild[] pointer followed to descend to the
** current element. Hence apTreeNode[0] always contains the root node of
** the tree.
*/
struct TreeCursor {
lsm_db *pDb; /* Database handle for this cursor */
int iNode; /* Cursor points at apTreeNode[iNode] */
TreeNode *apTreeNode[MAX_DEPTH];/* Current position in tree */
u8 aiCell[MAX_DEPTH]; /* Current position in tree */
TreeKey *pSave; /* Saved key */
};
#if defined(LSM_DEBUG) && defined(LSM_EXPENSIVE_ASSERT)
void assert_leaf_looks_ok(TreeNode *pNode){
assert( pNode->apKey[1] );
}
void assert_node_looks_ok(TreeNode *pNode, int nHeight){
if( pNode ){
assert( pNode->apKey[1] );
if( nHeight>1 ){
int i;
assert( getChildPtr(pNode, WORKING_VERSION, 1) );
assert( getChildPtr(pNode, WORKING_VERSION, 2) );
for(i=0; i<4; i++){
assert_node_looks_ok(getChildPtr(pNode, WORKING_VERSION, i), nHeight-1);
}
}
}
}
/*
** Run various assert() statements to check that the working-version of the
** tree is correct in the following respects:
**
** * todo...
*/
void assert_tree_looks_ok(int rc, Tree *pTree){
if( rc==LSM_OK ){
TreeVersion *p = pTree->pWorking ? pTree->pWorking : pTree->pCommit;
if( p ){
assert( (p->nHeight==0)==(p->pRoot==0) );
assert_node_looks_ok(p->pRoot, p->nHeight);
}
}
}
#else
# define assert_tree_looks_ok(x,y)
#endif
#ifdef LSM_DEBUG
static void lsmAppendStrBlob(LsmString *pStr, void *pBlob, int nBlob){
int i;
lsmStringExtend(pStr, nBlob);
if( pStr->nAlloc==0 ) return;
for(i=0; i<nBlob; i++){
u8 c = ((u8*)pBlob)[i];
pStr->z[pStr->n++] = "0123456789abcdef"[(c>>4)&0xf];
pStr->z[pStr->n++] = "0123456789abcdef"[c&0xf];
}
pStr->z[pStr->n] = 0;
}
static void lsmAppendIndent(LsmString *pStr, int nIndent){
int i;
lsmStringExtend(pStr, nIndent);
for(i=0; i<nIndent; i++) lsmStringAppend(pStr, " ", 1);
}
static void lsmAppendKeyValue(LsmString *pStr, TreeKey *pKey){
int i;
for(i=0; i<pKey->nKey; i++){
lsmStringAppendf(pStr, "%2X ", ((u8 *)(pKey->pKey))[i]);
}
lsmStringAppend(pStr, " ", -1);
if( pKey->nValue<0 ){
lsmStringAppend(pStr, "<deleted>", -1);
}else{
lsmAppendStrBlob(pStr, pKey->pValue, pKey->nValue);
}
}
void dump_node(TreeNode *pNode, int nIndent, int isNode){
if( pNode ){
LsmString s;
int i;
lsmStringInit(&s, NEED_ENV);
lsmAppendIndent(&s, nIndent);
lsmStringAppendf(&s, "0x%p", (void*)pNode);
printf("%s\n", s.z);
lsmStringClear(&s);
for(i=0; i<4; i++){
if( isNode ){
if( pNode->iV2 && i==pNode->iV2Ptr ){
lsmAppendIndent(&s, nIndent+2);
lsmStringAppendf(&s, "if( version>=%d )", pNode->iV2);
printf("%s\n", s.z);
lsmStringClear(&s);
dump_node(pNode->pV2Ptr, nIndent + 4, isNode-1);
if( pNode->apChild[i] ){
lsmAppendIndent(&s, nIndent+2);
lsmStringAppendf(&s, "else");
printf("%s\n", s.z);
lsmStringClear(&s);
}
}
dump_node(pNode->apChild[i], nIndent + 4, isNode-1);
}
if( i<3 && pNode->apKey[i] ){
lsmAppendIndent(&s, nIndent);
lsmStringAppendf(&s, "k%d: ", i);
lsmAppendKeyValue(&s, pNode->apKey[i]);
printf("%s\n", s.z);
lsmStringClear(&s);
}
}
}
}
void dump_node_contents(TreeNode *pNode, int iVersion, int nIndent, int isNode){
int i;
LsmString s;
lsmStringInit(&s, NEED_ENV);
lsmAppendIndent(&s, nIndent);
for(i=0; i<3; i++){
if( pNode->apKey[i] ){
TreeKey *pKey = pNode->apKey[i];
lsmAppendStrBlob(&s, pKey->pKey, pKey->nKey);
lsmStringAppend(&s, " ", -1);
}
}
printf("%s\n", s.z);
lsmStringClear(&s);
for(i=0; i<4 && isNode>0; i++){
TreeNode *pChild = getChildPtr(pNode, iVersion, i);
if( pChild ){
dump_node_contents(pChild, iVersion, nIndent + 2, isNode-1);
}
}
}
void dump_tree_contents(Tree *pTree, const char *zCaption){
TreeVersion *p = pTree->pWorking ? pTree->pWorking : pTree->pCommit;
printf("\n%s\n", zCaption);
if( p->pRoot ){
dump_node_contents(p->pRoot, WORKING_VERSION, 0, p->nHeight-1);
}
fflush(stdout);
}
void dump_tv_contents(TreeVersion *pTV, const char *zCaption){
printf("\n%s\n", zCaption);
if( pTV->pRoot ){
dump_node(pTV->pRoot, 2, pTV->nHeight-1);
}
fflush(stdout);
}
#endif
/*
** Allocate a new tree structure.
*/
int lsmTreeNew(
lsm_env *pEnv, /* Environment handle */
int (*xCmp)(void *, int, void *, int), /* Compare function */
Tree **ppTree /* OUT: New tree object */
){
int rc;
Tree *pTree = 0;
Mempool *pPool; /* Memory pool used by the new tree */
TreeVersion *pClient = 0; /* Initial client access handle */
rc = lsmPoolNew(pEnv, &pPool);
pClient = (TreeVersion *)lsmMallocZeroRc(pEnv, sizeof(TreeVersion), &rc);
if( rc==LSM_OK ){
pTree = (Tree *)lsmPoolMallocZero(pEnv, pPool, sizeof(Tree));
assert( pTree );
pTree->pPool = pPool;
pTree->xCmp = xCmp;
pTree->nTreeRef = 1;
pClient->iVersion = 1;
pClient->pTree = pTree;
pClient->nRef = 1;
pTree->pCommit = pClient;
}else{
assert( pClient==0 );
lsmPoolDestroy(pEnv, pPool);
}
*ppTree = pTree;
return rc;
}
/*
** Destroy a tree structure allocated by lsmTreeNew().
*/
static void treeDestroy(lsm_env *pEnv, Tree *pTree){
if( pTree ){
assert( pTree->pWorking==0 );
lsmPoolDestroy(pEnv, pTree->pPool);
}
}
/*
** Initialize a cursor object, the space for which has already been
** allocated.
*/
static void treeCursorInit(lsm_db *pDb, TreeCursor *pCsr){
memset(pCsr, 0, sizeof(TreeCursor));
pCsr->pDb = pDb;
pCsr->iNode = -1;
}
static TreeNode *newTreeLeaf(lsm_env *pEnv, Tree *pTree){
return (TreeNode *)lsmPoolMallocZero(pEnv, pTree->pPool, sizeof(TreeLeaf));
}
static TreeNode *newTreeNode(lsm_env *pEnv, Tree *pTree){
return (TreeNode *)lsmPoolMallocZero(pEnv, pTree->pPool, sizeof(TreeNode));
}
static TreeNode *copyTreeNode(lsm_env *pEnv, Tree *pTree, TreeNode *pOld){
TreeNode *pNew;
pNew = (TreeNode *)lsmPoolMallocZero(pEnv, pTree->pPool, sizeof(TreeNode));
memcpy(pNew->apKey, pOld->apKey, sizeof(pNew->apKey));
memcpy(pNew->apChild, pOld->apChild, sizeof(pNew->apChild));
if( pOld->iV2 ) pNew->apChild[pOld->iV2Ptr] = pOld->pV2Ptr;
return pNew;
}
static TreeNode *copyTreeLeaf(lsm_env *pEnv, Tree *pTree, TreeNode *pOld){
TreeNode *pNew;
pNew = newTreeLeaf(pEnv, pTree);
memcpy(pNew, pOld, sizeof(TreeLeaf));
return pNew;
}
/*
** Save the current position of tree cursor pCsr.
*/
void lsmTreeCursorSave(TreeCursor *pCsr){
if( pCsr->pSave==0 ){
int iNode = pCsr->iNode;
if( iNode>=0 ){
pCsr->pSave = pCsr->apTreeNode[iNode]->apKey[pCsr->aiCell[iNode]];
}
pCsr->iNode = -1;
}
}
/*
** Restore the position of a saved tree cursor.
*/
static int treeCursorRestore(TreeCursor *pCsr, int *pRes){
int rc = LSM_OK;
if( pCsr->pSave ){
TreeKey *pKey = pCsr->pSave;
pCsr->pSave = 0;
if( pRes ){
rc = lsmTreeCursorSeek(pCsr, pKey->pKey, pKey->nKey, pRes);
}
}
return rc;
}
/*
** The tree cursor passed as the second argument currently points to an
** internal node (not a leaf). Specifically, to a sub-tree pointer. This
** function replaces the sub-tree that the cursor currently points to
** with sub-tree pNew.
**
** The sub-tree may be replaced either by writing the "v2 data" on the
** internal node, or by allocating a new TreeNode structure and then
** calling this function on the parent of the internal node.
*/
static int treeUpdatePtr(Tree *pTree, TreeCursor *pCsr, TreeNode *pNew){
int rc = LSM_OK;
if( pCsr->iNode<0 ){
/* pNew is the new root node */
pTree->pWorking->pRoot = pNew;
}else{
/* If this node already has version 2 content, allocate a copy and
** update the copy with the new pointer value. Otherwise, store the
** new pointer as v2 data within the current node structure. */
TreeNode *p; /* The node to be modified */
int iChildPtr; /* apChild[] entry to modify */
p = pCsr->apTreeNode[pCsr->iNode];
iChildPtr = pCsr->aiCell[pCsr->iNode];
if( p->iV2 ){
/* The "allocate new TreeNode" option */
TreeNode *pCopy = copyTreeNode(pCsr->pDb->pEnv, pTree, p);
if( pCopy ){
pCopy->apChild[iChildPtr] = pNew;
pCsr->iNode--;
rc = treeUpdatePtr(pTree, pCsr, pCopy);
}else{
rc = LSM_NOMEM_BKPT;
}
}else{
/* The "v2 data" option */
p->iV2 = pTree->pWorking->iVersion;
p->iV2Ptr = (u8)iChildPtr;
p->pV2Ptr = (void *)pNew;
if( pTree->pRbLast ){
pTree->pRbLast->pNext = p;
}else{
pTree->pRbFirst = p;
}
pTree->pRbLast = p;
assert( pTree->pRbLast->pNext==0 );
}
}
return rc;
}
/*
** Cursor pCsr points at a node that is part of pTree. This function
** inserts a new key and optionally child node pointer into that node.
**
** The position into which the new key and pointer are inserted is
** determined by the iSlot parameter. The new key will be inserted to
** the left of the key currently stored in apKey[iSlot]. Or, if iSlot is
** greater than the index of the rightmost key in the node.
**
** Pointer pLeftPtr points to a child tree that contains keys that are
** smaller than pTreeKey.
*/
static int treeInsert(
lsm_env *pEnv,
Tree *pTree,
TreeCursor *pCsr, /* Cursor indicating path to insert at */
TreeNode *pLeftPtr, /* New child pointer (or NULL for leaves) */
TreeKey *pTreeKey, /* New key to insert */
TreeNode *pRightPtr, /* New child pointer (or NULL for leaves) */
int iSlot /* Position to insert key into */
){
int rc = LSM_OK;
TreeNode *pNode = pCsr->apTreeNode[pCsr->iNode];
/* Check if the leaf is currently full. If so, allocate a sibling node. */
if( pNode->apKey[0] && pNode->apKey[2] ){
TreeNode *pLeft; /* New sibling node. */
TreeNode *pRight; /* Sibling of pLeft (either new or pNode) */
pLeft = newTreeNode(pEnv, pTree);
pRight = newTreeNode(pEnv, pTree);
if( pCsr->iNode==0 ){
/* pNode is the root of the tree. Grow the tree by one level. */
TreeNode *pRoot; /* New root node */
pRoot = newTreeNode(pEnv, pTree);
pLeft->apChild[1] = getChildPtr(pNode, WORKING_VERSION, 0);
pLeft->apKey[1] = pNode->apKey[0];
pLeft->apChild[2] = getChildPtr(pNode, WORKING_VERSION, 1);
pRight->apChild[1] = getChildPtr(pNode, WORKING_VERSION, 2);
pRight->apKey[1] = pNode->apKey[2];
pRight->apChild[2] = getChildPtr(pNode, WORKING_VERSION, 3);
pRoot->apKey[1] = pNode->apKey[1];
pRoot->apChild[1] = pLeft;
pRoot->apChild[2] = pRight;
pTree->pWorking->pRoot = pRoot;
pTree->pWorking->nHeight++;
}else{
TreeKey *pParentKey; /* Key to insert into parent node */
pParentKey = pNode->apKey[1];
pLeft->apChild[1] = getChildPtr(pNode, WORKING_VERSION, 0);
pLeft->apKey[1] = pNode->apKey[0];
pLeft->apChild[2] = getChildPtr(pNode, WORKING_VERSION, 1);
pRight->apChild[1] = getChildPtr(pNode, WORKING_VERSION, 2);
pRight->apKey[1] = pNode->apKey[2];
pRight->apChild[2] = getChildPtr(pNode, WORKING_VERSION, 3);
pCsr->iNode--;
treeInsert(pEnv,
pTree, pCsr, pLeft, pParentKey, pRight, pCsr->aiCell[pCsr->iNode]
);
}
assert( pLeft->iV2==0 );
assert( pRight->iV2==0 );
switch( iSlot ){
case 0:
pLeft->apKey[0] = pTreeKey;
pLeft->apChild[0] = pLeftPtr;
if( pRightPtr ) pLeft->apChild[1] = pRightPtr;
break;
case 1:
pLeft->apChild[3] = (pRightPtr ? pRightPtr : pLeft->apChild[2]);
pLeft->apKey[2] = pTreeKey;
pLeft->apChild[2] = pLeftPtr;
break;
case 2:
pRight->apKey[0] = pTreeKey;
pRight->apChild[0] = pLeftPtr;
if( pRightPtr ) pRight->apChild[1] = pRightPtr;
break;
case 3:
pRight->apChild[3] = (pRightPtr ? pRightPtr : pRight->apChild[2]);
pRight->apKey[2] = pTreeKey;
pRight->apChild[2] = pLeftPtr;
break;
}
}else{
TreeNode *pNew;
TreeKey **pOut;
TreeNode **pPtr;
int i;
pNew = newTreeNode(pEnv, pTree);
if( pNew ){
TreeNode *pStore = 0;
pOut = pNew->apKey;
pPtr = pNew->apChild;
for(i=0; i<iSlot; i++){
if( pNode->apKey[i] ){
*(pOut++) = pNode->apKey[i];
*(pPtr++) = getChildPtr(pNode, WORKING_VERSION, i);
}
}
*pOut++ = pTreeKey;
*pPtr++ = pLeftPtr;
pStore = pRightPtr;
for(i=iSlot; i<3; i++){
if( pNode->apKey[i] ){
*(pOut++) = pNode->apKey[i];
*(pPtr++) = pStore ? pStore : getChildPtr(pNode, WORKING_VERSION, i);
pStore = 0;
}
}
if( pStore ){
*pPtr = pStore;
}else{
*pPtr = getChildPtr(pNode, WORKING_VERSION, (pNode->apKey[2] ? 3 : 2));
}
pCsr->iNode--;
rc = treeUpdatePtr(pTree, pCsr, pNew);
}else{
rc = LSM_NOMEM_BKPT;
}
}
return rc;
}
static int treeInsertLeaf(
lsm_env *pEnv,
Tree *pTree, /* Tree structure */
TreeCursor *pCsr, /* Cursor structure */
TreeKey *pTreeKey, /* Key to insert */
int iSlot /* Insert key to the left of this */
){
int rc; /* Return code */
TreeNode *pLeaf = pCsr->apTreeNode[pCsr->iNode];
TreeNode *pNew;
assert( iSlot>=0 && iSlot<=4 );
assert( pCsr->iNode>0 );
assert( pLeaf->apKey[1] );
pCsr->iNode--;
pNew = newTreeLeaf(pEnv, pTree);
if( !pNew ){
rc = LSM_NOMEM_BKPT;
}else if( pLeaf->apKey[0] && pLeaf->apKey[2] ){
TreeNode *pRight;
pRight = newTreeLeaf(pEnv, pTree);
if( pRight==0 ){
rc = LSM_NOMEM_BKPT;
}else{
pNew->apKey[1] = pLeaf->apKey[0];
pRight->apKey[1] = pLeaf->apKey[2];
switch( iSlot ){
case 0: pNew->apKey[0] = pTreeKey; break;
case 1: pNew->apKey[2] = pTreeKey; break;
case 2: pRight->apKey[0] = pTreeKey; break;
case 3: pRight->apKey[2] = pTreeKey; break;
}
rc = treeInsert(pEnv, pTree, pCsr, pNew, pLeaf->apKey[1], pRight,
pCsr->aiCell[pCsr->iNode]
);
}
}else{
int iOut = 0;
int i;
for(i=0; i<4; i++){
if( i==iSlot ) pNew->apKey[iOut++] = pTreeKey;
if( i<3 && pLeaf->apKey[i] ) pNew->apKey[iOut++] = pLeaf->apKey[i];
}
rc = treeUpdatePtr(pTree, pCsr, pNew);
}
return rc;
}
/*
** Insert a new entry into the in-memory tree.
**
** If the value of the 5th parameter, nVal, is negative, then a delete-marker
** is inserted into the tree. In this case the value pointer, pVal, must be
** NULL.
*/
int lsmTreeInsert(
lsm_db *pDb, /* Database handle */
void *pKey, /* Pointer to key data */
int nKey, /* Size of key data in bytes */
void *pVal, /* Pointer to value data (or NULL) */
int nVal /* Bytes in value data (or -ve for delete) */
){
lsm_env *pEnv = pDb->pEnv;
TreeVersion *pTV = pDb->pTV;
Tree *pTree = pTV->pTree;
int rc = LSM_OK; /* Return Code */
TreeKey *pTreeKey; /* New key-value being inserted */
int nTreeKey; /* Number of bytes allocated at pTreeKey */
assert( nVal>=0 || pVal==0 );
assert( pTV==pTree->pWorking );
assert_tree_looks_ok(LSM_OK, pTree);
/* dump_tree_contents(pTree, "before"); */
/* Allocate and populate a new key-value pair structure */
nTreeKey = sizeof(TreeKey) + nKey + (nVal>0 ? nVal : 0);
pTreeKey = (TreeKey *)lsmPoolMalloc(pDb->pEnv, pTree->pPool, nTreeKey);
if( !pTreeKey ) return LSM_NOMEM_BKPT;
pTreeKey->pKey = (void *)&pTreeKey[1];
memcpy(pTreeKey->pKey, pKey, nKey);
if( nVal>0 ){
pTreeKey->pValue = (void *)&((u8 *)(pTreeKey->pKey))[nKey];
memcpy(pTreeKey->pValue, pVal, nVal);
}else{
pTreeKey->pValue = 0;
}
pTreeKey->nValue = nVal;
pTreeKey->nKey = nKey;
if( pTree->pWorking->pRoot==0 ){
/* The tree is completely empty. Add a new root node and install
** (pKey/nKey) as the middle entry. Even though it is a leaf at the
** moment, use newTreeNode() to allocate the node (i.e. allocate enough
** space for the fields used by interior nodes). This is because the
** treeInsert() routine may convert this node to an interior node.
*/
TreeNode *pRoot; /* New tree root node */
pRoot = newTreeNode(pEnv, pTree);
if( !pRoot ){
rc = LSM_NOMEM_BKPT;
}else{
pRoot->apKey[1] = pTreeKey;
pTree->pWorking->pRoot = pRoot;
assert( pTree->pWorking->nHeight==0 );
pTree->pWorking->nHeight = 1;
}
}else{
TreeCursor csr;
int res;
/* Seek to the leaf (or internal node) that the new key belongs on */
treeCursorInit(pDb, &csr);
lsmTreeCursorSeek(&csr, pKey, nKey, &res);
if( res==0 ){
/* The search found a match within the tree. */
TreeNode *pNew;
TreeNode *pNode = csr.apTreeNode[csr.iNode];
int iCell = csr.aiCell[csr.iNode];
/* Create a copy of this node */
if( (csr.iNode>0 && csr.iNode==(pTree->pWorking->nHeight-1)) ){
pNew = copyTreeLeaf(pEnv, pTree, pNode);
}else{
pNew = copyTreeNode(pEnv, pTree, pNode);
}
/* Modify the value in the new version */
pNew->apKey[iCell] = pTreeKey;
/* Change the pointer in the parent (if any) to point at the new
** TreeNode */
csr.iNode--;
treeUpdatePtr(pTree, &csr, pNew);
}else{
/* The cursor now points to the leaf node into which the new entry should
** be inserted. There may or may not be a free slot within the leaf for
** the new key-value pair.
**
** iSlot is set to the index of the key within pLeaf that the new key
** should be inserted to the left of (or to a value 1 greater than the
** index of the rightmost key if the new key is larger than all keys
** currently stored in the node).
*/
int iSlot = csr.aiCell[csr.iNode] + (res<0);
if( csr.iNode==0 ){
rc = treeInsert(pEnv, pTree, &csr, 0, pTreeKey, 0, iSlot);
}else{
rc = treeInsertLeaf(pEnv, pTree, &csr, pTreeKey, iSlot);
}
}
}
/* dump_tree_contents(pTree, "after"); */
assert_tree_looks_ok(rc, pTree);
return rc;
}
/*
** Return, in bytes, the amount of memory currently used by the tree
** structure.
*/
int lsmTreeSize(TreeVersion *pTV){
return (lsmPoolUsed(pTV->pTree->pPool) - ROUND8(sizeof(Tree)));
}
/*
** Return true if the tree is empty. Otherwise false.
**
** The caller is responsible for ensuring that it has exclusive access
** to the Tree structure for this call.
*/
int lsmTreeIsEmpty(Tree *pTree){
assert( pTree==0 || pTree->pWorking==0 );
return (pTree==0 || pTree->pCommit->pRoot==0);
}
/*
** Open a cursor on the in-memory tree pTree.
*/
int lsmTreeCursorNew(lsm_db *pDb, TreeCursor **ppCsr){
TreeCursor *pCsr;
*ppCsr = pCsr = lsmMalloc(pDb->pEnv, sizeof(TreeCursor));
if( pCsr ){
treeCursorInit(pDb, pCsr);
return LSM_OK;
}
return LSM_NOMEM_BKPT;
}
/*
** Close an in-memory tree cursor.
*/
void lsmTreeCursorDestroy(TreeCursor *pCsr){
if( pCsr ){
lsmFree(pCsr->pDb->pEnv, pCsr);
}
}
void lsmTreeCursorReset(TreeCursor *pCsr){
pCsr->iNode = -1;
pCsr->pSave = 0;
}
#ifndef NDEBUG
static int treeCsrCompare(TreeCursor *pCsr, void *pKey, int nKey){
TreeKey *p;
int cmp;
assert( pCsr->iNode>=0 );
p = pCsr->apTreeNode[pCsr->iNode]->apKey[pCsr->aiCell[pCsr->iNode]];
cmp = memcmp(p->pKey, pKey, LSM_MIN(p->nKey, nKey));
if( cmp==0 ){
cmp = p->nKey - nKey;
}
return cmp;
}
#endif
/*
** Attempt to seek the cursor passed as the first argument to key (pKey/nKey)
** in the tree structure. If an exact match for the key is found, leave the
** cursor pointing to it and set *pRes to zero before returning. If an
** exact match cannot be found, do one of the following:
**
** * Leave the cursor pointing to the smallest element in the tree that
** is larger than the key and set *pRes to +1, or
**
** * Leave the cursor pointing to the largest element in the tree that
** is smaller than the key and set *pRes to -1, or
**
** * If the tree is empty, leave the cursor at EOF and set *pRes to -1.
*/
int lsmTreeCursorSeek(TreeCursor *pCsr, void *pKey, int nKey, int *pRes){
TreeVersion *p = pCsr->pDb->pTV;
int (*xCmp)(void *, int, void *, int) = p->pTree->xCmp;
TreeNode *pNode = p->pRoot; /* Current node in search */
/* Discard any saved position data */
treeCursorRestore(pCsr, 0);
if( pNode==0 ){
/* A special case - the tree is completely empty. */
*pRes = -1;
pCsr->iNode = -1;
}else{
int res = 0; /* Result of comparison function */
int iNode = -1;
while( pNode ){
int iTest; /* Index of second key to test (0 or 2) */
TreeKey *pTreeKey; /* Key to compare against */
iNode++;
pCsr->apTreeNode[iNode] = pNode;
/* Compare (pKey/nKey) with the key in the middle slot of B-tree node
** pNode. The middle slot is never empty. If the comparison is a match,
** then the search is finished. Break out of the loop. */
pTreeKey = pNode->apKey[1];
res = xCmp(pTreeKey->pKey, pTreeKey->nKey, pKey, nKey);
if( res==0 ){
pCsr->aiCell[iNode] = 1;
break;
}
/* Based on the results of the previous comparison, compare (pKey/nKey)
** to either the left or right key of the B-tree node, if such a key
** exists. */
iTest = (res>0 ? 0 : 2);
pTreeKey = pNode->apKey[iTest];
if( pTreeKey==0 ){
iTest = 1;
}else{
res = xCmp(pTreeKey->pKey, pTreeKey->nKey, pKey, nKey);
if( res==0 ){
pCsr->aiCell[iNode] = iTest;
break;
}
}
if( iNode<(p->nHeight-1) ){
pNode = getChildPtr(pNode, p->iVersion, iTest + (res<0));
}else{
pNode = 0;
}
pCsr->aiCell[iNode] = iTest + (pNode && (res<0));
}
*pRes = res;
pCsr->iNode = iNode;
}
/* assert() that *pRes has been set properly */
#ifndef NDEBUG
if( lsmTreeCursorValid(pCsr) ){
int cmp = treeCsrCompare(pCsr, pKey, nKey);
assert( *pRes==cmp || (*pRes ^ cmp)>0 );
}
#endif
return LSM_OK;
}
int lsmTreeCursorNext(TreeCursor *pCsr){
#ifndef NDEBUG
TreeKey *pK1;
#endif
TreeVersion *p = pCsr->pDb->pTV;
const int iLeaf = p->nHeight-1;
int iCell;
TreeNode *pNode;
/* Restore the cursor position, if required */
int iRestore = 0;
treeCursorRestore(pCsr, &iRestore);
if( iRestore>0 ) return LSM_OK;
/* Save a pointer to the current key. This is used in an assert() at the
** end of this function - to check that the 'next' key really is larger
** than the current key. */
#ifndef NDEBUG
pK1 = pCsr->apTreeNode[pCsr->iNode]->apKey[pCsr->aiCell[pCsr->iNode]];
#endif
assert( lsmTreeCursorValid(pCsr) );
assert( pCsr->aiCell[pCsr->iNode]<3 );
pNode = pCsr->apTreeNode[pCsr->iNode];
iCell = ++pCsr->aiCell[pCsr->iNode];
/* If the current node is not a leaf, and the current cell has sub-tree
** associated with it, descend to the left-most key on the left-most
** leaf of the sub-tree. */
if( pCsr->iNode<iLeaf && getChildPtr(pNode, p->iVersion, iCell) ){
do {
pCsr->iNode++;
pNode = getChildPtr(pNode, p->iVersion, iCell);
pCsr->apTreeNode[pCsr->iNode] = pNode;
iCell = pCsr->aiCell[pCsr->iNode] = (pNode->apKey[0]==0);
}while( pCsr->iNode < iLeaf );
}
/* Otherwise, the next key is found by following pointer up the tree
** until there is a key immediately to the right of the pointer followed
** to reach the sub-tree containing the current key. */
else if( iCell>=3 || pNode->apKey[iCell]==0 ){
while( (--pCsr->iNode)>=0 ){
iCell = pCsr->aiCell[pCsr->iNode];
if( iCell<3 && pCsr->apTreeNode[pCsr->iNode]->apKey[iCell] ) break;
}
}
#ifndef NDEBUG
if( pCsr->iNode>=0 ){
TreeKey *pK2;
int (*xCmp)(void *, int, void *, int) = pCsr->pDb->xCmp;
pK2 = pCsr->apTreeNode[pCsr->iNode]->apKey[pCsr->aiCell[pCsr->iNode]];
assert( xCmp(pK2->pKey, pK2->nKey, pK1->pKey, pK1->nKey)>0 );
}
#endif
return LSM_OK;
}
int lsmTreeCursorPrev(TreeCursor *pCsr){
#ifndef NDEBUG
TreeKey *pK1;
#endif
TreeVersion *p = pCsr->pDb->pTV;
const int iLeaf = p->nHeight-1;
int iCell;
TreeNode *pNode;
/* Restore the cursor position, if required */
int iRestore = 0;
treeCursorRestore(pCsr, &iRestore);
if( iRestore<0 ) return LSM_OK;
/* Save a pointer to the current key. This is used in an assert() at the
** end of this function - to check that the 'next' key really is smaller
** than the current key. */
#ifndef NDEBUG
pK1 = pCsr->apTreeNode[pCsr->iNode]->apKey[pCsr->aiCell[pCsr->iNode]];
#endif
assert( lsmTreeCursorValid(pCsr) );
pNode = pCsr->apTreeNode[pCsr->iNode];
iCell = pCsr->aiCell[pCsr->iNode];
assert( iCell>=0 && iCell<3 );
/* If the current node is not a leaf, and the current cell has sub-tree
** associated with it, descend to the right-most key on the right-most
** leaf of the sub-tree. */
if( pCsr->iNode<iLeaf && getChildPtr(pNode, p->iVersion, iCell) ){
do {
pCsr->iNode++;
pNode = getChildPtr(pNode, p->iVersion, iCell);
pCsr->apTreeNode[pCsr->iNode] = pNode;
iCell = 1 + (pNode->apKey[2]!=0) + (pCsr->iNode < iLeaf);
pCsr->aiCell[pCsr->iNode] = iCell;
}while( pCsr->iNode < iLeaf );
}
/* Otherwise, the next key is found by following pointer up the tree until
** there is a key immediately to the left of the pointer followed to reach
** the sub-tree containing the current key. */
else{
do {
iCell = pCsr->aiCell[pCsr->iNode]-1;
if( iCell>=0 && pCsr->apTreeNode[pCsr->iNode]->apKey[iCell] ) break;
}while( (--pCsr->iNode)>=0 );
pCsr->aiCell[pCsr->iNode] = iCell;
}
#ifndef NDEBUG
if( pCsr->iNode>=0 ){
TreeKey *pK2;
int (*xCmp)(void *, int, void *, int) = pCsr->pDb->xCmp;
pK2 = pCsr->apTreeNode[pCsr->iNode]->apKey[pCsr->aiCell[pCsr->iNode]];
assert( xCmp(pK2->pKey, pK2->nKey, pK1->pKey, pK1->nKey)<0 );
}
#endif
return LSM_OK;
}
/*
** Move the cursor to the first (bLast==0) or last (bLast!=0) entry in the
** in-memory tree.
*/
int lsmTreeCursorEnd(TreeCursor *pCsr, int bLast){
TreeVersion *p = pCsr->pDb->pTV;
TreeNode *pNode = p->pRoot;
pCsr->iNode = -1;
/* Discard any saved position data */
treeCursorRestore(pCsr, 0);
while( pNode ){
int iCell;
if( bLast ){
iCell = ((pNode->apKey[2]==0) ? 2 : 3);
}else{
iCell = ((pNode->apKey[0]==0) ? 1 : 0);
}
pCsr->iNode++;
pCsr->apTreeNode[pCsr->iNode] = pNode;
if( pCsr->iNode<p->nHeight-1 ){
pNode = getChildPtr(pNode, p->iVersion, iCell);
}else{
pNode = 0;
}
pCsr->aiCell[pCsr->iNode] = iCell - (pNode==0 && bLast);
}
return LSM_OK;
}
int lsmTreeCursorKey(TreeCursor *pCsr, void **ppKey, int *pnKey){
TreeKey *pTreeKey;
assert( lsmTreeCursorValid(pCsr) );
pTreeKey = pCsr->pSave;
if( !pTreeKey ){
pTreeKey = pCsr->apTreeNode[pCsr->iNode]->apKey[pCsr->aiCell[pCsr->iNode]];
}
*ppKey = pTreeKey->pKey;
*pnKey = pTreeKey->nKey;
return LSM_OK;
}
int lsmTreeCursorValue(TreeCursor *pCsr, void **ppVal, int *pnVal){
TreeKey *pTreeKey;
int res = 0;
treeCursorRestore(pCsr, &res);
if( res==0 ){
pTreeKey = pCsr->apTreeNode[pCsr->iNode]->apKey[pCsr->aiCell[pCsr->iNode]];
*ppVal = pTreeKey->pValue;
*pnVal = pTreeKey->nValue;
}else{
*ppVal = 0;
*pnVal = 0;
}
return LSM_OK;
}
/*
** Return true if the cursor currently points to a valid entry.
*/
int lsmTreeCursorValid(TreeCursor *pCsr){
return (pCsr && (pCsr->pSave || pCsr->iNode>=0));
}
/*
** Roll back to mark pMark. Structure *pMark should have been previously
** populated by a call to lsmTreeMark().
*/
void lsmTreeRollback(lsm_db *pDb, TreeMark *pMark){
TreeVersion *pWorking = pDb->pTV;
Tree *pTree = pWorking->pTree;
TreeNode *p;
assert( lsmTreeIsWriteVersion(pWorking) );
pWorking->pRoot = (TreeNode *)pMark->pRoot;
pWorking->nHeight = pMark->nHeight;
if( pMark->pRollback ){
p = ((TreeNode *)pMark->pRollback)->pNext;
}else{
p = pTree->pRbFirst;
}
while( p ){
TreeNode *pNext = p->pNext;
assert( p->iV2!=0 );
assert( pNext || p==pTree->pRbLast );
p->iV2 = 0;
p->iV2Ptr = 0;
p->pV2Ptr = 0;
p->pNext = 0;
p = pNext;
}
pTree->pRbLast = (TreeNode *)pMark->pRollback;
if( pTree->pRbLast ){
pTree->pRbLast->pNext = 0;
}else{
pTree->pRbFirst = 0;
}
lsmPoolRollback(pDb->pEnv, pTree->pPool, pMark->pMpChunk, pMark->iMpOff);
}
/*
** Store a mark in *pMark. Later on, a call to lsmTreeRollback() with a
** pointer to the same TreeMark structure may be used to roll the tree
** contents back to their current state.
*/
void lsmTreeMark(TreeVersion *pTV, TreeMark *pMark){
Tree *pTree = pTV->pTree;
memset(pMark, 0, sizeof(TreeMark));
pMark->pRoot = (void *)pTV->pRoot;
pMark->nHeight = pTV->nHeight;
pMark->pRollback = (void *)pTree->pRbLast;
lsmPoolMark(pTree->pPool, &pMark->pMpChunk, &pMark->iMpOff);
assert( lsmTreeIsWriteVersion(pTV) );
pTV->iVersion++;
}
/*
** This is called when a client wishes to upgrade from a read to a write
** transaction. If the read-version passed as the second version is the
** most recent one, decrement its ref-count and return a pointer to
** the write-version object. Otherwise return null. So we can do:
**
** // Open read-transaction
** pReadVersion = lsmTreeReadVersion(pTree);
**
** // Later on, attempt to upgrade to write transaction
** if( pWriteVersion = lsmTreeWriteVersion(pTree, pReadVersion) ){
** // Have upgraded to a write transaction!
** }else{
** // Reading an out-of-date snapshot. Upgrade fails.
** }
**
** The caller must take care of rejecting a clients attempt to upgrade to
** a write transaction *while* another client has a write transaction
** underway. This mechanism merely prevents writing to an out-of-date
** snapshot.
*/
int lsmTreeWriteVersion(
lsm_env *pEnv,
Tree *pTree,
TreeVersion **ppVersion
){
TreeVersion *pRead = *ppVersion;
TreeVersion *pRet;
/* The caller must ensure that no other write transaction is underway. */
assert( pTree->pWorking==0 );
if( pRead && pTree->pCommit!=pRead ) return LSM_BUSY;
pRet = lsmMallocZero(pEnv, sizeof(TreeVersion));
if( pRet==0 ) return LSM_NOMEM_BKPT;
pTree->pWorking = pRet;
memcpy(pRet, pTree->pCommit, sizeof(TreeVersion));
pRet->nRef = 1;
if( pRead ) pRead->nRef--;
*ppVersion = pRet;
assert( pRet->pTree==pTree );
return LSM_OK;
}
static void treeIncrRefcount(Tree *pTree){
pTree->nTreeRef++;
}
static void treeDecrRefcount(lsm_env *pEnv, Tree *pTree){
assert( pTree->nTreeRef>0 );
pTree->nTreeRef--;
if( pTree->nTreeRef==0 ){
assert( pTree->pWorking==0 );
treeDestroy(pEnv, pTree);
}
}
/*
** Release a reference to the write-version.
*/
int lsmTreeReleaseWriteVersion(
lsm_env *pEnv,
TreeVersion *pWorking, /* Write-version reference */
int bCommit, /* True for a commit */
TreeVersion **ppReadVersion /* OUT: Read-version reference */
){
Tree *pTree = pWorking->pTree;
assert( lsmTreeIsWriteVersion(pWorking) );
assert( pWorking->nRef==1 );
if( bCommit ){
treeIncrRefcount(pTree);
lsmTreeReleaseReadVersion(pEnv, pTree->pCommit);
pTree->pCommit = pWorking;
}else{
lsmFree(pEnv, pWorking);
}
pTree->pWorking = 0;
if( ppReadVersion ){
*ppReadVersion = lsmTreeReadVersion(pTree);
}
return LSM_OK;
}
TreeVersion *lsmTreeRecoverVersion(Tree *pTree){
return pTree->pCommit;
}
/*
** Return a reference to a TreeVersion structure that may be used to read
** the database. The reference should be released at some point in the future
** by calling lsmTreeReleaseReadVersion().
*/
TreeVersion *lsmTreeReadVersion(Tree *pTree){
TreeVersion *pRet = pTree->pCommit;
assert( pRet->nRef>0 );
pRet->nRef++;
return pRet;
}
/*
** Release a reference to a read-version.
*/
void lsmTreeReleaseReadVersion(lsm_env *pEnv, TreeVersion *pTreeVersion){
if( pTreeVersion ){
assert( pTreeVersion->nRef>0 );
pTreeVersion->nRef--;
if( pTreeVersion->nRef==0 ){
Tree *pTree = pTreeVersion->pTree;
lsmFree(pEnv, pTreeVersion);
treeDecrRefcount(pEnv, pTree);
}
}
}
/*
** Return true if the tree-version passed as the first argument is writable.
*/
int lsmTreeIsWriteVersion(TreeVersion *pTV){
return (pTV==pTV->pTree->pWorking);
}
void lsmTreeRelease(lsm_env *pEnv, Tree *pTree){
if( pTree ){
assert( pTree->nTreeRef>0 && pTree->pCommit );
lsmTreeReleaseReadVersion(pEnv, pTree->pCommit);
}
}
/************** End of lsm_tree.c ********************************************/
/************** Begin file lsm_unix.c ****************************************/
/*
** 2011-12-03
**
** 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.
**
*************************************************************************
**
** Unix-specific run-time environment implementation for LSM.
*/
/* #include <unistd.h> */
/* #include <sys/types.h> */
/* #include <sys/stat.h> */
/* #include <fcntl.h> */
/* #include <assert.h> */
/* #include <string.h> */
/* #include <stdlib.h> */
/* #include <stdarg.h> */
/* #include <stdio.h> */
/* #include <ctype.h> */
/* #include <unistd.h> */
#include <errno.h>
#include <sys/mman.h>
/*
** An open file is an instance of the following object
*/
typedef struct PosixFile PosixFile;
struct PosixFile {
lsm_env *pEnv; /* The run-time environment */
int fd; /* The open file descriptor */
void *pMap;
off_t nMap;
};
static int lsm_ioerr(void){ return LSM_IOERR; }
static int lsmPosixOsOpen(
lsm_env *pEnv,
const char *zFile,
lsm_file **ppFile
){
int rc = LSM_OK;
PosixFile *p;
p = lsm_malloc(pEnv, sizeof(PosixFile));
if( p==0 ){
rc = LSM_NOMEM;
}else{
memset(p, 0, sizeof(PosixFile));
p->pEnv = pEnv;
p->fd = open(zFile, O_RDWR|O_CREAT, 0644);
if( p->fd<0 ){
lsm_free(pEnv, p);
p = 0;
rc = lsm_ioerr();
}
}
*ppFile = (lsm_file *)p;
return rc;
}
static int lsmPosixOsWrite(
lsm_file *pFile, /* File to write to */
lsm_i64 iOff, /* Offset to write to */
void *pData, /* Write data from this buffer */
int nData /* Bytes of data to write */
){
int rc = LSM_OK;
PosixFile *p = (PosixFile *)pFile;
off_t offset;
offset = lseek(p->fd, (off_t)iOff, SEEK_SET);
if( offset!=iOff ){
rc = lsm_ioerr();
}else{
ssize_t prc = write(p->fd, pData, (size_t)nData);
if( prc<0 ) rc = lsm_ioerr();
}
return rc;
}
static int lsmPosixOsTruncate(
lsm_file *pFile, /* File to write to */
lsm_i64 nSize /* Size to truncate file to */
){
int rc = LSM_OK;
int prc; /* Posix Return Code */
PosixFile *p = (PosixFile *)pFile;
prc = ftruncate(p->fd, (off_t)nSize);
if( prc<0 ) rc = lsm_ioerr();
return rc;
}
static int lsmPosixOsRead(
lsm_file *pFile, /* File to read from */
lsm_i64 iOff, /* Offset to read from */
void *pData, /* Read data into this buffer */
int nData /* Bytes of data to read */
){
int rc = LSM_OK;
PosixFile *p = (PosixFile *)pFile;
off_t offset;
offset = lseek(p->fd, (off_t)iOff, SEEK_SET);
if( offset!=iOff ){
rc = lsm_ioerr();
}else{
ssize_t prc = read(p->fd, pData, (size_t)nData);
if( prc<0 ){
rc = lsm_ioerr();
}else if( prc<nData ){
memset(&((u8 *)pData)[prc], 0, nData - prc);
}
}
return rc;
}
static int lsmPosixOsSync(lsm_file *pFile){
int rc = LSM_OK;
#ifndef LSM_NO_SYNC
PosixFile *p = (PosixFile *)pFile;
int prc = 0;
if( p->pMap ){
prc = msync(p->pMap, p->nMap, MS_SYNC);
}
if( prc==0 ) prc = fdatasync(p->fd);
if( prc<0 ) rc = lsm_ioerr();
#else
(void)pFile;
#endif
return rc;
}
static int lsmPosixOsSectorSize(lsm_file *pFile){
return 512;
}
static int lsmPosixOsRemap(
lsm_file *pFile,
lsm_i64 iMin,
void **ppOut,
lsm_i64 *pnOut
){
off_t iSz;
int prc;
PosixFile *p = (PosixFile *)pFile;
struct stat buf;
if( p->pMap ){
munmap(p->pMap, p->nMap);
p->pMap = 0;
p->nMap = 0;
}
memset(&buf, 0, sizeof(buf));
prc = fstat(p->fd, &buf);
if( prc!=0 ) return LSM_IOERR_BKPT;
iSz = buf.st_size;
if( iSz<iMin ){
iSz = ((iMin + (2<<20) - 1) / (2<<20)) * (2<<20);
prc = ftruncate(p->fd, iSz);
if( prc!=0 ) return LSM_IOERR_BKPT;
}
p->pMap = mmap(0, iSz, PROT_READ|PROT_WRITE, MAP_SHARED, p->fd, 0);
p->nMap = iSz;
*ppOut = p->pMap;
*pnOut = p->nMap;
return LSM_OK;
}
static int lsmPosixOsFullpath(
lsm_env *pEnv,
const char *zName,
char *zOut,
int *pnOut
){
int nBuf = *pnOut;
int nReq;
if( zName[0]!='/' ){
char *z;
char *zTmp;
int nTmp = 512;
zTmp = lsmMalloc(pEnv, nTmp);
while( zTmp ){
z = getcwd(zTmp, nTmp);
if( z || errno!=ERANGE ) break;
nTmp = nTmp*2;
zTmp = lsmReallocOrFree(pEnv, zTmp, nTmp);
}
if( zTmp==0 ) return LSM_NOMEM_BKPT;
if( z==0 ) return LSM_IOERR_BKPT;
assert( z==zTmp );
nTmp = strlen(zTmp);
nReq = nTmp + 1 + strlen(zName) + 1;
if( nReq<=nBuf ){
memcpy(zOut, zTmp, nTmp);
zOut[nTmp] = '/';
memcpy(&zOut[nTmp+1], zName, strlen(zName)+1);
}
lsmFree(pEnv, zTmp);
}else{
nReq = strlen(zName)+1;
if( nReq<=nBuf ){
memcpy(zOut, zName, strlen(zName)+1);
}
}
*pnOut = nReq;
return LSM_OK;
}
static int lsmPosixOsFileid(
lsm_file *pFile,
void *pBuf,
int *pnBuf
){
int prc;
int nBuf;
int nReq;
PosixFile *p = (PosixFile *)pFile;
struct stat buf;
nBuf = *pnBuf;
nReq = (sizeof(buf.st_dev) + sizeof(buf.st_ino));
*pnBuf = nReq;
if( nReq>nBuf ) return LSM_OK;
memset(&buf, 0, sizeof(buf));
prc = fstat(p->fd, &buf);
if( prc!=0 ) return LSM_IOERR_BKPT;
memcpy(pBuf, &buf.st_dev, sizeof(buf.st_dev));
memcpy(&(((u8 *)pBuf)[sizeof(buf.st_dev)]), &buf.st_ino, sizeof(buf.st_ino));
return LSM_OK;
}
static int lsmPosixOsClose(lsm_file *pFile){
PosixFile *p = (PosixFile *)pFile;
if( p->pMap ) munmap(p->pMap, p->nMap);
close(p->fd);
lsm_free(p->pEnv, p);
return LSM_OK;
}
static int lsmPosixOsUnlink(lsm_env *pEnv, const char *zFile){
int prc = unlink(zFile);
return prc ? LSM_IOERR_BKPT : LSM_OK;
}
/****************************************************************************
** Memory allocation routines.
*/
static void *lsmPosixOsMalloc(lsm_env *pEnv, int N){ return malloc(N); }
static void lsmPosixOsFree(lsm_env *pEnv, void *p){ free(p); }
static void *lsmPosixOsRealloc(lsm_env *pEnv, void *p, int N){
return realloc(p, N);
}
#ifdef LSM_MUTEX_PTHREADS
/*************************************************************************
** Mutex methods for pthreads based systems. If LSM_MUTEX_PTHREADS is
** missing then a no-op implementation of mutexes found in lsm_mutex.c
** will be used instead.
*/
/* #include <pthread.h> */
typedef struct PthreadMutex PthreadMutex;
struct PthreadMutex {
lsm_env *pEnv;
pthread_mutex_t mutex;
#ifdef LSM_DEBUG
pthread_t owner;
#endif
};
#ifdef LSM_DEBUG
# define LSM_PTHREAD_STATIC_MUTEX { 0, PTHREAD_MUTEX_INITIALIZER, 0 }
#else
# define LSM_PTHREAD_STATIC_MUTEX { 0, PTHREAD_MUTEX_INITIALIZER }
#endif
static int lsmPosixOsMutexStatic(
lsm_env *pEnv,
int iMutex,
lsm_mutex **ppStatic
){
static PthreadMutex sMutex[2] = {
LSM_PTHREAD_STATIC_MUTEX,
LSM_PTHREAD_STATIC_MUTEX
};
assert( iMutex==LSM_MUTEX_GLOBAL || iMutex==LSM_MUTEX_HEAP );
assert( LSM_MUTEX_GLOBAL==1 && LSM_MUTEX_HEAP==2 );
*ppStatic = (lsm_mutex *)&sMutex[iMutex-1];
return LSM_OK;
}
static int lsmPosixOsMutexNew(lsm_env *pEnv, lsm_mutex **ppNew){
PthreadMutex *pMutex; /* Pointer to new mutex */
pthread_mutexattr_t attr; /* Attributes object */
pMutex = (PthreadMutex *)lsmMallocZero(pEnv, sizeof(PthreadMutex));
if( !pMutex ) return LSM_NOMEM_BKPT;
pMutex->pEnv = pEnv;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&pMutex->mutex, &attr);
pthread_mutexattr_destroy(&attr);
*ppNew = (lsm_mutex *)pMutex;
return LSM_OK;
}
static void lsmPosixOsMutexDel(lsm_mutex *p){
PthreadMutex *pMutex = (PthreadMutex *)p;
pthread_mutex_destroy(&pMutex->mutex);
lsmFree(pMutex->pEnv, pMutex);
}
static void lsmPosixOsMutexEnter(lsm_mutex *p){
PthreadMutex *pMutex = (PthreadMutex *)p;
pthread_mutex_lock(&pMutex->mutex);
#ifdef LSM_DEBUG
assert( !pthread_equal(pMutex->owner, pthread_self()) );
pMutex->owner = pthread_self();
assert( pthread_equal(pMutex->owner, pthread_self()) );
#endif
}
static int lsmPosixOsMutexTry(lsm_mutex *p){
int ret;
PthreadMutex *pMutex = (PthreadMutex *)p;
ret = pthread_mutex_trylock(&pMutex->mutex);
#ifdef LSM_DEBUG
if( ret==0 ){
assert( !pthread_equal(pMutex->owner, pthread_self()) );
pMutex->owner = pthread_self();
assert( pthread_equal(pMutex->owner, pthread_self()) );
}
#endif
return ret;
}
static void lsmPosixOsMutexLeave(lsm_mutex *p){
PthreadMutex *pMutex = (PthreadMutex *)p;
#ifdef LSM_DEBUG
assert( pthread_equal(pMutex->owner, pthread_self()) );
pMutex->owner = 0;
assert( !pthread_equal(pMutex->owner, pthread_self()) );
#endif
pthread_mutex_unlock(&pMutex->mutex);
}
#ifdef LSM_DEBUG
static int lsmPosixOsMutexHeld(lsm_mutex *p){
PthreadMutex *pMutex = (PthreadMutex *)p;
return pMutex ? pthread_equal(pMutex->owner, pthread_self()) : 1;
}
static int lsmPosixOsMutexNotHeld(lsm_mutex *p){
PthreadMutex *pMutex = (PthreadMutex *)p;
return pMutex ? !pthread_equal(pMutex->owner, pthread_self()) : 1;
}
#endif
/*
** End of pthreads mutex implementation.
*************************************************************************/
#else
/*************************************************************************
** Noop mutex implementation
*/
typedef struct NoopMutex NoopMutex;
struct NoopMutex {
lsm_env *pEnv; /* Environment handle (for xFree()) */
int bHeld; /* True if mutex is held */
int bStatic; /* True for a static mutex */
};
static NoopMutex aStaticNoopMutex[2] = {
{0, 0, 1},
{0, 0, 1},
};
static int lsmPosixOsMutexStatic(
lsm_env *pEnv,
int iMutex,
lsm_mutex **ppStatic
){
assert( iMutex>=1 && iMutex<=(int)array_size(aStaticNoopMutex) );
*ppStatic = (lsm_mutex *)&aStaticNoopMutex[iMutex-1];
return LSM_OK;
}
static int lsmPosixOsMutexNew(lsm_env *pEnv, lsm_mutex **ppNew){
NoopMutex *p;
p = (NoopMutex *)lsmMallocZero(pEnv, sizeof(NoopMutex));
if( p ) p->pEnv = pEnv;
*ppNew = (lsm_mutex *)p;
return (p ? LSM_OK : LSM_NOMEM_BKPT);
}
static void lsmPosixOsMutexDel(lsm_mutex *pMutex) {
NoopMutex *p = (NoopMutex *)pMutex;
assert( p->bStatic==0 && p->pEnv );
lsmFree(p->pEnv, p);
}
static void lsmPosixOsMutexEnter(lsm_mutex *pMutex){
NoopMutex *p = (NoopMutex *)pMutex;
assert( p->bHeld==0 );
p->bHeld = 1;
}
static int lsmPosixOsMutexTry(lsm_mutex *pMutex){
NoopMutex *p = (NoopMutex *)pMutex;
assert( p->bHeld==0 );
p->bHeld = 1;
return 0;
}
static void lsmPosixOsMutexLeave(lsm_mutex *pMutex){
NoopMutex *p = (NoopMutex *)pMutex;
assert( p->bHeld==1 );
p->bHeld = 0;
}
#ifdef LSM_DEBUG
static int lsmPosixOsMutexHeld(lsm_mutex *pMutex){
NoopMutex *p = (NoopMutex *)pMutex;
return p ? p->bHeld : 1;
}
static int lsmPosixOsMutexNotHeld(lsm_mutex *pMutex){
NoopMutex *p = (NoopMutex *)pMutex;
return p ? !p->bHeld : 1;
}
#endif
/***************************************************************************/
#endif /* else LSM_MUTEX_NONE */
/* Without LSM_DEBUG, the MutexHeld tests are never called */
#ifndef LSM_DEBUG
# define lsmPosixOsMutexHeld 0
# define lsmPosixOsMutexNotHeld 0
#endif
lsm_env *lsm_default_env(void){
static lsm_env posix_env = {
sizeof(lsm_env), /* nByte */
1, /* iVersion */
/***** file i/o ******************/
0, /* pVfsCtx */
lsmPosixOsFullpath, /* xFullpath */
lsmPosixOsOpen, /* xOpen */
lsmPosixOsRead, /* xRead */
lsmPosixOsWrite, /* xWrite */
lsmPosixOsTruncate, /* xTruncate */
lsmPosixOsSync, /* xSync */
lsmPosixOsSectorSize, /* xSectorSize */
lsmPosixOsRemap, /* xRemap */
lsmPosixOsFileid, /* xFileid */
lsmPosixOsClose, /* xClose */
lsmPosixOsUnlink, /* xUnlink */
/***** memory allocation *********/
0, /* pMemCtx */
lsmPosixOsMalloc, /* xMalloc */
lsmPosixOsRealloc, /* xRealloc */
lsmPosixOsFree, /* xFree */
0, /* pMutexCtx */
/***** mutexes *********************/
lsmPosixOsMutexStatic, /* xMutexStatic */
lsmPosixOsMutexNew, /* xMutexNew */
lsmPosixOsMutexDel, /* xMutexDel */
lsmPosixOsMutexEnter, /* xMutexEnter */
lsmPosixOsMutexTry, /* xMutexTry */
lsmPosixOsMutexLeave, /* xMutexLeave */
lsmPosixOsMutexHeld, /* xMutexHeld */
lsmPosixOsMutexNotHeld, /* xMutexNotHeld */
};
return &posix_env;
}
/************** End of lsm_unix.c ********************************************/
/************** Begin file lsm_varint.c **************************************/
/*
** 2012-02-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.
**
*************************************************************************
**
** SQLite4-compatible varint implementation.
*/
/*************************************************************************
** The following is a copy of the varint.c module from SQLite 4.
*/
/*
** Decode the varint in z[]. Write the integer value into *pResult and
** return the number of bytes in the varint.
*/
static int lsmSqlite4GetVarint64(const unsigned char *z, u64 *pResult){
unsigned int x;
if( z[0]<=240 ){
*pResult = z[0];
return 1;
}
if( z[0]<=248 ){
*pResult = (z[0]-241)*256 + z[1] + 240;
return 2;
}
if( z[0]==249 ){
*pResult = 2288 + 256*z[1] + z[2];
return 3;
}
if( z[0]==250 ){
*pResult = (z[1]<<16) + (z[2]<<8) + z[3];
return 4;
}
x = (z[1]<<24) + (z[2]<<16) + (z[3]<<8) + z[4];
if( z[0]==251 ){
*pResult = x;
return 5;
}
if( z[0]==252 ){
*pResult = (((u64)x)<<8) + z[5];
return 6;
}
if( z[0]==253 ){
*pResult = (((u64)x)<<16) + (z[5]<<8) + z[6];
return 7;
}
if( z[0]==254 ){
*pResult = (((u64)x)<<24) + (z[5]<<16) + (z[6]<<8) + z[7];
return 8;
}
*pResult = (((u64)x)<<32) +
(0xffffffff & ((z[5]<<24) + (z[6]<<16) + (z[7]<<8) + z[8]));
return 9;
}
/*
** Write a 32-bit unsigned integer as 4 big-endian bytes.
*/
static void lsmVarintWrite32(unsigned char *z, unsigned int y){
z[0] = (unsigned char)(y>>24);
z[1] = (unsigned char)(y>>16);
z[2] = (unsigned char)(y>>8);
z[3] = (unsigned char)(y);
}
/*
** Write a varint into z[]. The buffer z[] must be at least 9 characters
** long to accommodate the largest possible varint. Return the number of
** bytes of z[] used.
*/
static int lsmSqlite4PutVarint64(unsigned char *z, u64 x){
unsigned int w, y;
if( x<=240 ){
z[0] = (unsigned char)x;
return 1;
}
if( x<=2287 ){
y = (unsigned int)(x - 240);
z[0] = (unsigned char)(y/256 + 241);
z[1] = (unsigned char)(y%256);
return 2;
}
if( x<=67823 ){
y = (unsigned int)(x - 2288);
z[0] = 249;
z[1] = (unsigned char)(y/256);
z[2] = (unsigned char)(y%256);
return 3;
}
y = (unsigned int)x;
w = (unsigned int)(x>>32);
if( w==0 ){
if( y<=16777215 ){
z[0] = 250;
z[1] = (unsigned char)(y>>16);
z[2] = (unsigned char)(y>>8);
z[3] = (unsigned char)(y);
return 4;
}
z[0] = 251;
lsmVarintWrite32(z+1, y);
return 5;
}
if( w<=255 ){
z[0] = 252;
z[1] = (unsigned char)w;
lsmVarintWrite32(z+2, y);
return 6;
}
if( w<=32767 ){
z[0] = 253;
z[1] = (unsigned char)(w>>8);
z[2] = (unsigned char)w;
lsmVarintWrite32(z+3, y);
return 7;
}
if( w<=16777215 ){
z[0] = 254;
z[1] = (unsigned char)(w>>16);
z[2] = (unsigned char)(w>>8);
z[3] = (unsigned char)w;
lsmVarintWrite32(z+4, y);
return 8;
}
z[0] = 255;
lsmVarintWrite32(z+1, w);
lsmVarintWrite32(z+5, y);
return 9;
}
/*
** End of SQLite 4 code.
*************************************************************************/
int lsmVarintPut64(u8 *aData, i64 iVal){
return lsmSqlite4PutVarint64(aData, (u64)iVal);
}
int lsmVarintGet64(const u8 *aData, i64 *piVal){
return lsmSqlite4GetVarint64(aData, (u64 *)piVal);
}
int lsmVarintPut32(u8 *aData, int iVal){
return lsmSqlite4PutVarint64(aData, (u64)iVal);
}
int lsmVarintGet32(u8 *aData, int *piVal){
int nByte;
u64 iVal64;
nByte = lsmSqlite4GetVarint64(aData, &iVal64);
*piVal = (int)iVal64;
return nByte;
}
int lsmVarintLen32(int n){
u8 aData[9];
return lsmVarintPut32(aData, n);
}
/*
** The argument is the first byte of a varint. This function returns the
** total number of bytes in the entire varint (including the first byte).
*/
int lsmVarintSize(u8 c){
if( c<241 ) return 1;
if( c<249 ) return 2;
return (int)(c - 246);
}
/************** End of lsm_varint.c ******************************************/
/************** Begin file storage.c *****************************************/
/*
** 2012 January 21
**
** 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.
**
*************************************************************************
**
** General wrapper functions around the various KV storage engine
** implementations. It also implements tracing of calls to the KV
** engine and some higher-level ensembles of the low-level storage
** calls.
*/
/*
** Names of error codes used for tracing.
*/
static const char *kvErrName(int e){
const char *zName;
switch( e ){
case SQLITE_OK: zName = "OK"; break;
case SQLITE_ERROR: zName = "ERROR"; break;
case SQLITE_INTERNAL: zName = "INTERNAL"; break;
case SQLITE_PERM: zName = "PERM"; break;
case SQLITE_ABORT: zName = "ABORT"; break;
case SQLITE_BUSY: zName = "BUSY"; break;
case SQLITE_LOCKED: zName = "LOCKED"; break;
case SQLITE_NOMEM: zName = "NOMEM"; break;
case SQLITE_READONLY: zName = "READONLY"; break;
case SQLITE_INTERRUPT: zName = "INTERRUPT"; break;
case SQLITE_IOERR: zName = "IOERR"; break;
case SQLITE_CORRUPT: zName = "CORRUPT"; break;
case SQLITE_NOTFOUND: zName = "NOTFOUND"; break;
case SQLITE_FULL: zName = "FULL"; break;
case SQLITE_CANTOPEN: zName = "CANTOPEN"; break;
case SQLITE_PROTOCOL: zName = "PROTOCOL"; break;
case SQLITE_EMPTY: zName = "EMPTY"; break;
case SQLITE_SCHEMA: zName = "SCHEMA"; break;
case SQLITE_TOOBIG: zName = "TOOBIG"; break;
case SQLITE_CONSTRAINT: zName = "CONSTRAINT"; break;
case SQLITE_MISMATCH: zName = "MISMATCH"; break;
case SQLITE_MISUSE: zName = "MISUSE"; break;
case SQLITE_NOLFS: zName = "NOLFS"; break;
case SQLITE_AUTH: zName = "AUTH"; break;
case SQLITE_FORMAT: zName = "FORMAT"; break;
case SQLITE_RANGE: zName = "RANGE"; break;
case SQLITE_NOTADB: zName = "NOTADB"; break;
case SQLITE_ROW: zName = "ROW"; break;
case SQLITE_DONE: zName = "DONE"; break;
case SQLITE_INEXACT: zName = "INEXACT"; break;
default: zName = "???"; break;
}
return zName;
}
/*
** Do any requested tracing
*/
static void kvTrace(KVStore *p, const char *zFormat, ...){
if( p->fTrace ){
va_list ap;
char *z;
va_start(ap, zFormat);
z = sqlite4_vmprintf(p->pEnv, zFormat, ap);
va_end(ap);
printf("%s.%s\n", p->zKVName, z);
fflush(stdout);
sqlite4_free(p->pEnv, z);
}
}
/*
** Open a storage engine via URI
*/
SQLITE_PRIVATE int sqlite4KVStoreOpen(
sqlite4 *db, /* The database connection doing the open */
const char *zName, /* Symbolic name for this database */
const char *zUri, /* URI for this database */
KVStore **ppKVStore, /* Write the new KVStore object here */
unsigned flags /* Option flags */
){
KVStore *pNew = 0;
int rc;
sqlite4_env *pEnv = &sqlite4DefaultEnv; /* OR db->pEnv */
const char *zStorageName;
KVFactory *pMkr;
int (*xFactory)(sqlite4_env*,sqlite4_kvstore**,const char*,unsigned);
if( (flags & SQLITE_KVOPEN_TEMPORARY)!=0 || zUri==0 || zUri[0]==0 ){
zStorageName = "temp";
}else{
zStorageName = sqlite4_uri_parameter(zName, "kv");
if( zStorageName==0 ){
if( memcmp(":memory:", zUri, 8)==0 ){
zStorageName = "temp";
}else{
zStorageName = "main";
}
}
}
*ppKVStore = 0;
sqlite4_mutex_enter(pEnv->pFactoryMutex);
for(pMkr=pEnv->pFactory; pMkr && strcmp(zStorageName,pMkr->zName);
pMkr=pMkr->pNext){}
xFactory = pMkr ? pMkr->xFactory : 0;
sqlite4_mutex_leave(pEnv->pFactoryMutex);
if( xFactory==0 ){
return SQLITE_ERROR;
}
rc = xFactory(pEnv, &pNew, zUri, flags);
*ppKVStore = pNew;
if( pNew ){
sqlite4_randomness(pEnv, sizeof(pNew->kvId), &pNew->kvId);
sqlite4_snprintf(pNew->zKVName, sizeof(pNew->zKVName),
"%s", zName);
pNew->fTrace = (db->flags & SQLITE_KvTrace)!=0;
kvTrace(pNew, "open(%s,%d,0x%04x)", zUri, pNew->kvId, flags);
}
return rc;
}
/* Convert binary data to hex for display in trace messages */
static void binToHex(char *zOut, int mxOut, const KVByteArray *a, KVSize n){
int i;
if( n>mxOut/2-1 ) n = mxOut/2-1;
for(i=0; i<n; i++){
zOut[i*2] = "0123456789abcdef"[(a[i]>>4)&0xf];
zOut[i*2+1] = "0123456789abcdef"[a[i]&0xf];
}
zOut[i*2] = 0;
}
/*
** The following wrapper functions invoke the underlying methods of
** the storage object and add optional tracing.
*/
SQLITE_PRIVATE int sqlite4KVStoreReplace(
KVStore *p,
const KVByteArray *pKey, KVSize nKey,
const KVByteArray *pData, KVSize nData
){
if( p->fTrace ){
char zKey[52], zData[52];
binToHex(zKey, sizeof(zKey), pKey, nKey);
binToHex(zData, sizeof(zData), pData, nData);
kvTrace(p, "xReplace(%d,%s,%d,%s,%d)",
p->kvId, zKey, (int)nKey, zData, (int)nData);
}
return p->pStoreVfunc->xReplace(p,pKey,nKey,pData,nData);
}
SQLITE_PRIVATE int sqlite4KVStoreOpenCursor(KVStore *p, KVCursor **ppKVCursor){
KVCursor *pCur;
int rc;
rc = p->pStoreVfunc->xOpenCursor(p, &pCur);
*ppKVCursor = pCur;
if( pCur ){
sqlite4_randomness(pCur->pEnv, sizeof(pCur->curId), &pCur->curId);
pCur->fTrace = p->fTrace;
pCur->pStore = p;
}
kvTrace(p, "xOpenCursor(%d,%d) -> %s",
p->kvId, pCur?pCur->curId:-1, kvErrName(rc));
return rc;
}
SQLITE_PRIVATE int sqlite4KVCursorSeek(
KVCursor *p,
const KVByteArray *pKey, KVSize nKey,
int dir
){
int rc;
assert( dir==0 || dir==(+1) || dir==(-1) || dir==(-2) );
rc = p->pStoreVfunc->xSeek(p,pKey,nKey,dir);
if( p->fTrace ){
char zKey[52];
binToHex(zKey, sizeof(zKey), pKey, nKey);
kvTrace(p->pStore, "xSeek(%d,%s,%d,%d) -> %s",
p->curId, zKey, (int)nKey, dir, kvErrName(rc));
}
return rc;
}
SQLITE_PRIVATE int sqlite4KVCursorNext(KVCursor *p){
int rc;
rc = p->pStoreVfunc->xNext(p);
kvTrace(p->pStore, "xNext(%d) -> %s", p->curId, kvErrName(rc));
return rc;
}
SQLITE_PRIVATE int sqlite4KVCursorPrev(KVCursor *p){
int rc;
rc = p->pStoreVfunc->xPrev(p);
kvTrace(p->pStore, "xPrev(%d) -> %s", p->curId, kvErrName(rc));
return rc;
}
SQLITE_PRIVATE int sqlite4KVCursorDelete(KVCursor *p){
int rc;
rc = p->pStoreVfunc->xDelete(p);
kvTrace(p->pStore, "xDelete(%d) -> %s", p->curId, kvErrName(rc));
return rc;
}
SQLITE_PRIVATE int sqlite4KVCursorReset(KVCursor *p){
int rc;
rc = p->pStoreVfunc->xReset(p);
kvTrace(p->pStore, "xReset(%d) -> %s", p->curId, kvErrName(rc));
return rc;
}
SQLITE_PRIVATE int sqlite4KVCursorKey(KVCursor *p, const KVByteArray **ppKey, KVSize *pnKey){
int rc;
rc = p->pStoreVfunc->xKey(p, ppKey, pnKey);
if( p->fTrace ){
if( rc==SQLITE_OK ){
char zKey[52];
binToHex(zKey, sizeof(zKey), *ppKey, *pnKey);
kvTrace(p->pStore, "xKey(%d,%s,%d)", p->curId, zKey, (int)*pnKey);
}else{
kvTrace(p->pStore, "xKey(%d,<error-%d>)", p->curId, rc);
}
}
return rc;
}
SQLITE_PRIVATE int sqlite4KVCursorData(
KVCursor *p,
KVSize ofst,
KVSize n,
const KVByteArray **ppData,
KVSize *pnData
){
int rc;
rc = p->pStoreVfunc->xData(p, ofst, n, ppData, pnData);
if( p->fTrace ){
if( rc==SQLITE_OK ){
char zData[52];
binToHex(zData, sizeof(zData), *ppData, *pnData);
kvTrace(p->pStore, "xData(%d,%d,%d,%s,%d)",
p->curId, (int)ofst, (int)n, zData, (int)*pnData);
}else{
kvTrace(p->pStore, "xData(%d,%d,%d,<error-%d>)",
p->curId, (int)ofst, (int)n, rc);
}
}
return rc;
}
SQLITE_PRIVATE int sqlite4KVCursorClose(KVCursor *p){
int rc = SQLITE_OK;
if( p ){
KVStore *pStore = p->pStore;
int curId = p->curId;
rc = p->pStoreVfunc->xCloseCursor(p);
kvTrace(pStore, "xCloseCursor(%d) -> %s", curId, kvErrName(rc));
}
return rc;
}
SQLITE_PRIVATE int sqlite4KVStoreBegin(KVStore *p, int iLevel){
int rc;
rc = p->pStoreVfunc->xBegin(p, iLevel);
kvTrace(p, "xBegin(%d,%d) -> %s", p->kvId, iLevel, kvErrName(rc));
assert( p->iTransLevel==iLevel || rc!=SQLITE_OK );
return rc;
}
SQLITE_PRIVATE int sqlite4KVStoreCommitPhaseOne(KVStore *p, int iLevel){
int rc;
assert( iLevel>=0 );
assert( iLevel<=p->iTransLevel );
if( p->iTransLevel==iLevel ) return SQLITE_OK;
if( p->pStoreVfunc->xCommitPhaseOne ){
rc = p->pStoreVfunc->xCommitPhaseOne(p, iLevel);
}else{
rc = SQLITE_OK;
}
kvTrace(p, "xCommitPhaseOne(%d,%d) -> %s", p->kvId, iLevel, kvErrName(rc));
assert( p->iTransLevel>iLevel );
return rc;
}
SQLITE_PRIVATE int sqlite4KVStoreCommitPhaseTwo(KVStore *p, int iLevel){
int rc;
assert( iLevel>=0 );
assert( iLevel<=p->iTransLevel );
if( p->iTransLevel==iLevel ) return SQLITE_OK;
rc = p->pStoreVfunc->xCommitPhaseTwo(p, iLevel);
kvTrace(p, "xCommitPhaseTwo(%d,%d) -> %s", p->kvId, iLevel, kvErrName(rc));
assert( p->iTransLevel==iLevel || rc!=SQLITE_OK );
return rc;
}
SQLITE_PRIVATE int sqlite4KVStoreCommit(KVStore *p, int iLevel){
int rc;
rc = sqlite4KVStoreCommitPhaseOne(p, iLevel);
if( rc==SQLITE_OK ) rc = sqlite4KVStoreCommitPhaseTwo(p, iLevel);
return rc;
}
SQLITE_PRIVATE int sqlite4KVStoreRollback(KVStore *p, int iLevel){
int rc;
assert( iLevel>=0 );
assert( iLevel<=p->iTransLevel );
rc = p->pStoreVfunc->xRollback(p, iLevel);
kvTrace(p, "xRollback(%d,%d) -> %s", p->kvId, iLevel, kvErrName(rc));
assert( p->iTransLevel==iLevel || rc!=SQLITE_OK );
return rc;
}
SQLITE_PRIVATE int sqlite4KVStoreRevert(KVStore *p, int iLevel){
int rc;
assert( iLevel>0 );
assert( iLevel<=p->iTransLevel );
if( p->pStoreVfunc->xRevert ){
rc = p->pStoreVfunc->xRevert(p, iLevel);
kvTrace(p, "xRevert(%d,%d) -> %s", p->kvId, iLevel, kvErrName(rc));
}else{
rc = sqlite4KVStoreRollback(p, iLevel-1);
if( rc==SQLITE_OK ){
rc = sqlite4KVStoreBegin(p, iLevel);
}
}
assert( p->iTransLevel==iLevel || rc!=SQLITE_OK );
return rc;
}
SQLITE_PRIVATE int sqlite4KVStoreClose(KVStore *p){
int rc;
if( p ){
kvTrace(p, "xClose(%d)", p->kvId);
rc = p->pStoreVfunc->xClose(p);
}
return rc;
}
/*
** Key for the meta-data
*/
static const KVByteArray metadataKey[] = { 0x00, 0x00 };
static void writeMetaArray(KVByteArray *aMeta, int iElem, u32 iVal){
int i = sizeof(u32) * iElem;
aMeta[i+0] = (iVal>>24)&0xff;
aMeta[i+1] = (iVal>>16)&0xff;
aMeta[i+2] = (iVal>>8) &0xff;
aMeta[i+3] = (iVal>>0) &0xff;
}
/*
** Read nMeta unsigned 32-bit integers of metadata beginning at iStart.
*/
SQLITE_PRIVATE int sqlite4KVStoreGetMeta(KVStore *p, int iStart, int nMeta, unsigned int *a){
KVCursor *pCur;
int rc;
int i, j;
KVSize nData;
const KVByteArray *aData;
rc = sqlite4KVStoreOpenCursor(p, &pCur);
if( rc==SQLITE_OK ){
rc = sqlite4KVCursorSeek(pCur, metadataKey, sizeof(metadataKey), 0);
if( rc==SQLITE_NOTFOUND ){
rc = SQLITE_OK;
nData = 0;
}else if( rc==SQLITE_OK ){
rc = sqlite4KVCursorData(pCur, 0, -1, &aData, &nData);
}
if( rc==SQLITE_OK ){
i = 0;
j = iStart*4;
while( i<nMeta && j+3<nData ){
a[i] = (aData[j]<<24) | (aData[j+1]<<16)
| (aData[j+2]<<8) | aData[j+3];
i++;
j += 4;
}
while( i<nMeta ) a[i++] = 0;
}
sqlite4KVCursorClose(pCur);
}
return rc;
}
/*
** Write nMeta unsigned 32-bit integers beginning with iStart.
*/
SQLITE_PRIVATE int sqlite4KVStorePutMeta(
sqlite4 *db, /* Database connection. Needed to malloc */
KVStore *p, /* Write to this database */
int iStart, /* Start writing here */
int nMeta, /* number of 32-bit integers to be written */
unsigned int *a /* The integers to write */
){
KVCursor *pCur;
int rc;
rc = sqlite4KVStoreOpenCursor(p, &pCur);
if( rc==SQLITE_OK ){
const KVByteArray *aData; /* Original database meta-array value */
KVSize nData; /* Size of aData[] in bytes */
KVByteArray *aNew; /* New database meta-array value */
KVSize nNew; /* Size of aNew[] in bytes */
/* Read the current meta-array value from the database */
rc = sqlite4KVCursorSeek(pCur, metadataKey, sizeof(metadataKey), 0);
if( rc==SQLITE_OK ){
rc = sqlite4KVCursorData(pCur, 0, -1, &aData, &nData);
}else if( rc==SQLITE_NOTFOUND ){
nData = 0;
aData = 0;
rc = SQLITE_OK;
}
/* Encode and write the new meta-array value to the database */
if( rc==SQLITE_OK ){
nNew = sizeof(a[0]) * (iStart+nMeta);
if( nNew<nData ) nNew = nData;
aNew = sqlite4DbMallocRaw(db, nNew);
if( aNew==0 ){
rc = SQLITE_NOMEM;
}else{
int i;
memcpy(aNew, aData, nData);
for(i=iStart; i<iStart+nMeta; i++){
writeMetaArray(aNew, i, a[i]);
}
rc = sqlite4KVStoreReplace(p, metadataKey, sizeof(metadataKey),
aNew, nNew);
sqlite4DbFree(db, aNew);
}
}
sqlite4KVCursorClose(pCur);
}
return rc;
}
#if defined(SQLITE_DEBUG)
/*
** Output binary data for debugging display purposes.
*/
static void outputBinary(
KVByteArray const *a,
KVSize n,
const char *zPrefix
){
int i;
char zOut[80];
static const char base16[] = "0123456789abcdef";
memset(zOut, ' ', sizeof(zOut));
zOut[16*3+3+16] = 0;
while( n>=0 ){
for(i=0; i<16 && i<n; i++){
unsigned char v = a[i];
zOut[i*3] = base16[v>>4];
zOut[i*3+1] = base16[v&0xf];
zOut[16*3+3+i] = (v>=0x20 && v<=0x7e) ? v : '.';
}
while( i<16 ){
zOut[i*3] = ' ';
zOut[i*3+1] = ' ';
zOut[16*3+3+i] = ' ';
i++;
}
sqlite4DebugPrintf("%.3s %s\n", zPrefix, zOut);
n -= 16;
if( n<=0 ) break;
a += 16;
zPrefix = " ";
}
}
/*
** Dump the entire content of a key-value database
*/
SQLITE_PRIVATE void sqlite4KVStoreDump(KVStore *pStore){
int rc;
int nRow = 0;
KVCursor *pCur;
KVSize nKey, nData;
KVByteArray const *aKey;
KVByteArray const *aData;
static const KVByteArray aProbe[] = { 0x00 };
rc = sqlite4KVStoreOpenCursor(pStore, &pCur);
if( rc==SQLITE_OK ){
rc = sqlite4KVCursorSeek(pCur, aProbe, 1, +1);
while( rc!=SQLITE_NOTFOUND ){
rc = sqlite4KVCursorKey(pCur, &aKey, &nKey);
if( rc ) break;
if( nRow>0 ) sqlite4DebugPrintf("\n");
nRow++;
outputBinary(aKey, nKey, "K: ");
rc = sqlite4KVCursorData(pCur, 0, -1, &aData, &nData);
if( rc ) break;
outputBinary(aData, nData, "V: ");
rc = sqlite4KVCursorNext(pCur);
}
sqlite4KVCursorClose(pCur);
}
}
#endif /* SQLITE_DEBUG */
/************** End of storage.c *********************************************/
/************** Begin file kvmem.c *******************************************/
/*
** 2012 January 20
**
** 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.
**
*************************************************************************
**
** An in-memory key/value storage subsystem that presents the interfadce
** defined by storage.h
*/
/* Forward declarations of object names */
typedef struct KVMemNode KVMemNode;
typedef struct KVMemChng KVMemChng;
typedef struct KVMem KVMem;
typedef struct KVMemCursor KVMemCursor;
typedef struct KVMemData KVMemData;
/*
** The data payload for an entry in the tree.
*/
struct KVMemData {
int nRef; /* Number of references to this payload */
KVSize n; /* Size of a[] in bytes */
KVByteArray a[8]; /* The content */
};
/*
** A single row in a key/value memory store is an instance of the following
** object:
*/
struct KVMemNode {
KVMemData *pData; /* Content of the row. NULL means it is deleted. */
KVMemNode *pBefore; /* Other elements less than zKey */
KVMemNode *pAfter; /* Other elements greater than zKey */
KVMemNode *pUp; /* Parent element */
short int height; /* Height of this node. Leaf==1 */
short int imbalance; /* Height difference between pBefore and pAfter */
short int mxTrans; /* Maximum transaction for which this row is logged */
short int nRef; /* Number of references to this node */
KVSize nKey; /* Size of aKey[] */
KVByteArray aKey[2]; /* Key. Extra space allocated as necessary */
};
/*
** Changes to the tree that might be rolled back are recorded as instances
** of the following object.
*/
struct KVMemChng {
KVMemChng *pNext; /* Next entry in the change log */
KVMemNode *pNode; /* The node that is changing */
KVMemData *pData; /* Old data for the row. NULL for new content. */
short int oldTrans; /* Value of pNode->mxTrans prior to this entry */
};
/*
** A complete in-memory Key/Value tree together with its
** transaction logs is an instance of the following object.
*/
struct KVMem {
KVStore base; /* Base class, must be first */
KVMemNode *pRoot; /* Root of the tree of content */
unsigned openFlags; /* Flags used at open */
KVMemChng **apLog; /* Array of transaction logs */
int nCursor; /* Number of outstanding cursors */
int iMagicKVMemBase; /* Magic number of sanity */
};
#define SQLITE_KVMEMBASE_MAGIC 0xbfcd47d0
/*
** A cursor used for scanning through the tree
*/
struct KVMemCursor {
KVCursor base; /* Base class. Must be first */
KVMem *pOwner; /* The tree that owns this cursor */
KVMemNode *pNode; /* The entry this cursor points to */
KVMemData *pData; /* Data returned by xData */
int iMagicKVMemCur; /* Magic number for sanity */
};
#define SQLITE_KVMEMCUR_MAGIC 0xb19bdc1b
/****************************************************************************
** Utility routines.
*/
/* Recompute the KVMemNode.height and KVMemNode.imbalance fields for p.
** Assume that the children of p have correct heights.
*/
static void kvmemRecomputeHeight(KVMemNode *p){
short int hBefore = p->pBefore ? p->pBefore->height : 0;
short int hAfter = p->pAfter ? p->pAfter->height : 0;
p->imbalance = hBefore - hAfter; /* -: pAfter higher. +: pBefore higher */
p->height = (hBefore>hAfter ? hBefore : hAfter)+1;
}
/*
** P B
** / \ / \
** B Z ==> X P
** / \ / \
** X Y Y Z
**
*/
static KVMemNode *kvmemRotateBefore(KVMemNode *pP){
KVMemNode *pB = pP->pBefore;
KVMemNode *pY = pB->pAfter;
pB->pUp = pP->pUp;
pB->pAfter = pP;
pP->pUp = pB;
pP->pBefore = pY;
if( pY ) pY->pUp = pP;
kvmemRecomputeHeight(pP);
kvmemRecomputeHeight(pB);
return pB;
}
/*
** P A
** / \ / \
** X A ==> P Z
** / \ / \
** Y Z X Y
**
*/
static KVMemNode *kvmemRotateAfter(KVMemNode *pP){
KVMemNode *pA = pP->pAfter;
KVMemNode *pY = pA->pBefore;
pA->pUp = pP->pUp;
pA->pBefore = pP;
pP->pUp = pA;
pP->pAfter = pY;
if( pY ) pY->pUp = pP;
kvmemRecomputeHeight(pP);
kvmemRecomputeHeight(pA);
return pA;
}
/*
** Return a pointer to the pBefore or pAfter pointer in the parent
** of p that points to p. Or if p is the root node, return pp.
*/
static KVMemNode **kvmemFromPtr(KVMemNode *p, KVMemNode **pp){
KVMemNode *pUp = p->pUp;
if( pUp==0 ) return pp;
assert( pUp->pAfter==p || pUp->pBefore==p );
if( pUp->pAfter==p ) return &pUp->pAfter;
return &pUp->pBefore;
}
/*
** Rebalance all nodes starting with p and working up to the root.
** Return the new root.
*/
static KVMemNode *kvmemBalance(KVMemNode *p){
KVMemNode *pTop = p;
KVMemNode **pp;
while( p ){
kvmemRecomputeHeight(p);
if( p->imbalance>=2 ){
KVMemNode *pB = p->pBefore;
if( pB->imbalance<0 ) p->pBefore = kvmemRotateAfter(pB);
pp = kvmemFromPtr(p,&p);
p = *pp = kvmemRotateBefore(p);
}else if( p->imbalance<=(-2) ){
KVMemNode *pA = p->pAfter;
if( pA->imbalance>0 ) p->pAfter = kvmemRotateBefore(pA);
pp = kvmemFromPtr(p,&p);
p = *pp = kvmemRotateAfter(p);
}
pTop = p;
p = p->pUp;
}
return pTop;
}
/*
** Key comparison routine.
*/
static int kvmemKeyCompare(
const KVByteArray *aK1, KVSize nK1,
const KVByteArray *aK2, KVSize nK2
){
int c;
c = memcmp(aK1, aK2, nK1<nK2 ? nK1 : nK2);
if( c==0 ) c = nK1 - nK2;
return c;
}
/*
** Create a new KVMemData object
*/
static KVMemData *kvmemDataNew(
sqlite4_env *pEnv, /* Memory allocator context */
const KVByteArray *aData, /* Data for the new object */
KVSize nData /* Bytes of content in aData[] */
){
KVMemData *p = sqlite4_malloc(pEnv, sizeof(*p) + nData - 8 );
if( p ) {
p->nRef = 1;
p->n = nData;
memcpy(p->a, aData, nData);
}
return p;
}
/*
** Make a copy of a KVMemData object
*/
static KVMemData *kvmemDataRef(KVMemData *p){
if( p ) p->nRef++;
return p;
}
/*
** Dereference a KVMemData object
*/
static void kvmemDataUnref(sqlite4_env *pEnv, KVMemData *p){
if( p && (--p->nRef)<=0 ) sqlite4_free(pEnv, p);
}
/*
** Reference a KVMemNode object
*/
static KVMemNode *kvmemNodeRef(KVMemNode *p){
if( p ) p->nRef++;
return p;
}
/*
** Dereference a KVMemNode object
*/
static void kvmemNodeUnref(sqlite4_env *pEnv, KVMemNode *p){
if( p && (--p->nRef)<=0 ){
kvmemDataUnref(pEnv, p->pData);
sqlite4_free(pEnv, p);
}
}
/*
** Recursively delete all nodes in a tree
*/
static void kvmemClearTree(sqlite4_env *pEnv, KVMemNode *pNode){
if( pNode==0 ) return;
kvmemClearTree(pEnv, pNode->pBefore);
kvmemClearTree(pEnv, pNode->pAfter);
kvmemNodeUnref(pEnv, pNode);
}
/*
** End of utilities
***************************************************************************
** Low-level operations on the tree
*/
/* Find the first node (the one with the smallest key).
*/
static KVMemNode *kvmemFirst(KVMemNode *p){
if( p ) while( p->pBefore ) p = p->pBefore;
return p;
}
/* Return the node with the next larger key after p.
*/
static KVMemNode *kvmemNext(KVMemNode *p){
KVMemNode *pPrev = 0;
while( p && p->pAfter==pPrev ){
pPrev = p;
p = p->pUp;
}
if( p && pPrev==0 ){
p = kvmemFirst(p->pAfter);
}
return p;
}
/* Find the last node (the one with the largest key).
*/
static KVMemNode *kvmemLast(KVMemNode *p){
if( p ) while( p->pAfter ) p = p->pAfter;
return p;
}
/* Return the node with the next smaller key before p.
*/
static KVMemNode *kvmemPrev(KVMemNode *p){
KVMemNode *pPrior = 0;
while( p && p->pBefore==pPrior ){
pPrior = p;
p = p->pUp;
}
if( p && pPrior==0 ){
p = kvmemLast(p->pBefore);
}
return p;
}
/*
** Create a new change record
*/
static KVMemChng *kvmemNewChng(KVMem *p, KVMemNode *pNode){
KVMemChng *pChng;
assert( p->base.iTransLevel>=2 );
pChng = sqlite4_malloc(p->base.pEnv, sizeof(*pChng) );
if( pChng ){
pChng->pNext = p->apLog[p->base.iTransLevel-2];
p->apLog[p->base.iTransLevel-2] = pChng;
pChng->pNode = pNode;
pChng->oldTrans = pNode->mxTrans;
pNode->mxTrans = p->base.iTransLevel;
pChng->pData = pNode->pData;
pNode->pData = 0;
}
return pChng;
}
/* Create a new node.
*/
static KVMemNode *kvmemNewNode(
KVMem *p,
const KVByteArray *aKey,
KVSize nKey
){
KVMemNode *pNode;
KVMemChng *pChng;
assert( p->base.iTransLevel>=2 );
pNode = sqlite4_malloc(p->base.pEnv, sizeof(*pNode)+nKey-2 );
if( pNode ){
memset(pNode, 0, sizeof(*pNode));
memcpy(pNode->aKey, aKey, nKey);
pNode->nKey = nKey;
pNode->nRef = 1;
pChng = kvmemNewChng(p, pNode);
if( pChng==0 ){
sqlite4_free(p->base.pEnv, pNode);
pNode = 0;
}
assert( pChng==0 || pChng->pData==0 );
}
return pNode;
}
#ifdef SQLITE_DEBUG
/*
** Return the number of times that node pNode occurs in the sub-tree
** headed by node pSub. This is used to assert() that no node structure
** is linked into the tree more than once.
*/
#if 0
static int countNodeOccurences(KVMemNode *pSub, KVMemNode *pNode){
int iRet = (pSub==pNode);
if( pSub ){
iRet += countNodeOccurences(pSub->pBefore, pNode);
iRet += countNodeOccurences(pSub->pAfter, pNode);
}
return iRet;
}
#endif
/*
** Check that all the pUp pointers in the sub-tree headed by pSub are
** correct. Fail an assert if this is not the case.
*/
static void assertUpPointers(KVMemNode *pSub){
if( pSub ){
assert( pSub->pBefore==0 || pSub->pBefore->pUp==pSub );
assert( pSub->pAfter==0 || pSub->pAfter->pUp==pSub );
assertUpPointers(pSub->pBefore);
assertUpPointers(pSub->pAfter);
}
}
#else
#define assertUpPointers(x)
#endif
/* Remove node pOld from the tree. pOld must be an element of the tree.
*/
static void kvmemRemoveNode(KVMem *p, KVMemNode *pOld){
KVMemNode **ppParent; /* Location of pointer to pOld */
KVMemNode *pBalance; /* Node to run kvmemBalance() on */
kvmemDataUnref(p->base.pEnv, pOld->pData);
pOld->pData = 0;
ppParent = kvmemFromPtr(pOld, &p->pRoot);
if( pOld->pBefore==0 && pOld->pAfter==0 ){
*ppParent = 0;
pBalance = pOld->pUp;
}else if( pOld->pBefore && pOld->pAfter ){
KVMemNode *pX; /* Smallest node that is larger than pOld */
KVMemNode *pY; /* Left-hand child of pOld */
pX = kvmemFirst(pOld->pAfter);
assert( pX->pBefore==0 );
if( pX==pOld->pAfter ){
pBalance = pX;
}else{
*kvmemFromPtr(pX, 0) = pX->pAfter;
if( pX->pAfter ) pX->pAfter->pUp = pX->pUp;
pBalance = pX->pUp;
pX->pAfter = pOld->pAfter;
if( pX->pAfter ){
pX->pAfter->pUp = pX;
}else{
assert( pBalance==pOld );
pBalance = pX;
}
}
pX->pBefore = pY = pOld->pBefore;
if( pY ) pY->pUp = pX;
pX->pUp = pOld->pUp;
*ppParent = pX;
}else if( pOld->pBefore==0 ){
*ppParent = pBalance = pOld->pAfter;
pBalance->pUp = pOld->pUp;
}else if( pOld->pAfter==0 ){
*ppParent = pBalance = pOld->pBefore;
pBalance->pUp = pOld->pUp;
}
p->pRoot = kvmemBalance(pBalance);
kvmemNodeUnref(p->base.pEnv, pOld);
}
/*
** End of low-level access routines
***************************************************************************
** Interface routines follow
*/
/*
** Begin a transaction or subtransaction.
**
** If iLevel==1 then begin an outermost read transaction.
**
** If iLevel==2 then begin an outermost write transaction.
**
** If iLevel>2 then begin a nested write transaction.
**
** iLevel may not be less than 1. After this routine returns successfully
** the transaction level will be equal to iLevel. The transaction level
** must be at least 1 to read and at least 2 to write.
*/
static int kvmemBegin(KVStore *pKVStore, int iLevel){
KVMem *p = (KVMem*)pKVStore;
assert( p->iMagicKVMemBase==SQLITE_KVMEMBASE_MAGIC );
assert( iLevel>0 );
assert( iLevel==2 || iLevel==p->base.iTransLevel+1 );
if( iLevel>=2 ){
KVMemChng **apNewLog;
apNewLog = sqlite4_realloc(p->base.pEnv, p->apLog,
sizeof(apNewLog[0])*(iLevel-1) );
if( apNewLog==0 ) return SQLITE_NOMEM;
p->apLog = apNewLog;
p->apLog[iLevel-2] = 0;
}
p->base.iTransLevel = iLevel;
return SQLITE_OK;
}
/*
** Commit a transaction or subtransaction.
**
** Make permanent all changes back through the most recent xBegin
** with the iLevel+1. If iLevel==0 then make all changes permanent.
** The argument iLevel will always be less than the current transaction
** level when this routine is called.
**
** Commit is divided into two phases. A rollback is still possible after
** phase one completes. In this implementation, phase one is a no-op since
** phase two cannot fail.
**
** After this routine returns successfully, the transaction level will be
** equal to iLevel.
*/
static int kvmemCommitPhaseOne(KVStore *pKVStore, int iLevel){
return SQLITE_OK;
}
static int kvmemCommitPhaseTwo(KVStore *pKVStore, int iLevel){
KVMem *p = (KVMem*)pKVStore;
assert( p->iMagicKVMemBase==SQLITE_KVMEMBASE_MAGIC );
assert( iLevel>=0 );
assert( iLevel<p->base.iTransLevel );
assertUpPointers(p->pRoot);
while( p->base.iTransLevel>iLevel && p->base.iTransLevel>1 ){
KVMemChng *pChng, *pNext;
if( iLevel<2 ){
for(pChng=p->apLog[p->base.iTransLevel-2]; pChng; pChng=pNext){
KVMemNode *pNode = pChng->pNode;
if( pNode->pData ){
pNode->mxTrans = pChng->oldTrans;
}else{
kvmemRemoveNode(p, pNode);
}
kvmemDataUnref(p->base.pEnv, pChng->pData);
pNext = pChng->pNext;
sqlite4_free(p->base.pEnv, pChng);
}
}else{
KVMemChng **pp;
int iFrom = p->base.iTransLevel-2;
int iTo = p->base.iTransLevel-3;
assert( iTo>=0 );
for(pp=&p->apLog[iFrom]; *pp; pp=&((*pp)->pNext)){
assert( (*pp)->pNode->mxTrans==p->base.iTransLevel
|| (*pp)->pNode->mxTrans==(p->base.iTransLevel-1)
);
(*pp)->pNode->mxTrans = p->base.iTransLevel - 1;
}
*pp = p->apLog[iTo];
p->apLog[iTo] = p->apLog[iFrom];
}
p->apLog[p->base.iTransLevel-2] = 0;
p->base.iTransLevel--;
}
assertUpPointers(p->pRoot);
p->base.iTransLevel = iLevel;
return SQLITE_OK;
}
/*
** Rollback a transaction or subtransaction.
**
** Revert all uncommitted changes back through the most recent xBegin or
** xCommit with the same iLevel. If iLevel==0 then back out all uncommited
** changes.
**
** After this routine returns successfully, the transaction level will be
** equal to iLevel.
*/
static int kvmemRollback(KVStore *pKVStore, int iLevel){
KVMem *p = (KVMem*)pKVStore;
assert( p->iMagicKVMemBase==SQLITE_KVMEMBASE_MAGIC );
assert( iLevel>=0 );
while( p->base.iTransLevel>iLevel && p->base.iTransLevel>1 ){
KVMemChng *pChng, *pNext;
for(pChng=p->apLog[p->base.iTransLevel-2]; pChng; pChng=pNext){
KVMemNode *pNode = pChng->pNode;
if( pChng->pData || pChng->oldTrans>0 ){
kvmemDataUnref(p->base.pEnv, pNode->pData);
pNode->pData = pChng->pData;
pNode->mxTrans = pChng->oldTrans;
}else{
kvmemRemoveNode(p, pNode);
}
pNext = pChng->pNext;
sqlite4_free(p->base.pEnv, pChng);
}
p->apLog[p->base.iTransLevel-2] = 0;
p->base.iTransLevel--;
}
p->base.iTransLevel = iLevel;
return SQLITE_OK;
}
/*
** Revert a transaction back to what it was when it started.
*/
static int kvmemRevert(KVStore *pKVStore, int iLevel){
int rc = kvmemRollback(pKVStore, iLevel-1);
if( rc==SQLITE_OK ){
rc = kvmemBegin(pKVStore, iLevel);
}
return rc;
}
/*
** Implementation of the xReplace(X, aKey, nKey, aData, nData) method.
**
** Insert or replace the entry with the key aKey[0..nKey-1]. The data for
** the new entry is aData[0..nData-1]. Return SQLITE_OK on success or an
** error code if the insert fails.
**
** The inputs aKey[] and aData[] are only valid until this routine
** returns. If the storage engine needs to keep that information
** long-term, it will need to make its own copy of these values.
**
** A transaction will always be active when this routine is called.
*/
static int kvmemReplace(
KVStore *pKVStore,
const KVByteArray *aKey, KVSize nKey,
const KVByteArray *aData, KVSize nData
){
KVMem *p = (KVMem*)pKVStore;
KVMemNode *pNew, *pNode;
KVMemData *pData;
KVMemChng *pChng;
assert( p->iMagicKVMemBase==SQLITE_KVMEMBASE_MAGIC );
assert( p->base.iTransLevel>=2 );
pData = kvmemDataNew(p->base.pEnv, aData, nData);
if( pData==0 ) return SQLITE_NOMEM;
if( p->pRoot==0 ){
pNode = pNew = kvmemNewNode(p, aKey, nKey);
if( pNew==0 ) goto KVMemReplace_nomem;
pNew->pUp = 0;
}else{
pNode = p->pRoot;
while( pNode ){
int c = kvmemKeyCompare(aKey, nKey, pNode->aKey, pNode->nKey);
if( c<0 ){
if( pNode->pBefore ){
pNode = pNode->pBefore;
}else{
pNode->pBefore = pNew = kvmemNewNode(p, aKey, nKey);
if( pNew==0 ) goto KVMemReplace_nomem;
pNew->pUp = pNode;
break;
}
}else if( c>0 ){
if( pNode->pAfter ){
pNode = pNode->pAfter;
}else{
pNode->pAfter = pNew = kvmemNewNode(p, aKey, nKey);
if( pNew==0 ) goto KVMemReplace_nomem;
pNew->pUp = pNode;
break;
}
}else{
if( pNode->mxTrans==p->base.iTransLevel ){
kvmemDataUnref(p->base.pEnv, pNode->pData);
}else{
pChng = kvmemNewChng(p, pNode);
if( pChng==0 ) goto KVMemReplace_nomem;
}
pNode->pData = pData;
return SQLITE_OK;
}
}
}
pNew->pData = pData;
pNew->height = 1;
p->pRoot = kvmemBalance(pNew);
return SQLITE_OK;
KVMemReplace_nomem:
kvmemDataUnref(p->base.pEnv, pData);
return SQLITE_NOMEM;
}
/*
** Create a new cursor object.
*/
static int kvmemOpenCursor(KVStore *pKVStore, KVCursor **ppKVCursor){
KVMem *p = (KVMem*)pKVStore;
KVMemCursor *pCur;
assert( p->iMagicKVMemBase==SQLITE_KVMEMBASE_MAGIC );
pCur = sqlite4_malloc(p->base.pEnv, sizeof(*pCur) );
if( pCur==0 ){
*ppKVCursor = 0;
return SQLITE_NOMEM;
}
memset(pCur, 0, sizeof(*pCur));
pCur->pOwner = p;
p->nCursor++;
pCur->iMagicKVMemCur = SQLITE_KVMEMCUR_MAGIC;
pCur->base.pStore = pKVStore;
pCur->base.pStoreVfunc = pKVStore->pStoreVfunc;
*ppKVCursor = (KVCursor*)pCur;
return SQLITE_OK;
}
/*
** Reset a cursor
*/
static int kvmemReset(KVCursor *pKVCursor){
KVMemCursor *pCur = (KVMemCursor*)pKVCursor;
assert( pCur->iMagicKVMemCur==SQLITE_KVMEMCUR_MAGIC );
kvmemDataUnref(pCur->base.pEnv, pCur->pData);
pCur->pData = 0;
kvmemNodeUnref(pCur->base.pEnv, pCur->pNode);
pCur->pNode = 0;
return SQLITE_OK;
}
/*
** Destroy a cursor object
*/
static int kvmemCloseCursor(KVCursor *pKVCursor){
KVMemCursor *pCur = (KVMemCursor*)pKVCursor;
if( pCur ){
assert( pCur->iMagicKVMemCur==SQLITE_KVMEMCUR_MAGIC );
assert( pCur->pOwner->iMagicKVMemBase==SQLITE_KVMEMBASE_MAGIC );
pCur->pOwner->nCursor--;
kvmemReset(pKVCursor);
memset(pCur, 0, sizeof(*pCur));
sqlite4_free(pCur->base.pEnv, pCur);
}
return SQLITE_OK;
}
/*
** Move a cursor to the next non-deleted node.
*/
static int kvmemNextEntry(KVCursor *pKVCursor){
KVMemCursor *pCur;
KVMemNode *pNode;
pCur = (KVMemCursor*)pKVCursor;
assert( pCur->iMagicKVMemCur==SQLITE_KVMEMCUR_MAGIC );
pNode = pCur->pNode;
kvmemReset(pKVCursor);
do{
pNode = kvmemNext(pNode);
}while( pNode && pNode->pData==0 );
if( pNode ){
pCur->pNode = kvmemNodeRef(pNode);
pCur->pData = kvmemDataRef(pNode->pData);
}
return pNode ? SQLITE_OK : SQLITE_NOTFOUND;
}
/*
** Move a cursor to the previous non-deleted node.
*/
static int kvmemPrevEntry(KVCursor *pKVCursor){
KVMemCursor *pCur;
KVMemNode *pNode;
pCur = (KVMemCursor*)pKVCursor;
assert( pCur->iMagicKVMemCur==SQLITE_KVMEMCUR_MAGIC );
pNode = pCur->pNode;
kvmemReset(pKVCursor);
do{
pNode = kvmemPrev(pNode);
}while( pNode && pNode->pData==0 );
if( pNode ){
pCur->pNode = kvmemNodeRef(pNode);
pCur->pData = kvmemDataRef(pNode->pData);
}
return pNode ? SQLITE_OK : SQLITE_NOTFOUND;
}
/*
** Seek a cursor.
*/
static int kvmemSeek(
KVCursor *pKVCursor,
const KVByteArray *aKey,
KVSize nKey,
int direction
){
KVMemCursor *pCur;
KVMemNode *pNode;
KVMemNode *pBest = 0;
int c;
int rc = SQLITE_NOTFOUND;
kvmemReset(pKVCursor);
pCur = (KVMemCursor*)pKVCursor;
assert( pCur->iMagicKVMemCur==SQLITE_KVMEMCUR_MAGIC );
pNode = pCur->pOwner->pRoot;
while( pNode ){
c = kvmemKeyCompare(aKey, nKey, pNode->aKey, pNode->nKey);
if( c==0 ){
pBest = pNode;
rc = SQLITE_OK;
pNode = 0;
}else if( c>0 ){
if( direction<0 ){
pBest = pNode;
rc = SQLITE_INEXACT;
}
pNode = pNode->pAfter;
}else{
if( direction>0 ){
pBest = pNode;
rc = SQLITE_INEXACT;
}
pNode = pNode->pBefore;
}
}
kvmemNodeUnref(pCur->base.pEnv, pCur->pNode);
kvmemDataUnref(pCur->base.pEnv, pCur->pData);
if( pBest ){
pCur->pNode = kvmemNodeRef(pBest);
pCur->pData = kvmemDataRef(pBest->pData);
/* The cursor currently points to a deleted node. If parameter 'direction'
** was zero (exact matches only), then the search has failed - return
** SQLITE_NOTFOUND. Otherwise, advance to the next (if direction is +ve)
** or the previous (if direction is -ve) undeleted node in the tree. */
if( pCur->pData==0 ){
if( direction==0 ){
rc = SQLITE_NOTFOUND;
}else{
if( (direction>0 ? kvmemNextEntry : kvmemPrevEntry)(pKVCursor) ){
rc = SQLITE_NOTFOUND;
}else{
rc = SQLITE_INEXACT;
}
}
}
}else{
pCur->pNode = 0;
pCur->pData = 0;
}
assert( rc!=SQLITE_DONE );
return rc;
}
/*
** Delete the entry that the cursor is pointing to.
**
** Though the entry is "deleted", it still continues to exist as a
** phantom. Subsequent xNext or xPrev calls will work, as will
** calls to xKey and xData, thought the result from xKey and xData
** are undefined.
*/
static int kvmemDelete(KVCursor *pKVCursor){
KVMemCursor *pCur;
KVMemNode *pNode;
KVMemChng *pChng;
KVMem *p;
pCur = (KVMemCursor*)pKVCursor;
assert( pCur->iMagicKVMemCur==SQLITE_KVMEMCUR_MAGIC );
p = pCur->pOwner;
assert( p->iMagicKVMemBase==SQLITE_KVMEMBASE_MAGIC );
assert( p->base.iTransLevel>=2 );
pNode = pCur->pNode;
if( pNode==0 ) return SQLITE_OK;
if( pNode->pData==0 ) return SQLITE_OK;
if( pNode->mxTrans<p->base.iTransLevel ){
pChng = kvmemNewChng(p, pNode);
if( pChng==0 ) return SQLITE_NOMEM;
assert( pNode->pData==0 );
}else{
kvmemDataUnref(pCur->base.pEnv, pNode->pData);
pNode->pData = 0;
}
return SQLITE_OK;
}
/*
** Return the key of the node the cursor is pointing to.
*/
static int kvmemKey(
KVCursor *pKVCursor, /* The cursor whose key is desired */
const KVByteArray **paKey, /* Make this point to the key */
KVSize *pN /* Make this point to the size of the key */
){
KVMemCursor *pCur;
KVMemNode *pNode;
pCur = (KVMemCursor*)pKVCursor;
assert( pCur->iMagicKVMemCur==SQLITE_KVMEMCUR_MAGIC );
pNode = pCur->pNode;
if( pNode==0 ){
*paKey = 0;
*pN = 0;
return SQLITE_DONE;
}
*paKey = pNode->aKey;
*pN = pNode->nKey;
return SQLITE_OK;
}
/*
** Return the data of the node the cursor is pointing to.
*/
static int kvmemData(
KVCursor *pKVCursor, /* The cursor from which to take the data */
KVSize ofst, /* Offset into the data to begin reading */
KVSize n, /* Number of bytes requested */
const KVByteArray **paData, /* Pointer to the data written here */
KVSize *pNData /* Number of bytes delivered */
){
KVMemCursor *pCur;
KVMemData *pData;
pCur = (KVMemCursor*)pKVCursor;
assert( pCur->iMagicKVMemCur==SQLITE_KVMEMCUR_MAGIC );
pData = pCur->pData;
if( pData==0 ){
*paData = 0;
*pNData = 0;
return SQLITE_DONE;
}
*paData = pData->a + ofst;
*pNData = pData->n - ofst;
return SQLITE_OK;
}
/*
** Destructor for the entire in-memory storage tree.
*/
static int kvmemClose(KVStore *pKVStore){
KVMem *p = (KVMem*)pKVStore;
sqlite4_env *pEnv;
if( p==0 ) return SQLITE_OK;
assert( p->iMagicKVMemBase==SQLITE_KVMEMBASE_MAGIC );
assert( p->nCursor==0 );
pEnv = p->base.pEnv;
if( p->base.iTransLevel ){
kvmemCommitPhaseOne(pKVStore, 0);
kvmemCommitPhaseTwo(pKVStore, 0);
}
sqlite4_free(pEnv, p->apLog);
kvmemClearTree(pEnv, p->pRoot);
memset(p, 0, sizeof(*p));
sqlite4_free(pEnv, p);
return SQLITE_OK;
}
static int kvmemControl(KVStore *pKVStore, int op, void *pArg){
return SQLITE_NOTFOUND;
}
/* Virtual methods for the in-memory storage engine */
static const KVStoreMethods kvmemMethods = {
1, /* iVersion */
sizeof(KVStoreMethods), /* szSelf */
kvmemReplace, /* xReplace */
kvmemOpenCursor, /* xOpenCursor */
kvmemSeek, /* xSeek */
kvmemNextEntry, /* xNext */
kvmemPrevEntry, /* xPrev */
kvmemDelete, /* xDelete */
kvmemKey, /* xKey */
kvmemData, /* xData */
kvmemReset, /* xReset */
kvmemCloseCursor, /* xCloseCursor */
kvmemBegin, /* xBegin */
kvmemCommitPhaseOne, /* xCommitPhaseOne */
kvmemCommitPhaseTwo, /* xCommitPhaseTwo */
kvmemRollback, /* xRollback */
kvmemRevert, /* xRevert */
kvmemClose, /* xClose */
kvmemControl /* xControl */
};
/*
** Create a new in-memory storage engine and return a pointer to it.
*/
SQLITE_PRIVATE int sqlite4KVStoreOpenMem(
sqlite4_env *pEnv, /* Runtime environment */
KVStore **ppKVStore, /* OUT: Write the new KVStore here */
const char *zName, /* Name of in-memory storage unit */
unsigned openFlags /* Flags */
){
KVMem *pNew = sqlite4_malloc(pEnv, sizeof(*pNew) );
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
pNew->base.pStoreVfunc = &kvmemMethods;
pNew->base.pEnv = pEnv;
pNew->iMagicKVMemBase = SQLITE_KVMEMBASE_MAGIC;
pNew->openFlags = openFlags;
*ppKVStore = (KVStore*)pNew;
return SQLITE_OK;
}
/************** End of kvmem.c ***********************************************/
/************** Begin file kvlsm.c *******************************************/
/*
** 2012 January 20
**
** 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.
**
*************************************************************************
**
** An in-memory key/value storage subsystem that presents the interfadce
** defined by storage.h
*/
typedef struct KVLsm KVLsm;
typedef struct KVLsmCsr KVLsmCsr;
struct KVLsm {
KVStore base; /* Base class, must be first */
lsm_db *pDb; /* LSM database handle */
lsm_cursor *pCsr; /* LSM cursor holding read-trans open */
};
struct KVLsmCsr {
KVCursor base; /* Base class. Must be first */
lsm_cursor *pCsr; /* LSM cursor handle */
};
/*
** Begin a transaction or subtransaction.
**
** If iLevel==1 then begin an outermost read transaction.
**
** If iLevel==2 then begin an outermost write transaction.
**
** If iLevel>2 then begin a nested write transaction.
**
** iLevel may not be less than 1. After this routine returns successfully
** the transaction level will be equal to iLevel. The transaction level
** must be at least 1 to read and at least 2 to write.
*/
static int kvlsmBegin(KVStore *pKVStore, int iLevel){
int rc = SQLITE_OK;
KVLsm *p = (KVLsm *)pKVStore;
assert( iLevel>0 );
if( p->pCsr==0 ){
rc = lsm_csr_open(p->pDb, &p->pCsr);
}
if( rc==SQLITE_OK && iLevel>=2 && iLevel>=pKVStore->iTransLevel ){
rc = lsm_begin(p->pDb, iLevel-1);
}
if( rc==SQLITE_OK ){
pKVStore->iTransLevel = SQLITE_MAX(iLevel, pKVStore->iTransLevel);
}else if( pKVStore->iTransLevel==0 ){
lsm_csr_close(p->pCsr);
p->pCsr = 0;
}
return rc;
}
/*
** Commit a transaction or subtransaction.
**
** Make permanent all changes back through the most recent xBegin
** with the iLevel+1. If iLevel==0 then make all changes permanent.
** The argument iLevel will always be less than the current transaction
** level when this routine is called.
**
** Commit is divided into two phases. A rollback is still possible after
** phase one completes. In this implementation, phase one is a no-op since
** phase two cannot fail.
**
** After this routine returns successfully, the transaction level will be
** equal to iLevel.
*/
static int kvlsmCommitPhaseOne(KVStore *pKVStore, int iLevel){
return SQLITE_OK;
}
static int kvlsmCommitPhaseTwo(KVStore *pKVStore, int iLevel){
int rc = SQLITE_OK;
KVLsm *p = (KVLsm *)pKVStore;
if( pKVStore->iTransLevel>iLevel ){
if( pKVStore->iTransLevel>=2 ){
rc = lsm_commit(p->pDb, SQLITE_MAX(0, iLevel-1));
}
if( iLevel==0 ){
lsm_csr_close(p->pCsr);
p->pCsr = 0;
}
if( rc==SQLITE_OK ){
pKVStore->iTransLevel = iLevel;
}
}
return rc;
}
/*
** Rollback a transaction or subtransaction.
**
** Revert all uncommitted changes back through the most recent xBegin or
** xCommit with the same iLevel. If iLevel==0 then back out all uncommited
** changes.
**
** After this routine returns successfully, the transaction level will be
** equal to iLevel.
*/
static int kvlsmRollback(KVStore *pKVStore, int iLevel){
int rc = SQLITE_OK;
KVLsm *p = (KVLsm *)pKVStore;
if( pKVStore->iTransLevel>=iLevel ){
if( pKVStore->iTransLevel>=2 ){
rc = lsm_rollback(p->pDb, SQLITE_MAX(0, iLevel-1));
}
if( iLevel==0 ){
lsm_csr_close(p->pCsr);
p->pCsr = 0;
}
if( rc==SQLITE_OK ){
pKVStore->iTransLevel = iLevel;
}
}
return rc;
}
/*
** Revert a transaction back to what it was when it started.
*/
static int kvlsmRevert(KVStore *pKVStore, int iLevel){
return SQLITE_OK;
}
/*
** Implementation of the xReplace(X, aKey, nKey, aData, nData) method.
**
** Insert or replace the entry with the key aKey[0..nKey-1]. The data for
** the new entry is aData[0..nData-1]. Return SQLITE_OK on success or an
** error code if the insert fails.
**
** The inputs aKey[] and aData[] are only valid until this routine
** returns. If the storage engine needs to keep that information
** long-term, it will need to make its own copy of these values.
**
** A transaction will always be active when this routine is called.
*/
static int kvlsmReplace(
KVStore *pKVStore,
const KVByteArray *aKey, KVSize nKey,
const KVByteArray *aData, KVSize nData
){
KVLsm *p = (KVLsm *)pKVStore;
return lsm_write(p->pDb, (void *)aKey, nKey, (void *)aData, nData);
}
/*
** Create a new cursor object.
*/
static int kvlsmOpenCursor(KVStore *pKVStore, KVCursor **ppKVCursor){
int rc = SQLITE_OK;
KVLsm *p = (KVLsm *)pKVStore;
KVLsmCsr *pCsr;
pCsr = (KVLsmCsr *)sqlite4_malloc(pKVStore->pEnv, sizeof(KVLsmCsr));
if( pCsr==0 ){
rc = SQLITE_NOMEM;
}else{
memset(pCsr, 0, sizeof(KVLsmCsr));
rc = lsm_csr_open(p->pDb, &pCsr->pCsr);
if( rc==SQLITE_OK ){
pCsr->base.pStore = pKVStore;
pCsr->base.pStoreVfunc = pKVStore->pStoreVfunc;
}else{
sqlite4_free(pCsr->base.pEnv, pCsr);
pCsr = 0;
}
}
*ppKVCursor = (KVCursor*)pCsr;
return rc;
}
/*
** Reset a cursor
*/
static int kvlsmReset(KVCursor *pKVCursor){
return SQLITE_OK;
}
/*
** Destroy a cursor object
*/
static int kvlsmCloseCursor(KVCursor *pKVCursor){
KVLsmCsr *pCsr = (KVLsmCsr *)pKVCursor;
lsm_csr_close(pCsr->pCsr);
sqlite4_free(pCsr->base.pEnv, pCsr);
return SQLITE_OK;
}
/*
** Move a cursor to the next non-deleted node.
*/
static int kvlsmNextEntry(KVCursor *pKVCursor){
int rc;
KVLsmCsr *pCsr = (KVLsmCsr *)pKVCursor;
if( lsm_csr_valid(pCsr->pCsr)==0 ) return SQLITE_NOTFOUND;
rc = lsm_csr_next(pCsr->pCsr);
if( rc==LSM_OK && lsm_csr_valid(pCsr->pCsr)==0 ){
rc = SQLITE_NOTFOUND;
}
return rc;
}
/*
** Move a cursor to the previous non-deleted node.
*/
static int kvlsmPrevEntry(KVCursor *pKVCursor){
int rc;
KVLsmCsr *pCsr = (KVLsmCsr *)pKVCursor;
if( lsm_csr_valid(pCsr->pCsr)==0 ) return SQLITE_NOTFOUND;
rc = lsm_csr_prev(pCsr->pCsr);
if( rc==LSM_OK && lsm_csr_valid(pCsr->pCsr)==0 ){
rc = SQLITE_NOTFOUND;
}
return rc;
}
/*
** Seek a cursor.
*/
static int kvlsmSeek(
KVCursor *pKVCursor,
const KVByteArray *aKey,
KVSize nKey,
int dir
){
int rc;
KVLsmCsr *pCsr = (KVLsmCsr *)pKVCursor;
assert( dir==0 || dir==1 || dir==-1 || dir==-2 );
assert( LSM_SEEK_EQ==0 && LSM_SEEK_GE==1 && LSM_SEEK_LE==-1 );
assert( LSM_SEEK_LEFAST==-2 );
rc = lsm_csr_seek(pCsr->pCsr, (void *)aKey, nKey, dir);
if( rc==SQLITE_OK ){
if( lsm_csr_valid(pCsr->pCsr)==0 ){
rc = SQLITE_NOTFOUND;
}else{
void *pDbKey;
int nDbKey;
rc = lsm_csr_key(pCsr->pCsr, &pDbKey, &nDbKey);
if( rc==SQLITE_OK && (nDbKey!=nKey || memcmp(pDbKey, aKey, nKey)) ){
rc = SQLITE_INEXACT;
}
}
}
return rc;
}
/*
** Delete the entry that the cursor is pointing to.
**
** Though the entry is "deleted", it still continues to exist as a
** phantom. Subsequent xNext or xPrev calls will work, as will
** calls to xKey and xData, thought the result from xKey and xData
** are undefined.
*/
static int kvlsmDelete(KVCursor *pKVCursor){
int rc;
void *pKey;
int nKey;
KVLsmCsr *pCsr = (KVLsmCsr *)pKVCursor;
assert( lsm_csr_valid(pCsr->pCsr) );
rc = lsm_csr_key(pCsr->pCsr, &pKey, &nKey);
if( rc==SQLITE_OK ){
rc = lsm_delete(((KVLsm *)(pKVCursor->pStore))->pDb, pKey, nKey);
}
return SQLITE_OK;
}
/*
** Return the key of the node the cursor is pointing to.
*/
static int kvlsmKey(
KVCursor *pKVCursor, /* The cursor whose key is desired */
const KVByteArray **paKey, /* Make this point to the key */
KVSize *pN /* Make this point to the size of the key */
){
KVLsmCsr *pCsr = (KVLsmCsr *)pKVCursor;
assert( lsm_csr_valid(pCsr->pCsr) );
return lsm_csr_key(pCsr->pCsr, (void **)paKey, (int *)pN);
}
/*
** Return the data of the node the cursor is pointing to.
*/
static int kvlsmData(
KVCursor *pKVCursor, /* The cursor from which to take the data */
KVSize ofst, /* Offset into the data to begin reading */
KVSize n, /* Number of bytes requested */
const KVByteArray **paData, /* Pointer to the data written here */
KVSize *pNData /* Number of bytes delivered */
){
KVLsmCsr *pCsr = (KVLsmCsr *)pKVCursor;
int rc;
void *pData;
int nData;
rc = lsm_csr_value(pCsr->pCsr, &pData, &nData);
if( rc==SQLITE_OK ){
if( n<0 ){
*paData = pData;
*pNData = nData;
}else{
int nOut = n;
if( (ofst+n)>nData ) nOut = nData - ofst;
if( nOut<0 ) nOut = 0;
*paData = &((u8 *)pData)[n];
*pNData = nOut;
}
}
return rc;
}
/*
** Destructor for the entire in-memory storage tree.
*/
static int kvlsmClose(KVStore *pKVStore){
KVLsm *p = (KVLsm *)pKVStore;
/* If there is an active transaction, roll it back. The important
** part is that the read-transaction cursor is closed. Otherwise, the
** call to lsm_close() below will fail. */
kvlsmRollback(pKVStore, 0);
assert( p->pCsr==0 );
lsm_close(p->pDb);
sqlite4_free(p->base.pEnv, p);
return SQLITE_OK;
}
static int kvlsmControl(KVStore *pKVStore, int op, void *pArg){
int rc = SQLITE_OK;
KVLsm *p = (KVLsm *)pKVStore;
switch( op ){
case SQLITE_KVCTRL_LSM_HANDLE: {
lsm_db **ppOut = (lsm_db **)pArg;
*ppOut = p->pDb;
break;
}
case SQLITE_KVCTRL_SYNCHRONOUS: {
int *peSafety = (int *)pArg;
int eParam = *peSafety + 1;
lsm_config(p->pDb, LSM_CONFIG_SAFETY, &eParam);
*peSafety = eParam-1;
break;
}
default:
rc = SQLITE_NOTFOUND;
break;
}
return rc;
}
/*
** Create a new in-memory storage engine and return a pointer to it.
*/
SQLITE_PRIVATE int sqlite4KVStoreOpenLsm(
sqlite4_env *pEnv, /* Run-time environment */
KVStore **ppKVStore, /* OUT: write the new KVStore here */
const char *zName, /* Name of the file to open */
unsigned openFlags /* Flags */
){
/* Virtual methods for an LSM data store */
static const KVStoreMethods kvlsmMethods = {
1, /* iVersion */
sizeof(KVStoreMethods), /* szSelf */
kvlsmReplace, /* xReplace */
kvlsmOpenCursor, /* xOpenCursor */
kvlsmSeek, /* xSeek */
kvlsmNextEntry, /* xNext */
kvlsmPrevEntry, /* xPrev */
kvlsmDelete, /* xDelete */
kvlsmKey, /* xKey */
kvlsmData, /* xData */
kvlsmReset, /* xReset */
kvlsmCloseCursor, /* xCloseCursor */
kvlsmBegin, /* xBegin */
kvlsmCommitPhaseOne, /* xCommitPhaseOne */
kvlsmCommitPhaseTwo, /* xCommitPhaseTwo */
kvlsmRollback, /* xRollback */
kvlsmRevert, /* xRevert */
kvlsmClose, /* xClose */
kvlsmControl /* xControl */
};
KVLsm *pNew;
int rc = SQLITE_OK;
pNew = (KVLsm *)sqlite4_malloc(pEnv, sizeof(KVLsm));
if( pNew==0 ){
rc = SQLITE_NOMEM;
}else{
memset(pNew, 0, sizeof(KVLsm));
pNew->base.pStoreVfunc = &kvlsmMethods;
pNew->base.pEnv = pEnv;
rc = lsm_new(0, &pNew->pDb);
if( rc==SQLITE_OK ){
rc = lsm_open(pNew->pDb, zName);
}
if( rc!=SQLITE_OK ){
lsm_close(pNew->pDb);
sqlite4_free(pEnv, pNew);
pNew = 0;
}
}
*ppKVStore = (KVStore*)pNew;
return rc;
}
/************** End of kvlsm.c ***********************************************/
/************** Begin file rowset.c ******************************************/
/*
** 2008 December 3
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** This module implements an object called a "RowSet".
**
** The RowSet object is a collection of database keys. Keys
** are inserted into the RowSet in an arbitrary order. Inserts
** can be intermixed with tests to see if a given key is present
** in the RowSet.
**
** After all inserts are finished, it is possible to extract the
** elements of the RowSet in sorted order. Once this extraction
** process has started, no new elements may be inserted.
**
** Hence, the primitive operations for a RowSet are:
**
** CREATE
** INSERT
** TEST
** SMALLEST
** DESTROY
**
** The CREATE and DESTROY primitives are the constructor and destructor,
** obviously. The INSERT primitive adds a new element to the RowSet.
** TEST checks to see if an element is already in the RowSet. SMALLEST
** extracts the least value from the RowSet.
**
** The INSERT primitive might allocate additional memory. Memory is
** allocated in chunks so most INSERTs do no allocation. There is an
** upper bound on the size of allocated memory. No memory is freed
** until DESTROY.
**
** The TEST primitive includes a "batch" number. The TEST primitive
** will only see elements that were inserted before the last change
** in the batch number. In other words, if an INSERT occurs between
** two TESTs where the TESTs have the same batch nubmer, then the
** value added by the INSERT will not be visible to the second TEST.
** The initial batch number is zero, so if the very first TEST contains
** a non-zero batch number, it will see all prior INSERTs.
**
** No INSERTs may occurs after a SMALLEST. An assertion will fail if
** that is attempted.
**
** The cost of an INSERT is roughly constant. (Sometime new memory
** has to be allocated on an INSERT.) The cost of a TEST with a new
** batch number is O(NlogN) where N is the number of elements in the RowSet.
** The cost of a TEST using the same batch number is O(logN). The cost
** of the first SMALLEST is O(NlogN). Second and subsequent SMALLEST
** primitives are constant time. The cost of DESTROY is O(N).
** There is an added cost of O(N) when switching between TEST and
** SMALLEST primitives.
*/
typedef struct RowSetEntry RowSetEntry;
typedef struct RowSetChunk RowSetChunk;
/*
** Target size for allocation chunks.
*/
/*
** Total size of allocation chunks, and the number of bytes of usable
** space per chunk.
*/
#define ROWSET_ALLOCATION_SIZE 1024
#define ROWSET_BYTES_PER_CHUNK (ROWSET_ALLOCATION_SIZE - sizeof(RowSetChunk))
/*
** Each entry in a RowSet is an instance of the following object.
*/
struct RowSetEntry {
struct RowSetEntry *pRight; /* Right subtree (larger entries) or list */
struct RowSetEntry *pLeft; /* Left subtree (smaller entries) */
int nKey; /* Number of bytes in buffer aKey[] */
u8 aKey[0]; /* Buffer containing nKey byte key */
};
/*
** RowSetEntry objects are allocated in large chunks (instances of the
** following structure) to reduce memory allocation overhead. The
** chunks are kept on a linked list so that they can be deallocated
** when the RowSet is destroyed.
*/
struct RowSetChunk {
struct RowSetChunk *pNextChunk; /* Next chunk on list of them all */
};
/*
** A RowSet in an instance of the following structure.
**
** A typedef of this structure if found in sqliteInt.h.
*/
struct RowSet {
struct RowSetChunk *pChunk; /* List of all chunk allocations */
sqlite4 *db; /* The database connection */
struct RowSetEntry *pEntry; /* List of entries using pRight */
struct RowSetEntry *pLast; /* Last entry on the pEntry list */
struct RowSetEntry *pTree; /* Binary tree of entries */
u8 *aSpace; /* Space for new entries */
u16 nSpace; /* Number of bytes in buffer aSpace */
u8 isSorted; /* True if pEntry is sorted */
u8 iBatch; /* Current insert batch */
};
/*
** Turn bulk memory into a RowSet object. N bytes of memory
** are available at pSpace. The db pointer is used as a memory context
** for any subsequent allocations that need to occur.
** Return a pointer to the new RowSet object.
**
** It must be the case that N is sufficient to make a Rowset. If not
** an assertion fault occurs.
**
** If N is larger than the minimum, use the surplus as an initial
** allocation of entries available to be filled.
*/
SQLITE_PRIVATE RowSet *sqlite4RowSetInit(sqlite4 *db, void *pSpace, unsigned int N){
RowSet *p;
assert( N >= ROUND8(sizeof(*p)) );
p = pSpace;
p->pChunk = 0;
p->db = db;
p->pEntry = 0;
p->pLast = 0;
p->pTree = 0;
p->aSpace = 0;
p->nSpace = 0;
p->isSorted = 1;
p->iBatch = 0;
return p;
}
/*
** Deallocate all chunks from a RowSet. This frees all memory that
** the RowSet has allocated over its lifetime. This routine is
** the destructor for the RowSet.
*/
SQLITE_PRIVATE void sqlite4RowSetClear(RowSet *p){
struct RowSetChunk *pChunk, *pNextChunk;
for(pChunk=p->pChunk; pChunk; pChunk = pNextChunk){
pNextChunk = pChunk->pNextChunk;
sqlite4DbFree(p->db, pChunk);
}
memset(p, 0, sizeof(RowSet));
p->isSorted = 1;
}
static u8 *rowsetAllocateChunk(RowSet *p, int nByte){
RowSetChunk *pNew; /* New RowSetChunk */
int nAlloc; /* Bytes to request from malloc() */
nAlloc = ROUND8(sizeof(RowSetChunk)) + nByte;
pNew = (RowSetChunk *)sqlite4DbMallocRaw(p->db, nAlloc);
return (pNew ? &((u8 *)pNew)[ROUND8(sizeof(RowSetChunk))] : 0);
}
static int rowsetEntryKeyCmp(RowSetEntry *pLeft, const u8 *aKey, int nKey){
int nCmp = SQLITE_MIN(pLeft->nKey, nKey);
int res;
res = memcmp(pLeft->aKey, aKey, nCmp);
return (res ? res : (pLeft->nKey - nKey));
}
static int rowsetEntryCmp(RowSetEntry *pLeft, RowSetEntry *pRight){
return rowsetEntryKeyCmp(pLeft, pRight->aKey, pRight->nKey);
}
/*
** Insert a new database key into a RowSet.
**
** The mallocFailed flag of the database connection is set if a
** memory allocation fails.
*/
SQLITE_PRIVATE void sqlite4RowSetInsert(RowSet *p, u8 *aKey, int nKey){
int nByte; /* Space (in bytes) required by new entry */
struct RowSetEntry *pEntry; /* The new entry */
struct RowSetEntry *pLast; /* The last prior entry */
assert( p!=0 );
nByte = ROUND8(sizeof(RowSetEntry) + nKey);
if( nByte>(ROWSET_BYTES_PER_CHUNK/4) ){
/* This is quite a large key. Store it in a chunk of its own. */
pEntry = (RowSetEntry *)rowsetAllocateChunk(p, nByte);
}else{
if( nByte>p->nSpace ){
p->aSpace = rowsetAllocateChunk(p, ROWSET_BYTES_PER_CHUNK);
p->nSpace = ROWSET_BYTES_PER_CHUNK;
}
pEntry = (RowSetEntry *)p->aSpace;
p->aSpace += nByte;
p->nSpace -= nByte;
}
if( pEntry==0 ) return;
pEntry->pRight = 0;
pEntry->pLeft = 0;
pEntry->nKey = nKey;
memcpy(pEntry->aKey, aKey, nKey);
pLast = p->pLast;
if( pLast ){
if( p->isSorted && rowsetEntryCmp(pEntry, pLast)<0 ){
p->isSorted = 0;
}
pLast->pRight = pEntry;
}else{
assert( p->pEntry==0 ); /* Fires if INSERT after SMALLEST */
p->pEntry = pEntry;
}
p->pLast = pEntry;
}
/*
** Merge two lists of RowSetEntry objects. Remove duplicates.
**
** The input lists are connected via pRight pointers and are
** assumed to each already be in sorted order.
*/
static struct RowSetEntry *rowSetMerge(
struct RowSetEntry *pA, /* First sorted list to be merged */
struct RowSetEntry *pB /* Second sorted list to be merged */
){
struct RowSetEntry head;
struct RowSetEntry *pTail;
pTail = &head;
while( pA && pB ){
int res;
assert( pA->pRight==0 || rowsetEntryCmp(pA, pA->pRight)<=0 );
assert( pB->pRight==0 || rowsetEntryCmp(pB, pB->pRight)<=0 );
res = rowsetEntryCmp(pA, pB);
if( res<0 ){
pTail->pRight = pA;
pA = pA->pRight;
pTail = pTail->pRight;
}else if( res>0 ){
pTail->pRight = pB;
pB = pB->pRight;
pTail = pTail->pRight;
}else{
pA = pA->pRight;
}
}
if( pA ){
assert( pA->pRight==0 || rowsetEntryCmp(pA, pA->pRight)<=0 );
pTail->pRight = pA;
}else{
assert( pB==0 || pB->pRight==0 || rowsetEntryCmp(pB, pB->pRight)<=0 );
pTail->pRight = pB;
}
return head.pRight;
}
/*
** Sort all elements on the pEntry list of the RowSet into ascending order.
*/
static void rowSetSort(RowSet *p){
unsigned int i;
struct RowSetEntry *pEntry;
struct RowSetEntry *aBucket[40];
assert( p->isSorted==0 );
memset(aBucket, 0, sizeof(aBucket));
while( p->pEntry ){
pEntry = p->pEntry;
p->pEntry = pEntry->pRight;
pEntry->pRight = 0;
for(i=0; aBucket[i]; i++){
pEntry = rowSetMerge(aBucket[i], pEntry);
aBucket[i] = 0;
}
aBucket[i] = pEntry;
}
pEntry = 0;
for(i=0; i<sizeof(aBucket)/sizeof(aBucket[0]); i++){
pEntry = rowSetMerge(pEntry, aBucket[i]);
}
p->pEntry = pEntry;
p->pLast = 0;
p->isSorted = 1;
}
/*
** The input, pIn, is a binary tree (or subtree) of RowSetEntry objects.
** Convert this tree into a linked list connected by the pRight pointers
** and return pointers to the first and last elements of the new list.
*/
static void rowSetTreeToList(
struct RowSetEntry *pIn, /* Root of the input tree */
struct RowSetEntry **ppFirst, /* Write head of the output list here */
struct RowSetEntry **ppLast /* Write tail of the output list here */
){
assert( pIn!=0 );
if( pIn->pLeft ){
struct RowSetEntry *p;
rowSetTreeToList(pIn->pLeft, ppFirst, &p);
p->pRight = pIn;
}else{
*ppFirst = pIn;
}
if( pIn->pRight ){
rowSetTreeToList(pIn->pRight, &pIn->pRight, ppLast);
}else{
*ppLast = pIn;
}
assert( (*ppLast)->pRight==0 );
}
/*
** Convert a sorted list of elements (connected by pRight) into a binary
** tree with depth of iDepth. A depth of 1 means the tree contains a single
** node taken from the head of *ppList. A depth of 2 means a tree with
** three nodes. And so forth.
**
** Use as many entries from the input list as required and update the
** *ppList to point to the unused elements of the list. If the input
** list contains too few elements, then construct an incomplete tree
** and leave *ppList set to NULL.
**
** Return a pointer to the root of the constructed binary tree.
*/
static struct RowSetEntry *rowSetNDeepTree(
struct RowSetEntry **ppList,
int iDepth
){
struct RowSetEntry *p; /* Root of the new tree */
struct RowSetEntry *pLeft; /* Left subtree */
if( *ppList==0 ){
return 0;
}
if( iDepth==1 ){
p = *ppList;
*ppList = p->pRight;
p->pLeft = p->pRight = 0;
return p;
}
pLeft = rowSetNDeepTree(ppList, iDepth-1);
p = *ppList;
if( p==0 ){
return pLeft;
}
p->pLeft = pLeft;
*ppList = p->pRight;
p->pRight = rowSetNDeepTree(ppList, iDepth-1);
return p;
}
/*
** Convert a sorted list of elements into a binary tree. Make the tree
** as deep as it needs to be in order to contain the entire list.
*/
static struct RowSetEntry *rowSetListToTree(struct RowSetEntry *pList){
int iDepth; /* Depth of the tree so far */
struct RowSetEntry *p; /* Current tree root */
struct RowSetEntry *pLeft; /* Left subtree */
assert( pList!=0 );
p = pList;
pList = p->pRight;
p->pLeft = p->pRight = 0;
for(iDepth=1; pList; iDepth++){
pLeft = p;
p = pList;
pList = p->pRight;
p->pLeft = pLeft;
p->pRight = rowSetNDeepTree(&pList, iDepth);
}
return p;
}
/*
** Convert the list in p->pEntry into a sorted list if it is not
** sorted already. If there is a binary tree on p->pTree, then
** convert it into a list too and merge it into the p->pEntry list.
*/
static void rowSetToList(RowSet *p){
if( !p->isSorted ){
rowSetSort(p);
}
if( p->pTree ){
struct RowSetEntry *pHead, *pTail;
rowSetTreeToList(p->pTree, &pHead, &pTail);
p->pTree = 0;
p->pEntry = rowSetMerge(p->pEntry, pHead);
}
}
/*
** Extract the smallest element from the RowSet.
** Write the element into *pRowid. Return 1 on success. Return
** 0 if the RowSet is already empty.
**
** After this routine has been called, the sqlite4RowSetInsert()
** routine may not be called again.
*/
SQLITE_PRIVATE int sqlite4RowSetNext(RowSet *p){
rowSetToList(p);
assert( p->pEntry );
p->pEntry = p->pEntry->pRight;
return (p->pEntry!=0);
}
SQLITE_PRIVATE const u8 *sqlite4RowSetRead(RowSet *p, int *pnKey){
const u8 *aRet = 0;
rowSetToList(p);
if( p->pEntry ){
*pnKey = p->pEntry->nKey;
aRet = p->pEntry->aKey;
}
return aRet;
}
/*
** Check to see if element aKey/nKey has been inserted into the the
** rowset as part of any insert batch prior to iBatch. Return 1 or 0.
*/
SQLITE_PRIVATE int sqlite4RowSetTest(RowSet *pRowSet, u8 iBatch, u8 *aKey, int nKey){
struct RowSetEntry *p;
if( iBatch!=pRowSet->iBatch ){
if( pRowSet->pEntry ){
rowSetToList(pRowSet);
pRowSet->pTree = rowSetListToTree(pRowSet->pEntry);
pRowSet->pEntry = 0;
pRowSet->pLast = 0;
}
pRowSet->iBatch = iBatch;
}
p = pRowSet->pTree;
while( p ){
int res = rowsetEntryKeyCmp(p, aKey, nKey);
if( res<0 ){
p = p->pRight;
}else if( res>0 ){
p = p->pLeft;
}else{
return 1;
}
}
return 0;
}
/************** End of rowset.c **********************************************/
/************** Begin file vdbemem.c *****************************************/
/*
** 2004 May 26
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code use to manipulate "Mem" structure. A "Mem"
** stores a single value in the VDBE. Mem is an opaque structure visible
** only within the VDBE. Interface routines refer to a Mem using the
** name sqlite_value
*/
/*
** If pMem is an object with a valid string representation, this routine
** ensures the internal encoding for the string representation is
** 'desiredEnc', one of SQLITE_UTF8, SQLITE_UTF16LE or SQLITE_UTF16BE.
**
** If pMem is not a string object, or the encoding of the string
** representation is already stored using the requested encoding, then this
** routine is a no-op.
**
** SQLITE_OK is returned if the conversion is successful (or not required).
** SQLITE_NOMEM may be returned if a malloc() fails during conversion
** between formats.
*/
SQLITE_PRIVATE int sqlite4VdbeChangeEncoding(Mem *pMem, int desiredEnc){
int rc;
assert( (pMem->flags&MEM_RowSet)==0 );
assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE
|| desiredEnc==SQLITE_UTF16BE );
if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){
return SQLITE_OK;
}
assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
#ifdef SQLITE_OMIT_UTF16
return SQLITE_ERROR;
#else
/* MemTranslate() may return SQLITE_OK or SQLITE_NOMEM. If NOMEM is returned,
** then the encoding of the value may not have changed.
*/
rc = sqlite4VdbeMemTranslate(pMem, (u8)desiredEnc);
assert(rc==SQLITE_OK || rc==SQLITE_NOMEM);
assert(rc==SQLITE_OK || pMem->enc!=desiredEnc);
assert(rc==SQLITE_NOMEM || pMem->enc==desiredEnc);
return rc;
#endif
}
/*
** Make sure pMem->z points to a writable allocation of at least
** n bytes.
**
** If the memory cell currently contains string or blob data
** and the third argument passed to this function is true, the
** current content of the cell is preserved. Otherwise, it may
** be discarded.
**
** This function sets the MEM_Dyn flag and clears any xDel callback.
** It also clears MEM_Ephem and MEM_Static. If the preserve flag is
** not set, Mem.n is zeroed.
*/
SQLITE_PRIVATE int sqlite4VdbeMemGrow(Mem *pMem, int n, int preserve){
assert( 1 >=
((pMem->zMalloc && pMem->zMalloc==pMem->z) ? 1 : 0) +
(((pMem->flags&MEM_Dyn)&&pMem->xDel) ? 1 : 0) +
((pMem->flags&MEM_Ephem) ? 1 : 0) +
((pMem->flags&MEM_Static) ? 1 : 0)
);
assert( (pMem->flags&MEM_RowSet)==0 );
if( n<32 ) n = 32;
if( sqlite4DbMallocSize(pMem->db, pMem->zMalloc)<n ){
if( preserve && pMem->z==pMem->zMalloc ){
pMem->z = pMem->zMalloc = sqlite4DbReallocOrFree(pMem->db, pMem->z, n);
preserve = 0;
}else{
sqlite4DbFree(pMem->db, pMem->zMalloc);
pMem->zMalloc = sqlite4DbMallocRaw(pMem->db, n);
}
}
if( pMem->z && preserve && pMem->zMalloc && pMem->z!=pMem->zMalloc ){
memcpy(pMem->zMalloc, pMem->z, pMem->n);
}
if( pMem->flags&MEM_Dyn && pMem->xDel ){
assert( pMem->xDel!=SQLITE_DYNAMIC );
pMem->xDel((void *)(pMem->z));
}
pMem->z = pMem->zMalloc;
if( pMem->z==0 ){
pMem->flags = MEM_Null;
}else{
pMem->flags &= ~(MEM_Ephem|MEM_Static);
}
pMem->xDel = 0;
return (pMem->z ? SQLITE_OK : SQLITE_NOMEM);
}
/*
** Make the given Mem object MEM_Dyn. In other words, make it so
** that any TEXT or BLOB content is stored in memory obtained from
** malloc(). In this way, we know that the memory is safe to be
** overwritten or altered.
**
** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
*/
SQLITE_PRIVATE int sqlite4VdbeMemMakeWriteable(Mem *pMem){
int f;
assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
assert( (pMem->flags&MEM_RowSet)==0 );
ExpandBlob(pMem);
f = pMem->flags;
if( (f&(MEM_Str|MEM_Blob)) && pMem->z!=pMem->zMalloc ){
if( sqlite4VdbeMemGrow(pMem, pMem->n + 2, 1) ){
return SQLITE_NOMEM;
}
pMem->z[pMem->n] = 0;
pMem->z[pMem->n+1] = 0;
pMem->flags |= MEM_Term;
#ifdef SQLITE_DEBUG
pMem->pScopyFrom = 0;
#endif
}
return SQLITE_OK;
}
/*
** Make sure the given Mem is \u0000 terminated.
*/
SQLITE_PRIVATE int sqlite4VdbeMemNulTerminate(Mem *pMem){
assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
if( (pMem->flags & MEM_Term)!=0 || (pMem->flags & MEM_Str)==0 ){
return SQLITE_OK; /* Nothing to do */
}
if( sqlite4VdbeMemGrow(pMem, pMem->n+2, 1) ){
return SQLITE_NOMEM;
}
pMem->z[pMem->n] = 0;
pMem->z[pMem->n+1] = 0;
pMem->flags |= MEM_Term;
return SQLITE_OK;
}
/*
** Add MEM_Str to the set of representations for the given Mem. Numbers
** are converted using sqlite4_snprintf(). Converting a BLOB to a string
** is a no-op.
**
** Existing representations MEM_Int and MEM_Real are *not* invalidated.
**
** A MEM_Null value will never be passed to this function. This function is
** used for converting values to text for returning to the user (i.e. via
** sqlite4_value_text()), or for ensuring that values to be used as btree
** keys are strings. In the former case a NULL pointer is returned the
** user and the later is an internal programming error.
*/
SQLITE_PRIVATE int sqlite4VdbeMemStringify(Mem *pMem, int enc){
int rc = SQLITE_OK;
int fg = pMem->flags;
const int nByte = 32;
assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
assert( !(fg&MEM_Zero) );
assert( !(fg&(MEM_Str|MEM_Blob)) );
assert( fg&(MEM_Int|MEM_Real) );
assert( (pMem->flags&MEM_RowSet)==0 );
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
if( sqlite4VdbeMemGrow(pMem, nByte, 0) ){
return SQLITE_NOMEM;
}
/* For a Real or Integer, use sqlite4_mprintf() to produce the UTF-8
** string representation of the value. Then, if the required encoding
** is UTF-16le or UTF-16be do a translation.
**
** FIX ME: It would be better if sqlite4_snprintf() could do UTF-16.
*/
if( fg & MEM_Int ){
sqlite4_snprintf(pMem->z, nByte, "%lld", pMem->u.i);
}else{
assert( fg & MEM_Real );
sqlite4_snprintf(pMem->z, nByte, "%!.15g", pMem->r);
}
pMem->n = sqlite4Strlen30(pMem->z);
pMem->enc = SQLITE_UTF8;
pMem->flags |= MEM_Str|MEM_Term;
sqlite4VdbeChangeEncoding(pMem, enc);
return rc;
}
/*
** Memory cell pMem contains the context of an aggregate function.
** This routine calls the finalize method for that function. The
** result of the aggregate is stored back into pMem.
**
** Return SQLITE_ERROR if the finalizer reports an error. SQLITE_OK
** otherwise.
*/
SQLITE_PRIVATE int sqlite4VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
int rc = SQLITE_OK;
if( ALWAYS(pFunc && pFunc->xFinalize) ){
sqlite4_context ctx;
assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
memset(&ctx, 0, sizeof(ctx));
ctx.s.flags = MEM_Null;
ctx.s.db = pMem->db;
ctx.pMem = pMem;
ctx.pFunc = pFunc;
pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */
assert( 0==(pMem->flags&MEM_Dyn) && !pMem->xDel );
sqlite4DbFree(pMem->db, pMem->zMalloc);
memcpy(pMem, &ctx.s, sizeof(ctx.s));
rc = ctx.isError;
}
return rc;
}
/*
** If the memory cell contains a string value that must be freed by
** invoking an external callback, free it now. Calling this function
** does not free any Mem.zMalloc buffer.
*/
SQLITE_PRIVATE void sqlite4VdbeMemReleaseExternal(Mem *p){
assert( p->db==0 || sqlite4_mutex_held(p->db->mutex) );
if( p->flags&MEM_Agg ){
sqlite4VdbeMemFinalize(p, p->u.pDef);
assert( (p->flags & MEM_Agg)==0 );
sqlite4VdbeMemRelease(p);
}else if( p->flags&MEM_Dyn && p->xDel ){
assert( (p->flags&MEM_RowSet)==0 );
assert( p->xDel!=SQLITE_DYNAMIC );
p->xDel((void *)p->z);
p->xDel = 0;
}else if( p->flags&MEM_RowSet ){
sqlite4RowSetClear(p->u.pRowSet);
}else if( p->flags&MEM_Frame ){
sqlite4VdbeMemSetNull(p);
}
}
/*
** Release any memory held by the Mem. This may leave the Mem in an
** inconsistent state, for example with (Mem.z==0) and
** (Mem.type==SQLITE_TEXT).
*/
SQLITE_PRIVATE void sqlite4VdbeMemRelease(Mem *p){
VdbeMemRelease(p);
sqlite4DbFree(p->db, p->zMalloc);
p->z = 0;
p->zMalloc = 0;
p->xDel = 0;
}
/*
** Convert a 64-bit IEEE double into a 64-bit signed integer.
** If the double is too large, return 0x8000000000000000.
**
** Most systems appear to do this simply by assigning
** variables and without the extra range tests. But
** there are reports that windows throws an expection
** if the floating point value is out of range. (See ticket #2880.)
** Because we do not completely understand the problem, we will
** take the conservative approach and always do range tests
** before attempting the conversion.
*/
static i64 doubleToInt64(double r){
#ifdef SQLITE_OMIT_FLOATING_POINT
/* When floating-point is omitted, double and int64 are the same thing */
return r;
#else
/*
** Many compilers we encounter do not define constants for the
** minimum and maximum 64-bit integers, or they define them
** inconsistently. And many do not understand the "LL" notation.
** So we define our own static constants here using nothing
** larger than a 32-bit integer constant.
*/
static const i64 maxInt = LARGEST_INT64;
static const i64 minInt = SMALLEST_INT64;
if( r<(double)minInt ){
return minInt;
}else if( r>(double)maxInt ){
/* minInt is correct here - not maxInt. It turns out that assigning
** a very large positive number to an integer results in a very large
** negative integer. This makes no sense, but it is what x86 hardware
** does so for compatibility we will do the same in software. */
return minInt;
}else{
return (i64)r;
}
#endif
}
/*
** Return some kind of integer value which is the best we can do
** at representing the value that *pMem describes as an integer.
** If pMem is an integer, then the value is exact. If pMem is
** a floating-point then the value returned is the integer part.
** If pMem is a string or blob, then we make an attempt to convert
** it into a integer and return that. If pMem represents an
** an SQL-NULL value, return 0.
**
** If pMem represents a string value, its encoding might be changed.
*/
SQLITE_PRIVATE i64 sqlite4VdbeIntValue(Mem *pMem){
int flags;
assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
flags = pMem->flags;
if( flags & MEM_Int ){
return pMem->u.i;
}else if( flags & MEM_Real ){
return doubleToInt64(pMem->r);
}else if( flags & (MEM_Str|MEM_Blob) ){
i64 value = 0;
assert( pMem->z || pMem->n==0 );
testcase( pMem->z==0 );
sqlite4Atoi64(pMem->z, &value, pMem->n, pMem->enc);
return value;
}else{
return 0;
}
}
/*
** Return the best representation of pMem that we can get into a
** double. If pMem is already a double or an integer, return its
** value. If it is a string or blob, try to convert it to a double.
** If it is a NULL, return 0.0.
*/
SQLITE_PRIVATE double sqlite4VdbeRealValue(Mem *pMem){
assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
if( pMem->flags & MEM_Real ){
return pMem->r;
}else if( pMem->flags & MEM_Int ){
return (double)pMem->u.i;
}else if( pMem->flags & (MEM_Str|MEM_Blob) ){
/* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
double val = (double)0;
sqlite4AtoF(pMem->z, &val, pMem->n, pMem->enc);
return val;
}else{
/* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
return (double)0;
}
}
/*
** The MEM structure is already a MEM_Real. Try to also make it a
** MEM_Int if we can.
*/
SQLITE_PRIVATE void sqlite4VdbeIntegerAffinity(Mem *pMem){
assert( pMem->flags & MEM_Real );
assert( (pMem->flags & MEM_RowSet)==0 );
assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
pMem->u.i = doubleToInt64(pMem->r);
/* Only mark the value as an integer if
**
** (1) the round-trip conversion real->int->real is a no-op, and
** (2) The integer is neither the largest nor the smallest
** possible integer (ticket #3922)
**
** The second and third terms in the following conditional enforces
** the second condition under the assumption that addition overflow causes
** values to wrap around. On x86 hardware, the third term is always
** true and could be omitted. But we leave it in because other
** architectures might behave differently.
*/
if( pMem->r==(double)pMem->u.i && pMem->u.i>SMALLEST_INT64
&& ALWAYS(pMem->u.i<LARGEST_INT64) ){
pMem->flags |= MEM_Int;
}
}
/*
** Convert pMem to type integer. Invalidate any prior representations.
*/
SQLITE_PRIVATE int sqlite4VdbeMemIntegerify(Mem *pMem){
assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
assert( (pMem->flags & MEM_RowSet)==0 );
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
pMem->u.i = sqlite4VdbeIntValue(pMem);
MemSetTypeFlag(pMem, MEM_Int);
return SQLITE_OK;
}
/*
** Convert pMem so that it is of type MEM_Real.
** Invalidate any prior representations.
*/
SQLITE_PRIVATE int sqlite4VdbeMemRealify(Mem *pMem){
assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
pMem->r = sqlite4VdbeRealValue(pMem);
MemSetTypeFlag(pMem, MEM_Real);
return SQLITE_OK;
}
/*
** Convert pMem so that it has types MEM_Real or MEM_Int or both.
** Invalidate any prior representations.
**
** Every effort is made to force the conversion, even if the input
** is a string that does not look completely like a number. Convert
** as much of the string as we can and ignore the rest.
*/
SQLITE_PRIVATE int sqlite4VdbeMemNumerify(Mem *pMem){
if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){
assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
if( 0==sqlite4Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc) ){
MemSetTypeFlag(pMem, MEM_Int);
}else{
pMem->r = sqlite4VdbeRealValue(pMem);
MemSetTypeFlag(pMem, MEM_Real);
sqlite4VdbeIntegerAffinity(pMem);
}
}
assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 );
pMem->flags &= ~(MEM_Str|MEM_Blob);
return SQLITE_OK;
}
/*
** Delete any previous value and set the value stored in *pMem to NULL.
*/
SQLITE_PRIVATE void sqlite4VdbeMemSetNull(Mem *pMem){
if( pMem->flags & MEM_Frame ){
VdbeFrame *pFrame = pMem->u.pFrame;
pFrame->pParent = pFrame->v->pDelFrame;
pFrame->v->pDelFrame = pFrame;
}
if( pMem->flags & MEM_RowSet ){
sqlite4RowSetClear(pMem->u.pRowSet);
}
MemSetTypeFlag(pMem, MEM_Null);
pMem->type = SQLITE_NULL;
}
/*
** Delete any previous value and set the value to be a BLOB of length
** n containing all zeros.
*/
SQLITE_PRIVATE void sqlite4VdbeMemSetZeroBlob(Mem *pMem, int n){
sqlite4VdbeMemRelease(pMem);
pMem->flags = MEM_Blob|MEM_Zero;
pMem->type = SQLITE_BLOB;
pMem->n = 0;
if( n<0 ) n = 0;
pMem->u.nZero = n;
pMem->enc = SQLITE_UTF8;
}
/*
** Delete any previous value and set the value stored in *pMem to val,
** manifest type INTEGER.
*/
SQLITE_PRIVATE void sqlite4VdbeMemSetInt64(Mem *pMem, i64 val){
sqlite4VdbeMemRelease(pMem);
pMem->u.i = val;
pMem->flags = MEM_Int;
pMem->type = SQLITE_INTEGER;
}
#ifndef SQLITE_OMIT_FLOATING_POINT
/*
** Delete any previous value and set the value stored in *pMem to val,
** manifest type REAL.
*/
SQLITE_PRIVATE void sqlite4VdbeMemSetDouble(Mem *pMem, double val){
if( sqlite4IsNaN(val) ){
sqlite4VdbeMemSetNull(pMem);
}else{
sqlite4VdbeMemRelease(pMem);
pMem->r = val;
pMem->flags = MEM_Real;
pMem->type = SQLITE_FLOAT;
}
}
#endif
/*
** Delete any previous value and set the value of pMem to be an
** empty RowSet object.
*/
SQLITE_PRIVATE void sqlite4VdbeMemSetRowSet(Mem *pMem){
sqlite4 *db = pMem->db;
assert( db!=0 );
assert( (pMem->flags & MEM_RowSet)==0 );
sqlite4VdbeMemRelease(pMem);
sqlite4VdbeMemGrow(pMem, 64, 0);
if( db->mallocFailed ){
pMem->flags = MEM_Null;
}else{
int nAlloc = sqlite4DbMallocSize(db, pMem->zMalloc);
pMem->u.pRowSet = sqlite4RowSetInit(db, pMem->zMalloc, nAlloc);
pMem->flags = MEM_RowSet;
}
}
/*
** Return true if the Mem object contains a TEXT or BLOB that is
** too large - whose size exceeds SQLITE_MAX_LENGTH.
*/
SQLITE_PRIVATE int sqlite4VdbeMemTooBig(Mem *p){
assert( p->db!=0 );
if( p->flags & (MEM_Str|MEM_Blob) ){
int n = p->n;
if( p->flags & MEM_Zero ){
n += p->u.nZero;
}
return n>p->db->aLimit[SQLITE_LIMIT_LENGTH];
}
return 0;
}
#ifdef SQLITE_DEBUG
/*
** This routine prepares a memory cell for modication by breaking
** its link to a shallow copy and by marking any current shallow
** copies of this cell as invalid.
**
** This is used for testing and debugging only - to make sure shallow
** copies are not misused.
*/
SQLITE_PRIVATE void sqlite4VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
int i;
Mem *pX;
for(i=1, pX=&pVdbe->aMem[1]; i<=pVdbe->nMem; i++, pX++){
if( pX->pScopyFrom==pMem ){
pX->flags |= MEM_Invalid;
pX->pScopyFrom = 0;
}
}
pMem->pScopyFrom = 0;
}
#endif /* SQLITE_DEBUG */
/*
** Size of struct Mem not including the Mem.zMalloc member.
*/
#define MEMCELLSIZE (size_t)(&(((Mem *)0)->zMalloc))
/*
** Make an shallow copy of pFrom into pTo. Prior contents of
** pTo are freed. The pFrom->z field is not duplicated. If
** pFrom->z is used, then pTo->z points to the same thing as pFrom->z
** and flags gets srcType (either MEM_Ephem or MEM_Static).
*/
SQLITE_PRIVATE void sqlite4VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
assert( (pFrom->flags & MEM_RowSet)==0 );
VdbeMemRelease(pTo);
memcpy(pTo, pFrom, MEMCELLSIZE);
pTo->xDel = 0;
if( (pFrom->flags&MEM_Static)==0 ){
pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem);
assert( srcType==MEM_Ephem || srcType==MEM_Static );
pTo->flags |= srcType;
}
}
/*
** Make a full copy of pFrom into pTo. Prior contents of pTo are
** freed before the copy is made.
*/
SQLITE_PRIVATE int sqlite4VdbeMemCopy(Mem *pTo, const Mem *pFrom){
int rc = SQLITE_OK;
assert( (pFrom->flags & MEM_RowSet)==0 );
VdbeMemRelease(pTo);
memcpy(pTo, pFrom, MEMCELLSIZE);
pTo->flags &= ~MEM_Dyn;
if( pTo->flags&(MEM_Str|MEM_Blob) ){
if( 0==(pFrom->flags&MEM_Static) ){
pTo->flags |= MEM_Ephem;
rc = sqlite4VdbeMemMakeWriteable(pTo);
}
}
return rc;
}
/*
** Transfer the contents of pFrom to pTo. Any existing value in pTo is
** freed. If pFrom contains ephemeral data, a copy is made.
**
** pFrom contains an SQL NULL when this routine returns.
*/
SQLITE_PRIVATE void sqlite4VdbeMemMove(Mem *pTo, Mem *pFrom){
assert( pFrom->db==0 || sqlite4_mutex_held(pFrom->db->mutex) );
assert( pTo->db==0 || sqlite4_mutex_held(pTo->db->mutex) );
assert( pFrom->db==0 || pTo->db==0 || pFrom->db==pTo->db );
sqlite4VdbeMemRelease(pTo);
memcpy(pTo, pFrom, sizeof(Mem));
pFrom->flags = MEM_Null;
pFrom->xDel = 0;
pFrom->zMalloc = 0;
}
/*
** Change the value of a Mem to be a string or a BLOB.
**
** The memory management strategy depends on the value of the xDel
** parameter. If the value passed is SQLITE_TRANSIENT, then the
** string is copied into a (possibly existing) buffer managed by the
** Mem structure. Otherwise, any existing buffer is freed and the
** pointer copied.
**
** If the string is too large (if it exceeds the SQLITE_LIMIT_LENGTH
** size limit) then no memory allocation occurs. If the string can be
** stored without allocating memory, then it is. If a memory allocation
** is required to store the string, then value of pMem is unchanged. In
** either case, SQLITE_TOOBIG is returned.
*/
SQLITE_PRIVATE int sqlite4VdbeMemSetStr(
Mem *pMem, /* Memory cell to set to string value */
const char *z, /* String pointer */
int n, /* Bytes in string, or negative */
u8 enc, /* Encoding of z. 0 for BLOBs */
void (*xDel)(void*) /* Destructor function */
){
int nByte = n; /* New value for pMem->n */
int iLimit; /* Maximum allowed string or blob size */
u16 flags = 0; /* New value for pMem->flags */
assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
assert( (pMem->flags & MEM_RowSet)==0 );
/* If z is a NULL pointer, set pMem to contain an SQL NULL. */
if( !z ){
sqlite4VdbeMemSetNull(pMem);
return SQLITE_OK;
}
if( pMem->db ){
iLimit = pMem->db->aLimit[SQLITE_LIMIT_LENGTH];
}else{
iLimit = SQLITE_MAX_LENGTH;
}
flags = (enc==0?MEM_Blob:MEM_Str);
if( nByte<0 ){
assert( enc!=0 );
if( enc==SQLITE_UTF8 ){
for(nByte=0; nByte<=iLimit && z[nByte]; nByte++){}
}else{
for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){}
}
flags |= MEM_Term;
}
/* The following block sets the new values of Mem.z and Mem.xDel. It
** also sets a flag in local variable "flags" to indicate the memory
** management (one of MEM_Dyn or MEM_Static).
*/
if( xDel==SQLITE_TRANSIENT ){
int nAlloc = nByte;
if( flags&MEM_Term ){
nAlloc += (enc==SQLITE_UTF8?1:2);
}
if( nByte>iLimit ){
return SQLITE_TOOBIG;
}
if( sqlite4VdbeMemGrow(pMem, nAlloc, 0) ){
return SQLITE_NOMEM;
}
memcpy(pMem->z, z, nAlloc);
}else if( xDel==SQLITE_DYNAMIC ){
sqlite4VdbeMemRelease(pMem);
pMem->zMalloc = pMem->z = (char *)z;
pMem->xDel = 0;
}else{
sqlite4VdbeMemRelease(pMem);
pMem->z = (char *)z;
pMem->xDel = xDel;
flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn);
}
pMem->n = nByte;
pMem->flags = flags;
pMem->enc = (enc==0 ? SQLITE_UTF8 : enc);
pMem->type = (enc==0 ? SQLITE_BLOB : SQLITE_TEXT);
#ifndef SQLITE_OMIT_UTF16
if( pMem->enc!=SQLITE_UTF8 && sqlite4VdbeMemHandleBom(pMem) ){
return SQLITE_NOMEM;
}
#endif
if( nByte>iLimit ){
return SQLITE_TOOBIG;
}
return SQLITE_OK;
}
/*
** Compare the values contained by the two memory cells, returning
** negative, zero or positive if pMem1 is less than, equal to, or greater
** than pMem2. Sorting order is NULL's first, followed by numbers (integers
** and reals) sorted numerically, followed by text ordered by the collating
** sequence pColl and finally blob's ordered by memcmp().
**
** Two NULL values are considered equal by this function.
*/
SQLITE_PRIVATE int sqlite4MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
int rc;
int f1, f2;
int combined_flags;
f1 = pMem1->flags;
f2 = pMem2->flags;
combined_flags = f1|f2;
assert( (combined_flags & MEM_RowSet)==0 );
/* If one value is NULL, it is less than the other. If both values
** are NULL, return 0.
*/
if( combined_flags&MEM_Null ){
return (f2&MEM_Null) - (f1&MEM_Null);
}
/* If one value is a number and the other is not, the number is less.
** If both are numbers, compare as reals if one is a real, or as integers
** if both values are integers.
*/
if( combined_flags&(MEM_Int|MEM_Real) ){
if( !(f1&(MEM_Int|MEM_Real)) ){
return 1;
}
if( !(f2&(MEM_Int|MEM_Real)) ){
return -1;
}
if( (f1 & f2 & MEM_Int)==0 ){
double r1, r2;
if( (f1&MEM_Real)==0 ){
r1 = (double)pMem1->u.i;
}else{
r1 = pMem1->r;
}
if( (f2&MEM_Real)==0 ){
r2 = (double)pMem2->u.i;
}else{
r2 = pMem2->r;
}
if( r1<r2 ) return -1;
if( r1>r2 ) return 1;
return 0;
}else{
assert( f1&MEM_Int );
assert( f2&MEM_Int );
if( pMem1->u.i < pMem2->u.i ) return -1;
if( pMem1->u.i > pMem2->u.i ) return 1;
return 0;
}
}
/* If one value is a string and the other is a blob, the string is less.
** If both are strings, compare using the collating functions.
*/
if( combined_flags&MEM_Str ){
if( (f1 & MEM_Str)==0 ){
return 1;
}
if( (f2 & MEM_Str)==0 ){
return -1;
}
assert( pMem1->enc==pMem2->enc );
assert( pMem1->enc==SQLITE_UTF8 ||
pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE );
/* The collation sequence must be defined at this point, even if
** the user deletes the collation sequence after the vdbe program is
** compiled (this was not always the case).
*/
assert( !pColl || pColl->xCmp );
if( pColl ){
if( pMem1->enc==pColl->enc ){
/* The strings are already in the correct encoding. Call the
** comparison function directly */
return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z);
}else{
const void *v1, *v2;
int n1, n2;
Mem c1;
Mem c2;
memset(&c1, 0, sizeof(c1));
memset(&c2, 0, sizeof(c2));
sqlite4VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem);
sqlite4VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem);
v1 = sqlite4ValueText((sqlite4_value*)&c1, pColl->enc);
n1 = v1==0 ? 0 : c1.n;
v2 = sqlite4ValueText((sqlite4_value*)&c2, pColl->enc);
n2 = v2==0 ? 0 : c2.n;
rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2);
sqlite4VdbeMemRelease(&c1);
sqlite4VdbeMemRelease(&c2);
return rc;
}
}
/* If a NULL pointer was passed as the collate function, fall through
** to the blob case and use memcmp(). */
}
/* Both values must be blobs. Compare using memcmp(). */
rc = memcmp(pMem1->z, pMem2->z, (pMem1->n>pMem2->n)?pMem2->n:pMem1->n);
if( rc==0 ){
rc = pMem1->n - pMem2->n;
}
return rc;
}
/* This function is only available internally, it is not part of the
** external API. It works in a similar way to sqlite4_value_text(),
** except the data returned is in the encoding specified by the second
** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or
** SQLITE_UTF8.
**
** (2006-02-16:) The enc value can be or-ed with SQLITE_UTF16_ALIGNED.
** If that is the case, then the result must be aligned on an even byte
** boundary.
*/
SQLITE_PRIVATE const void *sqlite4ValueText(sqlite4_value* pVal, u8 enc){
if( !pVal ) return 0;
assert( pVal->db==0 || sqlite4_mutex_held(pVal->db->mutex) );
assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
assert( (pVal->flags & MEM_RowSet)==0 );
if( pVal->flags&MEM_Null ){
return 0;
}
assert( (MEM_Blob>>3) == MEM_Str );
pVal->flags |= (pVal->flags & MEM_Blob)>>3;
ExpandBlob(pVal);
if( pVal->flags&MEM_Str ){
sqlite4VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED);
if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&SQLITE_PTR_TO_INT(pVal->z)) ){
assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 );
if( sqlite4VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){
return 0;
}
}
sqlite4VdbeMemNulTerminate(pVal); /* IMP: R-31275-44060 */
}else{
assert( (pVal->flags&MEM_Blob)==0 );
sqlite4VdbeMemStringify(pVal, enc);
assert( 0==(1&SQLITE_PTR_TO_INT(pVal->z)) );
}
assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0
|| pVal->db->mallocFailed );
if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){
return pVal->z;
}else{
return 0;
}
}
/*
** Create a new sqlite4_value object.
*/
SQLITE_PRIVATE sqlite4_value *sqlite4ValueNew(sqlite4 *db){
Mem *p = sqlite4DbMallocZero(db, sizeof(*p));
if( p ){
p->flags = MEM_Null;
p->type = SQLITE_NULL;
p->db = db;
}
return p;
}
/*
** Create a new sqlite4_value object, containing the value of pExpr.
**
** This only works for very simple expressions that consist of one constant
** token (i.e. "5", "5.1", "'a string'"). If the expression can
** be converted directly into a value, then the value is allocated and
** a pointer written to *ppVal. The caller is responsible for deallocating
** the value by passing it to sqlite4ValueFree() later on. If the expression
** cannot be converted to a value, then *ppVal is set to NULL.
*/
SQLITE_PRIVATE int sqlite4ValueFromExpr(
sqlite4 *db, /* The database connection */
Expr *pExpr, /* The expression to evaluate */
u8 enc, /* Encoding to use */
u8 affinity, /* Affinity to use */
sqlite4_value **ppVal /* Write the new value here */
){
int op;
char *zVal = 0;
sqlite4_value *pVal = 0;
int negInt = 1;
const char *zNeg = "";
if( !pExpr ){
*ppVal = 0;
return SQLITE_OK;
}
op = pExpr->op;
/* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT3.
** The ifdef here is to enable us to achieve 100% branch test coverage even
** when SQLITE_ENABLE_STAT3 is omitted.
*/
#ifdef SQLITE_ENABLE_STAT3
if( op==TK_REGISTER ) op = pExpr->op2;
#else
if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
#endif
/* Handle negative integers in a single step. This is needed in the
** case when the value is -9223372036854775808.
*/
if( op==TK_UMINUS
&& (pExpr->pLeft->op==TK_INTEGER || pExpr->pLeft->op==TK_FLOAT) ){
pExpr = pExpr->pLeft;
op = pExpr->op;
negInt = -1;
zNeg = "-";
}
if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){
pVal = sqlite4ValueNew(db);
if( pVal==0 ) goto no_mem;
if( ExprHasProperty(pExpr, EP_IntValue) ){
sqlite4VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt);
}else{
zVal = sqlite4MPrintf(db, "%s%s", zNeg, pExpr->u.zToken);
if( zVal==0 ) goto no_mem;
sqlite4ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);
if( op==TK_FLOAT ) pVal->type = SQLITE_FLOAT;
}
if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){
sqlite4ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8);
}else{
sqlite4ValueApplyAffinity(pVal, affinity, SQLITE_UTF8);
}
if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str;
if( enc!=SQLITE_UTF8 ){
sqlite4VdbeChangeEncoding(pVal, enc);
}
}else if( op==TK_UMINUS ) {
/* This branch happens for multiple negative signs. Ex: -(-5) */
if( SQLITE_OK==sqlite4ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) ){
sqlite4VdbeMemNumerify(pVal);
if( pVal->u.i==SMALLEST_INT64 ){
pVal->flags &= MEM_Int;
pVal->flags |= MEM_Real;
pVal->r = (double)LARGEST_INT64;
}else{
pVal->u.i = -pVal->u.i;
}
pVal->r = -pVal->r;
sqlite4ValueApplyAffinity(pVal, affinity, enc);
}
}else if( op==TK_NULL ){
pVal = sqlite4ValueNew(db);
if( pVal==0 ) goto no_mem;
}
#ifndef SQLITE_OMIT_BLOB_LITERAL
else if( op==TK_BLOB ){
int nVal;
assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' );
assert( pExpr->u.zToken[1]=='\'' );
pVal = sqlite4ValueNew(db);
if( !pVal ) goto no_mem;
zVal = &pExpr->u.zToken[2];
nVal = sqlite4Strlen30(zVal)-1;
assert( zVal[nVal]=='\'' );
sqlite4VdbeMemSetStr(pVal, sqlite4HexToBlob(db, zVal, nVal), nVal/2,
0, SQLITE_DYNAMIC);
}
#endif
if( pVal ){
sqlite4VdbeMemStoreType(pVal);
}
*ppVal = pVal;
return SQLITE_OK;
no_mem:
db->mallocFailed = 1;
sqlite4DbFree(db, zVal);
sqlite4ValueFree(pVal);
*ppVal = 0;
return SQLITE_NOMEM;
}
/*
** Change the string value of an sqlite4_value object
*/
SQLITE_PRIVATE void sqlite4ValueSetStr(
sqlite4_value *v, /* Value to be set */
int n, /* Length of string z */
const void *z, /* Text of the new string */
u8 enc, /* Encoding to use */
void (*xDel)(void*) /* Destructor for the string */
){
if( v ) sqlite4VdbeMemSetStr((Mem *)v, z, n, enc, xDel);
}
/*
** Free an sqlite4_value object
*/
SQLITE_PRIVATE void sqlite4ValueFree(sqlite4_value *v){
if( !v ) return;
sqlite4VdbeMemRelease((Mem *)v);
sqlite4DbFree(((Mem*)v)->db, v);
}
/*
** Return the number of bytes in the sqlite4_value object assuming
** that it uses the encoding "enc"
*/
SQLITE_PRIVATE int sqlite4ValueBytes(sqlite4_value *pVal, u8 enc){
Mem *p = (Mem*)pVal;
if( (p->flags & MEM_Blob)!=0 || sqlite4ValueText(pVal, enc) ){
if( p->flags & MEM_Zero ){
return p->n + p->u.nZero;
}else{
return p->n;
}
}
return 0;
}
/************** End of vdbemem.c *********************************************/
/************** Begin file vdbeaux.c *****************************************/
/*
** 2003 September 6
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used for creating, destroying, and populating
** a VDBE (or an "sqlite4_stmt" as it is known to the outside world.) Prior
** to version 2.8.7, all this code was combined into the vdbe.c source file.
** But that file was getting too big so this subroutines were split out.
*/
/*
** When debugging the code generator in a symbolic debugger, one can
** set the sqlite4VdbeAddopTrace to 1 and all opcodes will be printed
** as they are added to the instruction stream.
*/
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE int sqlite4VdbeAddopTrace = 0;
#endif
/*
** Create a new virtual database engine.
*/
SQLITE_PRIVATE Vdbe *sqlite4VdbeCreate(sqlite4 *db){
Vdbe *p;
p = sqlite4DbMallocZero(db, sizeof(Vdbe) );
if( p==0 ) return 0;
p->db = db;
if( db->pVdbe ){
db->pVdbe->pPrev = p;
}
p->pNext = db->pVdbe;
p->pPrev = 0;
db->pVdbe = p;
p->magic = VDBE_MAGIC_INIT;
return p;
}
/*
** Remember the SQL string for a prepared statement.
*/
SQLITE_PRIVATE void sqlite4VdbeSetSql(Vdbe *p, const char *z, int n){
if( p==0 ) return;
assert( p->zSql==0 );
p->zSql = sqlite4DbStrNDup(p->db, z, n);
}
/*
** Return the SQL associated with a prepared statement
*/
SQLITE_API const char *sqlite4_sql(sqlite4_stmt *pStmt){
Vdbe *p = (Vdbe *)pStmt;
return p ? p->zSql : 0;
}
/*
** Swap all content between two VDBE structures.
*/
SQLITE_PRIVATE void sqlite4VdbeSwap(Vdbe *pA, Vdbe *pB){
Vdbe tmp, *pTmp;
char *zTmp;
tmp = *pA;
*pA = *pB;
*pB = tmp;
pTmp = pA->pNext;
pA->pNext = pB->pNext;
pB->pNext = pTmp;
pTmp = pA->pPrev;
pA->pPrev = pB->pPrev;
pB->pPrev = pTmp;
zTmp = pA->zSql;
pA->zSql = pB->zSql;
pB->zSql = zTmp;
}
#ifdef SQLITE_DEBUG
/*
** Turn tracing on or off
*/
SQLITE_PRIVATE void sqlite4VdbeTrace(Vdbe *p, FILE *trace){
p->trace = trace;
}
#endif
/*
** Resize the Vdbe.aOp array so that it is at least one op larger than
** it was.
**
** If an out-of-memory error occurs while resizing the array, return
** SQLITE_NOMEM. In this case Vdbe.aOp and Vdbe.nOpAlloc remain
** unchanged (this is so that any opcodes already allocated can be
** correctly deallocated along with the rest of the Vdbe).
*/
static int growOpArray(Vdbe *p){
VdbeOp *pNew;
int nNew = (p->nOpAlloc ? p->nOpAlloc*2 : (int)(1024/sizeof(Op)));
pNew = sqlite4DbRealloc(p->db, p->aOp, nNew*sizeof(Op));
if( pNew ){
p->nOpAlloc = sqlite4DbMallocSize(p->db, pNew)/sizeof(Op);
p->aOp = pNew;
}
return (pNew ? SQLITE_OK : SQLITE_NOMEM);
}
/*
** Add a new instruction to the list of instructions current in the
** VDBE. Return the address of the new instruction.
**
** Parameters:
**
** p Pointer to the VDBE
**
** op The opcode for this instruction
**
** p1, p2, p3 Operands
**
** Use the sqlite4VdbeResolveLabel() function to fix an address and
** the sqlite4VdbeChangeP4() function to change the value of the P4
** operand.
*/
SQLITE_PRIVATE int sqlite4VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
int i;
VdbeOp *pOp;
i = p->nOp;
assert( p->magic==VDBE_MAGIC_INIT );
assert( op>0 && op<0xff );
if( p->nOpAlloc<=i ){
if( growOpArray(p) ){
return 1;
}
}
p->nOp++;
pOp = &p->aOp[i];
pOp->opcode = (u8)op;
pOp->p5 = 0;
pOp->p1 = p1;
pOp->p2 = p2;
pOp->p3 = p3;
pOp->p4.p = 0;
pOp->p4type = P4_NOTUSED;
#ifdef SQLITE_DEBUG
pOp->zComment = 0;
if( sqlite4VdbeAddopTrace ) sqlite4VdbePrintOp(0, i, &p->aOp[i]);
#endif
#ifdef VDBE_PROFILE
pOp->cycles = 0;
pOp->cnt = 0;
#endif
return i;
}
SQLITE_PRIVATE int sqlite4VdbeAddOp0(Vdbe *p, int op){
return sqlite4VdbeAddOp3(p, op, 0, 0, 0);
}
SQLITE_PRIVATE int sqlite4VdbeAddOp1(Vdbe *p, int op, int p1){
return sqlite4VdbeAddOp3(p, op, p1, 0, 0);
}
SQLITE_PRIVATE int sqlite4VdbeAddOp2(Vdbe *p, int op, int p1, int p2){
return sqlite4VdbeAddOp3(p, op, p1, p2, 0);
}
/*
** Add an opcode that includes the p4 value as a pointer.
*/
SQLITE_PRIVATE int sqlite4VdbeAddOp4(
Vdbe *p, /* Add the opcode to this VM */
int op, /* The new opcode */
int p1, /* The P1 operand */
int p2, /* The P2 operand */
int p3, /* The P3 operand */
const char *zP4, /* The P4 operand */
int p4type /* P4 operand type */
){
int addr = sqlite4VdbeAddOp3(p, op, p1, p2, p3);
sqlite4VdbeChangeP4(p, addr, zP4, p4type);
return addr;
}
/*
** Add an OP_ParseSchema opcode. This routine is broken out from
** sqlite4VdbeAddOp4() since it needs to also needs to mark all btrees
** as having been used.
**
** The zWhere string must have been obtained from sqlite4_malloc().
** This routine will take ownership of the allocated memory.
*/
SQLITE_PRIVATE void sqlite4VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere){
int j;
int addr = sqlite4VdbeAddOp3(p, OP_ParseSchema, iDb, 0, 0);
sqlite4VdbeChangeP4(p, addr, zWhere, P4_DYNAMIC);
for(j=0; j<p->db->nDb; j++) sqlite4VdbeUsesStorage(p, j);
}
/*
** Add an opcode that includes the p4 value as an integer.
*/
SQLITE_PRIVATE int sqlite4VdbeAddOp4Int(
Vdbe *p, /* Add the opcode to this VM */
int op, /* The new opcode */
int p1, /* The P1 operand */
int p2, /* The P2 operand */
int p3, /* The P3 operand */
int p4 /* The P4 operand as an integer */
){
int addr = sqlite4VdbeAddOp3(p, op, p1, p2, p3);
sqlite4VdbeChangeP4(p, addr, SQLITE_INT_TO_PTR(p4), P4_INT32);
return addr;
}
/*
** Create a new symbolic label for an instruction that has yet to be
** coded. The symbolic label is really just a negative number. The
** label can be used as the P2 value of an operation. Later, when
** the label is resolved to a specific address, the VDBE will scan
** through its operation list and change all values of P2 which match
** the label into the resolved address.
**
** The VDBE knows that a P2 value is a label because labels are
** always negative and P2 values are suppose to be non-negative.
** Hence, a negative P2 value is a label that has yet to be resolved.
**
** Zero is returned if a malloc() fails.
*/
SQLITE_PRIVATE int sqlite4VdbeMakeLabel(Vdbe *p){
int i;
i = p->nLabel++;
assert( p->magic==VDBE_MAGIC_INIT );
if( i>=p->nLabelAlloc ){
int n = p->nLabelAlloc*2 + 5;
p->aLabel = sqlite4DbReallocOrFree(p->db, p->aLabel,
n*sizeof(p->aLabel[0]));
p->nLabelAlloc = sqlite4DbMallocSize(p->db, p->aLabel)/sizeof(p->aLabel[0]);
}
if( p->aLabel ){
p->aLabel[i] = -1;
}
return -1-i;
}
/*
** Resolve label "x" to be the address of the next instruction to
** be inserted. The parameter "x" must have been obtained from
** a prior call to sqlite4VdbeMakeLabel().
*/
SQLITE_PRIVATE void sqlite4VdbeResolveLabel(Vdbe *p, int x){
int j = -1-x;
assert( p->magic==VDBE_MAGIC_INIT );
assert( j>=0 && j<p->nLabel );
if( p->aLabel ){
p->aLabel[j] = p->nOp;
}
}
/*
** Mark the VDBE as one that can only be run one time.
*/
SQLITE_PRIVATE void sqlite4VdbeRunOnlyOnce(Vdbe *p){
p->runOnlyOnce = 1;
}
#ifdef SQLITE_DEBUG /* sqlite4AssertMayAbort() logic */
/*
** The following type and function are used to iterate through all opcodes
** in a Vdbe main program and each of the sub-programs (triggers) it may
** invoke directly or indirectly. It should be used as follows:
**
** Op *pOp;
** VdbeOpIter sIter;
**
** memset(&sIter, 0, sizeof(sIter));
** sIter.v = v; // v is of type Vdbe*
** while( (pOp = opIterNext(&sIter)) ){
** // Do something with pOp
** }
** sqlite4DbFree(v->db, sIter.apSub);
**
*/
typedef struct VdbeOpIter VdbeOpIter;
struct VdbeOpIter {
Vdbe *v; /* Vdbe to iterate through the opcodes of */
SubProgram **apSub; /* Array of subprograms */
int nSub; /* Number of entries in apSub */
int iAddr; /* Address of next instruction to return */
int iSub; /* 0 = main program, 1 = first sub-program etc. */
};
static Op *opIterNext(VdbeOpIter *p){
Vdbe *v = p->v;
Op *pRet = 0;
Op *aOp;
int nOp;
if( p->iSub<=p->nSub ){
if( p->iSub==0 ){
aOp = v->aOp;
nOp = v->nOp;
}else{
aOp = p->apSub[p->iSub-1]->aOp;
nOp = p->apSub[p->iSub-1]->nOp;
}
assert( p->iAddr<nOp );
pRet = &aOp[p->iAddr];
p->iAddr++;
if( p->iAddr==nOp ){
p->iSub++;
p->iAddr = 0;
}
if( pRet->p4type==P4_SUBPROGRAM ){
int nByte = (p->nSub+1)*sizeof(SubProgram*);
int j;
for(j=0; j<p->nSub; j++){
if( p->apSub[j]==pRet->p4.pProgram ) break;
}
if( j==p->nSub ){
p->apSub = sqlite4DbReallocOrFree(v->db, p->apSub, nByte);
if( !p->apSub ){
pRet = 0;
}else{
p->apSub[p->nSub++] = pRet->p4.pProgram;
}
}
}
}
return pRet;
}
/*
** Check if the program stored in the VM associated with pParse may
** throw an ABORT exception (causing the statement, but not entire transaction
** to be rolled back). This condition is true if the main program or any
** sub-programs contains any of the following:
**
** * OP_Halt with P1=SQLITE_CONSTRAINT and P2=OE_Abort.
** * OP_HaltIfNull with P1=SQLITE_CONSTRAINT and P2=OE_Abort.
** * OP_VUpdate
** * OP_VRename
** * OP_FkCounter with P2==0 (immediate foreign key constraint)
**
** Then check that the value of Parse.mayAbort is true if an
** ABORT may be thrown, or false otherwise. Return true if it does
** match, or false otherwise. This function is intended to be used as
** part of an assert statement in the compiler. Similar to:
**
** assert( sqlite4VdbeAssertMayAbort(pParse->pVdbe, pParse->mayAbort) );
*/
SQLITE_PRIVATE int sqlite4VdbeAssertMayAbort(Vdbe *v, int mayAbort){
int hasAbort = 0;
Op *pOp;
VdbeOpIter sIter;
memset(&sIter, 0, sizeof(sIter));
sIter.v = v;
while( (pOp = opIterNext(&sIter))!=0 ){
int opcode = pOp->opcode;
if( opcode==OP_VUpdate || opcode==OP_VRename
#ifndef SQLITE_OMIT_FOREIGN_KEY
|| (opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1)
#endif
|| ((opcode==OP_Halt || opcode==OP_HaltIfNull)
&& (pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
){
hasAbort = 1;
break;
}
}
sqlite4DbFree(v->db, sIter.apSub);
/* Return true if hasAbort==mayAbort. Or if a malloc failure occured.
** If malloc failed, then the while() loop above may not have iterated
** through all opcodes and hasAbort may be set incorrectly. Return
** true for this case to prevent the assert() in the callers frame
** from failing. */
return ( v->db->mallocFailed || hasAbort==mayAbort );
}
#endif /* SQLITE_DEBUG - the sqlite4AssertMayAbort() function */
/*
** Loop through the program looking for P2 values that are negative
** on jump instructions. Each such value is a label. Resolve the
** label by setting the P2 value to its correct non-zero value.
**
** This routine is called once after all opcodes have been inserted.
**
** Variable *pMaxFuncArgs is set to the maximum value of any P2 argument
** to an OP_Function, OP_AggStep or OP_VFilter opcode. This is used by
** sqlite4VdbeMakeReady() to size the Vdbe.apArg[] array.
**
** The Op.opflags field is set on all opcodes.
*/
static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
int i;
int nMaxArgs = *pMaxFuncArgs;
Op *pOp;
int *aLabel = p->aLabel;
p->readOnly = 1;
for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
u8 opcode = pOp->opcode;
pOp->opflags = sqlite4OpcodeProperty[opcode];
if( opcode==OP_Function || opcode==OP_AggStep ){
if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5;
}else if( (opcode==OP_Transaction && pOp->p2!=0) ){
p->readOnly = 0;
#ifndef SQLITE_OMIT_VIRTUALTABLE
}else if( opcode==OP_VUpdate ){
if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
}else if( opcode==OP_VFilter ){
int n;
assert( p->nOp - i >= 3 );
assert( pOp[-1].opcode==OP_Integer );
n = pOp[-1].p1;
if( n>nMaxArgs ) nMaxArgs = n;
#endif
}else if( opcode==OP_Next || opcode==OP_SorterNext ){
pOp->p4.xAdvance = sqlite4VdbeNext;
pOp->p4type = P4_ADVANCE;
}else if( opcode==OP_Prev ){
pOp->p4.xAdvance = sqlite4VdbePrevious;
pOp->p4type = P4_ADVANCE;
}
if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){
assert( -1-pOp->p2<p->nLabel );
pOp->p2 = aLabel[-1-pOp->p2];
}
}
sqlite4DbFree(p->db, p->aLabel);
p->aLabel = 0;
*pMaxFuncArgs = nMaxArgs;
}
/*
** Return the address of the next instruction to be inserted.
*/
SQLITE_PRIVATE int sqlite4VdbeCurrentAddr(Vdbe *p){
assert( p->magic==VDBE_MAGIC_INIT );
return p->nOp;
}
/*
** This function returns a pointer to the array of opcodes associated with
** the Vdbe passed as the first argument. It is the callers responsibility
** to arrange for the returned array to be eventually freed using the
** vdbeFreeOpArray() function.
**
** Before returning, *pnOp is set to the number of entries in the returned
** array. Also, *pnMaxArg is set to the larger of its current value and
** the number of entries in the Vdbe.apArg[] array required to execute the
** returned program.
*/
SQLITE_PRIVATE VdbeOp *sqlite4VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){
VdbeOp *aOp = p->aOp;
assert( aOp && !p->db->mallocFailed );
resolveP2Values(p, pnMaxArg);
*pnOp = p->nOp;
p->aOp = 0;
return aOp;
}
/*
** Add a whole list of operations to the operation stack. Return the
** address of the first operation added.
*/
SQLITE_PRIVATE int sqlite4VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
int addr;
assert( p->magic==VDBE_MAGIC_INIT );
if( p->nOp + nOp > p->nOpAlloc && growOpArray(p) ){
return 0;
}
addr = p->nOp;
if( ALWAYS(nOp>0) ){
int i;
VdbeOpList const *pIn = aOp;
for(i=0; i<nOp; i++, pIn++){
int p2 = pIn->p2;
VdbeOp *pOut = &p->aOp[i+addr];
pOut->opcode = pIn->opcode;
pOut->p1 = pIn->p1;
if( p2<0 && (sqlite4OpcodeProperty[pOut->opcode] & OPFLG_JUMP)!=0 ){
pOut->p2 = addr + ADDR(p2);
}else{
pOut->p2 = p2;
}
pOut->p3 = pIn->p3;
pOut->p4type = P4_NOTUSED;
pOut->p4.p = 0;
pOut->p5 = 0;
#ifdef SQLITE_DEBUG
pOut->zComment = 0;
if( sqlite4VdbeAddopTrace ){
sqlite4VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
}
#endif
}
p->nOp += nOp;
}
return addr;
}
/*
** Change the value of the P1 operand for a specific instruction.
** This routine is useful when a large program is loaded from a
** static array using sqlite4VdbeAddOpList but we want to make a
** few minor changes to the program.
*/
SQLITE_PRIVATE void sqlite4VdbeChangeP1(Vdbe *p, u32 addr, int val){
assert( p!=0 );
if( ((u32)p->nOp)>addr ){
p->aOp[addr].p1 = val;
}
}
/*
** Change the value of the P2 operand for a specific instruction.
** This routine is useful for setting a jump destination.
*/
SQLITE_PRIVATE void sqlite4VdbeChangeP2(Vdbe *p, u32 addr, int val){
assert( p!=0 );
if( ((u32)p->nOp)>addr ){
p->aOp[addr].p2 = val;
}
}
/*
** Change the value of the P3 operand for a specific instruction.
*/
SQLITE_PRIVATE void sqlite4VdbeChangeP3(Vdbe *p, u32 addr, int val){
assert( p!=0 );
if( ((u32)p->nOp)>addr ){
p->aOp[addr].p3 = val;
}
}
/*
** Change the value of the P5 operand for the most recently
** added operation.
*/
SQLITE_PRIVATE void sqlite4VdbeChangeP5(Vdbe *p, u8 val){
assert( p!=0 );
if( p->aOp ){
assert( p->nOp>0 );
p->aOp[p->nOp-1].p5 = val;
}
}
/*
** Change the P2 operand of instruction addr so that it points to
** the address of the next instruction to be coded.
*/
SQLITE_PRIVATE void sqlite4VdbeJumpHere(Vdbe *p, int addr){
assert( addr>=0 || p->db->mallocFailed );
if( addr>=0 ) sqlite4VdbeChangeP2(p, addr, p->nOp);
}
/*
** If the input FuncDef structure is ephemeral, then free it. If
** the FuncDef is not ephermal, then do nothing.
*/
static void freeEphemeralFunction(sqlite4 *db, FuncDef *pDef){
if( ALWAYS(pDef) && (pDef->flags & SQLITE_FUNC_EPHEM)!=0 ){
sqlite4DbFree(db, pDef);
}
}
static void vdbeFreeOpArray(sqlite4 *, Op *, int);
/*
** Delete a P4 value if necessary.
*/
static void freeP4(sqlite4 *db, int p4type, void *p4){
if( p4 ){
assert( db );
switch( p4type ){
case P4_REAL:
case P4_INT64:
case P4_DYNAMIC:
case P4_KEYINFO:
case P4_INTARRAY:
case P4_KEYINFO_HANDOFF: {
sqlite4DbFree(db, p4);
break;
}
case P4_MPRINTF: {
if( db->pnBytesFreed==0 ) sqlite4_free(db->pEnv, p4);
break;
}
case P4_VDBEFUNC: {
VdbeFunc *pVdbeFunc = (VdbeFunc *)p4;
freeEphemeralFunction(db, pVdbeFunc->pFunc);
if( db->pnBytesFreed==0 ) sqlite4VdbeDeleteAuxData(pVdbeFunc, 0);
sqlite4DbFree(db, pVdbeFunc);
break;
}
case P4_FUNCDEF: {
freeEphemeralFunction(db, (FuncDef*)p4);
break;
}
case P4_MEM: {
if( db->pnBytesFreed==0 ){
sqlite4ValueFree((sqlite4_value*)p4);
}else{
Mem *p = (Mem*)p4;
sqlite4DbFree(db, p->zMalloc);
sqlite4DbFree(db, p);
}
break;
}
case P4_VTAB : {
if( db->pnBytesFreed==0 ) sqlite4VtabUnlock((VTable *)p4);
break;
}
}
}
}
/*
** Free the space allocated for aOp and any p4 values allocated for the
** opcodes contained within. If aOp is not NULL it is assumed to contain
** nOp entries.
*/
static void vdbeFreeOpArray(sqlite4 *db, Op *aOp, int nOp){
if( aOp ){
Op *pOp;
for(pOp=aOp; pOp<&aOp[nOp]; pOp++){
freeP4(db, pOp->p4type, pOp->p4.p);
#ifdef SQLITE_DEBUG
sqlite4DbFree(db, pOp->zComment);
#endif
}
}
sqlite4DbFree(db, aOp);
}
/*
** Link the SubProgram object passed as the second argument into the linked
** list at Vdbe.pSubProgram. This list is used to delete all sub-program
** objects when the VM is no longer required.
*/
SQLITE_PRIVATE void sqlite4VdbeLinkSubProgram(Vdbe *pVdbe, SubProgram *p){
p->pNext = pVdbe->pProgram;
pVdbe->pProgram = p;
}
/*
** Change the opcode at addr into OP_Noop
*/
SQLITE_PRIVATE void sqlite4VdbeChangeToNoop(Vdbe *p, int addr){
if( p->aOp ){
VdbeOp *pOp = &p->aOp[addr];
sqlite4 *db = p->db;
freeP4(db, pOp->p4type, pOp->p4.p);
memset(pOp, 0, sizeof(pOp[0]));
pOp->opcode = OP_Noop;
}
}
/*
** Change the value of the P4 operand for a specific instruction.
** This routine is useful when a large program is loaded from a
** static array using sqlite4VdbeAddOpList but we want to make a
** few minor changes to the program.
**
** If n>=0 then the P4 operand is dynamic, meaning that a copy of
** the string is made into memory obtained from sqlite4_malloc().
** A value of n==0 means copy bytes of zP4 up to and including the
** first null byte. If n>0 then copy n+1 bytes of zP4.
**
** If n==P4_KEYINFO it means that zP4 is a pointer to a KeyInfo structure.
** A copy is made of the KeyInfo structure into memory obtained from
** sqlite4_malloc, to be freed when the Vdbe is finalized.
** n==P4_KEYINFO_HANDOFF indicates that zP4 points to a KeyInfo structure
** stored in memory that the caller has obtained from sqlite4_malloc. The
** caller should not free the allocation, it will be freed when the Vdbe is
** finalized.
**
** Other values of n (P4_STATIC, P4_COLLSEQ etc.) indicate that zP4 points
** to a string or structure that is guaranteed to exist for the lifetime of
** the Vdbe. In these cases we can just copy the pointer.
**
** If addr<0 then change P4 on the most recently inserted instruction.
*/
SQLITE_PRIVATE void sqlite4VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
Op *pOp;
sqlite4 *db;
assert( p!=0 );
db = p->db;
assert( p->magic==VDBE_MAGIC_INIT );
if( p->aOp==0 || db->mallocFailed ){
if ( n!=P4_KEYINFO && n!=P4_VTAB ) {
freeP4(db, n, (void*)*(char**)&zP4);
}
return;
}
assert( p->nOp>0 );
assert( addr<p->nOp );
if( addr<0 ){
addr = p->nOp - 1;
}
pOp = &p->aOp[addr];
freeP4(db, pOp->p4type, pOp->p4.p);
pOp->p4.p = 0;
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 ){
pOp->p4.p = 0;
pOp->p4type = P4_NOTUSED;
}else if( n==P4_KEYINFO ){
KeyInfo *pKeyInfo;
int nField, nByte;
nField = ((KeyInfo*)zP4)->nField;
nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]) + nField;
pKeyInfo = sqlite4DbMallocRaw(0, nByte);
pOp->p4.pKeyInfo = pKeyInfo;
if( pKeyInfo ){
u8 *aSortOrder;
memcpy((char*)pKeyInfo, zP4, nByte - nField);
aSortOrder = pKeyInfo->aSortOrder;
if( aSortOrder ){
pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField];
memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);
}
pOp->p4type = P4_KEYINFO;
}else{
p->db->mallocFailed = 1;
pOp->p4type = P4_NOTUSED;
}
}else if( n==P4_KEYINFO_HANDOFF ){
pOp->p4.p = (void*)zP4;
pOp->p4type = P4_KEYINFO;
}else if( n==P4_VTAB ){
pOp->p4.p = (void*)zP4;
pOp->p4type = P4_VTAB;
sqlite4VtabLock((VTable *)zP4);
assert( ((VTable *)zP4)->db==p->db );
}else if( n<0 ){
pOp->p4.p = (void*)zP4;
pOp->p4type = (signed char)n;
}else{
if( n==0 ) n = sqlite4Strlen30(zP4);
pOp->p4.z = sqlite4DbStrNDup(p->db, zP4, n);
pOp->p4type = P4_DYNAMIC;
}
}
#ifndef NDEBUG
/*
** Change the comment on the the most recently coded instruction. Or
** insert a No-op and add the comment to that new instruction. This
** makes the code easier to read during debugging. None of this happens
** in a production build.
*/
static void vdbeVComment(Vdbe *p, const char *zFormat, va_list ap){
assert( p->nOp>0 || p->aOp==0 );
assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed );
if( p->nOp ){
assert( p->aOp );
sqlite4DbFree(p->db, p->aOp[p->nOp-1].zComment);
p->aOp[p->nOp-1].zComment = sqlite4VMPrintf(p->db, zFormat, ap);
}
}
SQLITE_PRIVATE void sqlite4VdbeComment(Vdbe *p, const char *zFormat, ...){
va_list ap;
if( p ){
va_start(ap, zFormat);
vdbeVComment(p, zFormat, ap);
va_end(ap);
}
}
SQLITE_PRIVATE void sqlite4VdbeNoopComment(Vdbe *p, const char *zFormat, ...){
va_list ap;
if( p ){
sqlite4VdbeAddOp0(p, OP_Noop);
va_start(ap, zFormat);
vdbeVComment(p, zFormat, ap);
va_end(ap);
}
}
#endif /* NDEBUG */
/*
** Return the opcode for a given address. If the address is -1, then
** return the most recently inserted opcode.
**
** If a memory allocation error has occurred prior to the calling of this
** routine, then a pointer to a dummy VdbeOp will be returned. That opcode
** is readable but not writable, though it is cast to a writable value.
** The return of a dummy opcode allows the call to continue functioning
** after a OOM fault without having to check to see if the return from
** this routine is a valid pointer. But because the dummy.opcode is 0,
** dummy will never be written to. This is verified by code inspection and
** by running with Valgrind.
**
** About the #ifdef SQLITE_OMIT_TRACE: Normally, this routine is never called
** unless p->nOp>0. This is because in the absense of SQLITE_OMIT_TRACE,
** an OP_Trace instruction is always inserted by sqlite4VdbeGet() as soon as
** a new VDBE is created. So we are free to set addr to p->nOp-1 without
** having to double-check to make sure that the result is non-negative. But
** if SQLITE_OMIT_TRACE is defined, the OP_Trace is omitted and we do need to
** check the value of p->nOp-1 before continuing.
*/
SQLITE_PRIVATE VdbeOp *sqlite4VdbeGetOp(Vdbe *p, int addr){
/* C89 specifies that the constant "dummy" will be initialized to all
** zeros, which is correct. MSVC generates a warning, nevertheless. */
static VdbeOp dummy; /* Ignore the MSVC warning about no initializer */
assert( p->magic==VDBE_MAGIC_INIT );
if( addr<0 ){
#ifdef SQLITE_OMIT_TRACE
if( p->nOp==0 ) return (VdbeOp*)&dummy;
#endif
addr = p->nOp - 1;
}
assert( (addr>=0 && addr<p->nOp) || p->db->mallocFailed );
if( p->db->mallocFailed ){
return (VdbeOp*)&dummy;
}else{
return &p->aOp[addr];
}
}
#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
|| defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
/*
** Compute a string that describes the P4 parameter for an opcode.
** Use zTemp for any required temporary buffer space.
*/
static char *displayP4(Op *pOp, char *zTemp, int nTemp){
char *zP4 = zTemp;
assert( nTemp>=20 );
switch( pOp->p4type ){
case P4_KEYINFO_STATIC:
case P4_KEYINFO: {
int i, j;
KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
i = sqlite4_snprintf(zTemp, nTemp, "keyinfo(%d", pKeyInfo->nField);
for(j=0; j<pKeyInfo->nField; j++){
CollSeq *pColl = pKeyInfo->aColl[j];
if( pColl ){
int n = sqlite4Strlen30(pColl->zName);
if( i+n>nTemp-6 ){
memcpy(&zTemp[i],",...",4);
break;
}
zTemp[i++] = ',';
if( pKeyInfo->aSortOrder && pKeyInfo->aSortOrder[j] ){
zTemp[i++] = '-';
}
memcpy(&zTemp[i], pColl->zName,n+1);
i += n;
}else if( i+4<nTemp-6 ){
memcpy(&zTemp[i],",nil",4);
i += 4;
}
}
zTemp[i++] = ')';
zTemp[i] = 0;
assert( i<nTemp );
break;
}
case P4_COLLSEQ: {
CollSeq *pColl = pOp->p4.pColl;
sqlite4_snprintf(zTemp, nTemp, "collseq(%.20s)", pColl->zName);
break;
}
case P4_FUNCDEF: {
FuncDef *pDef = pOp->p4.pFunc;
sqlite4_snprintf(zTemp, nTemp, "%s(%d)", pDef->zName, pDef->nArg);
break;
}
case P4_INT64: {
sqlite4_snprintf(zTemp, nTemp, "%lld", *pOp->p4.pI64);
break;
}
case P4_INT32: {
sqlite4_snprintf(zTemp, nTemp, "%d", pOp->p4.i);
break;
}
case P4_REAL: {
sqlite4_snprintf(zTemp, nTemp, "%.16g", *pOp->p4.pReal);
break;
}
case P4_MEM: {
Mem *pMem = pOp->p4.pMem;
if( pMem->flags & MEM_Str ){
zP4 = pMem->z;
}else if( pMem->flags & MEM_Int ){
sqlite4_snprintf(zTemp, nTemp, "%lld", pMem->u.i);
}else if( pMem->flags & MEM_Real ){
sqlite4_snprintf(zTemp, nTemp, "%.16g", pMem->r);
}else if( pMem->flags & MEM_Null ){
sqlite4_snprintf(zTemp, nTemp, "NULL");
}else{
assert( pMem->flags & MEM_Blob );
zP4 = "(blob)";
}
break;
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
case P4_VTAB: {
sqlite4_vtab *pVtab = pOp->p4.pVtab->pVtab;
sqlite4_snprintf(zTemp, nTemp, "vtab:%p:%p", pVtab, pVtab->pModule);
break;
}
#endif
case P4_INTARRAY: {
sqlite4_snprintf(zTemp, nTemp, "intarray");
break;
}
case P4_SUBPROGRAM: {
sqlite4_snprintf(zTemp, nTemp, "program");
break;
}
case P4_ADVANCE: {
zTemp[0] = 0;
break;
}
default: {
zP4 = pOp->p4.z;
if( zP4==0 ){
zP4 = zTemp;
zTemp[0] = 0;
}
}
}
assert( zP4!=0 );
return zP4;
}
#endif
/*
** Declare to the Vdbe that the database at db->aDb[i] is used.
*/
SQLITE_PRIVATE void sqlite4VdbeUsesStorage(Vdbe *p, int i){
assert( i>=0 && i<p->db->nDb && i<(int)sizeof(yDbMask)*8 );
}
#if defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
/*
** Print a single opcode. This routine is used for debugging only.
*/
SQLITE_PRIVATE void sqlite4VdbePrintOp(FILE *pOut, int pc, Op *pOp){
char *zP4;
char zPtr[50];
static const char *zFormat1 = "%4d %-13s %4d %4d %4d %-4s %.2X %s\n";
if( pOut==0 ) pOut = stdout;
zP4 = displayP4(pOp, zPtr, sizeof(zPtr));
fprintf(pOut, zFormat1, pc,
sqlite4OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4, pOp->p5,
#ifdef SQLITE_DEBUG
pOp->zComment ? pOp->zComment : ""
#else
""
#endif
);
fflush(pOut);
}
#endif
/*
** Release an array of N Mem elements
*/
static void releaseMemArray(Mem *p, int N){
if( p && N ){
Mem *pEnd;
sqlite4 *db = p->db;
u8 malloc_failed = db->mallocFailed;
if( db->pnBytesFreed ){
for(pEnd=&p[N]; p<pEnd; p++){
sqlite4DbFree(db, p->zMalloc);
}
return;
}
for(pEnd=&p[N]; p<pEnd; p++){
assert( (&p[1])==pEnd || p[0].db==p[1].db );
/* This block is really an inlined version of sqlite4VdbeMemRelease()
** that takes advantage of the fact that the memory cell value is
** being set to NULL after releasing any dynamic resources.
**
** The justification for duplicating code is that according to
** callgrind, this causes a certain test case to hit the CPU 4.7
** percent less (x86 linux, gcc version 4.1.2, -O6) than if
** sqlite4MemRelease() were called from here. With -O2, this jumps
** to 6.6 percent. The test case is inserting 1000 rows into a table
** with no indexes using a single prepared INSERT statement, bind()
** and reset(). Inserts are grouped into a transaction.
*/
if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){
sqlite4VdbeMemRelease(p);
}else if( p->zMalloc ){
sqlite4DbFree(db, p->zMalloc);
p->zMalloc = 0;
}
p->flags = MEM_Invalid;
}
db->mallocFailed = malloc_failed;
}
}
/*
** Delete a VdbeFrame object and its contents. VdbeFrame objects are
** allocated by the OP_Program opcode in sqlite4VdbeExec().
*/
SQLITE_PRIVATE void sqlite4VdbeFrameDelete(VdbeFrame *p){
int i;
Mem *aMem = VdbeFrameMem(p);
VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem];
for(i=0; i<p->nChildCsr; i++){
sqlite4VdbeFreeCursor(p->v, apCsr[i]);
}
releaseMemArray(aMem, p->nChildMem);
sqlite4DbFree(p->v->db, p);
}
#ifndef SQLITE_OMIT_EXPLAIN
/*
** Give a listing of the program in the virtual machine.
**
** The interface is the same as sqlite4VdbeExec(). But instead of
** running the code, it invokes the callback once for each instruction.
** This feature is used to implement "EXPLAIN".
**
** When p->explain==1, each instruction is listed. When
** p->explain==2, only OP_Explain instructions are listed and these
** are shown in a different format. p->explain==2 is used to implement
** EXPLAIN QUERY PLAN.
**
** When p->explain==1, first the main program is listed, then each of
** the trigger subprograms are listed one by one.
*/
SQLITE_PRIVATE int sqlite4VdbeList(
Vdbe *p /* The VDBE */
){
int nRow; /* Stop when row count reaches this */
int nSub = 0; /* Number of sub-vdbes seen so far */
SubProgram **apSub = 0; /* Array of sub-vdbes */
Mem *pSub = 0; /* Memory cell hold array of subprogs */
sqlite4 *db = p->db; /* The database connection */
int i; /* Loop counter */
int rc = SQLITE_OK; /* Return code */
Mem *pMem = &p->aMem[1]; /* First Mem of result set */
assert( p->explain );
assert( p->magic==VDBE_MAGIC_RUN );
assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM );
/* Even though this opcode does not use dynamic strings for
** the result, result columns may become dynamic if the user calls
** sqlite4_column_text16(), causing a translation to UTF-16 encoding.
*/
releaseMemArray(pMem, 8);
p->pResultSet = 0;
if( p->rc==SQLITE_NOMEM ){
/* This happens if a malloc() inside a call to sqlite4_column_text() or
** sqlite4_column_text16() failed. */
db->mallocFailed = 1;
return SQLITE_ERROR;
}
/* When the number of output rows reaches nRow, that means the
** listing has finished and sqlite4_step() should return SQLITE_DONE.
** nRow is the sum of the number of rows in the main program, plus
** the sum of the number of rows in all trigger subprograms encountered
** so far. The nRow value will increase as new trigger subprograms are
** encountered, but p->pc will eventually catch up to nRow.
*/
nRow = p->nOp;
if( p->explain==1 ){
/* 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
** cells. */
assert( p->nMem>9 );
pSub = &p->aMem[9];
if( pSub->flags&MEM_Blob ){
/* On the first call to sqlite4_step(), pSub will hold a NULL. It is
** initialized to a BLOB by the P4_SUBPROGRAM processing logic below */
nSub = pSub->n/sizeof(Vdbe*);
apSub = (SubProgram **)pSub->z;
}
for(i=0; i<nSub; i++){
nRow += apSub[i]->nOp;
}
}
do{
i = p->pc++;
}while( i<nRow && p->explain==2 && p->aOp[i].opcode!=OP_Explain );
if( i>=nRow ){
p->rc = SQLITE_OK;
rc = SQLITE_DONE;
}else if( db->u1.isInterrupted ){
p->rc = SQLITE_INTERRUPT;
rc = SQLITE_ERROR;
sqlite4SetString(&p->zErrMsg, db, "%s", sqlite4ErrStr(p->rc));
}else{
char *z;
Op *pOp;
if( i<p->nOp ){
/* The output line number is small enough that we are still in the
** main program. */
pOp = &p->aOp[i];
}else{
/* We are currently listing subprograms. Figure out which one and
** pick up the appropriate opcode. */
int j;
i -= p->nOp;
for(j=0; i>=apSub[j]->nOp; j++){
i -= apSub[j]->nOp;
}
pOp = &apSub[j]->aOp[i];
}
if( p->explain==1 ){
pMem->flags = MEM_Int;
pMem->type = SQLITE_INTEGER;
pMem->u.i = i; /* Program counter */
pMem++;
pMem->flags = MEM_Static|MEM_Str|MEM_Term;
pMem->z = (char*)sqlite4OpcodeName(pOp->opcode); /* Opcode */
assert( pMem->z!=0 );
pMem->n = sqlite4Strlen30(pMem->z);
pMem->type = SQLITE_TEXT;
pMem->enc = SQLITE_UTF8;
pMem++;
/* When an OP_Program opcode is encounter (the only opcode that has
** a P4_SUBPROGRAM argument), expand the size of the array of subprograms
** kept in p->aMem[9].z to hold the new program - assuming this subprogram
** has not already been seen.
*/
if( pOp->p4type==P4_SUBPROGRAM ){
int nByte = (nSub+1)*sizeof(SubProgram*);
int j;
for(j=0; j<nSub; j++){
if( apSub[j]==pOp->p4.pProgram ) break;
}
if( j==nSub && SQLITE_OK==sqlite4VdbeMemGrow(pSub, nByte, 1) ){
apSub = (SubProgram **)pSub->z;
apSub[nSub++] = pOp->p4.pProgram;
pSub->flags |= MEM_Blob;
pSub->n = nSub*sizeof(SubProgram*);
}
}
}
pMem->flags = MEM_Int;
pMem->u.i = pOp->p1; /* P1 */
pMem->type = SQLITE_INTEGER;
pMem++;
pMem->flags = MEM_Int;
pMem->u.i = pOp->p2; /* P2 */
pMem->type = SQLITE_INTEGER;
pMem++;
pMem->flags = MEM_Int;
pMem->u.i = pOp->p3; /* P3 */
pMem->type = SQLITE_INTEGER;
pMem++;
if( sqlite4VdbeMemGrow(pMem, 32, 0) ){ /* P4 */
assert( p->db->mallocFailed );
return SQLITE_ERROR;
}
pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
z = displayP4(pOp, pMem->z, 32);
if( z!=pMem->z ){
sqlite4VdbeMemSetStr(pMem, z, -1, SQLITE_UTF8, 0);
}else{
assert( pMem->z!=0 );
pMem->n = sqlite4Strlen30(pMem->z);
pMem->enc = SQLITE_UTF8;
}
pMem->type = SQLITE_TEXT;
pMem++;
if( p->explain==1 ){
if( sqlite4VdbeMemGrow(pMem, 4, 0) ){
assert( p->db->mallocFailed );
return SQLITE_ERROR;
}
pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
pMem->n = 2;
sqlite4_snprintf(pMem->z, 3, "%.2x", pOp->p5); /* P5 */
pMem->type = SQLITE_TEXT;
pMem->enc = SQLITE_UTF8;
pMem++;
#ifdef SQLITE_DEBUG
if( pOp->zComment ){
pMem->flags = MEM_Str|MEM_Term;
pMem->z = pOp->zComment;
pMem->n = sqlite4Strlen30(pMem->z);
pMem->enc = SQLITE_UTF8;
pMem->type = SQLITE_TEXT;
}else
#endif
{
pMem->flags = MEM_Null; /* Comment */
pMem->type = SQLITE_NULL;
}
}
p->nResColumn = 8 - 4*(p->explain-1);
p->pResultSet = &p->aMem[1];
p->rc = SQLITE_OK;
rc = SQLITE_ROW;
}
return rc;
}
#endif /* SQLITE_OMIT_EXPLAIN */
#ifdef SQLITE_DEBUG
/*
** Print the SQL that was used to generate a VDBE program.
*/
SQLITE_PRIVATE void sqlite4VdbePrintSql(Vdbe *p){
int nOp = p->nOp;
VdbeOp *pOp;
if( nOp<1 ) return;
pOp = &p->aOp[0];
if( pOp->opcode==OP_Trace && pOp->p4.z!=0 ){
const char *z = pOp->p4.z;
while( sqlite4Isspace(*z) ) z++;
printf("SQL: [%s]\n", z);
}
}
#endif
#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)
/*
** Print an IOTRACE message showing SQL content.
*/
SQLITE_PRIVATE void sqlite4VdbeIOTraceSql(Vdbe *p){
int nOp = p->nOp;
VdbeOp *pOp;
if( sqlite4IoTrace==0 ) return;
if( nOp<1 ) return;
pOp = &p->aOp[0];
if( pOp->opcode==OP_Trace && pOp->p4.z!=0 ){
int i, j;
char z[1000];
sqlite4_snprintf(z, sizeof(z), "%s", pOp->p4.z);
for(i=0; sqlite4Isspace(z[i]); i++){}
for(j=0; z[i]; i++){
if( sqlite4Isspace(z[i]) ){
if( z[i-1]!=' ' ){
z[j++] = ' ';
}
}else{
z[j++] = z[i];
}
}
z[j] = 0;
sqlite4IoTrace("SQL %s\n", z);
}
}
#endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE */
/*
** Allocate space from a fixed size buffer and return a pointer to
** that space. If insufficient space is available, return NULL.
**
** The pBuf parameter is the initial value of a pointer which will
** receive the new memory. pBuf is normally NULL. If pBuf is not
** NULL, it means that memory space has already been allocated and that
** this routine should not allocate any new memory. When pBuf is not
** NULL simply return pBuf. Only allocate new memory space when pBuf
** is NULL.
**
** nByte is the number of bytes of space needed.
**
** *ppFrom points to available space and pEnd points to the end of the
** available space. When space is allocated, *ppFrom is advanced past
** the end of the allocated space.
**
** *pnByte is a counter of the number of bytes of space that have failed
** to allocate. If there is insufficient space in *ppFrom to satisfy the
** request, then increment *pnByte by the amount of the request.
*/
static void *allocSpace(
void *pBuf, /* Where return pointer will be stored */
int nByte, /* Number of bytes to allocate */
u8 **ppFrom, /* IN/OUT: Allocate from *ppFrom */
u8 *pEnd, /* Pointer to 1 byte past the end of *ppFrom buffer */
int *pnByte /* If allocation cannot be made, increment *pnByte */
){
assert( EIGHT_BYTE_ALIGNMENT(*ppFrom) );
if( pBuf ) return pBuf;
nByte = ROUND8(nByte);
if( &(*ppFrom)[nByte] <= pEnd ){
pBuf = (void*)*ppFrom;
*ppFrom += nByte;
}else{
*pnByte += nByte;
}
return pBuf;
}
/*
** Rewind the VDBE back to the beginning in preparation for
** running it.
*/
SQLITE_PRIVATE void sqlite4VdbeRewind(Vdbe *p){
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
int i;
#endif
assert( p!=0 );
assert( p->magic==VDBE_MAGIC_INIT );
/* There should be at least one opcode.
*/
assert( p->nOp>0 );
/* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */
p->magic = VDBE_MAGIC_RUN;
#ifdef SQLITE_DEBUG
for(i=1; i<p->nMem; i++){
assert( p->aMem[i].db==p->db );
}
#endif
p->pc = -1;
p->rc = SQLITE_OK;
p->errorAction = OE_Abort;
p->magic = VDBE_MAGIC_RUN;
p->nChange = 0;
p->cacheCtr = 1;
p->minWriteFileFormat = 255;
p->stmtTransMask = 0;
p->nFkConstraint = 0;
#ifdef VDBE_PROFILE
for(i=0; i<p->nOp; i++){
p->aOp[i].cnt = 0;
p->aOp[i].cycles = 0;
}
#endif
}
/*
** Prepare a virtual machine for execution for the first time after
** creating the virtual machine. This involves things such
** as allocating stack space and initializing the program counter.
** After the VDBE has be prepped, it can be executed by one or more
** calls to sqlite4VdbeExec().
**
** This function may be called exact once on a each virtual machine.
** After this routine is called the VM has been "packaged" and is ready
** to run. After this routine is called, futher calls to
** sqlite4VdbeAddOp() functions are prohibited. This routine disconnects
** the Vdbe from the Parse object that helped generate it so that the
** the Vdbe becomes an independent entity and the Parse object can be
** destroyed.
**
** Use the sqlite4VdbeRewind() procedure to restore a virtual machine back
** to its initial state after it has been run.
*/
SQLITE_PRIVATE void sqlite4VdbeMakeReady(
Vdbe *p, /* The VDBE */
Parse *pParse /* Parsing context */
){
sqlite4 *db; /* The database connection */
int nVar; /* Number of parameters */
int nMem; /* Number of VM memory registers */
int nCursor; /* Number of cursors required */
int nArg; /* Number of arguments in subprograms */
int nOnce; /* Number of OP_Once instructions */
int n; /* Loop counter */
u8 *zCsr; /* Memory available for allocation */
u8 *zEnd; /* First byte past allocated memory */
int nByte; /* How much extra memory is needed */
assert( p!=0 );
assert( p->nOp>0 );
assert( pParse!=0 );
assert( p->magic==VDBE_MAGIC_INIT );
db = p->db;
assert( db->mallocFailed==0 );
nVar = pParse->nVar;
nMem = pParse->nMem;
nCursor = pParse->nTab;
nArg = pParse->nMaxArg;
nOnce = pParse->nOnce;
if( nOnce==0 ) nOnce = 1; /* Ensure at least one byte in p->aOnceFlag[] */
/* For each cursor required, also allocate a memory cell. Memory
** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by
** the vdbe program. Instead they are used to allocate space for
** VdbeCursor/BtCursor structures. The blob of memory associated with
** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1)
** stores the blob of memory associated with cursor 1, etc.
**
** See also: allocateCursor().
*/
nMem += nCursor;
/* Allocate space for memory registers, SQL variables, VDBE cursors and
** an array to marshal SQL function arguments in.
*/
zCsr = (u8*)&p->aOp[p->nOp]; /* Memory avaliable for allocation */
zEnd = (u8*)&p->aOp[p->nOpAlloc]; /* First byte past end of zCsr[] */
resolveP2Values(p, &nArg);
p->needSavepoint = (u8)(pParse->isMultiWrite && pParse->mayAbort);
if( pParse->explain && nMem<10 ){
nMem = 10;
}
memset(zCsr, 0, zEnd-zCsr);
zCsr += (zCsr - (u8*)0)&7;
assert( EIGHT_BYTE_ALIGNMENT(zCsr) );
p->expired = 0;
/* Memory for registers, parameters, cursor, etc, is allocated in two
** passes. On the first pass, we try to reuse unused space 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 rest using a fresh allocation.
**
** This two-pass approach that reuses as much memory as possible from
** the leftover space at the end of the opcode array can significantly
** reduce the amount of memory held by a prepared statement.
*/
do {
nByte = 0;
p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte);
p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte);
p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte);
p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte);
p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*),
&zCsr, zEnd, &nByte);
p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce, &zCsr, zEnd, &nByte);
if( nByte ){
p->pFree = sqlite4DbMallocZero(db, nByte);
}
zCsr = p->pFree;
zEnd = &zCsr[nByte];
}while( nByte && !db->mallocFailed );
p->nCursor = (u16)nCursor;
p->nOnceFlag = nOnce;
if( p->aVar ){
p->nVar = (ynVar)nVar;
for(n=0; n<nVar; n++){
p->aVar[n].flags = MEM_Null;
p->aVar[n].db = db;
}
}
if( p->azVar ){
p->nzVar = pParse->nzVar;
memcpy(p->azVar, pParse->azVar, p->nzVar*sizeof(p->azVar[0]));
memset(pParse->azVar, 0, pParse->nzVar*sizeof(pParse->azVar[0]));
}
if( p->aMem ){
p->aMem--; /* aMem[] goes from 1..nMem */
p->nMem = nMem; /* not from 0..nMem-1 */
for(n=1; n<=nMem; n++){
p->aMem[n].flags = MEM_Invalid;
p->aMem[n].db = db;
}
}
p->explain = pParse->explain;
sqlite4VdbeRewind(p);
}
/*
** Close a VDBE cursor and release all the resources that cursor
** happens to hold.
*/
SQLITE_PRIVATE void sqlite4VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
if( pCx==0 ){
return;
}
if( pCx->pKVCur ){
sqlite4KVCursorClose(pCx->pKVCur);
}
if( pCx->pTmpKV ){
sqlite4KVStoreClose(pCx->pTmpKV);
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( pCx->pVtabCursor ){
sqlite4_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
const sqlite4_module *pModule = pCx->pModule;
p->inVtabMethod = 1;
pModule->xClose(pVtabCursor);
p->inVtabMethod = 0;
}
#endif
}
/*
** Copy the values stored in the VdbeFrame structure to its Vdbe. This
** is used, for example, when a trigger sub-program is halted to restore
** control to the main program.
*/
SQLITE_PRIVATE int sqlite4VdbeFrameRestore(VdbeFrame *pFrame){
Vdbe *v = pFrame->v;
v->aOnceFlag = pFrame->aOnceFlag;
v->nOnceFlag = pFrame->nOnceFlag;
v->aOp = pFrame->aOp;
v->nOp = pFrame->nOp;
v->aMem = pFrame->aMem;
v->nMem = pFrame->nMem;
v->apCsr = pFrame->apCsr;
v->nCursor = pFrame->nCursor;
v->db->lastRowid = pFrame->lastRowid;
v->nChange = pFrame->nChange;
return pFrame->pc;
}
/*
** Close all cursors.
**
** Also release any dynamic memory held by the VM in the Vdbe.aMem memory
** cell array. This is necessary as the memory cell array may contain
** pointers to VdbeFrame objects, which may in turn contain pointers to
** open cursors.
*/
static void closeAllCursors(Vdbe *p){
if( p->pFrame ){
VdbeFrame *pFrame;
for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
sqlite4VdbeFrameRestore(pFrame);
}
p->pFrame = 0;
p->nFrame = 0;
if( p->apCsr ){
int i;
for(i=0; i<p->nCursor; i++){
VdbeCursor *pC = p->apCsr[i];
if( pC ){
sqlite4VdbeFreeCursor(p, pC);
p->apCsr[i] = 0;
}
}
}
if( p->aMem ){
releaseMemArray(&p->aMem[1], p->nMem);
}
while( p->pDelFrame ){
VdbeFrame *pDel = p->pDelFrame;
p->pDelFrame = pDel->pParent;
sqlite4VdbeFrameDelete(pDel);
}
}
/*
** Clean up the VM after execution.
**
** This routine will automatically close any cursors, lists, and/or
** sorters that were left open. It also deletes the values of
** variables in the aVar[] array.
*/
static void Cleanup(Vdbe *p){
sqlite4 *db = p->db;
#ifdef SQLITE_DEBUG
/* Execute assert() statements to ensure that the Vdbe.apCsr[] and
** Vdbe.aMem[] arrays have already been cleaned up. */
int i;
if( p->apCsr ) for(i=0; i<p->nCursor; i++) assert( p->apCsr[i]==0 );
if( p->aMem ){
for(i=1; i<=p->nMem; i++) assert( p->aMem[i].flags==MEM_Invalid );
}
#endif
sqlite4DbFree(db, p->zErrMsg);
p->zErrMsg = 0;
p->pResultSet = 0;
}
/*
** Set the number of result columns that will be returned by this SQL
** statement. This is now set at compile time, rather than during
** execution of the vdbe program so that sqlite4_column_count() can
** be called on an SQL statement before sqlite4_step().
*/
SQLITE_PRIVATE void sqlite4VdbeSetNumCols(Vdbe *p, int nResColumn){
Mem *pColName;
int n;
sqlite4 *db = p->db;
releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
sqlite4DbFree(db, p->aColName);
n = nResColumn*COLNAME_N;
p->nResColumn = (u16)nResColumn;
p->aColName = pColName = (Mem*)sqlite4DbMallocZero(db, sizeof(Mem)*n );
if( p->aColName==0 ) return;
while( n-- > 0 ){
pColName->flags = MEM_Null;
pColName->db = p->db;
pColName++;
}
}
/*
** Set the name of the idx'th column to be returned by the SQL statement.
** zName must be a pointer to a nul terminated string.
**
** This call must be made after a call to sqlite4VdbeSetNumCols().
**
** The final parameter, xDel, must be one of SQLITE_DYNAMIC, SQLITE_STATIC
** or SQLITE_TRANSIENT. If it is SQLITE_DYNAMIC, then the buffer pointed
** to by zName will be freed by sqlite4DbFree() when the vdbe is destroyed.
*/
SQLITE_PRIVATE int sqlite4VdbeSetColName(
Vdbe *p, /* Vdbe being configured */
int idx, /* Index of column zName applies to */
int var, /* One of the COLNAME_* constants */
const char *zName, /* Pointer to buffer containing name */
void (*xDel)(void*) /* Memory management strategy for zName */
){
int rc;
Mem *pColName;
assert( idx<p->nResColumn );
assert( var<COLNAME_N );
if( p->db->mallocFailed ){
assert( !zName || xDel!=SQLITE_DYNAMIC );
return SQLITE_NOMEM;
}
assert( p->aColName!=0 );
pColName = &(p->aColName[idx+var*p->nResColumn]);
rc = sqlite4VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, xDel);
assert( rc!=0 || !zName || (pColName->flags&MEM_Term)!=0 );
return rc;
}
/*
** Free all Savepoint structures that correspond to transaction levels
** larger than iLevel. Passing iLevel==1 deletes all Savepoint structures.
** iLevel==2 deletes all except for the outermost. And so on.
*/
static void freeSavepoints(sqlite4 *db, int iLevel){
if( iLevel<1 ) iLevel = 1;
while( (iLevel-1)<db->nSavepoint ){
Savepoint *pDel = db->pSavepoint;
db->pSavepoint = pDel->pNext;
db->nSavepoint--;
sqlite4DbFree(db, pDel);
}
}
#ifdef SQLITE_DEBUG
static int countSavepoints(sqlite4 *db){
int nRet = 0;
Savepoint *p;
for(p=db->pSavepoint; p; p=p->pNext) nRet++;
return nRet;
}
#endif
/*
** Rollback to transaction level iLevel. iLevel is as defined by the kv-store
** layer. For example, if the user has done:
**
** BEGIN;
** write 1;
** SAVEPOINT one;
** write 2;
** SAVEPOINT two;
** write 3;
**
** then:
**
** iLevel==1 Roll back and close top-level transaction.
** iLevel==2 Roll back top-level transaction. Transaction remains open.
** iLevel==3 Roll back to just after "write 1". Savepoint "one" remains
** open. Savepoint "two" is closed.
** iLevel==4 Roll back to just after "write 2". Both savepoints remain
** open (but "write 3" has been backed out).
*/
SQLITE_PRIVATE int sqlite4VdbeRollback(sqlite4 *db, int iLevel){
int i;
assert( sqlite4_mutex_held(db->mutex) );
assert( db->nSavepoint==countSavepoints(db) );
/* Invoke the xRollback() hook on all backends. */
sqlite4BeginBenignMalloc(db->pEnv);
for(i=0; i<db->nDb; i++){
KVStore *pKV = db->aDb[i].pKV;
if( pKV && pKV->iTransLevel>=iLevel ){
sqlite4KVStoreRollback(pKV, iLevel);
}
}
sqlite4EndBenignMalloc(db->pEnv);
/* If the InternChanges flag is set, expire prepared statements and
** reload the schema. If this is not a rollback of the top-level
** transaction, do not clear the SQLITE_InternChanges flag. */
if( db->flags&SQLITE_InternChanges ){
sqlite4ExpirePreparedStatements(db);
sqlite4ResetInternalSchema(db, -1);
if( iLevel>2 ) db->flags |= SQLITE_InternChanges;
}
/* Free elements from the db->pSavepoint list. Restore the deferred FK
** constraint counter to the value consistent with the restored database
** state. */
freeSavepoints(db, iLevel);
db->nDeferredCons = (db->pSavepoint ? db->pSavepoint->nDeferredCons : 0);
assert( db->nSavepoint==countSavepoints(db) );
return SQLITE_OK;
}
/*
** Commit to transaction level iLevel.
*/
SQLITE_PRIVATE int sqlite4VdbeCommit(sqlite4 *db, int iLevel){
int rc = SQLITE_OK;
int i;
assert( sqlite4_mutex_held(db->mutex) );
assert( db->nSavepoint==countSavepoints(db) );
assert( iLevel>1 || db->nDeferredCons==0 );
/* Invoke the xCommit() hook on all backends. */
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
KVStore *pKV = db->aDb[i].pKV;
if( pKV && pKV->iTransLevel>iLevel ){
rc = sqlite4KVStoreCommit(pKV, iLevel);
}
}
if( rc!=SQLITE_OK ){
sqlite4VdbeRollback(db, 1);
}else{
freeSavepoints(db, iLevel);
}
assert( db->nSavepoint==countSavepoints(db) );
return rc;
}
static int vdbeCloseStatement(Vdbe *p, int bRollback){
int i;
int rc = SQLITE_OK;
sqlite4 *db = p->db;
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
if( p->stmtTransMask & ((yDbMask)1)<<i ){
KVStore *pKV = db->aDb[i].pKV;
assert( pKV->iTransLevel>2 );
if( bRollback ){
rc = sqlite4KVStoreRollback(pKV, pKV->iTransLevel);
}
if( rc==SQLITE_OK ){
rc = sqlite4KVStoreCommit(pKV, pKV->iTransLevel-1);
}
}
}
if( bRollback ){
p->db->nDeferredCons = p->nStmtDefCons;
}
if( rc ){
sqlite4VdbeRollback(db, 1);
}
return rc;
}
/*
** This routine checks that the sqlite4.activeVdbeCnt count variable
** matches the number of vdbe's in the list sqlite4.pVdbe that are
** currently active. An assertion fails if the two counts do not match.
** This is an internal self-check only - it is not an essential processing
** step.
**
** This is a no-op if NDEBUG is defined.
*/
#ifndef NDEBUG
static void checkActiveVdbeCnt(sqlite4 *db){
Vdbe *p;
int cnt = 0;
int nWrite = 0;
p = db->pVdbe;
while( p ){
if( p->magic==VDBE_MAGIC_RUN && p->pc>=0 ){
cnt++;
if( p->readOnly==0 ) nWrite++;
}
p = p->pNext;
}
assert( cnt==db->activeVdbeCnt );
assert( nWrite==db->writeVdbeCnt );
}
#else
#define checkActiveVdbeCnt(x)
#endif
/*
** If the Vdbe passed as the first argument opened a statement-transaction,
** close it now. Argument eOp must be either SAVEPOINT_ROLLBACK or
** SAVEPOINT_RELEASE. If it is SAVEPOINT_ROLLBACK, then the statement
** transaction is rolled back. If eOp is SAVEPOINT_RELEASE, then the
** statement transaction is commtted.
**
** If an IO error occurs, an SQLITE_IOERR_XXX error code is returned.
** Otherwise SQLITE_OK.
*/
SQLITE_PRIVATE int sqlite4VdbeCloseStatement(Vdbe *p, int 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
** committed. If there are outstanding deferred foreign key constraint
** violations, return SQLITE_ERROR. Otherwise, SQLITE_OK.
**
** If there are outstanding FK violations and this function returns
** SQLITE_ERROR, set the result of the VM to SQLITE_CONSTRAINT and write
** an error message to it. Then return SQLITE_ERROR.
*/
#ifndef SQLITE_OMIT_FOREIGN_KEY
SQLITE_PRIVATE int sqlite4VdbeCheckFk(Vdbe *p, int deferred){
sqlite4 *db = p->db;
if( (deferred && db->nDeferredCons>0) || (!deferred && p->nFkConstraint>0) ){
p->rc = SQLITE_CONSTRAINT;
p->errorAction = OE_Abort;
sqlite4SetString(&p->zErrMsg, db, "foreign key constraint failed");
return SQLITE_ERROR;
}
return SQLITE_OK;
}
#endif
/*
** This routine is called the when a VDBE tries to halt. If the VDBE
** has made changes and is in autocommit mode, then commit those
** changes. If a rollback is needed, then do the rollback.
**
** This routine is the only way to move the state of a VM from
** SQLITE_MAGIC_RUN to SQLITE_MAGIC_HALT. It is harmless to
** call this on a VM that is in the SQLITE_MAGIC_HALT state.
**
** Return an error code. If the commit could not complete because of
** lock contention, return SQLITE_BUSY. If SQLITE_BUSY is returned, it
** means the close did not happen and needs to be repeated.
*/
SQLITE_PRIVATE int sqlite4VdbeHalt(Vdbe *p){
int rc;
sqlite4 *db = p->db;
if( db->mallocFailed ) p->rc = SQLITE_NOMEM;
if( p->aOnceFlag ) memset(p->aOnceFlag, 0, p->nOnceFlag);
closeAllCursors(p);
if( p->magic!=VDBE_MAGIC_RUN ){
return SQLITE_OK;
}
checkActiveVdbeCnt(db);
if( p->pc>=0 ){
/* Figure out if a transaction or statement transaction needs to be
** committed or rolled back.
**
** 0 - Do commit, either statement or transaction.
** 1 - Do rollback, either statement or transaction.
** 2 - Do transaction rollback.
*/
int eAction = (p->rc!=SQLITE_OK);
if( p->rc==SQLITE_CONSTRAINT ){
if( p->errorAction==OE_Rollback ){
eAction = 2;
}else if( p->errorAction==OE_Fail ){
eAction = 0;
}
}
if( eAction==0 && sqlite4VdbeCheckFk(p, 0) ) eAction = 1;
if( eAction==2 || (
db->writeVdbeCnt==(p->readOnly==0) && db->pSavepoint==0
)){
if( eAction==0 && sqlite4VdbeCheckFk(p, 1) ) eAction = 1;
if( eAction==0 ){
int rc = sqlite4VdbeCommit(db, 1);
if( rc!=SQLITE_OK ){
p->rc = rc;
eAction = 1;
}else{
assert( db->nDeferredCons<=0 );
sqlite4CommitInternalChanges(db);
}
}
if( eAction ){
sqlite4VdbeRollback(db, 1);
}
db->nDeferredCons = 0;
}else if( p->stmtTransMask ){
/* Auto-commit mode is turned off and no "OR ROLLBACK" constraint was
** encountered. So either commit (if eAction==0) or rollback (if
** eAction==1) any statement transactions opened by this VM. */
assert( eAction==0 || eAction==1 );
rc = vdbeCloseStatement(p, eAction);
}
if( p->changeCntOn ){
sqlite4VdbeSetChanges(db, (eAction ? 0 : p->nChange));
}
p->nChange = 0;
/* We have successfully halted and closed the VM. Record this fact. */
db->activeVdbeCnt--;
if( !p->readOnly ){
db->writeVdbeCnt--;
}
assert( db->activeVdbeCnt>=db->writeVdbeCnt );
if( db->pSavepoint==0 && db->activeVdbeCnt==0 ){
sqlite4VdbeRollback(db, 0);
}
}
p->magic = VDBE_MAGIC_HALT;
checkActiveVdbeCnt(db);
if( p->db->mallocFailed ){
p->rc = SQLITE_NOMEM;
}
return (p->rc==SQLITE_BUSY ? SQLITE_BUSY : SQLITE_OK);
}
/*
** Each VDBE holds the result of the most recent sqlite4_step() call
** in p->rc. This routine sets that result back to SQLITE_OK.
*/
SQLITE_PRIVATE void sqlite4VdbeResetStepResult(Vdbe *p){
p->rc = SQLITE_OK;
}
/*
** Copy the error code and error message belonging to the VDBE passed
** as the first argument to its database handle (so that they will be
** returned by calls to sqlite4_errcode() and sqlite4_errmsg()).
**
** This function does not clear the VDBE error code or message, just
** copies them to the database handle.
*/
SQLITE_PRIVATE int sqlite4VdbeTransferError(Vdbe *p){
sqlite4 *db = p->db;
int rc = p->rc;
if( p->zErrMsg ){
u8 mallocFailed = db->mallocFailed;
sqlite4BeginBenignMalloc(db->pEnv);
sqlite4ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT);
sqlite4EndBenignMalloc(db->pEnv);
db->mallocFailed = mallocFailed;
db->errCode = rc;
}else{
sqlite4Error(db, rc, 0);
}
return rc;
}
/*
** Clean up a VDBE after execution but do not delete the VDBE just yet.
** Write any error messages into *pzErrMsg. Return the result code.
**
** After this routine is run, the VDBE should be ready to be executed
** again.
**
** To look at it another way, this routine resets the state of the
** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to
** VDBE_MAGIC_INIT.
*/
SQLITE_PRIVATE int sqlite4VdbeReset(Vdbe *p){
sqlite4 *db;
db = p->db;
/* If the VM did not run to completion or if it encountered an
** error, then it might not have been halted properly. So halt
** it now.
*/
sqlite4VdbeHalt(p);
/* If the VDBE has be run even partially, then transfer the error code
** and error message from the VDBE into the main database structure. But
** if the VDBE has just been set to run but has not actually executed any
** instructions yet, leave the main database error information unchanged.
*/
if( p->pc>=0 ){
sqlite4VdbeTransferError(p);
sqlite4DbFree(db, p->zErrMsg);
p->zErrMsg = 0;
if( p->runOnlyOnce ) p->expired = 1;
}else if( p->rc && p->expired ){
/* The expired flag was set on the VDBE before the first call
** to sqlite4_step(). For consistency (since sqlite4_step() was
** called), set the database error in this case as well.
*/
sqlite4Error(db, p->rc, 0);
sqlite4ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT);
sqlite4DbFree(db, p->zErrMsg);
p->zErrMsg = 0;
}
/* Reclaim all memory used by the VDBE
*/
Cleanup(p);
/* Save profiling information from this VDBE run.
*/
#ifdef VDBE_PROFILE
{
FILE *out = fopen("vdbe_profile.out", "a");
if( out ){
int i;
fprintf(out, "---- ");
for(i=0; i<p->nOp; i++){
fprintf(out, "%02x", p->aOp[i].opcode);
}
fprintf(out, "\n");
for(i=0; i<p->nOp; i++){
fprintf(out, "%6d %10lld %8lld ",
p->aOp[i].cnt,
p->aOp[i].cycles,
p->aOp[i].cnt>0 ? p->aOp[i].cycles/p->aOp[i].cnt : 0
);
sqlite4VdbePrintOp(out, i, &p->aOp[i]);
}
fclose(out);
}
}
#endif
p->magic = VDBE_MAGIC_INIT;
return p->rc;
}
/*
** Clean up and delete a VDBE after execution. Return an integer which is
** the result code. Write any error message text into *pzErrMsg.
*/
SQLITE_PRIVATE int sqlite4VdbeFinalize(Vdbe *p){
int rc = SQLITE_OK;
if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){
rc = sqlite4VdbeReset(p);
}
sqlite4VdbeDelete(p);
return rc;
}
/*
** Call the destructor for each auxdata entry in pVdbeFunc for which
** the corresponding bit in mask is clear. Auxdata entries beyond 31
** are always destroyed. To destroy all auxdata entries, call this
** routine with mask==0.
*/
SQLITE_PRIVATE void sqlite4VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){
int i;
for(i=0; i<pVdbeFunc->nAux; i++){
struct AuxData *pAux = &pVdbeFunc->apAux[i];
if( (i>31 || !(mask&(((u32)1)<<i))) && pAux->pAux ){
if( pAux->xDelete ){
pAux->xDelete(pAux->pAux);
}
pAux->pAux = 0;
}
}
}
/*
** Free all memory associated with the Vdbe passed as the second argument.
** The difference between this function and sqlite4VdbeDelete() is that
** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with
** the database connection.
*/
SQLITE_PRIVATE void sqlite4VdbeDeleteObject(sqlite4 *db, Vdbe *p){
SubProgram *pSub, *pNext;
int i;
assert( p->db==0 || p->db==db );
releaseMemArray(p->aVar, p->nVar);
releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
for(pSub=p->pProgram; pSub; pSub=pNext){
pNext = pSub->pNext;
vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
sqlite4DbFree(db, pSub);
}
for(i=p->nzVar-1; i>=0; i--) sqlite4DbFree(db, p->azVar[i]);
vdbeFreeOpArray(db, p->aOp, p->nOp);
sqlite4DbFree(db, p->aLabel);
sqlite4DbFree(db, p->aColName);
sqlite4DbFree(db, p->zSql);
sqlite4DbFree(db, p->pFree);
#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
sqlite4DbFree(db, p->zExplain);
sqlite4DbFree(db, p->pExplain);
#endif
sqlite4DbFree(db, p);
}
/*
** Delete an entire VDBE.
*/
SQLITE_PRIVATE void sqlite4VdbeDelete(Vdbe *p){
sqlite4 *db;
if( NEVER(p==0) ) return;
db = p->db;
if( p->pPrev ){
p->pPrev->pNext = p->pNext;
}else{
assert( db->pVdbe==p );
db->pVdbe = p->pNext;
}
if( p->pNext ){
p->pNext->pPrev = p->pPrev;
}
p->magic = VDBE_MAGIC_DEAD;
p->db = 0;
sqlite4VdbeDeleteObject(db, p);
}
/*
** The following functions:
**
** sqlite4VdbeSerialType()
** sqlite4VdbeSerialTypeLen()
** sqlite4VdbeSerialLen()
** sqlite4VdbeSerialPut()
** sqlite4VdbeSerialGet()
**
** encapsulate the code that serializes values for storage in SQLite
** data and index records. Each serialized value consists of a
** 'serial-type' and a blob of data. The serial type is an 8-byte unsigned
** integer, stored as a varint.
**
** In an SQLite index record, the serial type is stored directly before
** the blob of data that it corresponds to. In a table record, all serial
** types are stored at the start of the record, and the blobs of data at
** the end. Hence these functions allow the caller to handle the
** serial-type and data blob seperately.
**
** The following table describes the various storage classes for data:
**
** serial type bytes of data type
** -------------- --------------- ---------------
** 0 0 NULL
** 1 1 signed integer
** 2 2 signed integer
** 3 3 signed integer
** 4 4 signed integer
** 5 6 signed integer
** 6 8 signed integer
** 7 8 IEEE float
** 8 0 Integer constant 0
** 9 0 Integer constant 1
** 10,11 reserved for expansion
** N>=12 and even (N-12)/2 BLOB
** N>=13 and odd (N-13)/2 text
**
** The 8 and 9 types were added in 3.3.0, file format 4. Prior versions
** of SQLite will not understand those serial types.
*/
/*
** Return the serial-type for the value stored in pMem.
*/
SQLITE_PRIVATE u32 sqlite4VdbeSerialType(Mem *pMem, int file_format){
int flags = pMem->flags;
int n;
if( flags&MEM_Null ){
return 0;
}
if( flags&MEM_Int ){
/* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
# define MAX_6BYTE ((((i64)0x00008000)<<32)-1)
i64 i = pMem->u.i;
u64 u;
if( file_format>=4 && (i&1)==i ){
return 8+(u32)i;
}
if( i<0 ){
if( i<(-MAX_6BYTE) ) return 6;
/* Previous test prevents: u = -(-9223372036854775808) */
u = -i;
}else{
u = i;
}
if( u<=127 ) return 1;
if( u<=32767 ) return 2;
if( u<=8388607 ) return 3;
if( u<=2147483647 ) return 4;
if( u<=MAX_6BYTE ) return 5;
return 6;
}
if( flags&MEM_Real ){
return 7;
}
assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) );
n = pMem->n;
if( flags & MEM_Zero ){
n += pMem->u.nZero;
}
assert( n>=0 );
return ((n*2) + 12 + ((flags&MEM_Str)!=0));
}
/*
** Return the length of the data corresponding to the supplied serial-type.
*/
SQLITE_PRIVATE u32 sqlite4VdbeSerialTypeLen(u32 serial_type){
if( serial_type>=12 ){
return (serial_type-12)/2;
}else{
static const u8 aSize[] = { 0, 1, 2, 3, 4, 6, 8, 8, 0, 0, 0, 0 };
return aSize[serial_type];
}
}
/*
** If we are on an architecture with mixed-endian floating
** points (ex: ARM7) then swap the lower 4 bytes with the
** upper 4 bytes. Return the result.
**
** For most architectures, this is a no-op.
**
** (later): It is reported to me that the mixed-endian problem
** on ARM7 is an issue with GCC, not with the ARM7 chip. It seems
** that early versions of GCC stored the two words of a 64-bit
** float in the wrong order. And that error has been propagated
** ever since. The blame is not necessarily with GCC, though.
** GCC might have just copying the problem from a prior compiler.
** I am also told that newer versions of GCC that follow a different
** ABI get the byte order right.
**
** Developers using SQLite on an ARM7 should compile and run their
** application using -DSQLITE_DEBUG=1 at least once. With DEBUG
** enabled, some asserts below will ensure that the byte order of
** floating point values is correct.
**
** (2007-08-30) Frank van Vugt has studied this problem closely
** and has send his findings to the SQLite developers. Frank
** writes that some Linux kernels offer floating point hardware
** emulation that uses only 32-bit mantissas instead of a full
** 48-bits as required by the IEEE standard. (This is the
** CONFIG_FPE_FASTFPE option.) On such systems, floating point
** byte swapping becomes very complicated. To avoid problems,
** the necessary byte swapping is carried out using a 64-bit integer
** rather than a 64-bit float. Frank assures us that the code here
** works for him. We, the developers, have no way to independently
** verify this, but Frank seems to know what he is talking about
** so we trust him.
*/
#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
static u64 floatSwap(u64 in){
union {
u64 r;
u32 i[2];
} u;
u32 t;
u.r = in;
t = u.i[0];
u.i[0] = u.i[1];
u.i[1] = t;
return u.r;
}
# define swapMixedEndianFloat(X) X = floatSwap(X)
#else
# define swapMixedEndianFloat(X)
#endif
/*
** Write the serialized data blob for the value stored in pMem into
** buf. It is assumed that the caller has allocated sufficient space.
** Return the number of bytes written.
**
** nBuf is the amount of space left in buf[]. nBuf must always be
** large enough to hold the entire field. Except, if the field is
** a blob with a zero-filled tail, then buf[] might be just the right
** size to hold everything except for the zero-filled tail. If buf[]
** is only big enough to hold the non-zero prefix, then only write that
** prefix into buf[]. But if buf[] is large enough to hold both the
** prefix and the tail then write the prefix and set the tail to all
** zeros.
**
** Return the number of bytes actually written into buf[]. The number
** of bytes in the zero-filled tail is included in the return value only
** if those bytes were zeroed in buf[].
*/
SQLITE_PRIVATE u32 sqlite4VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_format){
u32 serial_type = sqlite4VdbeSerialType(pMem, file_format);
u32 len;
/* Integer and Real */
if( serial_type<=7 && serial_type>0 ){
u64 v;
u32 i;
if( serial_type==7 ){
assert( sizeof(v)==sizeof(pMem->r) );
memcpy(&v, &pMem->r, sizeof(v));
swapMixedEndianFloat(v);
}else{
v = pMem->u.i;
}
len = i = sqlite4VdbeSerialTypeLen(serial_type);
assert( len<=(u32)nBuf );
while( i-- ){
buf[i] = (u8)(v&0xFF);
v >>= 8;
}
return len;
}
/* String or blob */
if( serial_type>=12 ){
assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.nZero:0)
== (int)sqlite4VdbeSerialTypeLen(serial_type) );
assert( pMem->n<=nBuf );
len = pMem->n;
memcpy(buf, pMem->z, len);
if( pMem->flags & MEM_Zero ){
len += pMem->u.nZero;
assert( nBuf>=0 );
if( len > (u32)nBuf ){
len = (u32)nBuf;
}
memset(&buf[pMem->n], 0, len-pMem->n);
}
return len;
}
/* NULL or constants 0 or 1 */
return 0;
}
/*
** Deserialize the data blob pointed to by buf as serial type serial_type
** and store the result in pMem. Return the number of bytes read.
*/
SQLITE_PRIVATE u32 sqlite4VdbeSerialGet(
const unsigned char *buf, /* Buffer to deserialize from */
u32 serial_type, /* Serial type to deserialize */
Mem *pMem /* Memory cell to write value into */
){
switch( serial_type ){
case 10: /* Reserved for future use */
case 11: /* Reserved for future use */
case 0: { /* NULL */
pMem->flags = MEM_Null;
break;
}
case 1: { /* 1-byte signed integer */
pMem->u.i = (signed char)buf[0];
pMem->flags = MEM_Int;
return 1;
}
case 2: { /* 2-byte signed integer */
pMem->u.i = (((signed char)buf[0])<<8) | buf[1];
pMem->flags = MEM_Int;
return 2;
}
case 3: { /* 3-byte signed integer */
pMem->u.i = (((signed char)buf[0])<<16) | (buf[1]<<8) | buf[2];
pMem->flags = MEM_Int;
return 3;
}
case 4: { /* 4-byte signed integer */
pMem->u.i = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
pMem->flags = MEM_Int;
return 4;
}
case 5: { /* 6-byte signed integer */
u64 x = (((signed char)buf[0])<<8) | buf[1];
u32 y = (buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5];
x = (x<<32) | y;
pMem->u.i = *(i64*)&x;
pMem->flags = MEM_Int;
return 6;
}
case 6: /* 8-byte signed integer */
case 7: { /* IEEE floating point */
u64 x;
u32 y;
#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT)
/* Verify that integers and floating point values use the same
** byte order. Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is
** defined that 64-bit floating point values really are mixed
** endian.
*/
static const u64 t1 = ((u64)0x3ff00000)<<32;
static const double r1 = 1.0;
u64 t2 = t1;
swapMixedEndianFloat(t2);
assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 );
#endif
x = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
y = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7];
x = (x<<32) | y;
if( serial_type==6 ){
pMem->u.i = *(i64*)&x;
pMem->flags = MEM_Int;
}else{
assert( sizeof(x)==8 && sizeof(pMem->r)==8 );
swapMixedEndianFloat(x);
memcpy(&pMem->r, &x, sizeof(x));
pMem->flags = sqlite4IsNaN(pMem->r) ? MEM_Null : MEM_Real;
}
return 8;
}
case 8: /* Integer 0 */
case 9: { /* Integer 1 */
pMem->u.i = serial_type-8;
pMem->flags = MEM_Int;
return 0;
}
default: {
u32 len = (serial_type-12)/2;
pMem->z = (char *)buf;
pMem->n = len;
pMem->xDel = 0;
if( serial_type&0x01 ){
pMem->flags = MEM_Str | MEM_Ephem;
}else{
pMem->flags = MEM_Blob | MEM_Ephem;
}
return len;
}
}
return 0;
}
/*
** This routine is used to allocate sufficient space for an UnpackedRecord
** structure large enough to be used with sqlite4VdbeRecordUnpack() if
** the first argument is a pointer to KeyInfo structure pKeyInfo.
**
** The space is either allocated using sqlite4DbMallocRaw() or from within
** the unaligned buffer passed via the second and third arguments (presumably
** stack space). If the former, then *ppFree is set to a pointer that should
** be eventually freed by the caller using sqlite4DbFree(). Or, if the
** allocation comes from the pSpace/szSpace buffer, *ppFree is set to NULL
** before returning.
**
** If an OOM error occurs, NULL is returned.
*/
SQLITE_PRIVATE UnpackedRecord *sqlite4VdbeAllocUnpackedRecord(
KeyInfo *pKeyInfo, /* Description of the record */
char *pSpace, /* Unaligned space available */
int szSpace, /* Size of pSpace[] in bytes */
char **ppFree /* OUT: Caller should free this pointer */
){
UnpackedRecord *p; /* Unpacked record to return */
int nOff; /* Increment pSpace by nOff to align it */
int nByte; /* Number of bytes required for *p */
/* We want to shift the pointer pSpace up such that it is 8-byte aligned.
** Thus, we need to calculate a value, nOff, between 0 and 7, to shift
** it by. If pSpace is already 8-byte aligned, nOff should be zero.
*/
nOff = (8 - (SQLITE_PTR_TO_INT(pSpace) & 7)) & 7;
nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nField+1);
if( nByte>szSpace+nOff ){
p = (UnpackedRecord *)sqlite4DbMallocRaw(pKeyInfo->db, nByte);
*ppFree = (char *)p;
if( !p ) return 0;
}else{
p = (UnpackedRecord*)&pSpace[nOff];
*ppFree = 0;
}
p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))];
p->pKeyInfo = pKeyInfo;
p->nField = pKeyInfo->nField + 1;
return p;
}
/*
** Given the nKey-byte encoding of a record in pKey[], populate the
** UnpackedRecord structure indicated by the fourth argument with the
** contents of the decoded record.
*/
SQLITE_PRIVATE void sqlite4VdbeRecordUnpack(
KeyInfo *pKeyInfo, /* Information about the record format */
int nKey, /* Size of the binary record */
const void *pKey, /* The binary record */
UnpackedRecord *p /* Populate this structure before returning. */
){
const unsigned char *aKey = (const unsigned char *)pKey;
int d;
u32 idx; /* Offset in aKey[] to read from */
u16 u; /* Unsigned loop counter */
u32 szHdr;
Mem *pMem = p->aMem;
p->flags = 0;
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
idx = getVarint32(aKey, szHdr);
d = szHdr;
u = 0;
while( idx<szHdr && u<p->nField && d<=nKey ){
u32 serial_type;
idx += getVarint32(&aKey[idx], serial_type);
pMem->enc = pKeyInfo->enc;
pMem->db = pKeyInfo->db;
/* pMem->flags = 0; // sqlite4VdbeSerialGet() will set this for us */
pMem->zMalloc = 0;
d += sqlite4VdbeSerialGet(&aKey[d], serial_type, pMem);
pMem++;
u++;
}
assert( u<=pKeyInfo->nField + 1 );
p->nField = u;
}
/*
** This function compares the two table rows or index records
** specified by {nKey1, pKey1} and pPKey2. It returns a negative, zero
** or positive integer if key1 is less than, equal to or
** greater than key2. The {nKey1, pKey1} key must be a blob
** created by th OP_MakeRecord opcode of the VDBE. The pPKey2
** key must be a parsed key such as obtained from
** sqlite4VdbeParseRecord.
**
** Key1 and Key2 do not have to contain the same number of fields.
** The key with fewer fields is usually compares less than the
** longer key. However if the UNPACKED_INCRKEY flags in pPKey2 is set
** and the common prefixes are equal, then key1 is less than key2.
** Or if the UNPACKED_MATCH_PREFIX flag is set and the prefixes are
** equal, then the keys are considered to be equal and
** the parts beyond the common prefix are ignored.
*/
SQLITE_PRIVATE int sqlite4VdbeRecordCompare(
int nKey1, const void *pKey1, /* Left key */
UnpackedRecord *pPKey2 /* Right key */
){
int d1; /* Offset into aKey[] of next data element */
u32 idx1; /* Offset into aKey[] of next header element */
u32 szHdr1; /* Number of bytes in header */
int i = 0;
int nField;
int rc = 0;
const unsigned char *aKey1 = (const unsigned char *)pKey1;
KeyInfo *pKeyInfo;
Mem mem1;
pKeyInfo = pPKey2->pKeyInfo;
mem1.enc = pKeyInfo->enc;
mem1.db = pKeyInfo->db;
/* mem1.flags = 0; // Will be initialized by sqlite4VdbeSerialGet() */
VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */
/* Compilers may complain that mem1.u.i is potentially uninitialized.
** We could initialize it, as shown here, to silence those complaints.
** But in fact, mem1.u.i will never actually be used uninitialized, and doing
** the unnecessary initialization has a measurable negative performance
** impact, since this routine is a very high runner. And so, we choose
** to ignore the compiler warnings and leave this variable uninitialized.
*/
/* mem1.u.i = 0; // not needed, here to silence compiler warning */
idx1 = getVarint32(aKey1, szHdr1);
d1 = szHdr1;
nField = pKeyInfo->nField;
while( idx1<szHdr1 && i<pPKey2->nField ){
u32 serial_type1;
/* Read the serial types for the next element in each key. */
idx1 += getVarint32( aKey1+idx1, serial_type1 );
if( d1>=nKey1 && sqlite4VdbeSerialTypeLen(serial_type1)>0 ) break;
/* Extract the values to be compared.
*/
d1 += sqlite4VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);
/* Do the comparison
*/
rc = sqlite4MemCompare(&mem1, &pPKey2->aMem[i],
i<nField ? pKeyInfo->aColl[i] : 0);
if( rc!=0 ){
assert( mem1.zMalloc==0 ); /* See comment below */
/* Invert the result if we are using DESC sort order. */
if( pKeyInfo->aSortOrder && i<nField && pKeyInfo->aSortOrder[i] ){
rc = -rc;
}
/* If the PREFIX_SEARCH flag is set and all fields except the final
** rowid field were equal, then clear the PREFIX_SEARCH flag and set
** pPKey2->rowid to the value of the rowid field in (pKey1, nKey1).
** This is used by the OP_IsUnique opcode.
*/
if( (pPKey2->flags & UNPACKED_PREFIX_SEARCH) && i==(pPKey2->nField-1) ){
assert( idx1==szHdr1 && rc );
assert( mem1.flags & MEM_Int );
pPKey2->flags &= ~UNPACKED_PREFIX_SEARCH;
pPKey2->rowid = mem1.u.i;
}
return rc;
}
i++;
}
/* No memory allocation is ever used on mem1. Prove this using
** the following assert(). If the assert() fails, it indicates a
** memory leak and a need to call sqlite4VdbeMemRelease(&mem1).
*/
assert( mem1.zMalloc==0 );
/* rc==0 here means that one of the keys ran out of fields and
** all the fields up to that point were equal. If the UNPACKED_INCRKEY
** flag is set, then break the tie by treating key2 as larger.
** If the UPACKED_PREFIX_MATCH flag is set, then keys with common prefixes
** are considered to be equal. Otherwise, the longer key is the
** larger. As it happens, the pPKey2 will always be the longer
** if there is a difference.
*/
assert( rc==0 );
if( pPKey2->flags & UNPACKED_INCRKEY ){
rc = -1;
}else if( pPKey2->flags & UNPACKED_PREFIX_MATCH ){
/* Leave rc==0 */
}else if( idx1<szHdr1 ){
rc = 1;
}
return rc;
}
/*
** This routine sets the value to be returned by subsequent calls to
** sqlite4_changes() on the database handle 'db'.
*/
SQLITE_PRIVATE void sqlite4VdbeSetChanges(sqlite4 *db, int nChange){
assert( sqlite4_mutex_held(db->mutex) );
db->nChange = nChange;
db->nTotalChange += nChange;
}
/*
** Set a flag in the vdbe to update the change counter when it is finalised
** or reset.
*/
SQLITE_PRIVATE void sqlite4VdbeCountChanges(Vdbe *v){
v->changeCntOn = 1;
}
/*
** Mark every prepared statement associated with a database connection
** as expired.
**
** An expired statement means that recompilation of the statement is
** recommend. Statements expire when things happen that make their
** programs obsolete. Removing user-defined functions or collating
** sequences, or changing an authorization function are the types of
** things that make prepared statements obsolete.
*/
SQLITE_PRIVATE void sqlite4ExpirePreparedStatements(sqlite4 *db){
Vdbe *p;
for(p = db->pVdbe; p; p=p->pNext){
p->expired = 1;
}
}
/*
** Return the database associated with the Vdbe.
*/
SQLITE_PRIVATE sqlite4 *sqlite4VdbeDb(Vdbe *v){
return v->db;
}
/*
** Return a pointer to an sqlite4_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_*
** constants) to the value before returning it.
**
** The returned value must be freed by the caller using sqlite4ValueFree().
*/
SQLITE_PRIVATE sqlite4_value *sqlite4VdbeGetValue(Vdbe *v, int iVar, u8 aff){
assert( iVar>0 );
if( v ){
Mem *pMem = &v->aVar[iVar-1];
if( 0==(pMem->flags & MEM_Null) ){
sqlite4_value *pRet = sqlite4ValueNew(v->db);
if( pRet ){
sqlite4VdbeMemCopy((Mem *)pRet, pMem);
sqlite4ValueApplyAffinity(pRet, aff, SQLITE_UTF8);
sqlite4VdbeMemStoreType((Mem *)pRet);
}
return pRet;
}
}
return 0;
}
/*
** Configure SQL variable iVar so that binding a new value to it signals
** to sqlite4_reoptimize() that re-preparing the statement may result
** in a better query plan.
*/
SQLITE_PRIVATE void sqlite4VdbeSetVarmask(Vdbe *v, int iVar){
assert( iVar>0 );
if( iVar>32 ){
v->expmask = 0xffffffff;
}else{
v->expmask |= ((u32)1 << (iVar-1));
}
}
/************** End of vdbeaux.c *********************************************/
/************** Begin file vdbeapi.c *****************************************/
/*
** 2004 May 26
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code use to implement APIs that are part of the
** VDBE.
*/
#ifndef SQLITE_OMIT_DEPRECATED
/*
** Return TRUE (non-zero) of the statement supplied as an argument needs
** to be recompiled. A statement needs to be recompiled whenever the
** execution environment changes in a way that would alter the program
** that sqlite4_prepare() generates. For example, if new functions or
** collating sequences are registered or if an authorizer function is
** added or changed.
*/
SQLITE_API int sqlite4_expired(sqlite4_stmt *pStmt){
Vdbe *p = (Vdbe*)pStmt;
return p==0 || p->expired;
}
#endif
/*
** Check on a Vdbe to make sure it has not been finalized. Log
** an error and return true if it has been finalized (or is otherwise
** invalid). Return false if it is ok.
*/
static int vdbeSafety(Vdbe *p){
if( p->db==0 ){
sqlite4_log(0,SQLITE_MISUSE,"API called with finalized prepared statement");
return 1;
}else{
return 0;
}
}
static int vdbeSafetyNotNull(Vdbe *p){
if( p==0 ){
sqlite4_log(0,SQLITE_MISUSE, "API called with NULL prepared statement");
return 1;
}else{
return vdbeSafety(p);
}
}
/*
** The following routine destroys a virtual machine that is created by
** the sqlite4_compile() routine. The integer returned is an SQLITE_
** success/failure code that describes the result of executing the virtual
** machine.
**
** This routine sets the error code and string returned by
** sqlite4_errcode(), sqlite4_errmsg() and sqlite4_errmsg16().
*/
SQLITE_API int sqlite4_finalize(sqlite4_stmt *pStmt){
int rc;
if( pStmt==0 ){
/* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite4_finalize() on a NULL
** pointer is a harmless no-op. */
rc = SQLITE_OK;
}else{
Vdbe *v = (Vdbe*)pStmt;
sqlite4 *db = v->db;
#if SQLITE_THREADSAFE
sqlite4_mutex *mutex;
#endif
if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT;
#if SQLITE_THREADSAFE
mutex = v->db->mutex;
#endif
sqlite4_mutex_enter(mutex);
rc = sqlite4VdbeFinalize(v);
rc = sqlite4ApiExit(db, rc);
sqlite4_mutex_leave(mutex);
}
return rc;
}
/*
** Terminate the current execution of an SQL statement and reset it
** back to its starting state so that it can be reused. A success code from
** the prior execution is returned.
**
** This routine sets the error code and string returned by
** sqlite4_errcode(), sqlite4_errmsg() and sqlite4_errmsg16().
*/
SQLITE_API int sqlite4_reset(sqlite4_stmt *pStmt){
int rc;
if( pStmt==0 ){
rc = SQLITE_OK;
}else{
Vdbe *v = (Vdbe*)pStmt;
sqlite4_mutex_enter(v->db->mutex);
rc = sqlite4VdbeReset(v);
sqlite4VdbeRewind(v);
rc = sqlite4ApiExit(v->db, rc);
sqlite4_mutex_leave(v->db->mutex);
}
return rc;
}
/*
** Set all the parameters in the compiled SQL statement to NULL.
*/
SQLITE_API int sqlite4_clear_bindings(sqlite4_stmt *pStmt){
int i;
int rc = SQLITE_OK;
Vdbe *p = (Vdbe*)pStmt;
#if SQLITE_THREADSAFE
sqlite4_mutex *mutex = ((Vdbe*)pStmt)->db->mutex;
#endif
sqlite4_mutex_enter(mutex);
for(i=0; i<p->nVar; i++){
sqlite4VdbeMemRelease(&p->aVar[i]);
p->aVar[i].flags = MEM_Null;
}
if( p->expmask ){
p->expired = 1;
}
sqlite4_mutex_leave(mutex);
return rc;
}
/**************************** sqlite4_value_ *******************************
** The following routines extract information from a Mem or sqlite4_value
** structure.
*/
SQLITE_API const void *sqlite4_value_blob(sqlite4_value *pVal){
Mem *p = (Mem*)pVal;
if( p->flags & (MEM_Blob|MEM_Str) ){
sqlite4VdbeMemExpandBlob(p);
p->flags &= ~MEM_Str;
p->flags |= MEM_Blob;
return p->n ? p->z : 0;
}else{
return sqlite4_value_text(pVal);
}
}
SQLITE_API int sqlite4_value_bytes(sqlite4_value *pVal){
return sqlite4ValueBytes(pVal, SQLITE_UTF8);
}
SQLITE_API int sqlite4_value_bytes16(sqlite4_value *pVal){
return sqlite4ValueBytes(pVal, SQLITE_UTF16NATIVE);
}
SQLITE_API double sqlite4_value_double(sqlite4_value *pVal){
return sqlite4VdbeRealValue((Mem*)pVal);
}
SQLITE_API int sqlite4_value_int(sqlite4_value *pVal){
return (int)sqlite4VdbeIntValue((Mem*)pVal);
}
SQLITE_API sqlite_int64 sqlite4_value_int64(sqlite4_value *pVal){
return sqlite4VdbeIntValue((Mem*)pVal);
}
SQLITE_API const unsigned char *sqlite4_value_text(sqlite4_value *pVal){
return (const unsigned char *)sqlite4ValueText(pVal, SQLITE_UTF8);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API const void *sqlite4_value_text16(sqlite4_value* pVal){
return sqlite4ValueText(pVal, SQLITE_UTF16NATIVE);
}
SQLITE_API const void *sqlite4_value_text16be(sqlite4_value *pVal){
return sqlite4ValueText(pVal, SQLITE_UTF16BE);
}
SQLITE_API const void *sqlite4_value_text16le(sqlite4_value *pVal){
return sqlite4ValueText(pVal, SQLITE_UTF16LE);
}
#endif /* SQLITE_OMIT_UTF16 */
SQLITE_API int sqlite4_value_type(sqlite4_value* pVal){
return pVal->type;
}
/**************************** sqlite4_result_ *******************************
** The following routines are used by user-defined functions to specify
** the function result.
**
** The setStrOrError() funtion calls sqlite4VdbeMemSetStr() to store the
** result as a string or blob but if the string or blob is too large, it
** then sets the error code to SQLITE_TOOBIG
*/
static void setResultStrOrError(
sqlite4_context *pCtx, /* Function context */
const char *z, /* String pointer */
int n, /* Bytes in string, or negative */
u8 enc, /* Encoding of z. 0 for BLOBs */
void (*xDel)(void*) /* Destructor function */
){
if( xDel==SQLITE_DYNAMIC ){
assert( sqlite4MemdebugHasType(z, MEMTYPE_HEAP) );
assert( sqlite4MemdebugNoType(z, ~MEMTYPE_HEAP) );
sqlite4MemdebugSetType((char*)z, MEMTYPE_DB | MEMTYPE_HEAP);
}
if( sqlite4VdbeMemSetStr(&pCtx->s, z, n, enc, xDel)==SQLITE_TOOBIG ){
sqlite4_result_error_toobig(pCtx);
}
}
SQLITE_API void sqlite4_result_blob(
sqlite4_context *pCtx,
const void *z,
int n,
void (*xDel)(void *)
){
assert( n>=0 );
assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
setResultStrOrError(pCtx, z, n, 0, xDel);
}
SQLITE_API void sqlite4_result_double(sqlite4_context *pCtx, double rVal){
assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
sqlite4VdbeMemSetDouble(&pCtx->s, rVal);
}
SQLITE_API void sqlite4_result_error(sqlite4_context *pCtx, const char *z, int n){
assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
pCtx->isError = SQLITE_ERROR;
sqlite4VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API void sqlite4_result_error16(sqlite4_context *pCtx, const void *z, int n){
assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
pCtx->isError = SQLITE_ERROR;
sqlite4VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
}
#endif
SQLITE_API void sqlite4_result_int(sqlite4_context *pCtx, int iVal){
assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
sqlite4VdbeMemSetInt64(&pCtx->s, (i64)iVal);
}
SQLITE_API void sqlite4_result_int64(sqlite4_context *pCtx, i64 iVal){
assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
sqlite4VdbeMemSetInt64(&pCtx->s, iVal);
}
SQLITE_API void sqlite4_result_null(sqlite4_context *pCtx){
assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
sqlite4VdbeMemSetNull(&pCtx->s);
}
SQLITE_API void sqlite4_result_text(
sqlite4_context *pCtx,
const char *z,
int n,
void (*xDel)(void *)
){
assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API void sqlite4_result_text16(
sqlite4_context *pCtx,
const void *z,
int n,
void (*xDel)(void *)
){
assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
setResultStrOrError(pCtx, z, n, SQLITE_UTF16NATIVE, xDel);
}
SQLITE_API void sqlite4_result_text16be(
sqlite4_context *pCtx,
const void *z,
int n,
void (*xDel)(void *)
){
assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
setResultStrOrError(pCtx, z, n, SQLITE_UTF16BE, xDel);
}
SQLITE_API void sqlite4_result_text16le(
sqlite4_context *pCtx,
const void *z,
int n,
void (*xDel)(void *)
){
assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
setResultStrOrError(pCtx, z, n, SQLITE_UTF16LE, xDel);
}
#endif /* SQLITE_OMIT_UTF16 */
SQLITE_API void sqlite4_result_value(sqlite4_context *pCtx, sqlite4_value *pValue){
assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
sqlite4VdbeMemCopy(&pCtx->s, pValue);
}
SQLITE_API void sqlite4_result_zeroblob(sqlite4_context *pCtx, int n){
assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
sqlite4VdbeMemSetZeroBlob(&pCtx->s, n);
}
SQLITE_API void sqlite4_result_error_code(sqlite4_context *pCtx, int errCode){
pCtx->isError = errCode;
if( pCtx->s.flags & MEM_Null ){
sqlite4VdbeMemSetStr(&pCtx->s, sqlite4ErrStr(errCode), -1,
SQLITE_UTF8, SQLITE_STATIC);
}
}
/* Force an SQLITE_TOOBIG error. */
SQLITE_API void sqlite4_result_error_toobig(sqlite4_context *pCtx){
assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
pCtx->isError = SQLITE_TOOBIG;
sqlite4VdbeMemSetStr(&pCtx->s, "string or blob too big", -1,
SQLITE_UTF8, SQLITE_STATIC);
}
/* An SQLITE_NOMEM error. */
SQLITE_API void sqlite4_result_error_nomem(sqlite4_context *pCtx){
assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
sqlite4VdbeMemSetNull(&pCtx->s);
pCtx->isError = SQLITE_NOMEM;
pCtx->s.db->mallocFailed = 1;
}
/*
** Execute the statement pStmt, either until a row of data is ready, the
** statement is completely executed or an error occurs.
**
** This routine implements the bulk of the logic behind the sqlite_step()
** API. The only thing omitted is the automatic recompile if a
** schema change has occurred. That detail is handled by the
** outer sqlite4_step() wrapper procedure.
*/
static int sqlite4Step(Vdbe *p){
sqlite4 *db;
int rc;
assert(p);
if( p->magic!=VDBE_MAGIC_RUN ){
/* We used to require that sqlite4_reset() be called before retrying
** sqlite4_step() after any error or after SQLITE_DONE. But beginning
** with version 3.7.0, we changed this so that sqlite4_reset() would
** be called automatically instead of throwing the SQLITE_MISUSE error.
** This "automatic-reset" change is not technically an incompatibility,
** since any application that receives an SQLITE_MISUSE is broken by
** definition.
**
** Nevertheless, some published applications that were originally written
** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE
** returns, and those were broken by the automatic-reset change. As a
** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the
** legacy behavior of returning SQLITE_MISUSE for cases where the
** previous sqlite4_step() returned something other than a SQLITE_LOCKED
** or SQLITE_BUSY error.
*/
#ifdef SQLITE_OMIT_AUTORESET
if( p->rc==SQLITE_BUSY || p->rc==SQLITE_LOCKED ){
sqlite4_reset((sqlite4_stmt*)p);
}else{
return SQLITE_MISUSE_BKPT;
}
#else
sqlite4_reset((sqlite4_stmt*)p);
#endif
}
/* Check that malloc() has not failed. If it has, return early. */
db = p->db;
if( db->mallocFailed ){
p->rc = SQLITE_NOMEM;
return SQLITE_NOMEM;
}
if( p->pc<=0 && p->expired ){
p->rc = SQLITE_SCHEMA;
rc = SQLITE_ERROR;
goto end_of_step;
}
if( p->pc<0 ){
/* If there are no other statements currently running, then
** reset the interrupt flag. This prevents a call to sqlite4_interrupt
** from interrupting a statement that has not yet started.
*/
if( db->activeVdbeCnt==0 ){
db->u1.isInterrupted = 0;
}
assert( db->writeVdbeCnt>0 || db->pSavepoint || db->nDeferredCons==0 );
#ifndef SQLITE_OMIT_TRACE
if( db->xProfile && !db->init.busy ){
sqlite4OsCurrentTime(0, &p->startTime);
}
#endif
db->activeVdbeCnt++;
if( p->readOnly==0 ) db->writeVdbeCnt++;
p->pc = 0;
}
#ifndef SQLITE_OMIT_EXPLAIN
if( p->explain ){
rc = sqlite4VdbeList(p);
}else
#endif /* SQLITE_OMIT_EXPLAIN */
{
db->vdbeExecCnt++;
rc = sqlite4VdbeExec(p);
db->vdbeExecCnt--;
}
#ifndef SQLITE_OMIT_TRACE
/* Invoke the profile callback if there is one
*/
if( rc!=SQLITE_ROW && db->xProfile && !db->init.busy && p->zSql ){
sqlite4_int64 iNow;
sqlite4OsCurrentTime(0, &iNow);
db->xProfile(db->pProfileArg, p->zSql, (iNow - p->startTime)*1000000);
}
#endif
db->errCode = rc;
if( SQLITE_NOMEM==sqlite4ApiExit(p->db, p->rc) ){
p->rc = SQLITE_NOMEM;
}
end_of_step:
/* At this point local variable rc holds the value that should be
** returned if this statement was compiled using the legacy
** sqlite4_prepare() interface. According to the docs, this can only
** be one of the values in the first assert() below. Variable p->rc
** contains the value that would be returned if sqlite4_finalize()
** were called on statement p.
*/
assert( rc==SQLITE_ROW || rc==SQLITE_DONE || rc==SQLITE_ERROR
|| rc==SQLITE_BUSY || rc==SQLITE_MISUSE
);
assert( p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE );
if( rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
rc = sqlite4VdbeTransferError(p);
}
return rc;
}
/*
** The maximum number of times that a statement will try to reparse
** itself before giving up and returning SQLITE_SCHEMA.
*/
#ifndef SQLITE_MAX_SCHEMA_RETRY
# define SQLITE_MAX_SCHEMA_RETRY 5
#endif
/*
** This is the top-level implementation of sqlite4_step(). Call
** sqlite4Step() to do most of the work. If a schema error occurs,
** call sqlite4Reprepare() and try again.
*/
SQLITE_API int sqlite4_step(sqlite4_stmt *pStmt){
int rc = SQLITE_OK; /* Result from sqlite4Step() */
int rc2 = SQLITE_OK; /* Result from sqlite4Reprepare() */
Vdbe *v = (Vdbe*)pStmt; /* the prepared statement */
int cnt = 0; /* Counter to prevent infinite loop of reprepares */
sqlite4 *db; /* The database connection */
if( vdbeSafetyNotNull(v) ){
return SQLITE_MISUSE_BKPT;
}
db = v->db;
sqlite4_mutex_enter(db->mutex);
while( (rc = sqlite4Step(v))==SQLITE_SCHEMA
&& cnt++ < SQLITE_MAX_SCHEMA_RETRY
&& (rc2 = rc = sqlite4Reprepare(v))==SQLITE_OK ){
sqlite4_reset(pStmt);
assert( v->expired==0 );
}
if( rc2!=SQLITE_OK && ALWAYS(db->pErr) ){
/* This case occurs after failing to recompile an sql statement.
** The error message from the SQL compiler has already been loaded
** into the database handle. This block copies the error message
** from the database handle into the statement and sets the statement
** program counter to 0 to ensure that when the statement is
** finalized or reset the parser error message is available via
** sqlite4_errmsg() and sqlite4_errcode().
*/
const char *zErr = (const char *)sqlite4_value_text(db->pErr);
sqlite4DbFree(db, v->zErrMsg);
if( !db->mallocFailed ){
v->zErrMsg = sqlite4DbStrDup(db, zErr);
v->rc = rc2;
} else {
v->zErrMsg = 0;
v->rc = rc = SQLITE_NOMEM;
}
}
rc = sqlite4ApiExit(db, rc);
sqlite4_mutex_leave(db->mutex);
return rc;
}
/*
** Extract the user data from a sqlite4_context structure and return a
** pointer to it.
*/
SQLITE_API void *sqlite4_user_data(sqlite4_context *p){
assert( p && p->pFunc );
return p->pFunc->pUserData;
}
/*
** Return the sqlite4 object that owns the sqlite4_context.
**
** IMPLEMENTATION-OF: R-46798-50301 The sqlite4_context_db_handle() interface
** returns a copy of the pointer to the database connection (the 1st
** parameter) of the sqlite4_create_function() and
** sqlite4_create_function16() routines that originally registered the
** application defined function.
*/
SQLITE_API sqlite4 *sqlite4_context_db_handle(sqlite4_context *p){
assert( p && p->pFunc );
return p->s.db;
}
/*
** Return the sqlite4_env object associated with the sqlite4_context.
*/
SQLITE_API sqlite4_env *sqlite4_context_env(sqlite4_context *p){
assert( p && p->pFunc );
return p->s.db->pEnv;
}
/*
** The following is the implementation of an SQL function that always
** fails with an error message stating that the function is used in the
** wrong context. The sqlite4_overload_function() API might construct
** SQL function that use this routine so that the functions will exist
** for name resolution but are actually overloaded by the xFindFunction
** method of virtual tables.
*/
SQLITE_PRIVATE void sqlite4InvalidFunction(
sqlite4_context *context, /* The function calling context */
int NotUsed, /* Number of arguments to the function */
sqlite4_value **NotUsed2 /* Value of each argument */
){
const char *zName = context->pFunc->zName;
char *zErr;
sqlite4_env *pEnv = sqlite4_context_env(context);
UNUSED_PARAMETER2(NotUsed, NotUsed2);
zErr = sqlite4_mprintf(pEnv,
"unable to use function %s in the requested context", zName);
sqlite4_result_error(context, zErr, -1);
sqlite4_free(pEnv, zErr);
}
/*
** Allocate or return the aggregate context for a user function. A new
** context is allocated on the first call. Subsequent calls return the
** same context that was returned on prior calls.
*/
SQLITE_API void *sqlite4_aggregate_context(sqlite4_context *p, int nByte){
Mem *pMem;
assert( p && p->pFunc && p->pFunc->xStep );
assert( sqlite4_mutex_held(p->s.db->mutex) );
pMem = p->pMem;
testcase( nByte<0 );
if( (pMem->flags & MEM_Agg)==0 ){
if( nByte<=0 ){
sqlite4VdbeMemReleaseExternal(pMem);
pMem->flags = MEM_Null;
pMem->z = 0;
}else{
sqlite4VdbeMemGrow(pMem, nByte, 0);
pMem->flags = MEM_Agg;
pMem->u.pDef = p->pFunc;
if( pMem->z ){
memset(pMem->z, 0, nByte);
}
}
}
return (void*)pMem->z;
}
/*
** Return the auxilary data pointer, if any, for the iArg'th argument to
** the user-function defined by pCtx.
*/
SQLITE_API void *sqlite4_get_auxdata(sqlite4_context *pCtx, int iArg){
VdbeFunc *pVdbeFunc;
assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
pVdbeFunc = pCtx->pVdbeFunc;
if( !pVdbeFunc || iArg>=pVdbeFunc->nAux || iArg<0 ){
return 0;
}
return pVdbeFunc->apAux[iArg].pAux;
}
/*
** Set the auxilary 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.
*/
SQLITE_API void sqlite4_set_auxdata(
sqlite4_context *pCtx,
int iArg,
void *pAux,
void (*xDelete)(void*)
){
struct AuxData *pAuxData;
VdbeFunc *pVdbeFunc;
if( iArg<0 ) goto failed;
assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
pVdbeFunc = pCtx->pVdbeFunc;
if( !pVdbeFunc || pVdbeFunc->nAux<=iArg ){
int nAux = (pVdbeFunc ? pVdbeFunc->nAux : 0);
int nMalloc = sizeof(VdbeFunc) + sizeof(struct AuxData)*iArg;
pVdbeFunc = sqlite4DbRealloc(pCtx->s.db, pVdbeFunc, nMalloc);
if( !pVdbeFunc ){
goto failed;
}
pCtx->pVdbeFunc = pVdbeFunc;
memset(&pVdbeFunc->apAux[nAux], 0, sizeof(struct AuxData)*(iArg+1-nAux));
pVdbeFunc->nAux = iArg+1;
pVdbeFunc->pFunc = pCtx->pFunc;
}
pAuxData = &pVdbeFunc->apAux[iArg];
if( pAuxData->pAux && pAuxData->xDelete ){
pAuxData->xDelete(pAuxData->pAux);
}
pAuxData->pAux = pAux;
pAuxData->xDelete = xDelete;
return;
failed:
if( xDelete ){
xDelete(pAux);
}
}
#ifndef SQLITE_OMIT_DEPRECATED
/*
** Return the number of times the Step function of a aggregate has been
** called.
**
** This function is deprecated. Do not use it for new code. It is
** provide only to avoid breaking legacy code. New aggregate function
** implementations should keep their own counts within their aggregate
** context.
*/
SQLITE_API int sqlite4_aggregate_count(sqlite4_context *p){
assert( p && p->pMem && p->pFunc && p->pFunc->xStep );
return p->pMem->n;
}
#endif
/*
** Return the number of columns in the result set for the statement pStmt.
*/
SQLITE_API int sqlite4_column_count(sqlite4_stmt *pStmt){
Vdbe *pVm = (Vdbe *)pStmt;
return pVm ? pVm->nResColumn : 0;
}
/*
** Return the number of values available from the current row of the
** currently executing statement pStmt.
*/
SQLITE_API int sqlite4_data_count(sqlite4_stmt *pStmt){
Vdbe *pVm = (Vdbe *)pStmt;
if( pVm==0 || pVm->pResultSet==0 ) return 0;
return pVm->nResColumn;
}
/*
** Check to see if column iCol of the given statement is valid. If
** it is, return a pointer to the Mem for the value of that column.
** If iCol is not valid, return a pointer to a Mem which has a value
** of NULL.
*/
static Mem *columnMem(sqlite4_stmt *pStmt, int i){
Vdbe *pVm;
Mem *pOut;
pVm = (Vdbe *)pStmt;
if( pVm && pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){
sqlite4_mutex_enter(pVm->db->mutex);
pOut = &pVm->pResultSet[i];
}else{
/* If the value passed as the second argument is out of range, return
** a pointer to the following static Mem object which contains the
** value SQL NULL. Even though the Mem structure contains an element
** of type i64, on certain architectures (x86) with certain compiler
** switches (-Os), gcc may align this Mem object on a 4-byte boundary
** instead of an 8-byte one. This all works fine, except that when
** running with SQLITE_DEBUG defined the SQLite code sometimes assert()s
** that a Mem structure is located on an 8-byte boundary. To prevent
** these assert()s from failing, when building with SQLITE_DEBUG defined
** using gcc, we force nullMem to be 8-byte aligned using the magical
** __attribute__((aligned(8))) macro. */
static const Mem nullMem
#if defined(SQLITE_DEBUG) && defined(__GNUC__)
__attribute__((aligned(8)))
#endif
= {0, "", (double)0, {0}, 0, MEM_Null, SQLITE_NULL, 0,
#ifdef SQLITE_DEBUG
0, 0, /* pScopyFrom, pFiller */
#endif
0, 0 };
if( pVm && ALWAYS(pVm->db) ){
sqlite4_mutex_enter(pVm->db->mutex);
sqlite4Error(pVm->db, SQLITE_RANGE, 0);
}
pOut = (Mem*)&nullMem;
}
return pOut;
}
/*
** This function is called after invoking an sqlite4_value_XXX function on a
** column value (i.e. a value returned by evaluating an SQL expression in the
** select list of a SELECT statement) that may cause a malloc() failure. If
** malloc() has failed, the threads mallocFailed flag is cleared and the result
** code of statement pStmt set to SQLITE_NOMEM.
**
** Specifically, this is called from within:
**
** sqlite4_column_int()
** sqlite4_column_int64()
** sqlite4_column_text()
** sqlite4_column_text16()
** sqlite4_column_real()
** sqlite4_column_bytes()
** sqlite4_column_bytes16()
** sqiite3_column_blob()
*/
static void columnMallocFailure(sqlite4_stmt *pStmt)
{
/* If malloc() failed during an encoding conversion within an
** sqlite4_column_XXX API, then set the return code of the statement to
** SQLITE_NOMEM. The next call to _step() (if any) will return SQLITE_ERROR
** and _finalize() will return NOMEM.
*/
Vdbe *p = (Vdbe *)pStmt;
if( p ){
p->rc = sqlite4ApiExit(p->db, p->rc);
sqlite4_mutex_leave(p->db->mutex);
}
}
/**************************** sqlite4_column_ *******************************
** The following routines are used to access elements of the current row
** in the result set.
*/
SQLITE_API const void *sqlite4_column_blob(sqlite4_stmt *pStmt, int i){
const void *val;
val = sqlite4_value_blob( columnMem(pStmt,i) );
/* Even though there is no encoding conversion, value_blob() might
** need to call malloc() to expand the result of a zeroblob()
** expression.
*/
columnMallocFailure(pStmt);
return val;
}
SQLITE_API int sqlite4_column_bytes(sqlite4_stmt *pStmt, int i){
int val = sqlite4_value_bytes( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
SQLITE_API int sqlite4_column_bytes16(sqlite4_stmt *pStmt, int i){
int val = sqlite4_value_bytes16( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
SQLITE_API double sqlite4_column_double(sqlite4_stmt *pStmt, int i){
double val = sqlite4_value_double( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
SQLITE_API int sqlite4_column_int(sqlite4_stmt *pStmt, int i){
int val = sqlite4_value_int( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
SQLITE_API sqlite_int64 sqlite4_column_int64(sqlite4_stmt *pStmt, int i){
sqlite_int64 val = sqlite4_value_int64( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
SQLITE_API const unsigned char *sqlite4_column_text(sqlite4_stmt *pStmt, int i){
const unsigned char *val = sqlite4_value_text( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
SQLITE_API sqlite4_value *sqlite4_column_value(sqlite4_stmt *pStmt, int i){
Mem *pOut = columnMem(pStmt, i);
if( pOut->flags&MEM_Static ){
pOut->flags &= ~MEM_Static;
pOut->flags |= MEM_Ephem;
}
columnMallocFailure(pStmt);
return (sqlite4_value *)pOut;
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API const void *sqlite4_column_text16(sqlite4_stmt *pStmt, int i){
const void *val = sqlite4_value_text16( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
#endif /* SQLITE_OMIT_UTF16 */
SQLITE_API int sqlite4_column_type(sqlite4_stmt *pStmt, int i){
int iType = sqlite4_value_type( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return iType;
}
/* The following function is experimental and subject to change or
** removal */
/*int sqlite4_column_numeric_type(sqlite4_stmt *pStmt, int i){
** return sqlite4_value_numeric_type( columnMem(pStmt,i) );
**}
*/
/*
** Convert the N-th element of pStmt->pColName[] into a string using
** xFunc() then return that string. If N is out of range, return 0.
**
** There are up to 5 names for each column. useType determines which
** name is returned. Here are the names:
**
** 0 The column name as it should be displayed for output
** 1 The datatype name for the column
** 2 The name of the database that the column derives from
** 3 The name of the table that the column derives from
** 4 The name of the table column that the result column derives from
**
** If the result is not a simple column reference (if it is an expression
** or a constant) then useTypes 2, 3, and 4 return NULL.
*/
static const void *columnName(
sqlite4_stmt *pStmt,
int N,
const void *(*xFunc)(Mem*),
int useType
){
const void *ret = 0;
Vdbe *p = (Vdbe *)pStmt;
int n;
sqlite4 *db = p->db;
assert( db!=0 );
n = sqlite4_column_count(pStmt);
if( N<n && N>=0 ){
N += useType*n;
sqlite4_mutex_enter(db->mutex);
assert( db->mallocFailed==0 );
ret = xFunc(&p->aColName[N]);
/* A malloc may have failed inside of the xFunc() call. If this
** is the case, clear the mallocFailed flag and return NULL.
*/
if( db->mallocFailed ){
db->mallocFailed = 0;
ret = 0;
}
sqlite4_mutex_leave(db->mutex);
}
return ret;
}
/*
** Return the name of the Nth column of the result set returned by SQL
** statement pStmt.
*/
SQLITE_API const char *sqlite4_column_name(sqlite4_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite4_value_text, COLNAME_NAME);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API const void *sqlite4_column_name16(sqlite4_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite4_value_text16, COLNAME_NAME);
}
#endif
/*
** Constraint: If you have ENABLE_COLUMN_METADATA then you must
** not define OMIT_DECLTYPE.
*/
#if defined(SQLITE_OMIT_DECLTYPE) && defined(SQLITE_ENABLE_COLUMN_METADATA)
# error "Must not define both SQLITE_OMIT_DECLTYPE \
and SQLITE_ENABLE_COLUMN_METADATA"
#endif
#ifndef SQLITE_OMIT_DECLTYPE
/*
** Return the column declaration type (if applicable) of the 'i'th column
** of the result set of SQL statement pStmt.
*/
SQLITE_API const char *sqlite4_column_decltype(sqlite4_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite4_value_text, COLNAME_DECLTYPE);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API const void *sqlite4_column_decltype16(sqlite4_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite4_value_text16, COLNAME_DECLTYPE);
}
#endif /* SQLITE_OMIT_UTF16 */
#endif /* SQLITE_OMIT_DECLTYPE */
#ifdef SQLITE_ENABLE_COLUMN_METADATA
/*
** Return the name of the database from which a result column derives.
** NULL is returned if the result column is an expression or constant or
** anything else which is not an unabiguous reference to a database column.
*/
SQLITE_API const char *sqlite4_column_database_name(sqlite4_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite4_value_text, COLNAME_DATABASE);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API const void *sqlite4_column_database_name16(sqlite4_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite4_value_text16, COLNAME_DATABASE);
}
#endif /* SQLITE_OMIT_UTF16 */
/*
** Return the name of the table from which a result column derives.
** NULL is returned if the result column is an expression or constant or
** anything else which is not an unabiguous reference to a database column.
*/
SQLITE_API const char *sqlite4_column_table_name(sqlite4_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite4_value_text, COLNAME_TABLE);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API const void *sqlite4_column_table_name16(sqlite4_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite4_value_text16, COLNAME_TABLE);
}
#endif /* SQLITE_OMIT_UTF16 */
/*
** Return the name of the table column from which a result column derives.
** NULL is returned if the result column is an expression or constant or
** anything else which is not an unabiguous reference to a database column.
*/
SQLITE_API const char *sqlite4_column_origin_name(sqlite4_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite4_value_text, COLNAME_COLUMN);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API const void *sqlite4_column_origin_name16(sqlite4_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite4_value_text16, COLNAME_COLUMN);
}
#endif /* SQLITE_OMIT_UTF16 */
#endif /* SQLITE_ENABLE_COLUMN_METADATA */
/******************************* sqlite4_bind_ ***************************
**
** Routines used to attach values to wildcards in a compiled SQL statement.
*/
/*
** Unbind the value bound to variable i in virtual machine p. This is the
** the same as binding a NULL value to the column. If the "i" parameter is
** out of range, then SQLITE_RANGE is returned. Othewise SQLITE_OK.
**
** A successful evaluation of this routine acquires the mutex on p.
** the mutex is released if any kind of error occurs.
**
** The error code stored in database p->db is overwritten with the return
** value in any case.
*/
static int vdbeUnbind(Vdbe *p, int i){
Mem *pVar;
if( vdbeSafetyNotNull(p) ){
return SQLITE_MISUSE_BKPT;
}
sqlite4_mutex_enter(p->db->mutex);
if( p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){
sqlite4Error(p->db, SQLITE_MISUSE, 0);
sqlite4_mutex_leave(p->db->mutex);
sqlite4_log(p->db->pEnv,SQLITE_MISUSE,
"bind on a busy prepared statement: [%s]", p->zSql);
return SQLITE_MISUSE_BKPT;
}
if( i<1 || i>p->nVar ){
sqlite4Error(p->db, SQLITE_RANGE, 0);
sqlite4_mutex_leave(p->db->mutex);
return SQLITE_RANGE;
}
i--;
pVar = &p->aVar[i];
sqlite4VdbeMemRelease(pVar);
pVar->flags = MEM_Null;
sqlite4Error(p->db, SQLITE_OK, 0);
/* If the bit corresponding to this variable in Vdbe.expmask is set, then
** binding a new value to this variable invalidates the current query plan.
**
** IMPLEMENTATION-OF: R-48440-37595 If the specific value bound to host
** parameter in the WHERE clause might influence the choice of query plan
** for a statement, then the statement will be automatically recompiled,
** as if there had been a schema change, on the first sqlite4_step() call
** following any change to the bindings of that parameter.
*/
if( ((i<32 && p->expmask & ((u32)1 << i)) || p->expmask==0xffffffff)
){
p->expired = 1;
}
return SQLITE_OK;
}
/*
** Bind a text or BLOB value.
*/
static int bindText(
sqlite4_stmt *pStmt, /* The statement to bind against */
int i, /* Index of the parameter to bind */
const void *zData, /* Pointer to the data to be bound */
int nData, /* Number of bytes of data to be bound */
void (*xDel)(void*), /* Destructor for the data */
u8 encoding /* Encoding for the data */
){
Vdbe *p = (Vdbe *)pStmt;
Mem *pVar;
int rc;
rc = vdbeUnbind(p, i);
if( rc==SQLITE_OK ){
if( zData!=0 ){
pVar = &p->aVar[i-1];
rc = sqlite4VdbeMemSetStr(pVar, zData, nData, encoding, xDel);
if( rc==SQLITE_OK && encoding!=0 ){
rc = sqlite4VdbeChangeEncoding(pVar, ENC(p->db));
}
sqlite4Error(p->db, rc, 0);
rc = sqlite4ApiExit(p->db, rc);
}
sqlite4_mutex_leave(p->db->mutex);
}else if( xDel!=SQLITE_STATIC && xDel!=SQLITE_TRANSIENT ){
xDel((void*)zData);
}
return rc;
}
/*
** Bind a blob value to an SQL statement variable.
*/
SQLITE_API int sqlite4_bind_blob(
sqlite4_stmt *pStmt,
int i,
const void *zData,
int nData,
void (*xDel)(void*)
){
return bindText(pStmt, i, zData, nData, xDel, 0);
}
SQLITE_API int sqlite4_bind_double(sqlite4_stmt *pStmt, int i, double rValue){
int rc;
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, i);
if( rc==SQLITE_OK ){
sqlite4VdbeMemSetDouble(&p->aVar[i-1], rValue);
sqlite4_mutex_leave(p->db->mutex);
}
return rc;
}
SQLITE_API int sqlite4_bind_int(sqlite4_stmt *p, int i, int iValue){
return sqlite4_bind_int64(p, i, (i64)iValue);
}
SQLITE_API int sqlite4_bind_int64(sqlite4_stmt *pStmt, int i, sqlite_int64 iValue){
int rc;
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, i);
if( rc==SQLITE_OK ){
sqlite4VdbeMemSetInt64(&p->aVar[i-1], iValue);
sqlite4_mutex_leave(p->db->mutex);
}
return rc;
}
SQLITE_API int sqlite4_bind_null(sqlite4_stmt *pStmt, int i){
int rc;
Vdbe *p = (Vdbe*)pStmt;
rc = vdbeUnbind(p, i);
if( rc==SQLITE_OK ){
sqlite4_mutex_leave(p->db->mutex);
}
return rc;
}
SQLITE_API int sqlite4_bind_text(
sqlite4_stmt *pStmt,
int i,
const char *zData,
int nData,
void (*xDel)(void*)
){
return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API int sqlite4_bind_text16(
sqlite4_stmt *pStmt,
int i,
const void *zData,
int nData,
void (*xDel)(void*)
){
return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE);
}
#endif /* SQLITE_OMIT_UTF16 */
SQLITE_API int sqlite4_bind_value(sqlite4_stmt *pStmt, int i, const sqlite4_value *pValue){
int rc;
switch( pValue->type ){
case SQLITE_INTEGER: {
rc = sqlite4_bind_int64(pStmt, i, pValue->u.i);
break;
}
case SQLITE_FLOAT: {
rc = sqlite4_bind_double(pStmt, i, pValue->r);
break;
}
case SQLITE_BLOB: {
if( pValue->flags & MEM_Zero ){
rc = sqlite4_bind_zeroblob(pStmt, i, pValue->u.nZero);
}else{
rc = sqlite4_bind_blob(pStmt, i, pValue->z, pValue->n,SQLITE_TRANSIENT);
}
break;
}
case SQLITE_TEXT: {
rc = bindText(pStmt,i, pValue->z, pValue->n, SQLITE_TRANSIENT,
pValue->enc);
break;
}
default: {
rc = sqlite4_bind_null(pStmt, i);
break;
}
}
return rc;
}
SQLITE_API int sqlite4_bind_zeroblob(sqlite4_stmt *pStmt, int i, int n){
int rc;
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, i);
if( rc==SQLITE_OK ){
sqlite4VdbeMemSetZeroBlob(&p->aVar[i-1], n);
sqlite4_mutex_leave(p->db->mutex);
}
return rc;
}
/*
** Return the number of wildcards that can be potentially bound to.
** This routine is added to support DBD::SQLite.
*/
SQLITE_API int sqlite4_bind_parameter_count(sqlite4_stmt *pStmt){
Vdbe *p = (Vdbe*)pStmt;
return p ? p->nVar : 0;
}
/*
** Return the name of a wildcard parameter. Return NULL if the index
** is out of range or if the wildcard is unnamed.
**
** The result is always UTF-8.
*/
SQLITE_API const char *sqlite4_bind_parameter_name(sqlite4_stmt *pStmt, int i){
Vdbe *p = (Vdbe*)pStmt;
if( p==0 || i<1 || i>p->nzVar ){
return 0;
}
return p->azVar[i-1];
}
/*
** Given a wildcard parameter name, return the index of the variable
** with that name. If there is no variable with the given name,
** return 0.
*/
SQLITE_PRIVATE int sqlite4VdbeParameterIndex(Vdbe *p, const char *zName, int nName){
int i;
if( p==0 ){
return 0;
}
if( zName ){
for(i=0; i<p->nzVar; i++){
const char *z = p->azVar[i];
if( z && memcmp(z,zName,nName)==0 && z[nName]==0 ){
return i+1;
}
}
}
return 0;
}
SQLITE_API int sqlite4_bind_parameter_index(sqlite4_stmt *pStmt, const char *zName){
return sqlite4VdbeParameterIndex((Vdbe*)pStmt, zName, sqlite4Strlen30(zName));
}
/*
** Transfer all bindings from the first statement over to the second.
*/
SQLITE_PRIVATE int sqlite4TransferBindings(sqlite4_stmt *pFromStmt, sqlite4_stmt *pToStmt){
Vdbe *pFrom = (Vdbe*)pFromStmt;
Vdbe *pTo = (Vdbe*)pToStmt;
int i;
assert( pTo->db==pFrom->db );
assert( pTo->nVar==pFrom->nVar );
sqlite4_mutex_enter(pTo->db->mutex);
for(i=0; i<pFrom->nVar; i++){
sqlite4VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]);
}
sqlite4_mutex_leave(pTo->db->mutex);
return SQLITE_OK;
}
#ifndef SQLITE_OMIT_DEPRECATED
/*
** Deprecated external interface. Internal/core SQLite code
** should call sqlite4TransferBindings.
**
** Is is misuse to call this routine with statements from different
** database connections. But as this is a deprecated interface, we
** will not bother to check for that condition.
**
** If the two statements contain a different number of bindings, then
** an SQLITE_ERROR is returned. Nothing else can go wrong, so otherwise
** SQLITE_OK is returned.
*/
SQLITE_API int sqlite4_transfer_bindings(sqlite4_stmt *pFromStmt, sqlite4_stmt *pToStmt){
Vdbe *pFrom = (Vdbe*)pFromStmt;
Vdbe *pTo = (Vdbe*)pToStmt;
if( pFrom->nVar!=pTo->nVar ){
return SQLITE_ERROR;
}
if( pTo->expmask ){
pTo->expired = 1;
}
if( pFrom->expmask ){
pFrom->expired = 1;
}
return sqlite4TransferBindings(pFromStmt, pToStmt);
}
#endif
/*
** Return the sqlite4* database handle to which the prepared statement given
** in the argument belongs. This is the same database handle that was
** the first argument to the sqlite4_prepare() that was used to create
** the statement in the first place.
*/
SQLITE_API sqlite4 *sqlite4_db_handle(sqlite4_stmt *pStmt){
return pStmt ? ((Vdbe*)pStmt)->db : 0;
}
/*
** Return true if the prepared statement is guaranteed to not modify the
** database.
*/
SQLITE_API int sqlite4_stmt_readonly(sqlite4_stmt *pStmt){
return pStmt ? ((Vdbe*)pStmt)->readOnly : 1;
}
/*
** Return true if the prepared statement is in need of being reset.
*/
SQLITE_API int sqlite4_stmt_busy(sqlite4_stmt *pStmt){
Vdbe *v = (Vdbe*)pStmt;
return v!=0 && v->pc>0 && v->magic==VDBE_MAGIC_RUN;
}
/*
** Return a pointer to the next prepared statement after pStmt associated
** with database connection pDb. If pStmt is NULL, return the first
** prepared statement for the database connection. Return NULL if there
** are no more.
*/
SQLITE_API sqlite4_stmt *sqlite4_next_stmt(sqlite4 *pDb, sqlite4_stmt *pStmt){
sqlite4_stmt *pNext;
sqlite4_mutex_enter(pDb->mutex);
if( pStmt==0 ){
pNext = (sqlite4_stmt*)pDb->pVdbe;
}else{
pNext = (sqlite4_stmt*)((Vdbe*)pStmt)->pNext;
}
sqlite4_mutex_leave(pDb->mutex);
return pNext;
}
/*
** Return the value of a status counter for a prepared statement
*/
SQLITE_API int sqlite4_stmt_status(sqlite4_stmt *pStmt, int op, int resetFlag){
Vdbe *pVdbe = (Vdbe*)pStmt;
int v = pVdbe->aCounter[op-1];
if( resetFlag ) pVdbe->aCounter[op-1] = 0;
return v;
}
/************** End of vdbeapi.c *********************************************/
/************** Begin file vdbecodec.c ***************************************/
/*
** 2012 January 24
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code for encoding and decoding values and keys for
** insertion and reading from the key/value storage engine.
*/
/*
** The decoder object.
*/
struct ValueDecoder {
sqlite4 *db; /* The database connection */
const u8 *a; /* Content to be decoded */
int n; /* Bytes of content in a[] */
int mxCol; /* Maximum number of columns */
};
/*
** Create an object that can be used to decode fields of the data encoding.
**
** The aIn[] value must remain stable for the life of the decoder.
*/
SQLITE_PRIVATE int sqlite4VdbeCreateDecoder(
sqlite4 *db, /* The database connection */
const unsigned char *aIn, /* The input data blob */
int nIn, /* Number of bytes in aIn[] */
int mxCol, /* Maximum number of columns in aIn[] */
ValueDecoder **ppOut /* The newly generated decoder object */
){
ValueDecoder *p;
p = sqlite4DbMallocZero(db, sizeof(*p));
*ppOut = p;
if( p==0 ) return SQLITE_NOMEM;
p->db = db;
p->a = aIn;
p->n = nIn;
p->mxCol = mxCol;
return SQLITE_OK;
}
/*
** Destroy a decoder object previously created
** using sqlite4VdbeCreateDecoder().
*/
SQLITE_PRIVATE int sqlite4VdbeDestroyDecoder(ValueDecoder *p){
if( p ){
sqlite4DbFree(p->db, p);
}
return SQLITE_OK;
}
/*
** Decode a single value from a data string.
*/
SQLITE_PRIVATE int sqlite4VdbeDecodeValue(
ValueDecoder *p, /* The decoder for the whole string */
int iVal, /* Index of the value to decode. First is 0 */
Mem *pDefault, /* The default value. Often NULL */
Mem *pOut /* Write the result here */
){
u32 size; /* Size of a field */
sqlite4_uint64 ofst; /* Offset to the payload */
sqlite4_uint64 type; /* Datatype */
sqlite4_uint64 subtype; /* Subtype for a typed blob */
int cclass; /* class of content */
int n; /* Offset into the header */
int i; /* Loop counter */
int sz; /* Size of a varint */
int endHdr; /* First byte past header */
sqlite4VdbeMemSetNull(pOut);
assert( iVal<=p->mxCol );
n = sqlite4GetVarint64(p->a, p->n, &ofst);
if( n==0 ) return SQLITE_CORRUPT;
ofst += n;
endHdr = ofst;
if( endHdr>p->n ) return SQLITE_CORRUPT;
for(i=0; i<=iVal && n<endHdr; i++){
sz = sqlite4GetVarint64(p->a+n, p->n-n, &type);
if( sz==0 ) return SQLITE_CORRUPT;
n += sz;
if( type>=22 ){
cclass = (type-22)%3;
if( cclass==2 ){
sz = sqlite4GetVarint64(p->a+n, p->n-n, &subtype);
if( sz==0 ) return SQLITE_CORRUPT;
n += sz;
}
size = (type-22)/3;
}else if( type<=2 ){
size = 0;
}else if( type<=10 ){
size = type - 2;
}else{
size = type - 9;
}
if( i<iVal ){
ofst += size;
}else if( type==0 ){
/* no-op */
}else if( type<=2 ){
sqlite4VdbeMemSetInt64(pOut, type-1);
}else if( type<=10 ){
int iByte;
sqlite4_int64 v = ((char*)p->a)[ofst];
for(iByte=1; iByte<size; iByte++){
v = v*256 + p->a[ofst+iByte];
}
sqlite4VdbeMemSetInt64(pOut, v);
}else if( type<=21 ){
sqlite4_uint64 x;
int e;
double r;
n = sqlite4GetVarint64(p->a+ofst, p->n-ofst, &x);
e = (int)x;
n += sqlite4GetVarint64(p->a+ofst+n, p->n-(ofst+n), &x);
if( n!=size ) return SQLITE_CORRUPT;
r = (double)x;
if( e&1 ) r = -r;
if( e&2 ){
e = -(e>>2);
while( e<=-10 ){ r /= 1.0e10; e += 10; }
while( e<0 ){ r /= 10.0; e++; }
}else{
e = e>>2;
while( e>=10 ){ r *= 1.0e10; e -= 10; }
while( e>0 ){ r *= 10.0; e--; }
}
sqlite4VdbeMemSetDouble(pOut, r);
}else if( cclass==0 ){
if( size==0 ){
sqlite4VdbeMemSetStr(pOut, "", 0, SQLITE_UTF8, SQLITE_TRANSIENT);
}else if( p->a[ofst]>0x02 ){
sqlite4VdbeMemSetStr(pOut, (char*)(p->a+ofst), size,
SQLITE_UTF8, SQLITE_TRANSIENT);
}else{
static const u8 enc[] = { SQLITE_UTF8, SQLITE_UTF16LE, SQLITE_UTF16BE };
sqlite4VdbeMemSetStr(pOut, (char*)(p->a+ofst+1), size-1,
enc[p->a[ofst]], SQLITE_TRANSIENT);
}
}else{
sqlite4VdbeMemSetStr(pOut, (char*)(p->a+ofst), size, 0, SQLITE_TRANSIENT);
}
}
if( i<iVal ){
if( pDefault ){
sqlite4VdbeMemShallowCopy(pOut, pDefault, MEM_Static);
}else{
sqlite4VdbeMemSetNull(pOut);
}
}
return SQLITE_OK;
}
/*
** Return the number of bytes needed to represent a 64-bit signed integer.
*/
static int significantBytes(sqlite4_int64 v){
sqlite4_int64 x;
int n = 1;
if( v<0 ){
x = -128;
while( v<x && n<8 ){ n++; x *= 256; }
}else{
x = 127;
while( v>x && n<8 ){ n++; x *= 256; }
}
return n;
}
/*
** Encode 1 or more values using the data encoding.
**
** Assume that affinity has already been applied to all elements of the
** input array aIn[].
**
** Space to hold the record is obtained from sqlite4DbMalloc() and should
** be freed by the caller using sqlite4DbFree() to avoid a memory leak.
*/
SQLITE_PRIVATE int sqlite4VdbeEncodeData(
sqlite4 *db, /* The database connection */
Mem *aIn, /* Array of values to encode */
int nIn, /* Number of entries in aIn[] */
u8 **pzOut, /* The output data record */
int *pnOut /* Bytes of content in pzOut */
){
int i, j;
int rc = SQLITE_OK;
int nHdr;
int n;
u8 *aOut = 0; /* The result */
int nOut; /* Bytes of aOut used */
int nPayload = 0; /* Payload space required */
int encoding = ENC(db); /* Text encoding */
struct dencAux { /* For each input value of aIn[] */
int n; /* Size of encoding at this position */
u8 z[12]; /* Encoding for number at this position */
} *aAux;
aAux = sqlite4StackAllocZero(db, sizeof(*aAux)*nIn);
if( aAux==0 ) return SQLITE_NOMEM;
aOut = sqlite4DbMallocZero(db, (nIn+1)*9);
if( aOut==0 ){
rc = SQLITE_NOMEM;
goto vdbeEncodeData_error;
}
nOut = 9;
for(i=0; i<nIn; i++){
int flags = aIn[i].flags;
if( flags & MEM_Null ){
aOut[nOut++] = 0;
}else if( flags & MEM_Int ){
n = significantBytes(aIn[i].u.i);
aOut[nOut++] = n+2;
nPayload += n;
aAux[i].n = n;
}else if( flags & MEM_Real ){
int e = 0;
u8 sign = 0;
double r = aIn[i].r;
sqlite4_uint64 m;
if( sqlite4IsNaN(r) ){
m = 0;
e = 2;
}else if( sqlite4IsInf(r)!=0 ){
m = 1;
e = 2 + (sqlite4IsInf(r)<0);
}else{
if( r<0 ){ r = -r; sign = 1; }
while( r<1.0e+19 && r!=(sqlite4_uint64)r ){
e--;
r *= 10.0;
}
while( r>1.8e+19 ){
e++;
r /= 10.0;
}
m = r;
if( e<0 ){
e = (-e*4) + 2 + sign;
}else{
e = e*4 + sign;
}
}
n = sqlite4PutVarint64(aAux[i].z, (sqlite4_uint64)e);
n += sqlite4PutVarint64(aAux[i].z+n, m);
aAux[i].n = n;
aOut[nOut++] = n+9;
nPayload += n;
}else if( flags & MEM_Str ){
n = aIn[i].n;
if( n && (encoding!=SQLITE_UTF8 || aIn[i].z[0]<2) ) n++;
nPayload += n;
nOut += sqlite4PutVarint64(aOut+nOut, 22+3*(sqlite4_int64)n);
}else{
n = aIn[i].n;
assert( flags & MEM_Blob );
nPayload += n;
nOut += sqlite4PutVarint64(aOut+nOut, 23+3*(sqlite4_int64)n);
}
}
nHdr = nOut - 9;
n = sqlite4PutVarint64(aOut, nHdr);
for(i=n, j=9; j<nOut; j++) aOut[i++] = aOut[j];
nOut = i;
aOut = sqlite4DbReallocOrFree(db, aOut, nOut + nPayload);
if( aOut==0 ){ rc = SQLITE_NOMEM; goto vdbeEncodeData_error; }
for(i=0; i<nIn; i++){
int flags = aIn[i].flags;
if( flags & MEM_Null ){
/* No content */
}else if( flags & MEM_Int ){
sqlite4_int64 v = aIn[i].u.i;
n = aAux[i].n;
aOut[nOut+(--n)] = v & 0xff;
while( n ){
v >>= 8;
aOut[nOut+(--n)] = v & 0xff;
}
nOut += aAux[i].n;
}else if( flags & MEM_Real ){
memcpy(aOut+nOut, aAux[i].z, aAux[i].n);
nOut += aAux[i].n;
}else if( flags & MEM_Str ){
n = aIn[i].n;
if( n ){
if( encoding==SQLITE_UTF16LE ) aOut[nOut++] = 1;
else if( encoding==SQLITE_UTF16BE ) aOut[nOut++] = 2;
else if( aIn[i].z[0]<2 ) aOut[nOut++] = 0;
memcpy(aOut+nOut, aIn[i].z, n);
nOut += n;
}
}else{
assert( flags & MEM_Blob );
memcpy(aOut+nOut, aIn[i].z, aIn[i].n);
nOut += aIn[i].n;
}
}
*pzOut = aOut;
*pnOut = nOut;
sqlite4StackFree(db, aAux);
return SQLITE_OK;
vdbeEncodeData_error:
sqlite4StackFree(db, aAux);
sqlite4DbFree(db, aOut);
return rc;
}
/*
** An output buffer for EncodeKey
*/
typedef struct KeyEncoder KeyEncoder;
struct KeyEncoder {
sqlite4 *db; /* Database connection */
u8 *aOut; /* Output buffer */
int nOut; /* Slots of aOut[] used */
int nAlloc; /* Slots of aOut[] allocated */
};
/*
** Enlarge a memory allocation, if necessary
*/
static int enlargeEncoderAllocation(KeyEncoder *p, int needed){
if( p->nOut+needed>p->nAlloc ){
u8 *aNew;
p->nAlloc = p->nAlloc + needed + 10;
aNew = sqlite4DbRealloc(p->db, p->aOut, p->nAlloc);
if( aNew==0 ){
sqlite4DbFree(p->db, p->aOut);
memset(p, 0, sizeof(*p));
return SQLITE_NOMEM;
}
p->aOut = aNew;
p->nAlloc = sqlite4DbMallocSize(p->db, p->aOut);
}
return SQLITE_OK;
}
/*
** Encode the positive integer m using the key encoding.
**
** To encode an integer, the integer value is represented as centimal
** (base-100) with E digits. Each centimal digit is stored in one byte
** with the most significant digits coming first. For each centimal
** digit X (with X>=0 and X<=99) the byte value will be 2*X+1 except
** for the last digit for which the value is 2*X. Trailing 0 digits are
** omitted, so that the encoding of the mantissa will never contain
** a zero byte.
**
** The key encoding consists of the E value (the number of
** centimal digits in the original number, before trailing zero digits
** are removed), followed by the mantissa encoding M. This routine
** only writes the mantissa. The E values will be embedded in the
** initial byte of the encoding by the calling function. This
** routine returns the value of E. E will always be at least 1 and
** no more than 10.
**
** Note that values encoded by this routine have exactly the same
** byte representation as the equivalent floating-point values encoded
** by the encodeLargeFloatKey() routine below.
*/
static int encodeIntKey(sqlite4_uint64 m, KeyEncoder *p){
int i = 0;
int e;
unsigned char aDigits[20];
assert( m>0 );
do{
aDigits[i++] = m%100; m /= 100;
}while( m );
e = i;
while( i ) p->aOut[p->nOut++] = aDigits[--i]*2 + 1;
p->aOut[p->nOut-1] &= 0xfe;
return e;
}
/*
** Encode a single integer using the key encoding. The caller must
** ensure that sufficient space exits in a[] (at least 12 bytes).
** The return value is the number of bytes of a[] used.
*/
SQLITE_PRIVATE int sqlite4VdbeEncodeIntKey(u8 *a, sqlite4_int64 v){
int i, e;
KeyEncoder s;
s.aOut = a;
s.nOut = 1;
if( v<0 ){
e = encodeIntKey((sqlite4_uint64)-v, &s);
assert( e<=10 );
a[0] = 0x13-e;
for(i=1; i<s.nOut; i++) a[i] ^= 0xff;
}else if( v>0 ){
e = encodeIntKey((sqlite4_uint64)v, &s);
assert( e<=10 );
a[0] = 0x17+e;
}else{
a[0] = 0x15;
}
return s.nOut;
}
/*
** Encode the small positive floating point number r using the key
** encoding. The caller guarantees that r will be less than 1.0 and
** greater than 0.0.
**
** A floating point value is encoded as an integer exponent E and a
** mantissa M. The original value is equal to (M * 100^E). E is set
** to the smallest value possible without making M greater than or equal
** to 1.0.
**
** For this routine, E will always be zero or negative, since the original
** value is less than one. The encoding written by this routine is the
** ones-complement of the varint of the negative of E followed by the
** mantissa:
**
** Encoding: ~-E M
*/
static void encodeSmallFloatKey(double r, KeyEncoder *p){
int e = 0;
int i, n;
assert( r>0.0 && r<1.0 );
while( r<1e-10 ){ r *= 1e8; e+=4; }
while( r<0.01 ){ r *= 100.0; e++; }
n = sqlite4PutVarint64(p->aOut+p->nOut, e);
for(i=0; i<n; i++) p->aOut[i+p->nOut] ^= 0xff;
p->nOut += n;
for(i=0; i<18 && r!=0.0; i++){
r *= 100.0;
int d = r;
p->aOut[p->nOut++] = 2*d + 1;
r -= d;
}
p->aOut[p->nOut-1] &= 0xfe;
}
/*
** Encode the large positive floating point number r using the key
** encoding. The caller guarantees that r will be finite and greater than
** or equal to 1.0.
**
** A floating point value is encoded as an integer exponent E and a
** mantissa M. The original value is equal to (M * 100^E). E is set to
** the smallest value possible without making M greater than or equal
** to 1.0.
**
** Each centimal digit of the mantissa is stored in a byte. If the value
** of the centimal digit is X (hence X>=0 and X<=99) then the byte value
** will be 2*X+1 for every byte of the mantissa, except for the last byte
** which will be 2*X+0. The mantissa must be the minimum number of bytes
** necessary to represent the value; trailing X==0 digits are omitted.
** This means that the mantissa will never contain a byte with the
** value 0x00.
**
** If E is greater than 10, then this routine writes of E as a varint
** followed by the mantissa as described above. Otherwise, if E is 10 or
** less, this routine only writes the mantissa and leaves the E value
** to be encoded as part of the opening byte of the field by the
** calling function.
**
** Encoding: M (if E<=10)
** E M (if E>10)
**
** This routine returns the value of E.
*/
static int encodeLargeFloatKey(double r, KeyEncoder *p){
int e = 0;
int i, n;
assert( r>=1.0 );
while( r>=1e32 && e<=350 ){ r *= 1e-32; e+=16; }
while( r>=1e8 && e<=350 ){ r *= 1e-8; e+=4; }
while( r>=1.0 && e<=350 ){ r *= 0.01; e++; }
if( e>10 ){
n = sqlite4PutVarint64(p->aOut+p->nOut, e);
p->nOut += n;
}
for(i=0; i<18 && r!=0.0; i++){
r *= 100.0;
int d = r;
p->aOut[p->nOut++] = 2*d + 1;
r -= d;
}
p->aOut[p->nOut-1] &= 0xfe;
return e;
}
/*
** Encode a single column of the key
*/
static int encodeOneKeyValue(
KeyEncoder *p,
Mem *pMem,
u8 sortOrder,
CollSeq *pColl
){
int flags = pMem->flags;
int i, e;
int n;
int iStart = p->nOut;
if( flags & MEM_Null ){
if( enlargeEncoderAllocation(p, 1) ) return SQLITE_NOMEM;
p->aOut[p->nOut++] = 0x05; /* NULL */
}else
if( flags & MEM_Int ){
sqlite4_int64 v = pMem->u.i;
if( enlargeEncoderAllocation(p, 11) ) return SQLITE_NOMEM;
if( v==0 ){
p->aOut[p->nOut++] = 0x15; /* Numeric zero */
}else if( v<0 ){
p->aOut[p->nOut++] = 0x08; /* Large negative number */
i = p->nOut;
e = encodeIntKey((sqlite4_uint64)-v, p);
if( e<=10 ) p->aOut[i-1] = 0x13-e;
while( i<p->nOut ) p->aOut[i++] ^= 0xff;
}else{
i = p->nOut;
p->aOut[p->nOut++] = 0x22; /* Large positive number */
e = encodeIntKey((sqlite4_uint64)v, p);
if( e<=10 ) p->aOut[i] = 0x17+e;
}
}else
if( flags & MEM_Real ){
double r = pMem->r;
if( enlargeEncoderAllocation(p, 16) ) return SQLITE_NOMEM;
if( r==0.0 ){
p->aOut[p->nOut++] = 0x15; /* Numeric zero */
}else if( sqlite4IsNaN(r) ){
p->aOut[p->nOut++] = 0x06; /* NaN */
}else if( (n = sqlite4IsInf(r))!=0 ){
p->aOut[p->nOut++] = n<0 ? 0x07 : 0x23; /* Neg and Pos infinity */
}else if( r<=-1.0 ){
p->aOut[p->nOut++] = 0x08; /* Large negative values */
i = p->nOut;
e = encodeLargeFloatKey(-r, p);
if( e<=10 ) p->aOut[i-1] = 0x13-e;
while( i<p->nOut ) p->aOut[i++] ^= 0xff;
}else if( r<0.0 ){
p->aOut[p->nOut++] = 0x14; /* Small negative values */
i = p->nOut;
encodeSmallFloatKey(-r, p);
while( i<p->nOut ) p->aOut[i++] ^= 0xff;
}else if( r<1.0 ){
p->aOut[p->nOut++] = 0x16; /* Small positive values */
encodeSmallFloatKey(r, p);
}else{
i = p->nOut;
p->aOut[p->nOut++] = 0x22; /* Large positive values */
e = encodeLargeFloatKey(r, p);
if( e<=10 ) p->aOut[i] = 0x17+e;
}
}else
if( flags & MEM_Str ){
Mem *pEnc; /* Pointer to memory cell in correct enc. */
Mem sMem; /* Value converted to different encoding */
int enc; /* Required encoding */
/* Figure out the current encoding of pMem, and the encoding required
** (either the encoding specified by the collation sequence, or utf-8
** if there is no collation sequence). */
enc = ((pColl && pColl->xMkKey) ? pColl->enc : SQLITE_UTF8);
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
assert( pMem->enc==SQLITE_UTF8 || pMem->enc==SQLITE_UTF16LE
|| pMem->enc==SQLITE_UTF16BE
);
/* If necessary, convert the encoding of the input text. */
if( pMem->enc!=enc ){
memset(&sMem, 0, sizeof(sMem));
sqlite4VdbeMemShallowCopy(&sMem, pMem, MEM_Static);
sqlite4VdbeMemTranslate(&sMem, enc);
pEnc = &sMem;
}else{
pEnc = pMem;
}
/* Write the encoded key to the output buffer. */
if( enlargeEncoderAllocation(p, pMem->n*4 + 2) ) return SQLITE_NOMEM;
p->aOut[p->nOut++] = 0x24; /* Text */
if( pColl==0 || pColl->xMkKey==0 ){
memcpy(p->aOut+p->nOut, pEnc->z, pEnc->n);
p->nOut += pEnc->n;
}else{
int nSpc = p->nAlloc-p->nOut;
n = pColl->xMkKey(pColl->pUser, pEnc->n, pEnc->z, nSpc, p->aOut+p->nOut);
if( n>nSpc ){
if( enlargeEncoderAllocation(p, n) ) return SQLITE_NOMEM;
n + pColl->xMkKey(pColl->pUser, pEnc->n, pEnc->z, n, p->aOut+p->nOut);
}
p->nOut += n;
}
p->aOut[p->nOut++] = 0x00;
/* Release any memory allocated to hold the translated text */
if( pEnc==&sMem ) sqlite4VdbeMemRelease(&sMem);
}else
{
const unsigned char *a;
unsigned char s, t;
assert( flags & MEM_Blob );
n = pMem->n;
a = (u8*)pMem->z;
s = 1;
t = 0;
if( enlargeEncoderAllocation(p, (n*8+6)/7 + 2) ) return SQLITE_NOMEM;
p->aOut[p->nOut++] = 0x25; /* Blob */
for(i=0; i<n; i++){
unsigned char x = a[i];
p->aOut[p->nOut++] = 0x80 | t | (x>>s);
if( s<7 ){
t = x<<(7-s);
s++;
}else{
p->aOut[p->nOut++] = 0x80 | x;
s = 1;
t = 0;
}
}
if( s>1 ) p->aOut[p->nOut++] = 0x80 | t;
p->aOut[p->nOut++] = 0x00;
}
if( sortOrder==SQLITE_SO_DESC ){
for(i=iStart; i<p->nOut; i++) p->aOut[i] ^= 0xff;
}
return SQLITE_OK;
}
/*
** Variables aKey/nKey contain an encoded index key. This function returns
** the length (in bytes) of the key with all but the first nField fields
** removed.
*/
SQLITE_PRIVATE int sqlite4VdbeShortKey(
const u8 *aKey, /* Buffer containing encoded key */
int nKey, /* Size of buffer aKey[] in bytes */
int nField /* Number of fields */
){
u8 *p = aKey;
u8 *pEnd = &aKey[nKey];
u64 dummy;
int i;
p = aKey;
p += sqlite4GetVarint64(p, pEnd-p, &dummy);
for(i=0; i<nField; i++){
u8 c = *(p++);
switch( c ){
case 0x05: case 0xFA: /* NULL */
case 0x06: case 0xF9: /* NaN */
case 0x07: case 0xF8: /* -ve infinity */
case 0x15: case 0xEA: /* zero */
case 0x23: case 0xDC: /* +ve infinity */
break;
case 0x24: /* Text (ascending index) */
case 0x25: /* Blob (ascending index) */
while( *(p++) );
break;
case 0xDB: /* Text (descending index) */
case 0xDA: /* Blob (descending index) */
while( (0xFF!=*(p++)) );
break;
case 0x22: case 0xDD: /* Large positive number */
case 0x14: case 0xEB: /* Small negative number */
case 0x16: case 0xE9: /* Small positive number */
case 0x08: case 0xF7: { /* Large negative number */
u8 d; /* Value of byte following "c" */
/* For large positive and small negative integer keys skip over
** a varint here. For small positive integers and larger negative
** integers, skip over the ones-complement varint. */
if( c==0x16 || c==0x08 || c==0xDD || c==0xEB ){
d = ~(*(p++));
}else{
d = *(p++);
}
if( d>240 ){
p++;
if( d>248 ) p += (d - 248);
}
/* Fall through */
}
default: /* Medium sized number */
if( c<0x15 || (c>0xDC && c<0xEA) ){
while( !((*p++) & 0x01) );
}else{
while( ((*p++) & 0x01) );
}
break;
}
}
return (p - aKey);
}
/*
** Generate a database key from one or more data values.
**
** Space to hold the key is obtained from sqlite4DbMalloc() and should
** be freed by the caller using sqlite4DbFree() to avoid a memory leak.
*/
SQLITE_PRIVATE int sqlite4VdbeEncodeKey(
sqlite4 *db, /* The database connection */
Mem *aIn, /* Values to be encoded */
int nIn, /* Number of entries in aIn[] */
int iTabno, /* The table this key applies to */
KeyInfo *pKeyInfo, /* Collating sequence and sort-order info */
u8 **paOut, /* Write the resulting key here */
int *pnOut, /* Number of bytes in the key */
int nExtra /* See above */
){
int i;
int rc = SQLITE_OK;
KeyEncoder x;
u8 *so;
CollSeq **aColl;
CollSeq *xColl;
static const CollSeq defaultColl;
assert( pKeyInfo );
assert( nIn<=pKeyInfo->nField );
x.db = db;
x.aOut = 0;
x.nOut = 0;
x.nAlloc = 0;
*paOut = 0;
*pnOut = 0;
if( enlargeEncoderAllocation(&x, (nIn+1)*10) ) return SQLITE_NOMEM;
x.nOut = sqlite4PutVarint64(x.aOut, iTabno);
aColl = pKeyInfo->aColl;
so = pKeyInfo->aSortOrder;
for(i=0; i<nIn && rc==SQLITE_OK; i++){
rc = encodeOneKeyValue(&x, aIn+i, so ? so[i] : SQLITE_SO_ASC, aColl[i]);
}
if( rc==SQLITE_OK && nExtra ){ rc = enlargeEncoderAllocation(&x, nExtra); }
if( rc ){
sqlite4DbFree(db, x.aOut);
}else{
*paOut = x.aOut;
*pnOut = x.nOut;
}
return rc;
}
/*
** Decode an integer key encoding. Return the number of bytes in the
** encoding on success. On an error, return 0.
*/
SQLITE_PRIVATE int sqlite4VdbeDecodeIntKey(
const KVByteArray *aKey, /* Input encoding */
KVSize nKey, /* Number of bytes in aKey[] */
sqlite4_int64 *pVal /* Write the result here */
){
int isNeg;
int e, x;
int i, n;
sqlite4_int64 m;
KVByteArray aBuf[12];
if( nKey<2 ) return 0;
if( nKey>sizeof(aBuf) ) nKey = sizeof(aBuf);
x = aKey[0];
if( x>=0x09 && x<=0x13 ){
isNeg = 1;
memcpy(aBuf, aKey, nKey);
aKey = aBuf;
for(i=1; i<nKey; i++) aBuf[i] ^= 0xff;
e = 0x13-x;
}else if( x>=0x17 && x<=0x21 ){
isNeg = 0;
e = x-0x17;
}else if( x==0x15 ){
*pVal = 0;
return 1;
}else{
return 0;
}
m = 0;
i = 1;
do{
m = m*100 + aKey[i]/2;
e--;
}while( aKey[i++] & 1 );
if( isNeg ){
*pVal = -m;
}else{
*pVal = m;
}
return m==0 ? 0 : i;
}
/************** End of vdbecodec.c *******************************************/
/************** Begin file vdbecursor.c **************************************/
/*
** 2012 February 16
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains methods for the VdbeCursor object.
**
** A VdbeCursor is an abstraction of the KVCursor that includes knowledge
** about different "tables" in the key space. A VdbeCursor is only active
** over a particular table. Thus, for example, sqlite4VdbeNext() will
** return SQLITE_NOTFOUND when advancing off the end of a table into the
** next table whereas the lower-level sqlite4KVCursorNext() routine will
** not return SQLITE_NOTFOUND until it is advanced off the end of the very
** last table in the database.
*/
/*
** Move a VDBE cursor to the first or to the last element of its table. The
** first element is sought if iEnd==+1 and the last element if iEnd==-1.
**
** Return SQLITE_OK on success. Return SQLITE_NOTFOUND if the table is empty.
* Other error codes are also possible for various kinds of errors.
*/
SQLITE_PRIVATE int sqlite4VdbeSeekEnd(VdbeCursor *pC, int iEnd){
KVCursor *pCur = pC->pKVCur;
const KVByteArray *aKey;
KVSize nKey;
KVSize nProbe;
int rc;
KVByteArray aProbe[16];
assert( iEnd==(+1) || iEnd==(-1) || iEnd==(-2) );
nProbe = sqlite4PutVarint64(aProbe, pC->iRoot);
aProbe[nProbe] = 0xFF;
rc = sqlite4KVCursorSeek(pCur, aProbe, nProbe+(iEnd<0), iEnd);
if( rc==SQLITE_OK ){
rc = SQLITE_CORRUPT_BKPT;
}else if( rc==SQLITE_INEXACT ){
rc = sqlite4KVCursorKey(pCur, &aKey, &nKey);
if( rc==SQLITE_OK && (nKey<nProbe || memcmp(aKey, aProbe, nProbe)!=0) ){
rc = SQLITE_NOTFOUND;
}
}
return rc;
}
/*
** Move a VDBE cursor to the next element in its table.
** Return SQLITE_NOTFOUND if the seek falls of the end of the table.
*/
SQLITE_PRIVATE int sqlite4VdbeNext(VdbeCursor *pC){
KVCursor *pCur = pC->pKVCur;
const KVByteArray *aKey;
KVSize nKey;
int rc;
sqlite4_uint64 iTabno;
rc = sqlite4KVCursorNext(pCur);
if( rc==SQLITE_OK ){
rc = sqlite4KVCursorKey(pCur, &aKey, &nKey);
if( rc==SQLITE_OK ){
iTabno = 0;
sqlite4GetVarint64(aKey, nKey, &iTabno);
if( iTabno!=pC->iRoot ) rc = SQLITE_NOTFOUND;
}
}
return rc;
}
/*
** Move a VDBE cursor to the previous element in its table.
** Return SQLITE_NOTFOUND if the seek falls of the end of the table.
*/
SQLITE_PRIVATE int sqlite4VdbePrevious(VdbeCursor *pC){
KVCursor *pCur = pC->pKVCur;
const KVByteArray *aKey;
KVSize nKey;
int rc;
sqlite4_uint64 iTabno;
rc = sqlite4KVCursorPrev(pCur);
if( rc==SQLITE_OK ){
rc = sqlite4KVCursorKey(pCur, &aKey, &nKey);
if( rc==SQLITE_OK ){
iTabno = 0;
sqlite4GetVarint64(aKey, nKey, &iTabno);
if( iTabno!=pC->iRoot ) rc = SQLITE_NOTFOUND;
}
}
return rc;
}
/************** End of vdbecursor.c ******************************************/
/************** Begin file vdbetrace.c ***************************************/
/*
** 2009 November 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.
**
*************************************************************************
**
** This file contains code used to insert the values of host parameters
** (aka "wildcards") into the SQL text output by sqlite4_trace().
**
** The Vdbe parse-tree explainer is also found here.
*/
#ifndef SQLITE_OMIT_TRACE
/*
** zSql is a zero-terminated string of UTF-8 SQL text. Return the number of
** bytes in this text up to but excluding the first character in
** a host parameter. If the text contains no host parameters, return
** the total number of bytes in the text.
*/
static int findNextHostParameter(const char *zSql, int *pnToken){
int tokenType;
int nTotal = 0;
int n;
*pnToken = 0;
while( zSql[0] ){
n = sqlite4GetToken((u8*)zSql, &tokenType);
assert( n>0 && tokenType!=TK_ILLEGAL );
if( tokenType==TK_VARIABLE ){
*pnToken = n;
break;
}
nTotal += n;
zSql += n;
}
return nTotal;
}
/*
** This function returns a pointer to a nul-terminated string in memory
** obtained from sqlite4DbMalloc(). If sqlite4.vdbeExecCnt is 1, then the
** string contains a copy of zRawSql but with host parameters expanded to
** their current bindings. Or, if sqlite4.vdbeExecCnt is greater than 1,
** then the returned string holds a copy of zRawSql with "-- " prepended
** to each line of text.
**
** The calling function is responsible for making sure the memory returned
** is eventually freed.
**
** ALGORITHM: Scan the input string looking for host parameters in any of
** these forms: ?, ?N, $A, @A, :A. Take care to avoid text within
** string literals, quoted identifier names, and comments. For text forms,
** the host parameter index is found by scanning the perpared
** statement for the corresponding OP_Variable opcode. Once the host
** parameter index is known, locate the value in p->aVar[]. Then render
** the value as a literal in place of the host parameter name.
*/
SQLITE_PRIVATE char *sqlite4VdbeExpandSql(
Vdbe *p, /* The prepared statement being evaluated */
const char *zRawSql /* Raw text of the SQL statement */
){
sqlite4 *db; /* The database connection */
int idx = 0; /* Index of a host parameter */
int nextIndex = 1; /* Index of next ? host parameter */
int n; /* Length of a token prefix */
int nToken; /* Length of the parameter token */
int i; /* Loop counter */
Mem *pVar; /* Value of a host parameter */
StrAccum out; /* Accumulate the output here */
char zBase[100]; /* Initial working space */
db = p->db;
sqlite4StrAccumInit(&out, zBase, sizeof(zBase),
db->aLimit[SQLITE_LIMIT_LENGTH]);
out.db = db;
out.pEnv = db->pEnv;
if( db->vdbeExecCnt>1 ){
while( *zRawSql ){
const char *zStart = zRawSql;
while( *(zRawSql++)!='\n' && *zRawSql );
sqlite4StrAccumAppend(&out, "-- ", 3);
sqlite4StrAccumAppend(&out, zStart, (int)(zRawSql-zStart));
}
}else{
while( zRawSql[0] ){
n = findNextHostParameter(zRawSql, &nToken);
assert( n>0 );
sqlite4StrAccumAppend(&out, zRawSql, n);
zRawSql += n;
assert( zRawSql[0] || nToken==0 );
if( nToken==0 ) break;
if( zRawSql[0]=='?' ){
if( nToken>1 ){
assert( sqlite4Isdigit(zRawSql[1]) );
sqlite4GetInt32(&zRawSql[1], &idx);
}else{
idx = nextIndex;
}
}else{
assert( zRawSql[0]==':' || zRawSql[0]=='$' || zRawSql[0]=='@' );
testcase( zRawSql[0]==':' );
testcase( zRawSql[0]=='$' );
testcase( zRawSql[0]=='@' );
idx = sqlite4VdbeParameterIndex(p, zRawSql, nToken);
assert( idx>0 );
}
zRawSql += nToken;
nextIndex = idx + 1;
assert( idx>0 && idx<=p->nVar );
pVar = &p->aVar[idx-1];
if( pVar->flags & MEM_Null ){
sqlite4StrAccumAppend(&out, "NULL", 4);
}else if( pVar->flags & MEM_Int ){
sqlite4XPrintf(&out, "%lld", pVar->u.i);
}else if( pVar->flags & MEM_Real ){
sqlite4XPrintf(&out, "%!.16g", pVar->r);
}else if( pVar->flags & MEM_Str ){
#ifndef SQLITE_OMIT_UTF16
u8 enc = ENC(db);
if( enc!=SQLITE_UTF8 ){
Mem utf8;
memset(&utf8, 0, sizeof(utf8));
utf8.db = db;
sqlite4VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC);
sqlite4VdbeChangeEncoding(&utf8, SQLITE_UTF8);
sqlite4XPrintf(&out, "'%.*q'", utf8.n, utf8.z);
sqlite4VdbeMemRelease(&utf8);
}else
#endif
{
sqlite4XPrintf(&out, "'%.*q'", pVar->n, pVar->z);
}
}else if( pVar->flags & MEM_Zero ){
sqlite4XPrintf(&out, "zeroblob(%d)", pVar->u.nZero);
}else{
assert( pVar->flags & MEM_Blob );
sqlite4StrAccumAppend(&out, "x'", 2);
for(i=0; i<pVar->n; i++){
sqlite4XPrintf(&out, "%02x", pVar->z[i]&0xff);
}
sqlite4StrAccumAppend(&out, "'", 1);
}
}
}
return sqlite4StrAccumFinish(&out);
}
#endif /* #ifndef SQLITE_OMIT_TRACE */
/*****************************************************************************
** The following code implements the data-structure explaining logic
** for the Vdbe.
*/
#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
/*
** Allocate a new Explain object
*/
SQLITE_PRIVATE void sqlite4ExplainBegin(Vdbe *pVdbe){
if( pVdbe ){
Explain *p;
sqlite4 *db = pVdbe->db;
sqlite4_env *pEnv = db->pEnv;
sqlite4BeginBenignMalloc(pEnv);
p = sqlite4_malloc(pEnv, sizeof(Explain) );
if( p ){
memset(p, 0, sizeof(*p));
p->pVdbe = pVdbe;
sqlite4_free(pEnv, pVdbe->pExplain);
pVdbe->pExplain = p;
sqlite4StrAccumInit(&p->str, p->zBase, sizeof(p->zBase),
SQLITE_MAX_LENGTH);
p->str.useMalloc = 2;
p->str.pEnv = pEnv;
}else{
sqlite4EndBenignMalloc(pEnv);
}
}
}
/*
** Return true if the Explain ends with a new-line.
*/
static int endsWithNL(Explain *p){
return p && p->str.zText && p->str.nChar
&& p->str.zText[p->str.nChar-1]=='\n';
}
/*
** Append text to the indentation
*/
SQLITE_PRIVATE void sqlite4ExplainPrintf(Vdbe *pVdbe, const char *zFormat, ...){
Explain *p;
if( pVdbe && (p = pVdbe->pExplain)!=0 ){
va_list ap;
if( p->nIndent && endsWithNL(p) ){
int n = p->nIndent;
if( n>ArraySize(p->aIndent) ) n = ArraySize(p->aIndent);
sqlite4AppendSpace(&p->str, p->aIndent[n-1]);
}
va_start(ap, zFormat);
sqlite4VXPrintf(&p->str, 1, zFormat, ap);
va_end(ap);
}
}
/*
** Append a '\n' if there is not already one.
*/
SQLITE_PRIVATE void sqlite4ExplainNL(Vdbe *pVdbe){
Explain *p;
if( pVdbe && (p = pVdbe->pExplain)!=0 && !endsWithNL(p) ){
sqlite4StrAccumAppend(&p->str, "\n", 1);
}
}
/*
** Push a new indentation level. Subsequent lines will be indented
** so that they begin at the current cursor position.
*/
SQLITE_PRIVATE void sqlite4ExplainPush(Vdbe *pVdbe){
Explain *p;
if( pVdbe && (p = pVdbe->pExplain)!=0 ){
if( p->str.zText && p->nIndent<ArraySize(p->aIndent) ){
const char *z = p->str.zText;
int i = p->str.nChar-1;
int x;
while( i>=0 && z[i]!='\n' ){ i--; }
x = (p->str.nChar - 1) - i;
if( p->nIndent && x<p->aIndent[p->nIndent-1] ){
x = p->aIndent[p->nIndent-1];
}
p->aIndent[p->nIndent] = x;
}
p->nIndent++;
}
}
/*
** Pop the indentation stack by one level.
*/
SQLITE_PRIVATE void sqlite4ExplainPop(Vdbe *p){
if( p && p->pExplain ) p->pExplain->nIndent--;
}
/*
** Free the indentation structure
*/
SQLITE_PRIVATE void sqlite4ExplainFinish(Vdbe *pVdbe){
if( pVdbe && pVdbe->pExplain ){
sqlite4_env *pEnv = pVdbe->db->pEnv;
sqlite4_free(pEnv, pVdbe->zExplain);
sqlite4ExplainNL(pVdbe);
pVdbe->zExplain = sqlite4StrAccumFinish(&pVdbe->pExplain->str);
sqlite4_free(pEnv, pVdbe->pExplain);
pVdbe->pExplain = 0;
sqlite4EndBenignMalloc(pEnv);
}
}
/*
** Return the explanation of a virtual machine.
*/
SQLITE_PRIVATE const char *sqlite4VdbeExplanation(Vdbe *pVdbe){
return (pVdbe && pVdbe->zExplain) ? pVdbe->zExplain : 0;
}
#endif /* defined(SQLITE_DEBUG) */
/************** End of vdbetrace.c *******************************************/
/************** Begin file vdbe.c ********************************************/
/*
** 2001 September 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 code in this file implements execution method of the
** Virtual Database Engine (VDBE). A separate file ("vdbeaux.c")
** handles housekeeping details such as creating and deleting
** VDBE instances. This file is solely interested in executing
** the VDBE program.
**
** In the external interface, an "sqlite4_stmt*" is an opaque pointer
** to a VDBE.
**
** The SQL parser generates a program which is then executed by
** the VDBE to do the work of the SQL statement. VDBE programs are
** similar in form to assembly language. The program consists of
** a linear sequence of operations. Each operation has an opcode
** and 5 operands. Operands P1, P2, and P3 are integers. Operand P4
** is a null-terminated string. Operand P5 is an unsigned character.
** Few opcodes use all 5 operands.
**
** Computation results are stored on a set of registers numbered beginning
** with 1 and going up to Vdbe.nMem. Each register can store
** either an integer, a null-terminated string, a floating point
** number, or the SQL "NULL" value. An implicit conversion from one
** type to the other occurs as necessary.
**
** Most of the code in this file is taken up by the sqlite4VdbeExec()
** function which does the work of interpreting a VDBE program.
** But other routines are also provided to help in building up
** a program instruction by instruction.
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files. The formatting
** of the code in this file is, therefore, important. See other comments
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
*/
/*
** Invoke this macro on memory cells just prior to changing the
** value of the cell. This macro verifies that shallow copies are
** not misused.
*/
#ifdef SQLITE_DEBUG
# define memAboutToChange(P,M) sqlite4VdbeMemAboutToChange(P,M)
#else
# define memAboutToChange(P,M)
#endif
/*
** The following global variable is incremented every time a cursor
** moves, either by the OP_SeekXX, OP_Next, or OP_Prev opcodes. The test
** procedures use this information to make sure that indices are
** working correctly. This variable has no function other than to
** help verify the correct operation of the library.
*/
#ifdef SQLITE_TEST
SQLITE_API int sqlite4_search_count = 0;
#endif
/*
** When this global variable is positive, it gets decremented once before
** each instruction in the VDBE. When it reaches zero, the u1.isInterrupted
** field of the sqlite4 structure is set in order to simulate an interrupt.
**
** This facility is used for testing purposes only. It does not function
** in an ordinary build.
*/
#ifdef SQLITE_TEST
SQLITE_API int sqlite4_interrupt_count = 0;
#endif
/*
** The next global variable is incremented each type the OP_Sort opcode
** is executed. The test procedures use this information to make sure that
** sorting is occurring or not occurring at appropriate times. This variable
** has no function other than to help verify the correct operation of the
** library.
*/
#ifdef SQLITE_TEST
SQLITE_API int sqlite4_sort_count = 0;
#endif
/*
** The next global variable records the size of the largest MEM_Blob
** or MEM_Str that has been used by a VDBE opcode. The test procedures
** use this information to make sure that the zero-blob functionality
** is working correctly. This variable has no function other than to
** help verify the correct operation of the library.
*/
#ifdef SQLITE_TEST
SQLITE_API int sqlite4_max_blobsize = 0;
static void updateMaxBlobsize(Mem *p){
if( (p->flags & (MEM_Str|MEM_Blob))!=0 && p->n>sqlite4_max_blobsize ){
sqlite4_max_blobsize = p->n;
}
}
#endif
/*
** The next global variable is incremented each type 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
** has no function other than to help verify the correct operation of the
** library.
*/
#ifdef SQLITE_TEST
SQLITE_API int sqlite4_found_count = 0;
#endif
/*
** 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_OMIT_BUILTIN_TEST)
# define UPDATE_MAX_BLOBSIZE(P) updateMaxBlobsize(P)
#else
# define UPDATE_MAX_BLOBSIZE(P)
#endif
/*
** Convert the given register into a string if it isn't one
** already. Return non-zero if a malloc() fails.
*/
#define Stringify(P, enc) \
if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite4VdbeMemStringify(P,enc)) \
{ goto no_mem; }
/*
** An ephemeral string value (signified by the MEM_Ephem flag) contains
** a pointer to a dynamically allocated string where some other entity
** is responsible for deallocating that string. Because the register
** does not control the string, it might be deleted without the register
** knowing it.
**
** This routine converts an ephemeral string into a dynamically allocated
** string that the register itself controls. In other words, it
** converts an MEM_Ephem string into an MEM_Dyn string.
*/
#define Deephemeralize(P) \
if( ((P)->flags&MEM_Ephem)!=0 \
&& sqlite4VdbeMemMakeWriteable(P) ){ goto no_mem;}
/*
** Argument pMem points at a register that will be passed to a
** user-defined function or returned to the user as the result of a query.
** This routine sets the pMem->type variable used by the sqlite4_value_*()
** routines.
*/
SQLITE_PRIVATE void sqlite4VdbeMemStoreType(Mem *pMem){
int flags = pMem->flags;
if( flags & MEM_Null ){
pMem->type = SQLITE_NULL;
}
else if( flags & MEM_Int ){
pMem->type = SQLITE_INTEGER;
}
else if( flags & MEM_Real ){
pMem->type = SQLITE_FLOAT;
}
else if( flags & MEM_Str ){
pMem->type = SQLITE_TEXT;
}else{
pMem->type = SQLITE_BLOB;
}
}
/*
** Allocate VdbeCursor number iCur. Return a pointer to it. Return NULL
** if we run out of memory.
*/
static VdbeCursor *allocateCursor(
Vdbe *p, /* The virtual machine */
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 */
int isTrueCursor /* True real cursor. False for pseudo-table or vtab */
){
/* 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
** vdbe memory cell to manage the memory allocation required for a
** VdbeCursor structure for the following reasons:
**
** * Sometimes cursor numbers are used for a couple of different
** purposes in a vdbe program. The different uses might require
** different sized allocations. Memory cells provide growable
** allocations.
**
** Memory cells for cursors are allocated at the top of the address
** space. Memory cell (p->nMem) corresponds to cursor 0. Space for
** cursor 1 is managed by memory cell (p->nMem-1), etc.
*/
Mem *pMem = &p->aMem[p->nMem-iCur];
int nByte;
VdbeCursor *pCx = 0;
nByte =
ROUND8(sizeof(VdbeCursor)) +
2*nField*sizeof(u32);
assert( iCur<p->nCursor );
if( p->apCsr[iCur] ){
sqlite4VdbeFreeCursor(p, p->apCsr[iCur]);
p->apCsr[iCur] = 0;
}
if( SQLITE_OK==sqlite4VdbeMemGrow(pMem, nByte, 0) ){
p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
memset(pCx, 0, sizeof(VdbeCursor));
pCx->iDb = iDb;
pCx->nField = nField;
}
return pCx;
}
/*
** Try to convert a value into a numeric representation if we can
** do so without loss of information. In other words, if the string
** looks like a number, convert it into a number. If it does not
** look like a number, leave it alone.
*/
static void applyNumericAffinity(Mem *pRec){
if( (pRec->flags & (MEM_Real|MEM_Int))==0 ){
double rValue;
i64 iValue;
u8 enc = pRec->enc;
if( (pRec->flags&MEM_Str)==0 ) return;
if( sqlite4AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return;
if( 0==sqlite4Atoi64(pRec->z, &iValue, pRec->n, enc) ){
pRec->u.i = iValue;
pRec->flags |= MEM_Int;
}else{
pRec->r = rValue;
pRec->flags |= MEM_Real;
}
}
}
/*
** Processing is determine by the affinity parameter:
**
** SQLITE_AFF_INTEGER:
** SQLITE_AFF_REAL:
** SQLITE_AFF_NUMERIC:
** Try to convert pRec to an integer representation or a
** floating-point representation if an integer representation
** is not possible. Note that the integer representation is
** always preferred, even if the affinity is REAL, because
** an integer representation is more space efficient on disk.
**
** SQLITE_AFF_TEXT:
** Convert pRec to a text representation.
**
** SQLITE_AFF_NONE:
** No-op. pRec is unchanged.
*/
static void applyAffinity(
Mem *pRec, /* The value to apply affinity to */
char affinity, /* The affinity to be applied */
u8 enc /* Use this text encoding */
){
if( affinity==SQLITE_AFF_TEXT ){
/* 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.
*/
if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){
sqlite4VdbeMemStringify(pRec, enc);
}
pRec->flags &= ~(MEM_Real|MEM_Int);
}else if( affinity!=SQLITE_AFF_NONE ){
assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL
|| affinity==SQLITE_AFF_NUMERIC );
applyNumericAffinity(pRec);
if( pRec->flags & MEM_Real ){
sqlite4VdbeIntegerAffinity(pRec);
}
}
}
/*
** Try to convert the type of a function argument or a result column
** into a numeric representation. Use either INTEGER or REAL whichever
** 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 sqlite4_value_numeric_type(sqlite4_value *pVal){
Mem *pMem = (Mem*)pVal;
if( pMem->type==SQLITE_TEXT ){
applyNumericAffinity(pMem);
sqlite4VdbeMemStoreType(pMem);
}
return pMem->type;
}
/*
** Exported version of applyAffinity(). This one works on sqlite4_value*,
** not the internal Mem* type.
*/
SQLITE_PRIVATE void sqlite4ValueApplyAffinity(
sqlite4_value *pVal,
u8 affinity,
u8 enc
){
applyAffinity((Mem *)pVal, affinity, enc);
}
#ifdef SQLITE_DEBUG
/*
** Write a nice string representation of the contents of cell pMem
** into buffer zBuf, length nBuf.
*/
SQLITE_PRIVATE void sqlite4VdbeMemPrettyPrint(Mem *pMem, char *zBuf){
char *zCsr = zBuf;
int f = pMem->flags;
static const char *const encnames[] = {"(X)", "(8)", "(16LE)", "(16BE)"};
if( f&MEM_Blob ){
int i;
char c;
if( f & MEM_Dyn ){
c = 'z';
assert( (f & (MEM_Static|MEM_Ephem))==0 );
}else if( f & MEM_Static ){
c = 't';
assert( (f & (MEM_Dyn|MEM_Ephem))==0 );
}else if( f & MEM_Ephem ){
c = 'e';
assert( (f & (MEM_Static|MEM_Dyn))==0 );
}else{
c = 's';
}
zCsr += sqlite4_snprintf(zCsr, 100, "%c", c);
zCsr += sqlite4_snprintf(zCsr, 100, "%d[", pMem->n);
for(i=0; i<16 && i<pMem->n; i++){
zCsr += sqlite4_snprintf(zCsr, 100, "%02X", ((int)pMem->z[i] & 0xFF));
}
for(i=0; i<16 && i<pMem->n; i++){
char z = pMem->z[i];
if( z<32 || z>126 ) *zCsr++ = '.';
else *zCsr++ = z;
}
zCsr += sqlite4_snprintf(zCsr, 100, "]%s", encnames[pMem->enc]);
if( f & MEM_Zero ){
zCsr += sqlite4_snprintf(zCsr, 100, "+%dz",pMem->u.nZero);
}
*zCsr = '\0';
}else if( f & MEM_Str ){
int j, k;
zBuf[0] = ' ';
if( f & MEM_Dyn ){
zBuf[1] = 'z';
assert( (f & (MEM_Static|MEM_Ephem))==0 );
}else if( f & MEM_Static ){
zBuf[1] = 't';
assert( (f & (MEM_Dyn|MEM_Ephem))==0 );
}else if( f & MEM_Ephem ){
zBuf[1] = 'e';
assert( (f & (MEM_Static|MEM_Dyn))==0 );
}else{
zBuf[1] = 's';
}
k = 2;
k += sqlite4_snprintf(&zBuf[k], 100, "%d", pMem->n);
zBuf[k++] = '[';
for(j=0; j<15 && j<pMem->n; j++){
u8 c = pMem->z[j];
if( c>=0x20 && c<0x7f ){
zBuf[k++] = c;
}else{
zBuf[k++] = '.';
}
}
zBuf[k++] = ']';
k += sqlite4_snprintf(&zBuf[k], 100, encnames[pMem->enc]);
zBuf[k++] = 0;
}
}
#endif
#ifdef SQLITE_DEBUG
/*
** Print the value of a register for tracing purposes:
*/
static void memTracePrint(FILE *out, Mem *p){
if( p->flags & MEM_Null ){
fprintf(out, " NULL");
}else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
fprintf(out, " si:%lld", p->u.i);
}else if( p->flags & MEM_Int ){
fprintf(out, " i:%lld", p->u.i);
#ifndef SQLITE_OMIT_FLOATING_POINT
}else if( p->flags & MEM_Real ){
fprintf(out, " r:%g", p->r);
#endif
}else if( p->flags & MEM_RowSet ){
fprintf(out, " (keyset)");
}else{
char zBuf[200];
sqlite4VdbeMemPrettyPrint(p, zBuf);
fprintf(out, " ");
fprintf(out, "%s", zBuf);
}
}
static void registerTrace(FILE *out, int iReg, Mem *p){
fprintf(out, "REG[%d] = ", iReg);
memTracePrint(out, p);
fprintf(out, "\n");
}
#endif
#ifdef SQLITE_DEBUG
# define REGISTER_TRACE(R,M) if(p->trace)registerTrace(p->trace,R,M)
#else
# define REGISTER_TRACE(R,M)
#endif
#ifdef VDBE_PROFILE
/*
** hwtime.h contains inline assembler code for implementing
** high-performance timing routines.
*/
/************** Include hwtime.h in the middle of vdbe.c *********************/
/************** Begin file hwtime.h ******************************************/
/*
** 2008 May 27
**
** 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 inline asm code for retrieving "high-performance"
** counters for x86 class CPUs.
*/
#ifndef _HWTIME_H_
#define _HWTIME_H_
/*
** The following routine only works on pentium-class (or newer) processors.
** It uses the RDTSC opcode to read the cycle count value out of the
** processor and returns that value. This can be used for high-res
** profiling.
*/
#if (defined(__GNUC__) || defined(_MSC_VER)) && \
(defined(i386) || defined(__i386__) || defined(_M_IX86))
#if defined(__GNUC__)
__inline__ sqlite_uint64 sqlite4Hwtime(void){
unsigned int lo, hi;
__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
return (sqlite_uint64)hi << 32 | lo;
}
#elif defined(_MSC_VER)
__declspec(naked) __inline sqlite_uint64 __cdecl sqlite4Hwtime(void){
__asm {
rdtsc
ret ; return value at EDX:EAX
}
}
#endif
#elif (defined(__GNUC__) && defined(__x86_64__))
__inline__ sqlite_uint64 sqlite4Hwtime(void){
unsigned long val;
__asm__ __volatile__ ("rdtsc" : "=A" (val));
return val;
}
#elif (defined(__GNUC__) && defined(__ppc__))
__inline__ sqlite_uint64 sqlite4Hwtime(void){
unsigned long long retval;
unsigned long junk;
__asm__ __volatile__ ("\n\
1: mftbu %1\n\
mftb %L0\n\
mftbu %0\n\
cmpw %0,%1\n\
bne 1b"
: "=r" (retval), "=r" (junk));
return retval;
}
#else
#error Need implementation of sqlite4Hwtime() for your platform.
/*
** To compile without implementing sqlite4Hwtime() for your platform,
** you can remove the above #error and use the following
** stub function. You will lose timing support for many
** of the debugging and testing utilities, but it should at
** least compile and run.
*/
SQLITE_PRIVATE sqlite_uint64 sqlite4Hwtime(void){ return ((sqlite_uint64)0); }
#endif
#endif /* !defined(_HWTIME_H_) */
/************** End of hwtime.h **********************************************/
/************** Continuing where we left off in vdbe.c ***********************/
#endif
/*
** The CHECK_FOR_INTERRUPT macro defined here looks to see if the
** sqlite4_interrupt() routine has been called. If it has been, then
** processing of the VDBE program is interrupted.
**
** This macro added to every instruction that does a jump in order to
** implement a loop. This test used to be on every single instruction,
** but that meant we more testing than we needed. By only testing the
** flag on jump instructions, we get a (small) speed improvement.
*/
#define CHECK_FOR_INTERRUPT \
if( db->u1.isInterrupted ) goto abort_due_to_interrupt;
/*
** Transfer error message text from an sqlite4_vtab.zErrMsg (text stored
** in memory obtained from sqlite4_malloc) into a Vdbe.zErrMsg (text stored
** in memory obtained from sqlite4DbMalloc).
*/
static void importVtabErrMsg(Vdbe *p, sqlite4_vtab *pVtab){
sqlite4 *db = p->db;
sqlite4DbFree(db, p->zErrMsg);
p->zErrMsg = sqlite4DbStrDup(db, pVtab->zErrMsg);
sqlite4_free(db->pEnv, pVtab->zErrMsg);
pVtab->zErrMsg = 0;
}
/*
** Execute as much of a VDBE program as we can then return.
**
** sqlite4VdbeMakeReady() must be called before this routine in order to
** close the program with a final OP_Halt and to set up the callbacks
** and the error message pointer.
**
** Whenever a row or result data is available, this routine will either
** invoke the result callback (if there is one) or return with
** SQLITE_ROW.
**
** If an attempt is made to open a locked database, then this routine
** will either invoke the busy callback (if there is one) or it will
** return SQLITE_BUSY.
**
** If an error occurs, an error message is written to memory obtained
** from sqlite4_malloc() and p->zErrMsg is made to point to that memory.
** The error code is stored in p->rc and this routine returns SQLITE_ERROR.
**
** If the callback ever returns non-zero, then the program exits
** immediately. There will be no error message but the p->rc field is
** set to SQLITE_ABORT and this routine will return SQLITE_ERROR.
**
** A memory allocation error causes p->rc to be set to SQLITE_NOMEM and this
** routine to return SQLITE_ERROR.
**
** Other fatal errors return SQLITE_ERROR.
**
** After this routine has finished, sqlite4VdbeFinalize() should be
** used to clean up the mess that was left behind.
*/
SQLITE_PRIVATE int sqlite4VdbeExec(
Vdbe *p /* The VDBE */
){
int pc=0; /* The program counter */
Op *aOp = p->aOp; /* Copy of p->aOp */
Op *pOp; /* Current operation */
int rc = SQLITE_OK; /* Value to return */
sqlite4 *db = p->db; /* The database */
u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */
u8 encoding = ENC(db); /* The database encoding */
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
int checkProgress; /* True if progress callbacks are enabled */
int nProgressOps = 0; /* Opcodes executed since progress callback. */
#endif
Mem *aMem = p->aMem; /* Copy of p->aMem */
Mem *pIn1 = 0; /* 1st input operand */
Mem *pIn2 = 0; /* 2nd input operand */
Mem *pIn3 = 0; /* 3rd input operand */
Mem *pOut = 0; /* Output operand */
int iCompare = 0; /* Result of last OP_Compare operation */
int *aPermute = 0; /* Permutation of columns for OP_Compare */
i64 lastRowid = db->lastRowid; /* Saved value of the last insert ROWID */
#ifdef VDBE_PROFILE
u64 start; /* CPU clock count at start of opcode */
int origPc; /* Program counter at start of opcode */
#endif
/********************************************************************
** Automatically generated code
**
** The following union is automatically generated by the
** vdbe-compress.tcl script. The purpose of this union is to
** reduce the amount of stack space required by this function.
** See comments in the vdbe-compress.tcl script for details.
*/
union vdbeExecUnion {
struct OP_Yield_stack_vars {
int pcDest;
} aa;
struct OP_Null_stack_vars {
int cnt;
} ab;
struct OP_Variable_stack_vars {
Mem *pVar; /* Value being transferred */
} ac;
struct OP_Move_stack_vars {
char *zMalloc; /* Holding variable for allocated memory */
int n; /* Number of registers left to copy */
int p1; /* Register to copy from */
int p2; /* Register to copy to */
} ad;
struct OP_ResultRow_stack_vars {
Mem *pMem;
int i;
} ae;
struct OP_Concat_stack_vars {
i64 nByte;
} af;
struct OP_Remainder_stack_vars {
int flags; /* Combined MEM_* flags from both inputs */
i64 iA; /* Integer value of left operand */
i64 iB; /* Integer value of right operand */
double rA; /* Real value of left operand */
double rB; /* Real value of right operand */
} ag;
struct OP_Function_stack_vars {
int i;
Mem *pArg;
sqlite4_context ctx;
sqlite4_value **apVal;
int n;
} ah;
struct OP_ShiftRight_stack_vars {
i64 iA;
u64 uA;
i64 iB;
u8 op;
} ai;
struct OP_Ge_stack_vars {
int res; /* 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 */
} aj;
struct OP_Compare_stack_vars {
int n;
int i;
int p1;
int p2;
const KeyInfo *pKeyInfo;
int idx;
CollSeq *pColl; /* Collating sequence to use on this term */
int bRev; /* True for DESCENDING sort order */
} ak;
struct OP_Or_stack_vars {
int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
} al;
struct OP_IfNot_stack_vars {
int c;
} am;
struct OP_IsNull_stack_vars {
Mem *pEnd;
} an;
struct OP_Column_stack_vars {
KVCursor *pKVCur; /* Cursor for current entry in the KV storage */
ValueDecoder *pCodec; /* The decoder object */
int p1; /* Index of VdbeCursor to decode */
VdbeCursor *pC; /* The VDBE cursor */
Mem *pDest; /* Where to write the results */
const KVByteArray *aData; /* The content to be decoded */
KVSize nData; /* Size of aData[] in bytes */
Mem *pDefault; /* Default value from P4 */
Mem *pReg; /* */
} ao;
struct OP_Affinity_stack_vars {
const char *zAffinity; /* The affinity to be applied */
Mem *pEnd;
} ap;
struct OP_MakeIdxKey_stack_vars {
VdbeCursor *pC;
KeyInfo *pKeyInfo;
Mem *pData0; /* First in array of input registers */
u8 *aRec; /* The constructed database key */
int nRec; /* Size of aRec[] in bytes */
int nField; /* Number of fields in encoded record */
u8 aSeq[10]; /* Encoded sequence number */
int nSeq; /* Size of sequence number in bytes */
u64 iSeq; /* Sequence number, if any */
} aq;
struct OP_MakeRecord_stack_vars {
Mem *pData0; /* First field to be combined into the record */
Mem *pLast; /* Last field of the record */
Mem *pMem; /* For looping over inputs */
int nField; /* Number of fields in the record */
char *zAffinity; /* The affinity string for the record */
VdbeCursor *pC; /* Cursor to generate key for */
Mem *pKeyOut; /* Where to store the generated key */
int keyReg; /* Register into which to write the key */
u8 *aRec; /* The constructed key or value */
int nRec; /* Size of aRec[] in bytes */
} ar;
struct OP_Count_stack_vars {
i64 nEntry;
VdbeCursor *pC;
} as;
struct OP_Savepoint_stack_vars {
int iSave;
Savepoint *pSave; /* Savepoint object operated upon */
const char *zSave; /* Name of savepoint (or NULL for trans.) */
int nSave; /* Size of zSave in bytes */
int iOp; /* SAVEPOINT_XXX operation */
const char *zErr; /* Static error message */
} at;
struct OP_Transaction_stack_vars {
Db *pDb;
KVStore *pKV;
int bStmt; /* True to open statement transaction */
int iLevel; /* Savepoint level to open */
} au;
struct OP_SetCookie_stack_vars {
Db *pDb;
u32 v;
} av;
struct OP_OpenWrite_stack_vars {
int nField;
KeyInfo *pKeyInfo;
int p2;
int iDb;
KVStore *pX;
VdbeCursor *pCur;
Db *pDb;
} aw;
struct OP_OpenEphemeral_stack_vars {
VdbeCursor *pCx;
} ax;
struct OP_OpenPseudo_stack_vars {
VdbeCursor *pCx;
} ay;
struct OP_SeekPk_stack_vars {
VdbeCursor *pPk; /* Cursor P1 */
VdbeCursor *pIdx; /* Cursor P3 */
} az;
struct OP_SeekGt_stack_vars {
int op; /* Copy of pOp->opcode (the op-code) */
VdbeCursor *pC; /* Cursor P1 */
int nField; /* Number of values to encode into key */
KVByteArray *aProbe; /* Buffer containing encoded key */
KVSize nProbe; /* Size of aProbe[] in bytes */
int dir; /* KV search dir (+ve or -ve) */
const KVByteArray *aKey; /* Pointer to final cursor key */
KVSize nKey; /* Size of aKey[] in bytes */
} ba;
struct OP_Seek_stack_vars {
VdbeCursor *pC;
KVCursor *pKVCur;
KVByteArray *aKey;
KVSize nKey;
} bb;
struct OP_Found_stack_vars {
int alreadyExists;
VdbeCursor *pC;
KVByteArray *pFree;
KVByteArray *pProbe;
KVSize nProbe;
const KVByteArray *pKey;
KVSize nKey;
} bc;
struct OP_IsUnique_stack_vars {
VdbeCursor *pC;
Mem *pProbe;
Mem *pOut;
int iOut;
int nShort;
int dir;
u64 dummy;
} bd;
struct OP_NewRowid_stack_vars {
i64 v; /* The new rowid */
VdbeCursor *pC; /* Cursor of table to get the new rowid */
const KVByteArray *aKey; /* Key of an existing row */
KVSize nKey; /* Size of the existing row key */
int n; /* Number of bytes decoded */
} be;
struct OP_NewIdxid_stack_vars {
u64 iMax;
KVStore *pKV;
KVCursor *pCsr;
int iDb;
} bf;
struct OP_InsertInt_stack_vars {
Mem *pData; /* MEM cell holding data for the record to be inserted */
Mem *pKey; /* MEM cell holding key for the record */
i64 iKey; /* The integer ROWID or key for the record to be inserted */
VdbeCursor *pC; /* Cursor to table into which insert is written */
const char *zDb; /* database name - used by the update hook */
const char *zTbl; /* Table name - used by the opdate hook */
int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */
int n;
KVByteArray aKey[24];
} bg;
struct OP_Delete_stack_vars {
VdbeCursor *pC;
} bh;
struct OP_GrpCompare_stack_vars {
VdbeCursor *pC; /* Cursor P1 */
} bi;
struct OP_SorterData_stack_vars {
VdbeCursor *pC;
} bj;
struct OP_RowData_stack_vars {
VdbeCursor *pC;
KVCursor *pCrsr;
const KVByteArray *pData;
KVSize nData;
} bk;
struct OP_Rowid_stack_vars {
VdbeCursor *pC;
i64 v;
sqlite4_vtab *pVtab;
const sqlite4_module *pModule;
const KVByteArray *aKey;
KVSize nKey;
int n;
} bl;
struct OP_NullRow_stack_vars {
VdbeCursor *pC;
} bm;
struct OP_Last_stack_vars {
VdbeCursor *pC;
} bn;
struct OP_Rewind_stack_vars {
VdbeCursor *pC;
int doJump;
} bo;
struct OP_Next_stack_vars {
VdbeCursor *pC;
int res;
} bp;
struct OP_IdxInsert_stack_vars {
VdbeCursor *pC;
Mem *pKey;
Mem *pData;
} bq;
struct OP_IdxDelete_stack_vars {
VdbeCursor *pC;
Mem *pKey;
} br;
struct OP_IdxGT_stack_vars {
VdbeCursor *pC; /* Cursor P1 */
} bs;
struct OP_Clear_stack_vars {
KVCursor *pCur;
} bt;
struct OP_ParseSchema_stack_vars {
int iDb;
const char *zMaster;
char *zSql;
InitData initData;
} bu;
struct OP_RowSetTest_stack_vars {
int iSet;
} bv;
struct OP_RowSetRead_stack_vars {
const char *aKey;
int nKey;
} bw;
struct OP_Program_stack_vars {
int nMem; /* Number of memory registers for sub-program */
int nByte; /* Bytes of runtime space required for sub-program */
Mem *pRt; /* Register to allocate runtime space */
Mem *pMem; /* Used to iterate through memory cells */
Mem *pEnd; /* Last memory cell in new array */
VdbeFrame *pFrame; /* New vdbe frame to execute in */
SubProgram *pProgram; /* Sub-program to execute */
} bx;
struct OP_Param_stack_vars {
VdbeFrame *pFrame;
Mem *pIn;
} by;
struct OP_MemMax_stack_vars {
Mem *pIn1;
VdbeFrame *pFrame;
} bz;
struct OP_AggStep_stack_vars {
int n;
int i;
Mem *pMem;
Mem *pRec;
sqlite4_context ctx;
sqlite4_value **apVal;
} ca;
struct OP_AggFinal_stack_vars {
Mem *pMem;
} cb;
struct OP_VBegin_stack_vars {
VTable *pVTab;
} cc;
struct OP_VOpen_stack_vars {
VdbeCursor *pCur;
sqlite4_vtab_cursor *pVtabCursor;
sqlite4_vtab *pVtab;
sqlite4_module *pModule;
} cd;
struct OP_VFilter_stack_vars {
int nArg;
int iQuery;
const sqlite4_module *pModule;
Mem *pQuery;
Mem *pArgc;
sqlite4_vtab_cursor *pVtabCursor;
sqlite4_vtab *pVtab;
VdbeCursor *pCur;
int res;
int i;
Mem **apArg;
} ce;
struct OP_VColumn_stack_vars {
sqlite4_vtab *pVtab;
const sqlite4_module *pModule;
Mem *pDest;
sqlite4_context sContext;
} cf;
struct OP_VNext_stack_vars {
sqlite4_vtab *pVtab;
const sqlite4_module *pModule;
int res;
VdbeCursor *pCur;
} cg;
struct OP_VRename_stack_vars {
sqlite4_vtab *pVtab;
Mem *pName;
} ch;
struct OP_VUpdate_stack_vars {
sqlite4_vtab *pVtab;
sqlite4_module *pModule;
int nArg;
int i;
sqlite_int64 rowid;
Mem **apArg;
Mem *pX;
} ci;
struct OP_Trace_stack_vars {
char *zTrace;
char *z;
} cj;
} u;
/* End automatically generated code
********************************************************************/
assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite4_step() verifies this */
if( p->rc==SQLITE_NOMEM ){
/* This happens if a malloc() inside a call to sqlite4_column_text() or
** sqlite4_column_text16() failed. */
goto no_mem;
}
assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
p->rc = SQLITE_OK;
assert( p->explain==0 );
p->pResultSet = 0;
CHECK_FOR_INTERRUPT;
sqlite4VdbeIOTraceSql(p);
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
checkProgress = db->xProgress!=0;
#endif
#ifdef SQLITE_DEBUG
sqlite4BeginBenignMalloc(db->pEnv);
if( p->pc==0 && (db->flags & SQLITE_VdbeListing)!=0 ){
int i;
printf("VDBE Program Listing:\n");
sqlite4VdbePrintSql(p);
for(i=0; i<p->nOp; i++){
sqlite4VdbePrintOp(stdout, i, &aOp[i]);
}
}
sqlite4EndBenignMalloc(db->pEnv);
#endif
for(pc=p->pc; rc==SQLITE_OK; pc++){
assert( pc>=0 && pc<p->nOp );
if( db->mallocFailed ) goto no_mem;
#ifdef VDBE_PROFILE
origPc = pc;
start = sqlite4Hwtime();
#endif
pOp = &aOp[pc];
/* Only allow tracing if SQLITE_DEBUG is defined.
*/
#ifdef SQLITE_DEBUG
if( p->trace ){
if( pc==0 ){
printf("VDBE Execution Trace:\n");
sqlite4VdbePrintSql(p);
}
sqlite4VdbePrintOp(p->trace, pc, pOp);
}
#endif
/* Check to see if we need to simulate an interrupt. This only happens
** if we have a special test build.
*/
#ifdef SQLITE_TEST
if( sqlite4_interrupt_count>0 ){
sqlite4_interrupt_count--;
if( sqlite4_interrupt_count==0 ){
sqlite4_interrupt(db);
}
}
#endif
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
/* Call the progress callback if it is configured and the required number
** of VDBE ops have been executed (either since this invocation of
** sqlite4VdbeExec() or since last time the progress callback was called).
** If the progress callback returns non-zero, exit the virtual machine with
** a return code SQLITE_ABORT.
*/
if( checkProgress ){
if( db->nProgressOps==nProgressOps ){
int prc;
prc = db->xProgress(db->pProgressArg);
if( prc!=0 ){
rc = SQLITE_INTERRUPT;
goto vdbe_error_halt;
}
nProgressOps = 0;
}
nProgressOps++;
}
#endif
/* On any opcode with the "out2-prerelase" tag, free any
** external allocations out of mem[p2] and set mem[p2] to be
** an undefined integer. Opcodes will either fill in the integer
** value or convert mem[p2] to a different type.
*/
assert( pOp->opflags==sqlite4OpcodeProperty[pOp->opcode] );
if( pOp->opflags & OPFLG_OUT2_PRERELEASE ){
assert( pOp->p2>0 );
assert( pOp->p2<=p->nMem );
pOut = &aMem[pOp->p2];
memAboutToChange(p, pOut);
VdbeMemRelease(pOut);
pOut->flags = MEM_Int;
}
/* Sanity checking on other operands */
#ifdef SQLITE_DEBUG
if( (pOp->opflags & OPFLG_IN1)!=0 ){
assert( pOp->p1>0 );
assert( pOp->p1<=p->nMem );
assert( memIsValid(&aMem[pOp->p1]) );
REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]);
}
if( (pOp->opflags & OPFLG_IN2)!=0 ){
assert( pOp->p2>0 );
assert( pOp->p2<=p->nMem );
assert( memIsValid(&aMem[pOp->p2]) );
REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]);
}
if( (pOp->opflags & OPFLG_IN3)!=0 ){
assert( pOp->p3>0 );
assert( pOp->p3<=p->nMem );
assert( memIsValid(&aMem[pOp->p3]) );
REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]);
}
if( (pOp->opflags & OPFLG_OUT2)!=0 ){
assert( pOp->p2>0 );
assert( pOp->p2<=p->nMem );
memAboutToChange(p, &aMem[pOp->p2]);
}
if( (pOp->opflags & OPFLG_OUT3)!=0 ){
assert( pOp->p3>0 );
assert( pOp->p3<=p->nMem );
memAboutToChange(p, &aMem[pOp->p3]);
}
#endif
switch( pOp->opcode ){
/*****************************************************************************
** What follows is a massive switch statement where each case implements a
** separate instruction in the virtual machine. If we follow the usual
** indentation conventions, each case should be indented by 6 spaces. But
** that is a lot of wasted space on the left margin. So the code within
** the switch statement will break with convention and be flush-left. Another
** big comment (similar to this one) will mark the point in the code where
** we transition back to normal indentation.
**
** The formatting of each case is important. The makefile for SQLite
** generates two C files "opcodes.h" and "opcodes.c" by scanning this
** file looking for lines that begin with "case OP_". The opcodes.h files
** will be filled with #defines that give unique integer values to each
** opcode and the opcodes.c file is filled with an array of strings where
** each string is the symbolic name for the corresponding opcode. If the
** case statement is followed by a comment of the form "/# same as ... #/"
** that comment is used to determine the particular value of the opcode.
**
** Other keywords in the comment that follows each case are used to
** construct the OPFLG_INITIALIZER value that initializes opcodeProperty[].
** Keywords include: in1, in2, in3, out2_prerelease, out2, out3. See
** the mkopcodeh.awk script for additional information.
**
** Documentation about VDBE opcodes is generated by scanning this file
** for lines of that contain "Opcode:". That line and all subsequent
** comment lines are used in the generation of the opcode.html documentation
** file.
**
** SUMMARY:
**
** Formatting is important to scripts that scan this file.
** Do not deviate from the formatting style currently in use.
**
*****************************************************************************/
/* Opcode: Goto * P2 * * *
**
** An unconditional jump to address P2.
** The next instruction executed will be
** the one at index P2 from the beginning of
** the program.
*/
case OP_Goto: { /* jump */
CHECK_FOR_INTERRUPT;
pc = pOp->p2 - 1;
break;
}
/* Opcode: Gosub P1 P2 * * *
**
** Write the current address onto register P1
** and then jump to address P2.
*/
case OP_Gosub: { /* jump */
assert( pOp->p1>0 && pOp->p1<=p->nMem );
pIn1 = &aMem[pOp->p1];
assert( (pIn1->flags & MEM_Dyn)==0 );
memAboutToChange(p, pIn1);
pIn1->flags = MEM_Int;
pIn1->u.i = pc;
REGISTER_TRACE(pOp->p1, pIn1);
pc = pOp->p2 - 1;
break;
}
/* Opcode: Return P1 * * * *
**
** Jump to the next instruction after the address in register P1.
*/
case OP_Return: { /* in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags & MEM_Int );
pc = (int)pIn1->u.i;
break;
}
/* Opcode: Yield P1 * * * *
**
** Swap the program counter with the value in register P1.
*/
case OP_Yield: { /* in1 */
#if 0 /* local variables moved into u.aa */
int pcDest;
#endif /* local variables moved into u.aa */
pIn1 = &aMem[pOp->p1];
assert( (pIn1->flags & MEM_Dyn)==0 );
pIn1->flags = MEM_Int;
u.aa.pcDest = (int)pIn1->u.i;
pIn1->u.i = pc;
REGISTER_TRACE(pOp->p1, pIn1);
pc = u.aa.pcDest;
break;
}
/* Opcode: HaltIfNull P1 P2 P3 P4 *
**
** 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
** value in register P3 is not NULL, then this routine is a no-op.
*/
case OP_HaltIfNull: { /* in3 */
pIn3 = &aMem[pOp->p3];
if( (pIn3->flags & MEM_Null)==0 ) break;
/* Fall through into OP_Halt */
}
/* Opcode: Halt P1 P2 * P4 *
**
** Exit immediately. All open cursors, etc are closed
** automatically.
**
** P1 is the result code returned by sqlite4_exec(), sqlite4_reset(),
** or sqlite4_finalize(). For a normal halt, this should be SQLITE_OK (0).
** For errors, it can be some other value. If P1!=0 then P2 will determine
** whether or not to rollback the current transaction. Do not rollback
** if P2==OE_Fail. Do the rollback if P2==OE_Rollback. If P2==OE_Abort,
** then back out all changes that have occurred during this execution of the
** VDBE, but do not rollback the transaction.
**
** If P4 is not null then it is an error message string.
**
** There is an implied "Halt 0 0 0" instruction inserted at the very end of
** every program. So a jump past the last instruction of the program
** is the same as executing Halt.
*/
case OP_Halt: {
if( pOp->p1==SQLITE_OK && p->pFrame ){
/* Halt the sub-program. Return control to the parent frame. */
VdbeFrame *pFrame = p->pFrame;
p->pFrame = pFrame->pParent;
p->nFrame--;
sqlite4VdbeSetChanges(db, p->nChange);
pc = sqlite4VdbeFrameRestore(pFrame);
lastRowid = db->lastRowid;
if( pOp->p2==OE_Ignore ){
/* Instruction pc is the OP_Program that invoked the sub-program
** currently being halted. If the p2 instruction of this OP_Halt
** instruction is set to OE_Ignore, then the sub-program is throwing
** an IGNORE exception. In this case jump to the address specified
** as the p2 of the calling OP_Program. */
pc = p->aOp[pc].p2-1;
}
aOp = p->aOp;
aMem = p->aMem;
break;
}
p->rc = pOp->p1;
p->errorAction = (u8)pOp->p2;
p->pc = pc;
if( pOp->p4.z ){
assert( p->rc!=SQLITE_OK );
sqlite4SetString(&p->zErrMsg, db, "%s", pOp->p4.z);
testcase( sqlite4DefaultEnv.xLog!=0 );
sqlite4_log(db->pEnv, pOp->p1,
"abort at %d in [%s]: %s", pc, p->zSql, pOp->p4.z);
}else if( p->rc ){
testcase( sqlite4DefaultEnv.xLog!=0 );
sqlite4_log(db->pEnv, pOp->p1,
"constraint failed at %d in [%s]", pc, p->zSql);
}
rc = sqlite4VdbeHalt(p);
assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
if( rc==SQLITE_BUSY ){
p->rc = rc = SQLITE_BUSY;
}else{
assert( rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT );
assert( rc==SQLITE_OK || db->nDeferredCons>0 );
rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
}
goto vdbe_return;
}
/* Opcode: Integer P1 P2 * * *
**
** The 32-bit integer value P1 is written into register P2.
*/
case OP_Integer: { /* out2-prerelease */
pOut->u.i = pOp->p1;
break;
}
/* Opcode: Int64 * P2 * P4 *
**
** P4 is a pointer to a 64-bit integer value.
** Write that value into register P2.
*/
case OP_Int64: { /* out2-prerelease */
assert( pOp->p4.pI64!=0 );
pOut->u.i = *pOp->p4.pI64;
break;
}
#ifndef SQLITE_OMIT_FLOATING_POINT
/* Opcode: Real * P2 * P4 *
**
** P4 is a pointer to a 64-bit floating point value.
** Write that value into register P2.
*/
case OP_Real: { /* same as TK_FLOAT, out2-prerelease */
pOut->flags = MEM_Real;
assert( !sqlite4IsNaN(*pOp->p4.pReal) );
pOut->r = *pOp->p4.pReal;
break;
}
#endif
/* Opcode: String8 * P2 * P4 *
**
** P4 points to a nul terminated UTF-8 string. This opcode is transformed
** into an OP_String before it is executed for the first time.
*/
case OP_String8: { /* same as TK_STRING, out2-prerelease */
assert( pOp->p4.z!=0 );
pOp->opcode = OP_String;
pOp->p1 = sqlite4Strlen30(pOp->p4.z);
#ifndef SQLITE_OMIT_UTF16
if( encoding!=SQLITE_UTF8 ){
rc = sqlite4VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC);
if( rc==SQLITE_TOOBIG ) goto too_big;
if( SQLITE_OK!=sqlite4VdbeChangeEncoding(pOut, encoding) ) goto no_mem;
assert( pOut->zMalloc==pOut->z );
assert( pOut->flags & MEM_Dyn );
pOut->zMalloc = 0;
pOut->flags |= MEM_Static;
pOut->flags &= ~MEM_Dyn;
if( pOp->p4type==P4_DYNAMIC ){
sqlite4DbFree(db, pOp->p4.z);
}
pOp->p4type = P4_DYNAMIC;
pOp->p4.z = pOut->z;
pOp->p1 = pOut->n;
}
#endif
if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
/* Fall through to the next case, OP_String */
}
/* Opcode: String P1 P2 * P4 *
**
** The string value P4 of length P1 (bytes) is stored in register P2.
*/
case OP_String: { /* out2-prerelease */
assert( pOp->p4.z!=0 );
pOut->flags = MEM_Str|MEM_Static|MEM_Term;
pOut->z = pOp->p4.z;
pOut->n = pOp->p1;
pOut->enc = encoding;
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
/* Opcode: Null * P2 P3 * *
**
** Write a NULL into registers P2. If P3 greater than P2, then also write
** NULL into register P3 and ever register in between P2 and P3. If P3
** is less than P2 (typically P3 is zero) then only register P2 is
** set to NULL
*/
case OP_Null: { /* out2-prerelease */
#if 0 /* local variables moved into u.ab */
int cnt;
#endif /* local variables moved into u.ab */
u.ab.cnt = pOp->p3-pOp->p2;
assert( pOp->p3<=p->nMem );
pOut->flags = MEM_Null;
while( u.ab.cnt>0 ){
pOut++;
memAboutToChange(p, pOut);
VdbeMemRelease(pOut);
pOut->flags = MEM_Null;
u.ab.cnt--;
}
break;
}
/* Opcode: Blob P1 P2 * P4
**
** P4 points to a blob of data P1 bytes long. Store this
** blob in register P2.
*/
case OP_Blob: { /* out2-prerelease */
assert( pOp->p1 <= SQLITE_MAX_LENGTH );
sqlite4VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0);
pOut->enc = encoding;
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
/* Opcode: Variable P1 P2 * P4 *
**
** Transfer the values of bound parameter P1 into register P2
**
** If the parameter is named, then its name appears in P4 and P3==1.
** The P4 value is used by sqlite4_bind_parameter_name().
*/
case OP_Variable: { /* out2-prerelease */
#if 0 /* local variables moved into u.ac */
Mem *pVar; /* Value being transferred */
#endif /* local variables moved into u.ac */
assert( pOp->p1>0 && pOp->p1<=p->nVar );
assert( pOp->p4.z==0 || pOp->p4.z==p->azVar[pOp->p1-1] );
u.ac.pVar = &p->aVar[pOp->p1 - 1];
if( sqlite4VdbeMemTooBig(u.ac.pVar) ){
goto too_big;
}
sqlite4VdbeMemShallowCopy(pOut, u.ac.pVar, MEM_Static);
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
/* Opcode: Move P1 P2 P3 * *
**
** Move the values in register P1..P1+P3-1 over into
** registers P2..P2+P3-1. Registers P1..P1+P1-1 are
** left holding a NULL. It is an error for register ranges
** P1..P1+P3-1 and P2..P2+P3-1 to overlap.
*/
case OP_Move: {
#if 0 /* local variables moved into u.ad */
char *zMalloc; /* Holding variable for allocated memory */
int n; /* Number of registers left to copy */
int p1; /* Register to copy from */
int p2; /* Register to copy to */
#endif /* local variables moved into u.ad */
u.ad.n = pOp->p3;
u.ad.p1 = pOp->p1;
u.ad.p2 = pOp->p2;
assert( u.ad.n>0 && u.ad.p1>0 && u.ad.p2>0 );
assert( u.ad.p1+u.ad.n<=u.ad.p2 || u.ad.p2+u.ad.n<=u.ad.p1 );
pIn1 = &aMem[u.ad.p1];
pOut = &aMem[u.ad.p2];
while( u.ad.n-- ){
assert( pOut<=&aMem[p->nMem] );
assert( pIn1<=&aMem[p->nMem] );
assert( memIsValid(pIn1) );
memAboutToChange(p, pOut);
u.ad.zMalloc = pOut->zMalloc;
pOut->zMalloc = 0;
sqlite4VdbeMemMove(pOut, pIn1);
#ifdef SQLITE_DEBUG
if( pOut->pScopyFrom>=&aMem[u.ad.p1] && pOut->pScopyFrom<&aMem[u.ad.p1+pOp->p3] ){
pOut->pScopyFrom += u.ad.p1 - pOp->p2;
}
#endif
pIn1->zMalloc = u.ad.zMalloc;
REGISTER_TRACE(u.ad.p2++, pOut);
pIn1++;
pOut++;
}
break;
}
/* Opcode: Copy P1 P2 * * *
**
** Make a copy of register P1 into register P2.
**
** This instruction makes a deep copy of the value. A duplicate
** is made of any string or blob constant. See also OP_SCopy.
*/
case OP_Copy: { /* in1, out2 */
pIn1 = &aMem[pOp->p1];
pOut = &aMem[pOp->p2];
assert( pOut!=pIn1 );
sqlite4VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
Deephemeralize(pOut);
REGISTER_TRACE(pOp->p2, pOut);
break;
}
/* Opcode: SCopy P1 P2 * * *
**
** Make a shallow copy of register P1 into register P2.
**
** This instruction makes a shallow copy of the value. If the value
** is a string or blob, then the copy is only a pointer to the
** original and hence if the original changes so will the copy.
** Worse, if the original is deallocated, the copy becomes invalid.
** Thus the program must guarantee that the original will not change
** during the lifetime of the copy. Use OP_Copy to make a complete
** copy.
*/
case OP_SCopy: { /* in1, out2 */
pIn1 = &aMem[pOp->p1];
pOut = &aMem[pOp->p2];
assert( pOut!=pIn1 );
sqlite4VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
#ifdef SQLITE_DEBUG
if( pOut->pScopyFrom==0 ) pOut->pScopyFrom = pIn1;
#endif
REGISTER_TRACE(pOp->p2, pOut);
break;
}
/* Opcode: ResultRow P1 P2 * * *
**
** The registers P1 through P1+P2-1 contain a single row of
** results. This opcode causes the sqlite4_step() call to terminate
** with an SQLITE_ROW return code and it sets up the sqlite4_stmt
** structure to provide access to the top P1 values as the result
** row.
*/
case OP_ResultRow: {
#if 0 /* local variables moved into u.ae */
Mem *pMem;
int i;
#endif /* local variables moved into u.ae */
assert( p->nResColumn==pOp->p2 );
assert( pOp->p1>0 );
assert( pOp->p1+pOp->p2<=p->nMem+1 );
assert( p->nFkConstraint==0 );
/* If the SQLITE_CountRows flag is set in sqlite4.flags mask, then
** DML statements invoke this opcode to return the number of rows
** modified to the user. This is the only way that a VM that
** opens a statement transaction may invoke this opcode.
**
** In case this is such a statement, close any statement transaction
** opened by this VM before returning control to the user. This is to
** ensure that statement-transactions are always nested, not overlapping.
** If the open statement-transaction is not closed here, then the user
** may step another VM that opens its own statement transaction. This
** may lead to overlapping statement transactions.
**
** The statement transaction is never a top-level transaction. Hence
** the RELEASE call below can never fail.
*/
rc = sqlite4VdbeCloseStatement(p, SAVEPOINT_RELEASE);
if( NEVER(rc!=SQLITE_OK) ){
break;
}
/* Invalidate all ephemeral cursor row caches */
p->cacheCtr = (p->cacheCtr + 2)|1;
/* Make sure the results of the current row are \000 terminated
** and have an assigned type. The results are de-ephemeralized as
** a side effect.
*/
u.ae.pMem = p->pResultSet = &aMem[pOp->p1];
for(u.ae.i=0; u.ae.i<pOp->p2; u.ae.i++){
assert( memIsValid(&u.ae.pMem[u.ae.i]) );
Deephemeralize(&u.ae.pMem[u.ae.i]);
assert( (u.ae.pMem[u.ae.i].flags & MEM_Ephem)==0
|| (u.ae.pMem[u.ae.i].flags & (MEM_Str|MEM_Blob))==0 );
sqlite4VdbeMemNulTerminate(&u.ae.pMem[u.ae.i]);
sqlite4VdbeMemStoreType(&u.ae.pMem[u.ae.i]);
REGISTER_TRACE(pOp->p1+u.ae.i, &u.ae.pMem[u.ae.i]);
}
if( db->mallocFailed ) goto no_mem;
/* Return SQLITE_ROW
*/
p->pc = pc + 1;
rc = SQLITE_ROW;
goto vdbe_return;
}
/* Opcode: Concat P1 P2 P3 * *
**
** Add the text in register P1 onto the end of the text in
** register P2 and store the result in register P3.
** If either the P1 or P2 text are NULL then store NULL in P3.
**
** P3 = P2 || P1
**
** It is illegal for P1 and P3 to be the same register. Sometimes,
** if P3 is the same register as P2, the implementation is able
** to avoid a memcpy().
*/
case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
#if 0 /* local variables moved into u.af */
i64 nByte;
#endif /* local variables moved into u.af */
pIn1 = &aMem[pOp->p1];
pIn2 = &aMem[pOp->p2];
pOut = &aMem[pOp->p3];
assert( pIn1!=pOut );
if( (pIn1->flags | pIn2->flags) & MEM_Null ){
sqlite4VdbeMemSetNull(pOut);
break;
}
if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem;
Stringify(pIn1, encoding);
Stringify(pIn2, encoding);
u.af.nByte = pIn1->n + pIn2->n;
if( u.af.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
MemSetTypeFlag(pOut, MEM_Str);
if( sqlite4VdbeMemGrow(pOut, (int)u.af.nByte+2, pOut==pIn2) ){
goto no_mem;
}
if( pOut!=pIn2 ){
memcpy(pOut->z, pIn2->z, pIn2->n);
}
memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n);
pOut->z[u.af.nByte] = 0;
pOut->z[u.af.nByte+1] = 0;
pOut->flags |= MEM_Term;
pOut->n = (int)u.af.nByte;
pOut->enc = encoding;
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
/* Opcode: Add P1 P2 P3 * *
**
** 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 * *
**
**
** Multiply the value in register P1 by the value in register P2
** and store the result in register P3.
** If either input is NULL, the result is NULL.
*/
/* Opcode: Subtract P1 P2 P3 * *
**
** 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 * *
**
** 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
** register P1 is zero, then the result is NULL. If either input is
** NULL, the result is NULL.
*/
/* Opcode: Remainder P1 P2 P3 * *
**
** Compute the remainder after integer division of the value in
** register P1 by the value in register P2 and store the result in P3.
** If the value in register P2 is zero the result is NULL.
** If either operand is NULL, the result is NULL.
*/
case OP_Add: /* same as TK_PLUS, in1, in2, out3 */
case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */
case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */
case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */
case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
#if 0 /* local variables moved into u.ag */
int flags; /* Combined MEM_* flags from both inputs */
i64 iA; /* Integer value of left operand */
i64 iB; /* Integer value of right operand */
double rA; /* Real value of left operand */
double rB; /* Real value of right operand */
#endif /* local variables moved into u.ag */
pIn1 = &aMem[pOp->p1];
applyNumericAffinity(pIn1);
pIn2 = &aMem[pOp->p2];
applyNumericAffinity(pIn2);
pOut = &aMem[pOp->p3];
u.ag.flags = pIn1->flags | pIn2->flags;
if( (u.ag.flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
u.ag.iA = pIn1->u.i;
u.ag.iB = pIn2->u.i;
switch( pOp->opcode ){
case OP_Add: if( sqlite4AddInt64(&u.ag.iB,u.ag.iA) ) goto fp_math; break;
case OP_Subtract: if( sqlite4SubInt64(&u.ag.iB,u.ag.iA) ) goto fp_math; break;
case OP_Multiply: if( sqlite4MulInt64(&u.ag.iB,u.ag.iA) ) goto fp_math; break;
case OP_Divide: {
if( u.ag.iA==0 ) goto arithmetic_result_is_null;
if( u.ag.iA==-1 && u.ag.iB==SMALLEST_INT64 ) goto fp_math;
u.ag.iB /= u.ag.iA;
break;
}
default: {
if( u.ag.iA==0 ) goto arithmetic_result_is_null;
if( u.ag.iA==-1 ) u.ag.iA = 1;
u.ag.iB %= u.ag.iA;
break;
}
}
pOut->u.i = u.ag.iB;
MemSetTypeFlag(pOut, MEM_Int);
}else{
fp_math:
u.ag.rA = sqlite4VdbeRealValue(pIn1);
u.ag.rB = sqlite4VdbeRealValue(pIn2);
switch( pOp->opcode ){
case OP_Add: u.ag.rB += u.ag.rA; break;
case OP_Subtract: u.ag.rB -= u.ag.rA; break;
case OP_Multiply: u.ag.rB *= u.ag.rA; break;
case OP_Divide: {
/* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
if( u.ag.rA==(double)0 ) goto arithmetic_result_is_null;
u.ag.rB /= u.ag.rA;
break;
}
default: {
u.ag.iA = (i64)u.ag.rA;
u.ag.iB = (i64)u.ag.rB;
if( u.ag.iA==0 ) goto arithmetic_result_is_null;
if( u.ag.iA==-1 ) u.ag.iA = 1;
u.ag.rB = (double)(u.ag.iB % u.ag.iA);
break;
}
}
#ifdef SQLITE_OMIT_FLOATING_POINT
pOut->u.i = u.ag.rB;
MemSetTypeFlag(pOut, MEM_Int);
#else
if( sqlite4IsNaN(u.ag.rB) ){
goto arithmetic_result_is_null;
}
pOut->r = u.ag.rB;
MemSetTypeFlag(pOut, MEM_Real);
if( (u.ag.flags & MEM_Real)==0 ){
sqlite4VdbeIntegerAffinity(pOut);
}
#endif
}
break;
arithmetic_result_is_null:
sqlite4VdbeMemSetNull(pOut);
break;
}
/* Opcode: CollSeq * * P4
**
** P4 is a pointer to a CollSeq struct. If the next call to a user function
** or aggregate calls sqlite4GetFuncCollSeq(), this collation sequence will
** be returned. This is used by the built-in min(), max() and nullif()
** functions.
**
** The interface used by the implementation of the aforementioned functions
** to retrieve the collation sequence set by this opcode is not available
** publicly, only to user functions defined in func.c.
*/
case OP_CollSeq: {
assert( pOp->p4type==P4_COLLSEQ );
break;
}
/* Opcode: Function P1 P2 P3 P4 P5
**
** Invoke a user function (P4 is a pointer to a Function structure that
** defines the function) with P5 arguments taken from register P2 and
** successors. The result of the function is stored in register P3.
** Register P3 must not be one of the function inputs.
**
** P1 is a 32-bit bitmask indicating whether or not each argument to the
** function was determined to be constant at compile time. If the first
** 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
** sqlite4_set_auxdata() API may be safely retained until the next
** invocation of this opcode.
**
** See also: AggStep and AggFinal
*/
case OP_Function: {
#if 0 /* local variables moved into u.ah */
int i;
Mem *pArg;
sqlite4_context ctx;
sqlite4_value **apVal;
int n;
#endif /* local variables moved into u.ah */
u.ah.n = pOp->p5;
u.ah.apVal = p->apArg;
assert( u.ah.apVal || u.ah.n==0 );
assert( pOp->p3>0 && pOp->p3<=p->nMem );
pOut = &aMem[pOp->p3];
memAboutToChange(p, pOut);
assert( u.ah.n==0 || (pOp->p2>0 && pOp->p2+u.ah.n<=p->nMem+1) );
assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+u.ah.n );
u.ah.pArg = &aMem[pOp->p2];
for(u.ah.i=0; u.ah.i<u.ah.n; u.ah.i++, u.ah.pArg++){
assert( memIsValid(u.ah.pArg) );
u.ah.apVal[u.ah.i] = u.ah.pArg;
Deephemeralize(u.ah.pArg);
sqlite4VdbeMemStoreType(u.ah.pArg);
REGISTER_TRACE(pOp->p2+u.ah.i, u.ah.pArg);
}
assert( pOp->p4type==P4_FUNCDEF || pOp->p4type==P4_VDBEFUNC );
if( pOp->p4type==P4_FUNCDEF ){
u.ah.ctx.pFunc = pOp->p4.pFunc;
u.ah.ctx.pVdbeFunc = 0;
}else{
u.ah.ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.pVdbeFunc;
u.ah.ctx.pFunc = u.ah.ctx.pVdbeFunc->pFunc;
}
u.ah.ctx.s.flags = MEM_Null;
u.ah.ctx.s.db = db;
u.ah.ctx.s.xDel = 0;
u.ah.ctx.s.zMalloc = 0;
/* The output cell may already have a buffer allocated. Move
** the pointer to u.ah.ctx.s so in case the user-function can use
** the already allocated buffer instead of allocating a new one.
*/
sqlite4VdbeMemMove(&u.ah.ctx.s, pOut);
MemSetTypeFlag(&u.ah.ctx.s, MEM_Null);
u.ah.ctx.isError = 0;
if( u.ah.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
assert( pOp>aOp );
assert( pOp[-1].p4type==P4_COLLSEQ );
assert( pOp[-1].opcode==OP_CollSeq );
u.ah.ctx.pColl = pOp[-1].p4.pColl;
}
db->lastRowid = lastRowid;
(*u.ah.ctx.pFunc->xFunc)(&u.ah.ctx, u.ah.n, u.ah.apVal); /* IMP: R-24505-23230 */
lastRowid = db->lastRowid;
/* If any auxiliary data functions have been called by this user function,
** immediately call the destructor for any non-static values.
*/
if( u.ah.ctx.pVdbeFunc ){
sqlite4VdbeDeleteAuxData(u.ah.ctx.pVdbeFunc, pOp->p1);
pOp->p4.pVdbeFunc = u.ah.ctx.pVdbeFunc;
pOp->p4type = P4_VDBEFUNC;
}
if( db->mallocFailed ){
/* Even though a malloc() has failed, the implementation of the
** user function may have called an sqlite4_result_XXX() function
** to return a value. The following call releases any resources
** associated with such a value.
*/
sqlite4VdbeMemRelease(&u.ah.ctx.s);
goto no_mem;
}
/* If the function returned an error, throw an exception */
if( u.ah.ctx.isError ){
sqlite4SetString(&p->zErrMsg, db, "%s", sqlite4_value_text(&u.ah.ctx.s));
rc = u.ah.ctx.isError;
}
/* Copy the result of the function into register P3 */
sqlite4VdbeChangeEncoding(&u.ah.ctx.s, encoding);
sqlite4VdbeMemMove(pOut, &u.ah.ctx.s);
if( sqlite4VdbeMemTooBig(pOut) ){
goto too_big;
}
#if 0
/* The app-defined function has done something that as caused this
** statement to expire. (Perhaps the function called sqlite4_exec()
** with a CREATE TABLE statement.)
*/
if( p->expired ) rc = SQLITE_ABORT;
#endif
REGISTER_TRACE(pOp->p3, pOut);
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
/* Opcode: BitAnd P1 P2 P3 * *
**
** 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 * *
**
** 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 * *
**
** Shift the integer value in register P2 to the left by the
** number of bits specified by the integer in register P1.
** Store the result in register P3.
** If either input is NULL, the result is NULL.
*/
/* Opcode: ShiftRight P1 P2 P3 * *
**
** Shift the integer value in register P2 to the right by the
** number of bits specified by the integer in register P1.
** Store the result in register P3.
** If either input is NULL, the result is NULL.
*/
case OP_BitAnd: /* same as TK_BITAND, in1, in2, out3 */
case OP_BitOr: /* same as TK_BITOR, in1, in2, out3 */
case OP_ShiftLeft: /* same as TK_LSHIFT, in1, in2, out3 */
case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */
#if 0 /* local variables moved into u.ai */
i64 iA;
u64 uA;
i64 iB;
u8 op;
#endif /* local variables moved into u.ai */
pIn1 = &aMem[pOp->p1];
pIn2 = &aMem[pOp->p2];
pOut = &aMem[pOp->p3];
if( (pIn1->flags | pIn2->flags) & MEM_Null ){
sqlite4VdbeMemSetNull(pOut);
break;
}
u.ai.iA = sqlite4VdbeIntValue(pIn2);
u.ai.iB = sqlite4VdbeIntValue(pIn1);
u.ai.op = pOp->opcode;
if( u.ai.op==OP_BitAnd ){
u.ai.iA &= u.ai.iB;
}else if( u.ai.op==OP_BitOr ){
u.ai.iA |= u.ai.iB;
}else if( u.ai.iB!=0 ){
assert( u.ai.op==OP_ShiftRight || u.ai.op==OP_ShiftLeft );
/* If shifting by a negative amount, shift in the other direction */
if( u.ai.iB<0 ){
assert( OP_ShiftRight==OP_ShiftLeft+1 );
u.ai.op = 2*OP_ShiftLeft + 1 - u.ai.op;
u.ai.iB = u.ai.iB>(-64) ? -u.ai.iB : 64;
}
if( u.ai.iB>=64 ){
u.ai.iA = (u.ai.iA>=0 || u.ai.op==OP_ShiftLeft) ? 0 : -1;
}else{
memcpy(&u.ai.uA, &u.ai.iA, sizeof(u.ai.uA));
if( u.ai.op==OP_ShiftLeft ){
u.ai.uA <<= u.ai.iB;
}else{
u.ai.uA >>= u.ai.iB;
/* Sign-extend on a right shift of a negative number */
if( u.ai.iA<0 ) u.ai.uA |= ((((u64)0xffffffff)<<32)|0xffffffff) << (64-u.ai.iB);
}
memcpy(&u.ai.iA, &u.ai.uA, sizeof(u.ai.iA));
}
}
pOut->u.i = u.ai.iA;
MemSetTypeFlag(pOut, MEM_Int);
break;
}
/* Opcode: AddImm P1 P2 * * *
**
** Add the constant P2 to the value in register P1.
** The result is always an integer.
**
** To force any register to be an integer, just add 0.
*/
case OP_AddImm: { /* in1 */
pIn1 = &aMem[pOp->p1];
memAboutToChange(p, pIn1);
sqlite4VdbeMemIntegerify(pIn1);
pIn1->u.i += pOp->p2;
break;
}
/* Opcode: MustBeInt P1 P2 * * *
**
** Force the value in register P1 to be an integer. If the value
** in P1 is not an integer and cannot be converted into an integer
** without data loss, then jump immediately to P2, or if P2==0
** raise an SQLITE_MISMATCH exception.
*/
case OP_MustBeInt: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
if( (pIn1->flags & MEM_Int)==0 ){
if( pOp->p2==0 ){
rc = SQLITE_MISMATCH;
goto abort_due_to_error;
}else{
pc = pOp->p2 - 1;
}
}else{
MemSetTypeFlag(pIn1, MEM_Int);
}
break;
}
#ifndef SQLITE_OMIT_FLOATING_POINT
/* Opcode: RealAffinity P1 * * * *
**
** If register P1 holds an integer convert it to a real value.
**
** This opcode is used when extracting information from a column that
** has REAL affinity. Such column values may still be stored as
** integers, for space efficiency, but after extraction we want them
** to have only a real value.
*/
case OP_RealAffinity: { /* in1 */
pIn1 = &aMem[pOp->p1];
if( pIn1->flags & MEM_Int ){
sqlite4VdbeMemRealify(pIn1);
}
break;
}
#endif
#ifndef SQLITE_OMIT_CAST
/* Opcode: ToText P1 * * * *
**
** Force the value in register P1 to be text.
** If the value is numeric, convert it to a string using the
** equivalent of printf(). Blob values are unchanged and
** are afterwards simply interpreted as text.
**
** A NULL value is not changed by this routine. It remains NULL.
*/
case OP_ToText: { /* same as TK_TO_TEXT, in1 */
pIn1 = &aMem[pOp->p1];
memAboutToChange(p, pIn1);
if( pIn1->flags & MEM_Null ) break;
assert( MEM_Str==(MEM_Blob>>3) );
pIn1->flags |= (pIn1->flags&MEM_Blob)>>3;
applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding);
rc = ExpandBlob(pIn1);
assert( pIn1->flags & MEM_Str || db->mallocFailed );
pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero);
UPDATE_MAX_BLOBSIZE(pIn1);
break;
}
/* Opcode: ToBlob P1 * * * *
**
** Force the value in register P1 to be a BLOB.
** If the value is numeric, convert it to a string first.
** Strings are simply reinterpreted as blobs with no change
** to the underlying data.
**
** A NULL value is not changed by this routine. It remains NULL.
*/
case OP_ToBlob: { /* same as TK_TO_BLOB, in1 */
pIn1 = &aMem[pOp->p1];
if( pIn1->flags & MEM_Null ) break;
if( (pIn1->flags & MEM_Blob)==0 ){
applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding);
assert( pIn1->flags & MEM_Str || db->mallocFailed );
MemSetTypeFlag(pIn1, MEM_Blob);
}else{
pIn1->flags &= ~(MEM_TypeMask&~MEM_Blob);
}
UPDATE_MAX_BLOBSIZE(pIn1);
break;
}
/* Opcode: ToNumeric P1 * * * *
**
** Force the value in register P1 to be numeric (either an
** integer or a floating-point number.)
** If the value is text or blob, try to convert it to an using the
** equivalent of atoi() or atof() and store 0 if no such conversion
** is possible.
**
** A NULL value is not changed by this routine. It remains NULL.
*/
case OP_ToNumeric: { /* same as TK_TO_NUMERIC, in1 */
pIn1 = &aMem[pOp->p1];
sqlite4VdbeMemNumerify(pIn1);
break;
}
#endif /* SQLITE_OMIT_CAST */
/* Opcode: ToInt P1 * * * *
**
** Force the value in register P1 to be an integer. If
** The value is currently a real number, drop its fractional part.
** If the value is text or blob, try to convert it to an integer using the
** equivalent of atoi() and store 0 if no such conversion is possible.
**
** A NULL value is not changed by this routine. It remains NULL.
*/
case OP_ToInt: { /* same as TK_TO_INT, in1 */
pIn1 = &aMem[pOp->p1];
if( (pIn1->flags & MEM_Null)==0 ){
sqlite4VdbeMemIntegerify(pIn1);
}
break;
}
#if !defined(SQLITE_OMIT_CAST) && !defined(SQLITE_OMIT_FLOATING_POINT)
/* Opcode: ToReal P1 * * * *
**
** Force the value in register P1 to be a floating point number.
** If The value is currently an integer, convert it.
** If the value is text or blob, try to convert it to an integer using the
** equivalent of atoi() and store 0.0 if no such conversion is possible.
**
** A NULL value is not changed by this routine. It remains NULL.
*/
case OP_ToReal: { /* same as TK_TO_REAL, in1 */
pIn1 = &aMem[pOp->p1];
memAboutToChange(p, pIn1);
if( (pIn1->flags & MEM_Null)==0 ){
sqlite4VdbeMemRealify(pIn1);
}
break;
}
#endif /* !defined(SQLITE_OMIT_CAST) && !defined(SQLITE_OMIT_FLOATING_POINT) */
/* Opcode: Lt P1 P2 P3 P4 P5
**
** 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
** reg(P3) is NULL then 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 -
** 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.
**
** 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.
**
** If the SQLITE_STOREP2 bit of P5 is set, then do not jump. Instead,
** store a boolean result (either 0, or 1, or NULL) in register P2.
*/
/* Opcode: Ne P1 P2 P3 P4 P5
**
** This works just like the Lt opcode except that the jump is taken if
** the operands in registers P1 and P3 are not equal. See the Lt opcode for
** additional information.
**
** 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 false. If either operand is NULL then the result is true.
** If neither operand is NULL the result is the same as it would be if
** the SQLITE_NULLEQ flag were omitted from P5.
*/
/* Opcode: Eq P1 P2 P3 P4 P5
**
** This works just like the Lt opcode except that the jump is taken if
** the operands in registers P1 and P3 are equal.
** See the Lt opcode for additional information.
**
** 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.
*/
/* Opcode: Le P1 P2 P3 P4 P5
**
** 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
**
** 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
**
** 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
** register P1. See the Lt opcode for additional information.
*/
case OP_Eq: /* same as TK_EQ, jump, in1, in3 */
case OP_Ne: /* same as TK_NE, jump, in1, in3 */
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 */
#if 0 /* local variables moved into u.aj */
int res; /* 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 */
#endif /* local variables moved into u.aj */
pIn1 = &aMem[pOp->p1];
pIn3 = &aMem[pOp->p3];
u.aj.flags1 = pIn1->flags;
u.aj.flags3 = pIn3->flags;
if( (u.aj.flags1 | u.aj.flags3)&MEM_Null ){
/* One or both operands are NULL */
if( pOp->p5 & SQLITE_NULLEQ ){
/* If SQLITE_NULLEQ is set (which will only happen if the operator is
** OP_Eq or OP_Ne) then take the jump or not depending on whether
** or not both operands are null.
*/
assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
u.aj.res = (u.aj.flags1 & u.aj.flags3 & MEM_Null)==0;
}else{
/* SQLITE_NULLEQ is clear and at least one operand is NULL,
** then the result is always NULL.
** The jump is taken if the SQLITE_JUMPIFNULL bit is set.
*/
if( pOp->p5 & SQLITE_STOREP2 ){
pOut = &aMem[pOp->p2];
MemSetTypeFlag(pOut, MEM_Null);
REGISTER_TRACE(pOp->p2, pOut);
}else if( pOp->p5 & SQLITE_JUMPIFNULL ){
pc = pOp->p2-1;
}
break;
}
}else{
/* Neither operand is NULL. Do a comparison. */
u.aj.affinity = pOp->p5 & SQLITE_AFF_MASK;
if( u.aj.affinity ){
applyAffinity(pIn1, u.aj.affinity, encoding);
applyAffinity(pIn3, u.aj.affinity, encoding);
if( db->mallocFailed ) goto no_mem;
}
assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
u.aj.res = sqlite4MemCompare(pIn3, pIn1, pOp->p4.pColl);
}
switch( pOp->opcode ){
case OP_Eq: u.aj.res = u.aj.res==0; break;
case OP_Ne: u.aj.res = u.aj.res!=0; break;
case OP_Lt: u.aj.res = u.aj.res<0; break;
case OP_Le: u.aj.res = u.aj.res<=0; break;
case OP_Gt: u.aj.res = u.aj.res>0; break;
default: u.aj.res = u.aj.res>=0; break;
}
if( pOp->p5 & SQLITE_STOREP2 ){
pOut = &aMem[pOp->p2];
memAboutToChange(p, pOut);
MemSetTypeFlag(pOut, MEM_Int);
pOut->u.i = u.aj.res;
REGISTER_TRACE(pOp->p2, pOut);
}else if( u.aj.res ){
pc = pOp->p2-1;
}
/* Undo any changes made by applyAffinity() to the input registers. */
pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (u.aj.flags1&MEM_TypeMask);
pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (u.aj.flags3&MEM_TypeMask);
break;
}
/* Opcode: Permutation * * * P4 *
**
** Set the permutation used by the OP_Compare operator to be the array
** of integers in P4.
**
** The permutation is only valid until the next OP_Permutation, OP_Compare,
** OP_Halt, or OP_ResultRow. Typically the OP_Permutation should occur
** immediately prior to the OP_Compare.
*/
case OP_Permutation: {
assert( pOp->p4type==P4_INTARRAY );
assert( pOp->p4.ai );
aPermute = pOp->p4.ai;
break;
}
/* Opcode: Compare P1 P2 P3 P4 *
**
** Compare two vectors of registers in reg(P1)..reg(P1+P3-1) (call this
** vector "A") and in reg(P2)..reg(P2+P3-1) ("B"). Save the result of
** the comparison for use by the next OP_Jump instruct.
**
** P4 is a KeyInfo structure that defines collating sequences and sort
** orders for the comparison. The permutation applies to registers
** only. The KeyInfo elements are used sequentially.
**
** The comparison is a sort comparison, so NULLs compare equal,
** NULLs are less than numbers, numbers are less than strings,
** and strings are less than blobs.
*/
case OP_Compare: {
#if 0 /* local variables moved into u.ak */
int n;
int i;
int p1;
int p2;
const KeyInfo *pKeyInfo;
int idx;
CollSeq *pColl; /* Collating sequence to use on this term */
int bRev; /* True for DESCENDING sort order */
#endif /* local variables moved into u.ak */
u.ak.n = pOp->p3;
u.ak.pKeyInfo = pOp->p4.pKeyInfo;
assert( u.ak.n>0 );
assert( u.ak.pKeyInfo!=0 );
u.ak.p1 = pOp->p1;
u.ak.p2 = pOp->p2;
#if SQLITE_DEBUG
if( aPermute ){
int k, mx = 0;
for(k=0; k<u.ak.n; k++) if( aPermute[k]>mx ) mx = aPermute[k];
assert( u.ak.p1>0 && u.ak.p1+mx<=p->nMem+1 );
assert( u.ak.p2>0 && u.ak.p2+mx<=p->nMem+1 );
}else{
assert( u.ak.p1>0 && u.ak.p1+u.ak.n<=p->nMem+1 );
assert( u.ak.p2>0 && u.ak.p2+u.ak.n<=p->nMem+1 );
}
#endif /* SQLITE_DEBUG */
for(u.ak.i=0; u.ak.i<u.ak.n; u.ak.i++){
u.ak.idx = aPermute ? aPermute[u.ak.i] : u.ak.i;
assert( memIsValid(&aMem[u.ak.p1+u.ak.idx]) );
assert( memIsValid(&aMem[u.ak.p2+u.ak.idx]) );
REGISTER_TRACE(u.ak.p1+u.ak.idx, &aMem[u.ak.p1+u.ak.idx]);
REGISTER_TRACE(u.ak.p2+u.ak.idx, &aMem[u.ak.p2+u.ak.idx]);
assert( u.ak.i<u.ak.pKeyInfo->nField );
u.ak.pColl = u.ak.pKeyInfo->aColl[u.ak.i];
u.ak.bRev = u.ak.pKeyInfo->aSortOrder[u.ak.i];
iCompare = sqlite4MemCompare(&aMem[u.ak.p1+u.ak.idx], &aMem[u.ak.p2+u.ak.idx], u.ak.pColl);
if( iCompare ){
if( u.ak.bRev ) iCompare = -iCompare;
break;
}
}
aPermute = 0;
break;
}
/* Opcode: Jump P1 P2 P3 * *
**
** Jump to the instruction at address P1, P2, or P3 depending on whether
** in the most recent OP_Compare instruction the P1 vector was less than
** equal to, or greater than the P2 vector, respectively.
*/
case OP_Jump: { /* jump */
if( iCompare<0 ){
pc = pOp->p1 - 1;
}else if( iCompare==0 ){
pc = pOp->p2 - 1;
}else{
pc = pOp->p3 - 1;
}
break;
}
/* Opcode: And P1 P2 P3 * *
**
** Take the logical AND of the values in registers P1 and P2 and
** write the result into register P3.
**
** If either P1 or P2 is 0 (false) then the result is 0 even if
** the other input is NULL. A NULL and true or two NULLs give
** a NULL output.
*/
/* Opcode: Or P1 P2 P3 * *
**
** Take the logical OR of the values in register P1 and P2 and
** store the answer in register P3.
**
** If either P1 or P2 is nonzero (true) then the result is 1 (true)
** even if the other input is NULL. A NULL and false or two NULLs
** give a NULL output.
*/
case OP_And: /* same as TK_AND, in1, in2, out3 */
case OP_Or: { /* same as TK_OR, in1, in2, out3 */
#if 0 /* local variables moved into u.al */
int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
#endif /* local variables moved into u.al */
pIn1 = &aMem[pOp->p1];
if( pIn1->flags & MEM_Null ){
u.al.v1 = 2;
}else{
u.al.v1 = sqlite4VdbeIntValue(pIn1)!=0;
}
pIn2 = &aMem[pOp->p2];
if( pIn2->flags & MEM_Null ){
u.al.v2 = 2;
}else{
u.al.v2 = sqlite4VdbeIntValue(pIn2)!=0;
}
if( pOp->opcode==OP_And ){
static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 };
u.al.v1 = and_logic[u.al.v1*3+u.al.v2];
}else{
static const unsigned char or_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 };
u.al.v1 = or_logic[u.al.v1*3+u.al.v2];
}
pOut = &aMem[pOp->p3];
if( u.al.v1==2 ){
MemSetTypeFlag(pOut, MEM_Null);
}else{
pOut->u.i = u.al.v1;
MemSetTypeFlag(pOut, MEM_Int);
}
break;
}
/* Opcode: Not P1 P2 * * *
**
** Interpret the value in register P1 as a boolean value. Store the
** boolean complement in register P2. If the value in register P1 is
** NULL, then a NULL is stored in P2.
*/
case OP_Not: { /* same as TK_NOT, in1, out2 */
pIn1 = &aMem[pOp->p1];
pOut = &aMem[pOp->p2];
if( pIn1->flags & MEM_Null ){
sqlite4VdbeMemSetNull(pOut);
}else{
sqlite4VdbeMemSetInt64(pOut, !sqlite4VdbeIntValue(pIn1));
}
break;
}
/* Opcode: BitNot P1 P2 * * *
**
** Interpret the content of register P1 as an integer. Store the
** ones-complement of the P1 value into register P2. If P1 holds
** a NULL then store a NULL in P2.
*/
case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */
pIn1 = &aMem[pOp->p1];
pOut = &aMem[pOp->p2];
if( pIn1->flags & MEM_Null ){
sqlite4VdbeMemSetNull(pOut);
}else{
sqlite4VdbeMemSetInt64(pOut, ~sqlite4VdbeIntValue(pIn1));
}
break;
}
/* Opcode: Once P1 P2 * * *
**
** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise,
** set the flag and fall through to the next instruction.
**
** See also: JumpOnce
*/
case OP_Once: { /* jump */
assert( pOp->p1<p->nOnceFlag );
if( p->aOnceFlag[pOp->p1] ){
pc = pOp->p2-1;
}else{
p->aOnceFlag[pOp->p1] = 1;
}
break;
}
/* Opcode: If P1 P2 P3 * *
**
** Jump to P2 if the value in register P1 is true. The value
** is considered true if it is numeric and non-zero. If the value
** in P1 is NULL then take the jump if P3 is non-zero.
*/
/* Opcode: IfNot P1 P2 P3 * *
**
** Jump to P2 if the value in register P1 is False. The value
** is considered false if it has a numeric value of zero. If the value
** in P1 is NULL then take the jump if P3 is zero.
*/
case OP_If: /* jump, in1 */
case OP_IfNot: { /* jump, in1 */
#if 0 /* local variables moved into u.am */
int c;
#endif /* local variables moved into u.am */
pIn1 = &aMem[pOp->p1];
if( pIn1->flags & MEM_Null ){
u.am.c = pOp->p3;
}else{
#ifdef SQLITE_OMIT_FLOATING_POINT
u.am.c = sqlite4VdbeIntValue(pIn1)!=0;
#else
u.am.c = sqlite4VdbeRealValue(pIn1)!=0.0;
#endif
if( pOp->opcode==OP_IfNot ) u.am.c = !u.am.c;
}
if( u.am.c ){
pc = pOp->p2-1;
}
break;
}
/* Opcode: IsNull P1 P2 P3 * *
**
** P1 is the first in an array of P3 registers. Or, if P3 is 0, the first
** in an array of a single register. If any registers in the array are
** NULL, jump to instruction P2.
*/
case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */
#if 0 /* local variables moved into u.an */
Mem *pEnd;
#endif /* local variables moved into u.an */
pIn1 = &aMem[pOp->p1];
u.an.pEnd = &aMem[pOp->p1+pOp->p3];
do {
if( (pIn1->flags & MEM_Null)!=0 ){
pc = pOp->p2 - 1;
break;
}
}while( (++pIn1)<u.an.pEnd );
break;
}
/* Opcode: NotNull P1 P2 * * *
**
** Jump to P2 if the value in register P1 is not NULL.
*/
case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */
pIn1 = &aMem[pOp->p1];
if( (pIn1->flags & MEM_Null)==0 ){
pc = pOp->p2 - 1;
}
break;
}
/* Opcode: Column P1 P2 P3 P4 P5
**
** Interpret the data that cursor P1 points to as a structure built using
** the MakeRecord instruction. (See the MakeRecord opcode for additional
** information about the format of the data.) Extract the P2-th column
** from this record. If there are less that (P2+1)
** values in the record, extract a NULL.
**
** The value extracted is stored in register P3.
**
** If the column 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_CLEARCACHE bit is set on P5 and P1 is a pseudo-table cursor,
** then the cache of the cursor is reset prior to extracting the column.
** The first OP_Column against a pseudo-table after the value of the content
** register has changed should have this bit set.
*/
case OP_Column: {
#if 0 /* local variables moved into u.ao */
KVCursor *pKVCur; /* Cursor for current entry in the KV storage */
ValueDecoder *pCodec; /* The decoder object */
int p1; /* Index of VdbeCursor to decode */
VdbeCursor *pC; /* The VDBE cursor */
Mem *pDest; /* Where to write the results */
const KVByteArray *aData; /* The content to be decoded */
KVSize nData; /* Size of aData[] in bytes */
Mem *pDefault; /* Default value from P4 */
Mem *pReg; /* */
#endif /* local variables moved into u.ao */
u.ao.p1 = pOp->p1;
assert( u.ao.p1<p->nCursor );
assert( pOp->p3>0 && pOp->p3<=p->nMem );
u.ao.pDest = &aMem[pOp->p3];
memAboutToChange(p, u.ao.pDest);
u.ao.pC = p->apCsr[u.ao.p1];
assert( u.ao.pC!=0 );
#ifndef SQLITE_OMIT_VIRTUALTABLE
assert( u.ao.pC->pVtabCursor==0 );
#endif
u.ao.pKVCur = u.ao.pC->pKVCur;
if( u.ao.pKVCur!=0 ){
if( u.ao.pC->nullRow ){
u.ao.aData = 0;
}else{
rc = sqlite4KVCursorData(u.ao.pKVCur, 0, -1, &u.ao.aData, &u.ao.nData);
}
}else if( ALWAYS(u.ao.pC->pseudoTableReg>0) ){
u.ao.pReg = &aMem[u.ao.pC->pseudoTableReg];
assert( u.ao.pReg->flags & MEM_Blob );
assert( memIsValid(u.ao.pReg) );
u.ao.aData = (const KVByteArray*)u.ao.pReg->z;
u.ao.nData = u.ao.pReg->n;
}else{
u.ao.aData = 0;
MemSetTypeFlag(u.ao.pDest, MEM_Null);
}
if( rc==SQLITE_OK && u.ao.aData ){
/* TODO: Fix this somehow... */
int nField = u.ao.pC->nField;
if( u.ao.pC->pKeyInfo && u.ao.pC->pKeyInfo->nData ) nField = u.ao.pC->pKeyInfo->nData;
rc = sqlite4VdbeCreateDecoder(db, u.ao.aData, u.ao.nData, nField, &u.ao.pCodec);
if( rc==0 ){
u.ao.pDefault = (pOp->p4type==P4_MEM) ? pOp->p4.pMem : 0;
rc = sqlite4VdbeDecodeValue(u.ao.pCodec, pOp->p2, u.ao.pDefault, u.ao.pDest);
assert( rc==SQLITE_OK );
sqlite4VdbeDestroyDecoder(u.ao.pCodec);
}
}else{
sqlite4VdbeMemSetNull(u.ao.pDest);
}
UPDATE_MAX_BLOBSIZE(u.ao.pDest);
REGISTER_TRACE(pOp->p3, u.ao.pDest);
assert( rc<100 );
break;
}
/* Opcode: Affinity P1 P2 * P4 *
**
** Apply affinities to a range of P2 registers starting with P1.
**
** P4 is a string that is P2 characters long. The nth character of the
** string indicates the column affinity that should be used for the nth
** memory cell in the range.
*/
case OP_Affinity: {
#if 0 /* local variables moved into u.ap */
const char *zAffinity; /* The affinity to be applied */
Mem *pEnd;
#endif /* local variables moved into u.ap */
u.ap.zAffinity = pOp->p4.z;
assert( u.ap.zAffinity!=0 );
assert( sqlite4Strlen30(u.ap.zAffinity)>=pOp->p2 );
u.ap.pEnd = &aMem[pOp->p2+pOp->p1];
for(pIn1=&aMem[pOp->p1]; pIn1<u.ap.pEnd; pIn1++){
assert( memIsValid(pIn1) );
memAboutToChange(p, pIn1);
applyAffinity(pIn1, *(u.ap.zAffinity++), encoding);
REGISTER_TRACE(pIn1-aMem, pIn1);
}
break;
}
/* Opcode: MakeIdxKey P1 P2 P3 P4 P5
**
** P1 is an open cursor. P2 is the first register in a contiguous array
** of N registers containing values to encode into a database key. Normally,
** N is equal to the number of columns indexed by P1, plus the number of
** trailing primary key columns (if any).
**
** Or, if P4 is a non-zero integer, then it contains the value for N.
**
** This instruction encodes the N values into a database key and writes
** the result to register P3. No affinity transformations are applied to
** the input values before they are encoded.
**
** If P5 is non-zero, then a sequence number (unique within the cursor)
** is appended to the record. The sole purpose of this is to ensure that
** the key blob is unique within the cursors table.
*/
case OP_MakeIdxKey: {
#if 0 /* local variables moved into u.aq */
VdbeCursor *pC;
KeyInfo *pKeyInfo;
Mem *pData0; /* First in array of input registers */
u8 *aRec; /* The constructed database key */
int nRec; /* Size of aRec[] in bytes */
int nField; /* Number of fields in encoded record */
u8 aSeq[10]; /* Encoded sequence number */
int nSeq; /* Size of sequence number in bytes */
u64 iSeq; /* Sequence number, if any */
#endif /* local variables moved into u.aq */
u.aq.pC = p->apCsr[pOp->p1];
u.aq.pKeyInfo = u.aq.pC->pKeyInfo;
u.aq.pData0 = &aMem[pOp->p2];
pOut = &aMem[pOp->p3];
u.aq.aRec = 0;
/* If pOp->p5 is non-zero, encode the sequence number blob to append to
** the end of the key. Variable u.aq.nSeq is set to the number of bytes in
** the encoded key.
*/
u.aq.nSeq = 0;
if( pOp->p5 ){
u.aq.iSeq = u.aq.pC->seqCount++;
do {
u.aq.nSeq++;
u.aq.aSeq[sizeof(u.aq.aSeq)-u.aq.nSeq] = (u8)(u.aq.iSeq & 0x007F);
u.aq.iSeq = u.aq.iSeq >> 7;
}while( u.aq.iSeq );
u.aq.aSeq[sizeof(u.aq.aSeq)-u.aq.nSeq] |= 0x80;
}
memAboutToChange(p, pOut);
u.aq.nField = u.aq.pKeyInfo->nField;
if( pOp->p4type==P4_INT32 && pOp->p4.i ){
u.aq.nField = pOp->p4.i;
assert( u.aq.nField<=u.aq.pKeyInfo->nField );
}
rc = sqlite4VdbeEncodeKey(
db, u.aq.pData0, u.aq.nField, u.aq.pC->iRoot, u.aq.pKeyInfo, &u.aq.aRec, &u.aq.nRec, u.aq.nSeq
);
if( rc ){
sqlite4DbFree(db, u.aq.aRec);
}else{
if( u.aq.nSeq ){
memcpy(&u.aq.aRec[u.aq.nRec], &u.aq.aSeq[sizeof(u.aq.aSeq)-u.aq.nSeq], u.aq.nSeq);
}
rc = sqlite4VdbeMemSetStr(pOut, (char *)u.aq.aRec, u.aq.nRec+u.aq.nSeq, 0, SQLITE_DYNAMIC);
REGISTER_TRACE(pOp->p3, pOut);
UPDATE_MAX_BLOBSIZE(pOut);
}
break;
}
/* Opcode: MakeKey P1 P2 * * *
**
** This must be followed immediately by a MakeRecord opcode. This
** opcode performs the subsequent MakeRecord and also generates
** a key for the cursor P1 and stores that key in register P2.
*/
/* Opcode: MakeRecord P1 P2 P3 P4 *
**
** This opcode uses the array of P2 registers starting at P1 as inputs.
**
** P4 may be a string that is P2 characters long, or it may be NULL. The nth
** character of the string indicates the column affinity that should be used
** for the nth field of the index key. The mapping from character to affinity
** is given by the SQLITE_AFF_ macros defined in sqliteInt.h. If P4 is NULL
** then all index fields have the affinity NONE.
**
** This opcode expands any zero-blobs within the input array. Then if
** P4 is not NULL it applies the affinities that it specifies to the input
** array elements. Finally, if P3 is not 0, it encodes the input array
** into a data record and stores the result in register P3. The OP_Column
** opcode can be used to decode the record.
**
** Specifying P3==0 is only useful if the previous opcode is an OP_MakeKey.
*/
case OP_MakeKey:
case OP_MakeRecord: {
#if 0 /* local variables moved into u.ar */
Mem *pData0; /* First field to be combined into the record */
Mem *pLast; /* Last field of the record */
Mem *pMem; /* For looping over inputs */
int nField; /* Number of fields in the record */
char *zAffinity; /* The affinity string for the record */
VdbeCursor *pC; /* Cursor to generate key for */
Mem *pKeyOut; /* Where to store the generated key */
int keyReg; /* Register into which to write the key */
u8 *aRec; /* The constructed key or value */
int nRec; /* Size of aRec[] in bytes */
#endif /* local variables moved into u.ar */
if( pOp->opcode==OP_MakeKey ){
u.ar.pC = p->apCsr[pOp->p1];
u.ar.keyReg = pOp->p2;
u.ar.pKeyOut = &aMem[u.ar.keyReg];
memAboutToChange(p, u.ar.pKeyOut);
assert( u.ar.pC!=0 );
assert( u.ar.pC->pKeyInfo!=0 );
pc++;
pOp++;
assert( pOp->opcode==OP_MakeRecord );
#ifdef SQLITE_DEBUG
if( p->trace ) sqlite4VdbePrintOp(p->trace, pc, pOp);
#endif
}else{
u.ar.pC = 0;
}
u.ar.nField = pOp->p1;
u.ar.zAffinity = pOp->p4.z;
assert( u.ar.nField>0 && pOp->p2>0 && pOp->p2+u.ar.nField<=p->nMem+1 );
u.ar.pData0 = &aMem[u.ar.nField];
u.ar.nField = pOp->p2;
u.ar.pLast = &u.ar.pData0[u.ar.nField-1];
/* Loop through the input elements. Apply affinity to each one and
** expand all zero-blobs.
*/
for(u.ar.pMem=u.ar.pData0; u.ar.pMem<=u.ar.pLast; u.ar.pMem++){
assert( memIsValid(u.ar.pMem) );
if( u.ar.zAffinity ){
applyAffinity(u.ar.pMem, *(u.ar.zAffinity++), encoding);
}
if( u.ar.pMem->flags&MEM_Zero ){
ExpandBlob(u.ar.pMem);
}
}
/* Compute the key (if this is a MakeKey opcode) */
if( u.ar.pC ){
u.ar.aRec = 0;
rc = sqlite4VdbeEncodeKey(db,
u.ar.pData0, u.ar.pC->pKeyInfo->nField, u.ar.pC->iRoot, u.ar.pC->pKeyInfo, &u.ar.aRec, &u.ar.nRec, 0
);
if( rc ){
sqlite4DbFree(db, u.ar.aRec);
}else{
rc = sqlite4VdbeMemSetStr(u.ar.pKeyOut, (char *)u.ar.aRec, u.ar.nRec, 0, SQLITE_DYNAMIC);
REGISTER_TRACE(u.ar.keyReg, u.ar.pKeyOut);
UPDATE_MAX_BLOBSIZE(u.ar.pKeyOut);
}
}
/* If P3 is not 0, compute the data rescord */
if( rc==SQLITE_OK && pOp->p3 ){
assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 );
pOut = &aMem[pOp->p3];
memAboutToChange(p, pOut);
u.ar.aRec = 0;
rc = sqlite4VdbeEncodeData(db, u.ar.pData0, u.ar.nField, &u.ar.aRec, &u.ar.nRec);
if( rc ){
sqlite4DbFree(db, u.ar.aRec);
}else{
rc = sqlite4VdbeMemSetStr(pOut, (char *)u.ar.aRec, u.ar.nRec, 0, SQLITE_DYNAMIC);
REGISTER_TRACE(pOp->p3, pOut);
UPDATE_MAX_BLOBSIZE(pOut);
}
}
break;
}
/* Opcode: Count P1 P2 * * *
**
** Store the number of entries (an integer value) in the table or index
** opened by cursor P1 in register P2
*/
case OP_Count: { /* out2-prerelease */
#if 0 /* local variables moved into u.as */
i64 nEntry;
VdbeCursor *pC;
#endif /* local variables moved into u.as */
u.as.pC = p->apCsr[pOp->p1];
rc = sqlite4VdbeSeekEnd(u.as.pC, +1);
u.as.nEntry = 0;
while( rc!=SQLITE_NOTFOUND ){
u.as.nEntry++;
rc = sqlite4VdbeNext(u.as.pC);
}
sqlite4VdbeMemSetInt64(pOut, u.as.nEntry);
break;
}
/* Opcode: Savepoint P1 * * P4 *
**
** This opcode is used to implement the SQL BEGIN, COMMIT, ROLLBACK,
** SAVEPOINT, RELEASE and ROLLBACK TO commands. As follows:
**
** sql command p1 p4
** -------------------------------------
** BEGIN 0 0
** COMMIT 1 0
** ROLLBACK 2 0
** SAVEPOINT 0 <name of savepoint to open>
** RELEASE 1 <name of savepoint to release>
** ROLLBACK TO 2 <name of savepoint to rollback>
*/
case OP_Savepoint: {
#if 0 /* local variables moved into u.at */
int iSave;
Savepoint *pSave; /* Savepoint object operated upon */
const char *zSave; /* Name of savepoint (or NULL for trans.) */
int nSave; /* Size of zSave in bytes */
int iOp; /* SAVEPOINT_XXX operation */
const char *zErr; /* Static error message */
#endif /* local variables moved into u.at */
u.at.zErr = 0;
u.at.zSave = pOp->p4.z;
u.at.nSave = u.at.zSave ? sqlite4Strlen30(u.at.zSave) : 0;
u.at.iOp = pOp->p1;
assert( pOp->p1==SAVEPOINT_BEGIN
|| pOp->p1==SAVEPOINT_RELEASE
|| pOp->p1==SAVEPOINT_ROLLBACK
);
if( u.at.iOp==SAVEPOINT_BEGIN ){
if( u.at.zSave==0 && db->pSavepoint ){
/* If u.at.zSave==0 this is a "BEGIN" command. Return an error if there is
** already an open transaction in this case. */
u.at.zErr = "cannot start a transaction within a transaction";
}else{
u.at.pSave = (Savepoint *)sqlite4DbMallocZero(db, u.at.nSave+1+sizeof(Savepoint));
if( u.at.pSave==0 ) break;
if( u.at.zSave ){
u.at.pSave->zName = (char *)&u.at.pSave[1];
memcpy(u.at.pSave->zName, u.at.zSave, u.at.nSave);
}
u.at.pSave->pNext = db->pSavepoint;
u.at.pSave->nDeferredCons = db->nDeferredCons;
db->pSavepoint = u.at.pSave;
db->nSavepoint++;
}
}
else{
/* Determine which of the zero or more nested savepoints (if any) to
** commit or rollback to. This block sets variable u.at.pSave to point
** to the Savepoint object and u.at.iSave to the kvstore layer transaction
** number. For example, to commit or rollback the top level transaction
** u.at.iSave==2. */
u.at.iSave = db->nSavepoint+1;
for(u.at.pSave=db->pSavepoint; u.at.pSave; u.at.pSave=u.at.pSave->pNext){
if( u.at.zSave ){
if( u.at.pSave->zName && 0==sqlite4StrICmp(u.at.zSave, u.at.pSave->zName) ) break;
}else{
if( u.at.pSave->pNext==0 ) break;
}
u.at.iSave--;
}
if( u.at.pSave==0 ){
if( u.at.zSave ){
sqlite4SetString(&p->zErrMsg, db, "no such savepoint: %s", u.at.zSave);
rc = SQLITE_ERROR;
}else if( u.at.iOp==SAVEPOINT_RELEASE ){
u.at.zErr = "cannot commit - no transaction is active";
}else{
u.at.zErr = "cannot rollback - no transaction is active";
}
}else{
/* If this is an attempt to commit the top level transaction, check
** that there are no outstanding deferred foreign key violations. If
** there are, return an SQLITE_CONSTRAINT error. Do not release any
** savepoints in this case. */
if( u.at.iOp==SAVEPOINT_RELEASE && u.at.iSave==2 ){
rc = sqlite4VdbeCheckFk(p, 1);
if( rc!=SQLITE_OK ) break;
}
if( u.at.iOp==SAVEPOINT_RELEASE ){
rc = sqlite4VdbeCommit(db, u.at.iSave-1);
}else{
rc = sqlite4VdbeRollback(db, u.at.iSave-(u.at.zSave==0));
}
}
}
if( u.at.zErr ){
sqlite4SetString(&p->zErrMsg, db, "%s", u.at.zErr);
rc = SQLITE_ERROR;
}
break;
}
/* Opcode: Transaction P1 P2 * * *
**
** Begin a transaction.
**
** P1 is the index of the database file on which the transaction is
** started. Index 0 is the main database file and index 1 is the
** file used for temporary tables. Indices of 2 or more are used for
** attached databases.
**
** If P2 is non-zero, then a write-transaction is started. If P2 is zero
** then a read-transaction is started.
**
** If a write-transaction is started and the Vdbe.needSavepoint flag is
** true (this flag is set if the Vdbe may modify more than one row and may
** throw an ABORT exception), a statement transaction may also be opened.
** More specifically, a statement transaction is opened iff the database
** connection is currently not in autocommit mode, or if there are other
** active statements. A statement transaction allows the affects of this
** VDBE to be rolled back after an error without having to roll back the
** entire transaction. If no error is encountered, the statement transaction
** will automatically commit when the VDBE halts.
*/
case OP_Transaction: {
#if 0 /* local variables moved into u.au */
Db *pDb;
KVStore *pKV;
int bStmt; /* True to open statement transaction */
int iLevel; /* Savepoint level to open */
#endif /* local variables moved into u.au */
assert( pOp->p1>=0 && pOp->p1<db->nDb );
u.au.pDb = &db->aDb[pOp->p1];
u.au.pKV = u.au.pDb->pKV;
if( u.au.pKV ){
if( pOp->p2==0 ){
/* Read transaction needed. Start if we are not already in one. */
if( u.au.pKV->iTransLevel==0 ){
rc = sqlite4KVStoreBegin(u.au.pKV, 1);
}
}else{
/* A write transaction is needed */
u.au.iLevel = db->nSavepoint + 1;
if( u.au.iLevel<2 ) u.au.iLevel = 2;
u.au.bStmt = db->pSavepoint && (p->needSavepoint || db->activeVdbeCnt>1);
if( u.au.pKV->iTransLevel<u.au.iLevel ){
rc = sqlite4KVStoreBegin(u.au.pKV, u.au.iLevel);
}
if( rc==SQLITE_OK && u.au.bStmt ){
rc = sqlite4KVStoreBegin(u.au.pKV, u.au.pKV->iTransLevel+1);
if( rc==SQLITE_OK ){
p->stmtTransMask |= ((yDbMask)1)<<pOp->p1;
}
p->nStmtDefCons = db->nDeferredCons;
}
}
}
break;
}
/* Opcode: SetCookie P1 P2 P3 * *
**
** Write the content of register P3 (interpreted as an integer)
** 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.
**
** A transaction must be started before executing this opcode.
*/
case OP_SetCookie: { /* in3 */
#if 0 /* local variables moved into u.av */
Db *pDb;
u32 v;
#endif /* local variables moved into u.av */
assert( pOp->p1>=0 && pOp->p1<db->nDb );
u.av.pDb = &db->aDb[pOp->p1];
pIn3 = &aMem[pOp->p3];
sqlite4VdbeMemIntegerify(pIn3);
u.av.v = (u32)pIn3->u.i;
rc = sqlite4KVStorePutMeta(db, u.av.pDb->pKV, 0, 1, &u.av.v);
u.av.pDb->pSchema->schema_cookie = (int)pIn3->u.i;
db->flags |= SQLITE_InternChanges;
if( pOp->p1==1 ){
/* Invalidate all prepared statements whenever the TEMP database
** schema is changed. Ticket #1644 */
sqlite4ExpirePreparedStatements(db);
p->expired = 0;
}
break;
}
/* Opcode: VerifyCookie P1 P2 P3 * *
**
** Check the value of global database parameter number 0 (the
** schema version) and make sure it is equal to P2 and that the
** generation counter on the local schema parse equals P3.
**
** P1 is the database number which is 0 for the main database file
** and 1 for the file holding temporary tables and some higher number
** for auxiliary databases.
**
** The cookie changes its value whenever the database schema changes.
** This operation is used to detect when that the cookie has changed
** and that the current process needs to reread the schema.
**
** Either a transaction needs to have been started or an OP_Open needs
** to be executed (to establish a read lock) before this opcode is
** invoked.
*/
case OP_VerifyCookie: {
unsigned int iMeta;
int iGen;
KVStore *pKV;
assert( pOp->p1>=0 && pOp->p1<db->nDb );
pKV = db->aDb[pOp->p1].pKV;
if( pKV ){
rc = sqlite4KVStoreGetMeta(pKV, 0, 1, &iMeta);
if( rc ) break;
iGen = db->aDb[pOp->p1].pSchema->iGeneration;
}else{
iGen = iMeta = 0;
}
if( iMeta!=pOp->p2 || iGen!=pOp->p3 ){
sqlite4DbFree(db, p->zErrMsg);
p->zErrMsg = sqlite4DbStrDup(db, "database schema has changed");
/* If the schema-cookie from the database file matches the cookie
** stored with the in-memory representation of the schema, do
** not reload the schema from the database file.
**
** If virtual-tables are in use, this is not just an optimization.
** Often, v-tables store their data in other SQLite tables, which
** are queried from within xNext() and other v-table methods using
** prepared queries. If such a query is out-of-date, we do not want to
** discard the database schema, as the user code implementing the
** v-table would have to be ready for the sqlite4_vtab structure itself
** to be invalidated whenever sqlite4_step() is called from within
** a v-table method.
*/
if( db->aDb[pOp->p1].pSchema->schema_cookie!=iMeta ){
sqlite4ResetInternalSchema(db, pOp->p1);
}
p->expired = 1;
rc = SQLITE_SCHEMA;
}
break;
}
/* Opcode: OpenRead P1 P2 P3 P4 P5
**
** Open a read-only cursor for the database table whose root page is
** P2 in a database file. The database file is determined by P3.
** P3==0 means the main database, P3==1 means the database used for
** temporary tables, and P3>1 means used the corresponding attached
** database. Give the new cursor an identifier of P1. The P1
** values need not be contiguous but all P1 values should be small integers.
** It is an error for P1 to be negative.
**
** If P5!=0 then use the content of register P2 as the root page, not
** the value of P2 itself.
**
** There will be a read lock on the database whenever there is an
** open cursor. If the database was unlocked prior to this instruction
** then a read lock is acquired as part of this instruction. A read
** lock allows other processes to read the database but prohibits
** any other process from modifying the database. The read lock is
** released when all cursors are closed. If this instruction attempts
** to get a read lock but fails, the script terminates with an
** SQLITE_BUSY error code.
**
** The P4 value may be either an integer (P4_INT32) or a pointer to
** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo
** structure, then said structure defines the content and collating
** sequence of the index being opened. Otherwise, if P4 is an integer
** value, it is set to the number of columns in the table.
**
** See also OpenWrite.
*/
/* Opcode: OpenWrite P1 P2 P3 P4 P5
**
** Open a read/write cursor named P1 on the table or index whose root
** page is P2. Or if P5!=0 use the content of register P2 to find the
** root page.
**
** The P4 value may be either an integer (P4_INT32) or a pointer to
** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo
** structure, then said structure defines the content and collating
** sequence of the index being opened. Otherwise, if P4 is an integer
** value, it is set to the number of columns in the table, or to the
** largest index of any column of the table that is actually used.
**
** This instruction works just like OpenRead except that it opens the cursor
** in read/write mode. For a given table, there can be one or more read-only
** cursors or a single read/write cursor but not both.
**
** See also OpenRead.
*/
case OP_OpenRead:
case OP_OpenWrite: {
#if 0 /* local variables moved into u.aw */
int nField;
KeyInfo *pKeyInfo;
int p2;
int iDb;
KVStore *pX;
VdbeCursor *pCur;
Db *pDb;
#endif /* local variables moved into u.aw */
if( p->expired ){
rc = SQLITE_ABORT;
break;
}
u.aw.nField = 0;
u.aw.pKeyInfo = 0;
u.aw.p2 = pOp->p2;
u.aw.iDb = pOp->p3;
assert( u.aw.iDb>=0 && u.aw.iDb<db->nDb );
u.aw.pDb = &db->aDb[u.aw.iDb];
u.aw.pX = u.aw.pDb->pKV;
assert( u.aw.pX!=0 );
if( pOp->p5 ){
assert( u.aw.p2>0 );
assert( u.aw.p2<=p->nMem );
pIn2 = &aMem[u.aw.p2];
assert( memIsValid(pIn2) );
assert( (pIn2->flags & MEM_Int)!=0 );
sqlite4VdbeMemIntegerify(pIn2);
u.aw.p2 = (int)pIn2->u.i;
/* The u.aw.p2 value always comes from a prior OP_NewIdxid opcode and
** that opcode will always set the u.aw.p2 value to 2 or more or else fail.
** If there were a failure, the prepared statement would have halted
** before reaching this instruction. */
if( NEVER(u.aw.p2<2) ) {
rc = SQLITE_CORRUPT_BKPT;
goto abort_due_to_error;
}
}
if( pOp->p4type==P4_KEYINFO ){
u.aw.pKeyInfo = pOp->p4.pKeyInfo;
u.aw.pKeyInfo->enc = ENC(p->db);
u.aw.nField = u.aw.pKeyInfo->nField+1;
}else if( pOp->p4type==P4_INT32 ){
u.aw.nField = pOp->p4.i;
}
assert( pOp->p1>=0 );
u.aw.pCur = allocateCursor(p, pOp->p1, u.aw.nField, u.aw.iDb, 1);
if( u.aw.pCur==0 ) goto no_mem;
u.aw.pCur->nullRow = 1;
u.aw.pCur->isOrdered = 1;
u.aw.pCur->iRoot = u.aw.p2;
rc = sqlite4KVStoreOpenCursor(u.aw.pX, &u.aw.pCur->pKVCur);
u.aw.pCur->pKeyInfo = u.aw.pKeyInfo;
/* Set the VdbeCursor.isTable and isIndex variables. Previous versions of
** SQLite used to check if the root-page flags were sane at this point
** and report database corruption if they were not, but this check has
** since moved into the btree layer. */
u.aw.pCur->isTable = pOp->p4type!=P4_KEYINFO;
u.aw.pCur->isIndex = !u.aw.pCur->isTable;
break;
}
/* Opcode: OpenEphemeral P1 P2 * P4 P5
**
** Open a new cursor P1 to a transient table.
** The cursor is always opened read/write even if
** the main database is read-only. The ephemeral
** table is deleted automatically when the cursor is closed.
**
** P2 is the number of columns in the ephemeral table.
** The cursor points to a BTree table if P4==0 and to a BTree index
** if P4 is not 0. If P4 is not NULL, it points to a KeyInfo structure
** that defines the format of keys in the index.
**
** This opcode was once called OpenTemp. But that created
** confusion because the term "temp table", might refer either
** to a TEMP table at the SQL level, or to a table opened by
** this opcode. Then this opcode was call OpenVirtual. But
** that created confusion with the whole virtual-table idea.
**
** The P5 parameter can be a mask of the BTREE_* flags defined
** in btree.h. These flags control aspects of the operation of
** the btree. The BTREE_OMIT_JOURNAL and BTREE_SINGLE flags are
** added automatically.
*/
/* Opcode: OpenAutoindex P1 P2 * P4 *
**
** This opcode works the same as OP_OpenEphemeral. It has a
** different name to distinguish its use. Tables created using
** by this opcode will be used for automatically created transient
** indices in joins.
*/
case OP_OpenAutoindex:
case OP_OpenEphemeral: {
#if 0 /* local variables moved into u.ax */
VdbeCursor *pCx;
#endif /* local variables moved into u.ax */
assert( pOp->p1>=0 );
u.ax.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
if( u.ax.pCx==0 ) goto no_mem;
u.ax.pCx->nullRow = 1;
rc = sqlite4KVStoreOpen(db, "ephm", 0, &u.ax.pCx->pTmpKV,
SQLITE_KVOPEN_TEMPORARY | SQLITE_KVOPEN_NO_TRANSACTIONS
);
if( rc==SQLITE_OK ) rc = sqlite4KVStoreOpenCursor(u.ax.pCx->pTmpKV, &u.ax.pCx->pKVCur);
if( rc==SQLITE_OK ) rc = sqlite4KVStoreBegin(u.ax.pCx->pTmpKV, 2);
u.ax.pCx->pKeyInfo = pOp->p4.pKeyInfo;
if( u.ax.pCx->pKeyInfo ) u.ax.pCx->pKeyInfo->enc = ENC(p->db);
u.ax.pCx->isIndex = !u.ax.pCx->isTable;
u.ax.pCx->isOrdered = 1;
break;
}
/* Opcode: OpenSorter P1 P2 * P4 *
**
** This opcode works like OP_OpenEphemeral except that it opens
** a transient index that is specifically designed to sort large
** tables using an external merge-sort algorithm.
*/
case OP_SorterOpen: {
/* VdbeCursor *pCx; */
pOp->opcode = OP_OpenEphemeral;
pc--;
break;
}
/* Opcode: OpenPseudo P1 P2 P3 * *
**
** Open a new cursor that points to a fake table that contains a single
** row of data. The content of that one row is the content of memory
** register P2. In other words, cursor P1 becomes an alias for the
** MEM_Blob content contained in register P2.
**
** A pseudo-table created by this opcode is used to hold a single
** row output from the sorter so that the row can be decomposed into
** individual columns using the OP_Column opcode. The OP_Column opcode
** is the only cursor opcode that works with a pseudo-table.
**
** P3 is the number of fields in the records that will be stored by
** the pseudo-table.
*/
case OP_OpenPseudo: {
#if 0 /* local variables moved into u.ay */
VdbeCursor *pCx;
#endif /* local variables moved into u.ay */
assert( pOp->p1>=0 );
u.ay.pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0);
if( u.ay.pCx==0 ) goto no_mem;
u.ay.pCx->nullRow = 1;
u.ay.pCx->pseudoTableReg = pOp->p2;
u.ay.pCx->isTable = 1;
u.ay.pCx->isIndex = 0;
break;
}
/* Opcode: Close P1 * * * *
**
** Close a cursor previously opened as P1. If P1 is not
** currently open, this instruction is a no-op.
*/
case OP_Close: {
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
sqlite4VdbeFreeCursor(p, p->apCsr[pOp->p1]);
p->apCsr[pOp->p1] = 0;
break;
}
/* Opcode: SeekPk P1 * P3 * *
**
** P1 must be a cursor open on a PRIMARY KEY index. P3 is a cursor open
** on an auxiliary index on the same table. P3 must be pointing to a valid
** index entry.
**
** This opcode seeks cursor P1 so that it points to the PK index entry
** that corresponds to the same table row as the current entry that
** cursor P3 points to. The entry must exist. If it does not, this opcode
** throws an SQLITE_CORRUPT exception.
*/
case OP_SeekPk: {
#if 0 /* local variables moved into u.az */
VdbeCursor *pPk; /* Cursor P1 */
VdbeCursor *pIdx; /* Cursor P3 */
#endif /* local variables moved into u.az */
KVByteArray const *aKey; /* Key data from cursor u.az.pIdx */
KVSize nKey; /* Size of aKey[] in bytes */
int nShort; /* Size of aKey[] without PK fields */
KVByteArray *aPkKey;
KVSize nPkKey;
u.az.pPk = p->apCsr[pOp->p1];
u.az.pIdx = p->apCsr[pOp->p3];
assert( u.az.pIdx->pKeyInfo->nPK>0 );
assert( u.az.pPk->pKeyInfo->nPK==0 );
rc = sqlite4KVCursorKey(u.az.pIdx->pKVCur, &aKey, &nKey);
if( rc==SQLITE_OK ){
nShort = sqlite4VdbeShortKey(aKey, nKey,
u.az.pIdx->pKeyInfo->nField - u.az.pIdx->pKeyInfo->nPK
);
nPkKey = sqlite4VarintLen(u.az.pPk->iRoot) + nKey - nShort;
aPkKey = sqlite4DbMallocRaw(db, nPkKey);
if( aPkKey ){
putVarint32(aPkKey, u.az.pPk->iRoot);
memcpy(&aPkKey[nPkKey - (nKey-nShort)], &aKey[nShort], nKey-nShort);
rc = sqlite4KVCursorSeek(u.az.pPk->pKVCur, aPkKey, nPkKey, 0);
if( rc==SQLITE_NOTFOUND ){
rc = SQLITE_CORRUPT_BKPT;
}
u.az.pPk->nullRow = 0;
sqlite4DbFree(db, aPkKey);
}
}
break;
}
/* Opcode: SeekGe P1 P2 P3 P4 *
**
** If cursor P1 refers to an SQL table (B-Tree that uses integer keys),
** use the value in register P3 as the key. If cursor P1 refers
** to an SQL index, then P3 is the first in an array of P4 registers
** that are used as an unpacked index key.
**
** Reposition cursor P1 so that it points to the smallest entry that
** 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.
**
** See also: Found, NotFound, Distinct, SeekLt, SeekGt, SeekLe
*/
/* Opcode: SeekGt P1 P2 P3 P4 *
**
** If cursor P1 refers to an SQL table (B-Tree that uses integer keys),
** use the value in register P3 as a key. If cursor P1 refers
** to an SQL index, then P3 is the first in an array of P4 registers
** that are used as an unpacked index key.
**
** Reposition cursor P1 so that it points to the smallest entry that
** is greater than the key value. If there are no records greater than
** the key and P2 is not zero, then jump to P2.
**
** See also: Found, NotFound, Distinct, SeekLt, SeekGe, SeekLe
*/
/* Opcode: SeekLt P1 P2 P3 P4 *
**
** If cursor P1 refers to an SQL table (B-Tree that uses integer keys),
** use the value in register P3 as a key. If cursor P1 refers
** to an SQL index, then P3 is the first in an array of P4 registers
** that are used as an unpacked index key.
**
** Reposition cursor P1 so that it points to the largest entry that
** is less than the key value. If there are no records less than
** the key and P2 is not zero, then jump to P2.
**
** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLe
*/
/* Opcode: SeekLe P1 P2 P3 P4 *
**
** If cursor P1 refers to an SQL table (B-Tree that uses integer keys),
** use the value in register P3 as a key. If cursor P1 refers
** to an SQL index, then P3 is the first in an array of P4 registers
** that are used as an unpacked index key.
**
** Reposition cursor P1 so that it points to the largest entry that
** is less than or equal to the key value. If there are no records
** less than or equal to the key and P2 is not zero, then jump to P2.
**
** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLt
*/
case OP_SeekLt: /* jump, in3 */
case OP_SeekLe: /* jump, in3 */
case OP_SeekGe: /* jump, in3 */
case OP_SeekGt: { /* jump, in3 */
#if 0 /* local variables moved into u.ba */
int op; /* Copy of pOp->opcode (the op-code) */
VdbeCursor *pC; /* Cursor P1 */
int nField; /* Number of values to encode into key */
KVByteArray *aProbe; /* Buffer containing encoded key */
KVSize nProbe; /* Size of aProbe[] in bytes */
int dir; /* KV search dir (+ve or -ve) */
const KVByteArray *aKey; /* Pointer to final cursor key */
KVSize nKey; /* Size of aKey[] in bytes */
#endif /* local variables moved into u.ba */
u.ba.pC = p->apCsr[pOp->p1];
u.ba.pC->nullRow = 0;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( pOp->p2!=0 );
assert( u.ba.pC!=0 );
assert( u.ba.pC->pseudoTableReg==0 );
assert( OP_SeekLe == OP_SeekLt+1 );
assert( OP_SeekGe == OP_SeekLt+2 );
assert( OP_SeekGt == OP_SeekLt+3 );
assert( u.ba.pC->isOrdered );
/* Encode a database key consisting of the contents of the P4 registers
** starting at register P3. Have the vdbecodec module allocate an extra
** free byte at the end of the database key (see below). */
u.ba.op = pOp->opcode;
u.ba.nField = pOp->p4.i;
pIn3 = &aMem[pOp->p3];
rc = sqlite4VdbeEncodeKey(
db, pIn3, u.ba.nField, u.ba.pC->iRoot, u.ba.pC->pKeyInfo, &u.ba.aProbe, &u.ba.nProbe, 1
);
/* Opcode search-u.ba.dir increment-key
** --------------------------------------
** SeekLt -1 no
** SeekLe -1 yes
** SeekGe +1 no
** SeekGt +1 yes
*/
u.ba.dir = +1;
if( u.ba.op==OP_SeekLe || u.ba.op==OP_SeekLt ) u.ba.dir = -1;
if( u.ba.op==OP_SeekLe || u.ba.op==OP_SeekGt ) u.ba.aProbe[u.ba.nProbe++] = 0xFF;
if( rc==SQLITE_OK ){
rc = sqlite4KVCursorSeek(u.ba.pC->pKVCur, u.ba.aProbe, u.ba.nProbe, u.ba.dir);
}
if( rc==SQLITE_OK ){
if( u.ba.op==OP_SeekLt ){
rc = sqlite4KVCursorPrev(u.ba.pC->pKVCur);
}else if( u.ba.op==OP_SeekGt ){
rc = sqlite4KVCursorNext(u.ba.pC->pKVCur);
}
}
/* Check that the KV cursor currently points to an entry belonging
** to index u.ba.pC->iRoot (and not an entry that is part of some other
** index). */
if( rc==SQLITE_OK || rc==SQLITE_INEXACT ){
rc = sqlite4KVCursorKey(u.ba.pC->pKVCur, &u.ba.aKey, &u.ba.nKey);
if( rc==SQLITE_OK && memcmp(u.ba.aKey, u.ba.aProbe, sqlite4VarintLen(u.ba.pC->iRoot)) ){
rc = SQLITE_NOTFOUND;
}
}
/* Free the key allocated above. If no error has occurred but the cursor
** does not currently point to a valid entry, jump to instruction P2. */
sqlite4DbFree(db, u.ba.aProbe);
if( rc==SQLITE_NOTFOUND ){
rc = SQLITE_OK;
pc = pOp->p2 - 1;
}
break;
}
/* Opcode: Seek P1 P2 * * *
**
** P1 is an open table cursor and P2 is a rowid integer. Arrange
** for P1 to move so that it points to the rowid given by P2.
*/
case OP_Seek: { /* in2 */
#if 0 /* local variables moved into u.bb */
VdbeCursor *pC;
KVCursor *pKVCur;
KVByteArray *aKey;
KVSize nKey;
#endif /* local variables moved into u.bb */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
u.bb.pC = p->apCsr[pOp->p1];
assert( u.bb.pC!=0 );
assert( u.bb.pC->isTable );
u.bb.pKVCur = u.bb.pC->pKVCur;
rc = sqlite4VdbeEncodeKey(db, aMem+pOp->p2, 1, u.bb.pC->iRoot, 0,
&u.bb.aKey, &u.bb.nKey, 0);
if( rc==SQLITE_OK ){
rc = sqlite4KVCursorSeek(u.bb.pKVCur, u.bb.aKey, u.bb.nKey, 0);
if( rc==SQLITE_NOTFOUND ) rc = SQLITE_CORRUPT_BKPT;
}
sqlite4DbFree(db, u.bb.aKey);
break;
}
/* Opcode: Found P1 P2 P3 P4 *
**
** If P4==0 then register P3 holds a blob constructed by MakeKey. If
** P4>0 then register P3 is the first of P4 registers that should be
** combined to generate a key.
**
** Cursor P1 is open on an index. If the record identified by P3 and P4
** is a prefix of any entry in P1 then a jump is made to P2 and
** P1 is left pointing at the matching entry.
*/
/* Opcode: NotFound P1 P2 P3 P4 *
**
** If P4==0 then register P3 holds a blob constructed by MakeKey. If
** P4>0 then register P3 is the first of P4 registers that should be
** combined to generate key.
**
** Cursor P1 is on an index. If the record identified by P3 and P4
** is not the prefix of any entry in P1 then a jump is made to P2. If P1
** does contain an entry whose prefix matches the P3/P4 record then control
** falls through to the next instruction and P1 is left pointing at the
** matching entry.
**
** See also: Found, NotExists, IsUnique
*/
/* Opcode: NotExists P1 P2 P3 * *
**
** Use the content of register P3 as an integer key. If a record
** with that key does not exist in table of P1, then jump to P2.
** If the record does exist, then fall through. The cursor is left
** pointing to the record if it exists.
**
** The difference between this operation and NotFound is that this
** operation assumes the key is an integer and that P1 is a table whereas
** NotFound assumes key is a blob constructed from MakeRecord and
** P1 is an index.
**
** See also: Found, NotFound, IsUnique
*/
case OP_NotExists: { /* jump, in3 */
pOp->p4.i = 1;
pOp->p4type = P4_INT32;
/* Fall through into OP_NotFound */
}
case OP_NotFound: /* jump, in3 */
case OP_Found: { /* jump, in3 */
#if 0 /* local variables moved into u.bc */
int alreadyExists;
VdbeCursor *pC;
KVByteArray *pFree;
KVByteArray *pProbe;
KVSize nProbe;
const KVByteArray *pKey;
KVSize nKey;
#endif /* local variables moved into u.bc */
#ifdef SQLITE_TEST
sqlite4_found_count++;
#endif
u.bc.alreadyExists = 0;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( pOp->p4type==P4_INT32 );
u.bc.pC = p->apCsr[pOp->p1];
assert( u.bc.pC!=0 );
pIn3 = &aMem[pOp->p3];
assert( u.bc.pC->pKVCur!=0 );
assert( u.bc.pC->isTable==0 || pOp->opcode==OP_NotExists );
if( pOp->p4.i>0 ){
rc = sqlite4VdbeEncodeKey(db, pIn3, pOp->p4.i, u.bc.pC->iRoot,
u.bc.pC->pKeyInfo, &u.bc.pProbe, &u.bc.nProbe, 0);
u.bc.pFree = u.bc.pProbe;
}else{
u.bc.pProbe = (KVByteArray*)pIn3->z;
u.bc.nProbe = pIn3->n;
u.bc.pFree = 0;
}
if( rc==SQLITE_OK ){
rc = sqlite4KVCursorSeek(u.bc.pC->pKVCur, u.bc.pProbe, u.bc.nProbe, +1);
if( rc==SQLITE_INEXACT || rc==SQLITE_OK ){
rc = sqlite4KVCursorKey(u.bc.pC->pKVCur, &u.bc.pKey, &u.bc.nKey);
if( rc==SQLITE_OK && u.bc.nKey>=u.bc.nProbe && memcmp(u.bc.pKey, u.bc.pProbe, u.bc.nProbe)==0 ){
u.bc.alreadyExists = 1;
u.bc.pC->nullRow = 0;
}
}else if( rc==SQLITE_NOTFOUND ){
rc = SQLITE_OK;
}
}
sqlite4DbFree(db, u.bc.pFree);
if( pOp->opcode==OP_Found ){
if( u.bc.alreadyExists ) pc = pOp->p2 - 1;
}else{
if( !u.bc.alreadyExists ) pc = pOp->p2 - 1;
}
break;
}
/* Opcode: IsUnique P1 P2 P3 P4 *
**
** Cursor P1 is open on an index that enforces a UNIQUE constraint.
** Register P3 contains an encoded key suitable to be inserted into the
** index. If the key can be inserted into the index without violating
** a UNIQUE constraint, jump to instruction P2. Otherwise, fall through
** to the next instruction.
**
** If P4 is a non-zero integer and the jump is not taken, then it is
** a register that currently contains a blob. At the start of the blob
** is a varint that contains the index number for the PRIMARY KEY index
** of the table. The contents of P4 are overwritten with an index key
** composed of the varint from the start of the initial blob content
** and the PRIMARY KEY values from the index entry causing the UNIQUE
** constraint to fail.
*/
case OP_IsUnique: { /* jump, in3 */
#if 0 /* local variables moved into u.bd */
VdbeCursor *pC;
Mem *pProbe;
Mem *pOut;
int iOut;
int nShort;
int dir;
u64 dummy;
#endif /* local variables moved into u.bd */
KVByteArray const *aKey; /* Key read from cursor */
KVSize nKey; /* Size of aKey in bytes */
assert( pOp->p4type==P4_INT32 );
u.bd.pProbe = &aMem[pOp->p3];
u.bd.pC = p->apCsr[pOp->p1];
u.bd.pOut = (pOp->p4.i==0 ? 0 : &aMem[pOp->p4.i]);
assert( u.bd.pOut==0 || (u.bd.pOut->flags & MEM_Blob) );
u.bd.nShort = sqlite4VdbeShortKey((u8 *)u.bd.pProbe->z, u.bd.pProbe->n,
u.bd.pC->pKeyInfo->nField - u.bd.pC->pKeyInfo->nPK
);
assert( u.bd.nShort<=u.bd.pProbe->n );
assert( (u.bd.nShort==u.bd.pProbe->n)==(u.bd.pC->pKeyInfo->nPK==0) );
u.bd.dir = (u.bd.pC->pKeyInfo->nPK==0 ? 0 : 1);
rc = sqlite4KVCursorSeek(u.bd.pC->pKVCur, (u8 *)u.bd.pProbe->z, u.bd.nShort, u.bd.dir);
if( rc==SQLITE_OK && u.bd.pOut ){
sqlite4VdbeMemCopy(u.bd.pOut, u.bd.pProbe);
}else if( rc==SQLITE_NOTFOUND ){
rc = SQLITE_OK;
pc = pOp->p2-1;
}else if( rc==SQLITE_INEXACT ){
assert( u.bd.nShort<u.bd.pProbe->n );
rc = sqlite4KVCursorKey(u.bd.pC->pKVCur, &aKey, &nKey);
if( rc==SQLITE_OK ){
if( nKey<u.bd.nShort || memcmp(u.bd.pProbe->z, aKey, u.bd.nShort) ){
pc = pOp->p2-1;
}else if( u.bd.pOut ){
u.bd.iOut = sqlite4GetVarint64((u8 *)u.bd.pOut->z, u.bd.pOut->n, &u.bd.dummy);
rc = sqlite4VdbeMemGrow(u.bd.pOut, u.bd.iOut+(nKey - u.bd.nShort), 1);
if( rc==SQLITE_OK ){
memcpy(&u.bd.pOut->z[u.bd.iOut], &aKey[u.bd.nShort], (nKey - u.bd.nShort));
u.bd.pOut->n = u.bd.iOut + (nKey - u.bd.nShort);
}
}
}
}
break;
}
/* Opcode: Sequence P1 P2 * * *
**
** Find the next available sequence number for cursor P1.
** Write the sequence number into register P2.
** The sequence number on the cursor is incremented after this
** instruction.
*/
case OP_Sequence: { /* out2-prerelease */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( p->apCsr[pOp->p1]!=0 );
pOut->u.i = p->apCsr[pOp->p1]->seqCount++;
break;
}
/* Opcode: NewRowid P1 P2 * * *
**
** Get a new integer record number (a.k.a "rowid") used as the key to a table.
** The record number is not previously used as a key in the database
** table that cursor P1 points to. The new record number is written
** to register P2.
*/
case OP_NewRowid: { /* out2-prerelease */
#if 0 /* local variables moved into u.be */
i64 v; /* The new rowid */
VdbeCursor *pC; /* Cursor of table to get the new rowid */
const KVByteArray *aKey; /* Key of an existing row */
KVSize nKey; /* Size of the existing row key */
int n; /* Number of bytes decoded */
#endif /* local variables moved into u.be */
u.be.v = 0;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
u.be.pC = p->apCsr[pOp->p1];
assert( u.be.pC!=0 );
/* Some compilers complain about constants of the form 0x7fffffffffffffff.
** Others complain about 0x7ffffffffffffffffLL. The following macro seems
** to provide the constant while making all compilers happy.
*/
# define MAX_ROWID (i64)( (((u64)0x7fffffff)<<32) | (u64)0xffffffff )
/* The next rowid or record number (different terms for the same
** thing) is obtained in a two-step algorithm.
**
** First we attempt to find the largest existing rowid and add one
** to that. But if the largest existing rowid is already the maximum
** positive integer, we have to fall through to the second
** probabilistic algorithm
**
** The second algorithm is to select a rowid at random and see if
** it already exists in the table. If it does not exist, we have
** succeeded. If the random rowid does exist, we select a new one
** and try again, up to 100 times.
*/
rc = sqlite4VdbeSeekEnd(u.be.pC, -2);
if( rc==SQLITE_NOTFOUND ){
u.be.v = 0;
rc = SQLITE_OK;
}else if( rc==SQLITE_OK ){
rc = sqlite4KVCursorKey(u.be.pC->pKVCur, &u.be.aKey, &u.be.nKey);
if( rc==SQLITE_OK ){
u.be.n = sqlite4GetVarint64((u8 *)u.be.aKey, u.be.nKey, (u64 *)&u.be.v);
if( u.be.n==0 ) rc = SQLITE_CORRUPT_BKPT;
if( u.be.v!=u.be.pC->iRoot ) rc = SQLITE_CORRUPT_BKPT;
}
if( rc==SQLITE_OK ){
u.be.n = sqlite4VdbeDecodeIntKey(&u.be.aKey[u.be.n], u.be.nKey-u.be.n, &u.be.v);
if( u.be.n==0 ) rc = SQLITE_CORRUPT_BKPT;
}
}else{
break;
}
pOut->flags = MEM_Int;
pOut->u.i = u.be.v+1;
break;
}
/* Opcode: NewIdxid P1 P2 * * *
**
** This opcode is used to allocated new integer index numbers. P1 must
** be an integer value when this opcode is invoked. Before the opcode
** concludes, P1 is set to a value 1 greater than the larger of:
**
** * its current value, or
** * the largest index number still visible in the database using the
** LEFAST query mode used by OP_NewRowid in database P2.
*/
case OP_NewIdxid: { /* in1 */
#if 0 /* local variables moved into u.bf */
u64 iMax;
KVStore *pKV;
KVCursor *pCsr;
int iDb;
#endif /* local variables moved into u.bf */
u.bf.pKV = db->aDb[pOp->p2].pKV;
pIn1 = &aMem[pOp->p1];
u.bf.iMax = 0;
assert( pIn1->flags & MEM_Int );
rc = sqlite4KVStoreOpenCursor(u.bf.pKV, &u.bf.pCsr);
if( rc==SQLITE_OK ){
const u8 aKey[] = { 0xFF, 0xFF };
rc = sqlite4KVCursorSeek(u.bf.pCsr, aKey, sizeof(aKey), -2);
if( rc==SQLITE_OK || rc==SQLITE_INEXACT ){
const KVByteArray *pKey;
KVSize nKey;
rc = sqlite4KVCursorKey(u.bf.pCsr, &pKey, &nKey);
if( rc==SQLITE_OK ){
sqlite4GetVarint64((const unsigned char *)pKey, nKey, &u.bf.iMax);
}
}else if( rc==SQLITE_NOTFOUND ){
rc = SQLITE_OK;
}
sqlite4KVCursorClose(u.bf.pCsr);
}
if( pIn1->u.i>=(i64)u.bf.iMax ){
pIn1->u.i++;
}else{
pIn1->u.i = u.bf.iMax+1;
}
break;
}
/* Opcode: Insert P1 P2 P3 P4 P5
**
** Write an entry into the table of cursor P1. A new entry is
** created if it doesn't already exist or the data for an existing
** entry is overwritten. The data is the value MEM_Blob stored in register
** number P2. The key is stored in register P3. The key must
** be a MEM_Int.
**
** If the OPFLAG_NCHANGE flag of P5 is set, then the row change count is
** incremented (otherwise not). If the OPFLAG_LASTROWID flag of P5 is set,
** then rowid is stored for subsequent return by the
** sqlite4_last_insert_rowid() function (otherwise it is unmodified).
**
** If the OPFLAG_USESEEKRESULT flag of P5 is set and if the result of
** the last seek operation (OP_NotExists) was a success, then this
** operation will not attempt to find the appropriate row before doing
** the insert but will instead overwrite the row that the cursor is
** currently pointing to. Presumably, the prior OP_NotExists opcode
** has already positioned the cursor correctly. This is an optimization
** that boosts performance by avoiding redundant seeks.
**
** 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
** is part of an INSERT operation. The difference is only important to
** the update hook.
**
** Parameter P4 may point to a string containing the table-name, or
** may be NULL. If it is not NULL, then the update-hook
** (sqlite4.xUpdateCallback) is invoked 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
** and register P2 becomes ephemeral. If the cursor is changed, the
** value of register P2 will then change. Make sure this does not
** cause any problems.)
**
** This instruction only works on tables. The equivalent instruction
** for indices is OP_IdxInsert.
*/
/* Opcode: InsertInt P1 P2 P3 P4 P5
**
** This works exactly like OP_Insert except that the key is the
** integer value P3, not the value of the integer stored in register P3.
*/
case OP_Insert:
case OP_InsertInt: {
#if 0 /* local variables moved into u.bg */
Mem *pData; /* MEM cell holding data for the record to be inserted */
Mem *pKey; /* MEM cell holding key for the record */
i64 iKey; /* The integer ROWID or key for the record to be inserted */
VdbeCursor *pC; /* Cursor to table into which insert is written */
const char *zDb; /* database name - used by the update hook */
const char *zTbl; /* Table name - used by the opdate hook */
int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */
int n;
KVByteArray aKey[24];
#endif /* local variables moved into u.bg */
u.bg.pData = &aMem[pOp->p2];
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( memIsValid(u.bg.pData) );
u.bg.pC = p->apCsr[pOp->p1];
assert( u.bg.pC!=0 );
REGISTER_TRACE(pOp->p2, u.bg.pData);
if( pOp->opcode==OP_Insert ){
u.bg.pKey = &aMem[pOp->p3];
assert( u.bg.pKey->flags & MEM_Int );
assert( memIsValid(u.bg.pKey) );
REGISTER_TRACE(pOp->p3, u.bg.pKey);
u.bg.iKey = u.bg.pKey->u.i;
}else{
/* assert( pOp->opcode==OP_InsertInt ); */
u.bg.iKey = pOp->p3;
}
if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = u.bg.iKey;
if( u.bg.pData->flags & MEM_Null ){
u.bg.pData->z = 0;
u.bg.pData->n = 0;
}else{
assert( u.bg.pData->flags & (MEM_Blob|MEM_Str) );
}
u.bg.n = sqlite4PutVarint64(u.bg.aKey, u.bg.pC->iRoot);
u.bg.n += sqlite4VdbeEncodeIntKey(&u.bg.aKey[u.bg.n], u.bg.iKey);
rc = sqlite4KVStoreReplace(u.bg.pC->pKVCur->pStore, u.bg.aKey, u.bg.n,
(const KVByteArray*)u.bg.pData->z, u.bg.pData->n);
break;
}
/* Opcode: Delete P1 P2 * * *
**
** Delete the record at which the P1 cursor is currently pointing.
**
** 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. Hence it is OK to delete
** a record from within an Next loop.
**
** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is
** incremented (otherwise not).
**
** P1 must not be pseudo-table. It has to be a real table.
*/
case OP_Delete: {
#if 0 /* local variables moved into u.bh */
VdbeCursor *pC;
#endif /* local variables moved into u.bh */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
u.bh.pC = p->apCsr[pOp->p1];
assert( u.bh.pC!=0 );
rc = sqlite4KVCursorDelete(u.bh.pC->pKVCur);
if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
break;
}
/* Opcode: ResetCount * * * * *
**
** The value of the change counter is copied to the database handle
** change counter (returned by subsequent calls to sqlite4_changes()).
** Then the VMs internal change counter resets to 0.
** This is used by trigger programs.
*/
case OP_ResetCount: {
sqlite4VdbeSetChanges(db, p->nChange);
p->nChange = 0;
break;
}
/* Opcode: GrpCompare P1 P2 P3
**
** P1 is a cursor used to sort records. Its keys consist of the fields being
** sorted on encoded as an ordinary database key, followed by a sequence
** number encoded as defined by the comments surrounding OP_MakeIdxKey.
** Register P3 either contains NULL, or such a key truncated so as to
** remove the sequence number.
**
** This opcode compares the current key of P1, less the sequence number,
** with the contents of register P3. If they are identical, jump to
** instruction P2. Otherwise, replace the contents of P3 with the current
** key of P1 (minus the sequence number) and fall through to the next
** instruction.
*/
case OP_GrpCompare: {
#if 0 /* local variables moved into u.bi */
VdbeCursor *pC; /* Cursor P1 */
#endif /* local variables moved into u.bi */
KVByteArray const *aKey; /* Key from cursor P1 */
KVSize nKey; /* Size of aKey[] in bytes */
u.bi.pC = p->apCsr[pOp->p1];
rc = sqlite4KVCursorKey(u.bi.pC->pKVCur, &aKey, &nKey);
if( rc==SQLITE_OK ){
for(nKey--; (aKey[nKey] & 0x80)==0; nKey--);
}
pIn3 = &aMem[pOp->p3];
if( (pIn3->flags & MEM_Blob)
&& pIn3->n==nKey && 0==memcmp(pIn3->z, aKey, nKey)
){
pc = pOp->p2-1;
}else{
sqlite4VdbeMemSetStr(pIn3, (const char*)aKey, nKey, 0, SQLITE_TRANSIENT);
}
break;
};
/* Opcode: SorterData P1 P2 * * *
**
** Write into register P2 the current sorter data for sorter cursor P1.
*/
case OP_SorterData: {
#if 0 /* local variables moved into u.bj */
VdbeCursor *pC;
#endif /* local variables moved into u.bj */
pOut = &aMem[pOp->p2];
u.bj.pC = p->apCsr[pOp->p1];
assert( u.bj.pC!=0 );
pOp->opcode = OP_RowData;
pc--;
break;
}
/* Opcode: RowData P1 P2 * * *
**
** Write into register P2 the complete row data for cursor P1.
** 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 the P1 cursor must be pointing to a valid row (not a NULL row)
** of a real table, not a pseudo-table.
*/
/* Opcode: RowKey P1 P2 * * *
**
** Write into register P2 the complete row key for cursor P1.
** There is no interpretation of the data.
** The key is copied onto the P3 register exactly as
** it is found in the database file.
**
** If the P1 cursor must be pointing to a valid row (not a NULL row)
** of a real table, not a pseudo-table.
*/
case OP_RowKey:
case OP_RowData: {
#if 0 /* local variables moved into u.bk */
VdbeCursor *pC;
KVCursor *pCrsr;
const KVByteArray *pData;
KVSize nData;
#endif /* local variables moved into u.bk */
pOut = &aMem[pOp->p2];
memAboutToChange(p, pOut);
/* Note that RowKey and RowData are really exactly the same instruction */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
u.bk.pC = p->apCsr[pOp->p1];
assert( u.bk.pC!=0 );
assert( u.bk.pC->nullRow==0 );
assert( u.bk.pC->pseudoTableReg==0 );
assert( u.bk.pC->pKVCur!=0 );
u.bk.pCrsr = u.bk.pC->pKVCur;
if( pOp->opcode==OP_RowKey ){
rc = sqlite4KVCursorKey(u.bk.pCrsr, &u.bk.pData, &u.bk.nData);
}else{
rc = sqlite4KVCursorData(u.bk.pCrsr, 0, -1, &u.bk.pData, &u.bk.nData);
}
if( rc==SQLITE_OK && u.bk.nData>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
sqlite4VdbeMemSetStr(pOut, (const char*)u.bk.pData, u.bk.nData, 0, SQLITE_TRANSIENT);
pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
/* Opcode: Rowid P1 P2 * * *
**
** Store in register P2 an integer which is the key of the table entry that
** P1 is currently point to.
**
** P1 can be either an ordinary table or a virtual table. There used to
** be a separate OP_VRowid opcode for use with virtual tables, but this
** one opcode now works for both table types.
*/
case OP_Rowid: { /* out2-prerelease */
#if 0 /* local variables moved into u.bl */
VdbeCursor *pC;
i64 v;
sqlite4_vtab *pVtab;
const sqlite4_module *pModule;
const KVByteArray *aKey;
KVSize nKey;
int n;
#endif /* local variables moved into u.bl */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
u.bl.pC = p->apCsr[pOp->p1];
assert( u.bl.pC!=0 );
assert( u.bl.pC->pseudoTableReg==0 );
if( u.bl.pC->nullRow ){
pOut->flags = MEM_Null;
break;
#ifndef SQLITE_OMIT_VIRTUALTABLE
}else if( u.bl.pC->pVtabCursor ){
u.bl.pVtab = u.bl.pC->pVtabCursor->pVtab;
u.bl.pModule = u.bl.pVtab->pModule;
assert( u.bl.pModule->xRowid );
rc = u.bl.pModule->xRowid(u.bl.pC->pVtabCursor, &u.bl.v);
importVtabErrMsg(p, u.bl.pVtab);
#endif /* SQLITE_OMIT_VIRTUALTABLE */
}else{
rc = sqlite4KVCursorKey(u.bl.pC->pKVCur, &u.bl.aKey, &u.bl.nKey);
if( rc==SQLITE_OK ){
u.bl.n = sqlite4GetVarint64(u.bl.aKey, u.bl.nKey, (sqlite4_uint64*)&u.bl.v);
u.bl.n = sqlite4VdbeDecodeIntKey(&u.bl.aKey[u.bl.n], u.bl.nKey-u.bl.n, &u.bl.v);
if( u.bl.n==0 ) rc = SQLITE_CORRUPT;
}
}
pOut->u.i = u.bl.v;
break;
}
/* Opcode: NullRow P1 * * * *
**
** Move the cursor P1 to a null row. Any OP_Column operations
** that occur while the cursor is on the null row will always
** write a NULL.
*/
case OP_NullRow: {
#if 0 /* local variables moved into u.bm */
VdbeCursor *pC;
#endif /* local variables moved into u.bm */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
u.bm.pC = p->apCsr[pOp->p1];
assert( u.bm.pC!=0 );
u.bm.pC->nullRow = 1;
u.bm.pC->rowidIsValid = 0;
break;
}
/* Opcode: Last P1 P2 * * *
**
** The next use of the Rowid or Column or Next instruction for P1
** will refer to the last entry in the database table or index.
** If the table or index is empty and P2>0, then jump immediately to P2.
** If P2 is 0 or if the table or index is not empty, fall through
** to the following instruction.
*/
case OP_Last: { /* jump */
#if 0 /* local variables moved into u.bn */
VdbeCursor *pC;
#endif /* local variables moved into u.bn */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
u.bn.pC = p->apCsr[pOp->p1];
assert( u.bn.pC!=0 );
rc = sqlite4VdbeSeekEnd(u.bn.pC, -1);
if( rc==SQLITE_NOTFOUND ){
rc = SQLITE_OK;
if( pOp->p2 ) pc = pOp->p2 - 1;
}else{
u.bn.pC->nullRow = 0;
}
break;
}
/* Opcode: Sort P1 P2 * * *
**
** This opcode does exactly the same thing as OP_Rewind except that
** it increments an undocumented global variable used for testing.
**
** Sorting is accomplished by writing records into a sorting index,
** then rewinding that index and playing it back from beginning to
** end. We use the OP_Sort opcode instead of OP_Rewind to do the
** rewinding so that the global variable will be incremented and
** regression tests can determine whether or not the optimizer is
** correctly optimizing out sorts.
*/
case OP_SorterSort: /* jump */
pOp->opcode = OP_Sort;
case OP_Sort: { /* jump */
#ifdef SQLITE_TEST
sqlite4_sort_count++;
sqlite4_search_count--;
#endif
p->aCounter[SQLITE_STMTSTATUS_SORT-1]++;
/* Fall through into OP_Rewind */
}
/* Opcode: Rewind P1 P2 * * *
**
** The next use of the Rowid or Column or Next instruction for P1
** will refer to the first entry in the database table or index.
** If the table or index is empty and P2>0, then jump immediately to P2.
** If P2 is 0 or if the table or index is not empty, fall through
** to the following instruction.
*/
case OP_Rewind: { /* jump */
#if 0 /* local variables moved into u.bo */
VdbeCursor *pC;
int doJump;
#endif /* local variables moved into u.bo */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
u.bo.pC = p->apCsr[pOp->p1];
assert( u.bo.pC!=0 );
u.bo.doJump = 1;
rc = sqlite4VdbeSeekEnd(u.bo.pC, +1);
if( rc==SQLITE_NOTFOUND ){
rc = SQLITE_OK;
u.bo.doJump = 1;
}else{
u.bo.doJump = 0;
}
u.bo.pC->nullRow = (u8)u.bo.doJump;
assert( pOp->p2>0 && pOp->p2<p->nOp );
if( u.bo.doJump ){
pc = pOp->p2 - 1;
}
break;
}
/* Opcode: Next P1 P2 * P4 P5
**
** Advance cursor P1 so that it points to the next key/data pair in its
** table or index. If there are no more key/value pairs then fall through
** to the following instruction. But if the cursor advance was successful,
** jump immediately to P2.
**
** The P1 cursor must be for a real table, not a pseudo-table.
**
** P4 is always of type P4_ADVANCE. The function pointer points to
** sqlite4VdbeNext().
**
** If P5 is positive and the jump is taken, then event counter
** number P5-1 in the prepared statement is incremented.
**
** See also: Prev
*/
/* Opcode: Prev P1 P2 * * P5
**
** Back up cursor P1 so that it points to the previous key/data pair in its
** table or index. If there is no previous key/value pairs then fall through
** to the following instruction. But if the cursor backup was successful,
** jump immediately to P2.
**
** The P1 cursor must be for a real table, not a pseudo-table.
**
** P4 is always of type P4_ADVANCE. The function pointer points to
** sqlite4VdbePrevious().
**
** If P5 is positive and the jump is taken, then event counter
** number P5-1 in the prepared statement is incremented.
*/
case OP_SorterNext: /* jump */
pOp->opcode = OP_Next;
case OP_Prev: /* jump */
case OP_Next: { /* jump */
#if 0 /* local variables moved into u.bp */
VdbeCursor *pC;
int res;
#endif /* local variables moved into u.bp */
CHECK_FOR_INTERRUPT;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( pOp->p5<=ArraySize(p->aCounter) );
u.bp.pC = p->apCsr[pOp->p1];
if( u.bp.pC==0 ){
break; /* See ticket #2273 */
}
u.bp.res = 1;
assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite4VdbeNext );
assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite4VdbePrevious );
rc = pOp->p4.xAdvance(u.bp.pC);
if( rc==SQLITE_OK ){
pc = pOp->p2 - 1;
if( pOp->p5 ) p->aCounter[pOp->p5-1]++;
u.bp.pC->nullRow = 0;
#ifdef SQLITE_TEST
sqlite4_search_count++;
#endif
}else if( rc==SQLITE_NOTFOUND ){
u.bp.pC->nullRow = 1;
rc = SQLITE_OK;
}
u.bp.pC->rowidIsValid = 0;
break;
}
/* Opcode: SorterInsert P1 P2 P3
*/
/* Opcode: IdxInsert P1 P2 P3 * P5
**
** Register P3 holds the key and register P2 holds the data for an
** index entry. Write this record into the index specified by the
** cursor P1.
**
** If the OPFLAG_NCHANGE flag of P5 is set, then the row change count is
** incremented (otherwise not).
*/
case OP_SorterInsert:
case OP_IdxInsert: {
#if 0 /* local variables moved into u.bq */
VdbeCursor *pC;
Mem *pKey;
Mem *pData;
#endif /* local variables moved into u.bq */
u.bq.pC = p->apCsr[pOp->p1];
u.bq.pKey = &aMem[pOp->p3];
u.bq.pData = pOp->p2 ? &aMem[pOp->p2] : 0;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( u.bq.pC && u.bq.pC->pKVCur && u.bq.pC->pKVCur->pStore );
assert( u.bq.pKey->flags & MEM_Blob );
assert( u.bq.pData==0 || (u.bq.pData->flags & MEM_Blob) );
if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
rc = sqlite4KVStoreReplace(
u.bq.pC->pKVCur->pStore,
(u8 *)u.bq.pKey->z, u.bq.pKey->n,
(u8 *)(u.bq.pData ? u.bq.pData->z : 0), (u.bq.pData ? u.bq.pData->n : 0)
);
break;
}
/* Opcode: IdxDelete P1 * P3 * *
**
** P1 is a cursor open on a database index. P3 contains a key suitable for
** the index. Delete P3 from P1 if it is present.
*/
case OP_IdxDelete: {
#if 0 /* local variables moved into u.br */
VdbeCursor *pC;
Mem *pKey;
#endif /* local variables moved into u.br */
u.br.pC = p->apCsr[pOp->p1];
u.br.pKey = &aMem[pOp->p3];
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( u.br.pC && u.br.pC->pKVCur && u.br.pC->pKVCur->pStore );
assert( u.br.pKey->flags & MEM_Blob );
rc = sqlite4KVCursorSeek(u.br.pC->pKVCur, (u8 *)u.br.pKey->z, u.br.pKey->n, 0);
if( rc==SQLITE_OK ){
rc = sqlite4KVCursorDelete(u.br.pC->pKVCur);
}else if( rc==SQLITE_NOTFOUND ){
rc = SQLITE_OK;
}
break;
}
/* Opcode: IdxRowid P1 P2 * * *
**
** Write into register P2 an integer which is the last entry in the record at
** the end of the index key pointed to by cursor P1. This integer should be
** the rowid of the table entry to which this index entry points.
**
** See also: Rowid, MakeRecord.
*/
case OP_IdxRowid: { /* out2-prerelease */
assert( 0 );
break;
}
/* Opcode: IdxGE P1 P2 P3
**
** P1 is an open cursor. P3 contains a database key formatted by MakeKey.
** This opcode compares the current key that index P1 points to with
** the key in register P3.
**
** If the index key is greater than or equal to the key in register P3,
** then jump to instruction P2. Otherwise, fall through to the next VM
** instruction. The comparison is done using memcmp(), except that if P3
** is a prefix of the P1 key they are considered equal.
*/
case OP_IdxLT: /* jump */
case OP_IdxLE: /* jump */
case OP_IdxGE: /* jump */
case OP_IdxGT: { /* jump */
#if 0 /* local variables moved into u.bs */
VdbeCursor *pC; /* Cursor P1 */
#endif /* local variables moved into u.bs */
KVByteArray const *aKey; /* Key from cursor P1 */
KVSize nKey; /* Size of aKey[] in bytes */
Mem *pCmp; /* Memory cell to compare index key with */
int nCmp; /* Bytes of data to compare using memcmp() */
int res; /* Result of memcmp() call */
int bJump; /* True to take the jump */
pCmp = &aMem[pOp->p3];
assert( pCmp->flags & MEM_Blob );
u.bs.pC = p->apCsr[pOp->p1];
rc = sqlite4KVCursorKey(u.bs.pC->pKVCur, &aKey, &nKey);
if( rc==SQLITE_OK ){
nCmp = pCmp->n;
if( nCmp>nKey ) nCmp = nKey;
res = memcmp(aKey, pCmp->z, nCmp);
switch( pOp->opcode ){
case OP_IdxLT: bJump = (res < 0); break;
case OP_IdxLE: bJump = (res <= 0); break;
case OP_IdxGE: bJump = (res >= 0); break;
case OP_IdxGT: bJump = (res > 0); break;
}
if( bJump ) pc = pOp->p2 - 1;
}
break;
}
/* Opcode: Clear P1 P2 * * P5
**
** Delete all contents of the database table or index whose table number
** in the database file is given by P1.
**
** The table being clear is in the main database file if P2==0. If
** P2==1 then the table to be clear is in the auxiliary database file
** that is used to store tables create using CREATE TEMPORARY TABLE.
**
** If the OPFLAG_NCHANGE flag of P5 is set, then the row change count is
** incremented (otherwise not).
**
** See also: Destroy
*/
case OP_Clear: {
#if 0 /* local variables moved into u.bt */
KVCursor *pCur;
#endif /* local variables moved into u.bt */
KVByteArray const *aKey;
KVSize nKey;
KVSize nProbe;
KVByteArray aProbe[12];
nProbe = sqlite4PutVarint64(aProbe, pOp->p1);
rc = sqlite4KVStoreOpenCursor(db->aDb[pOp->p2].pKV, &u.bt.pCur);
if( rc ) break;
rc = sqlite4KVCursorSeek(u.bt.pCur, aProbe, nProbe, +1);
while( rc!=SQLITE_NOTFOUND ){
if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
rc = sqlite4KVCursorKey(u.bt.pCur, &aKey, &nKey);
if( rc!=SQLITE_OK ) break;
if( nKey<nProbe ){ rc = SQLITE_CORRUPT; break; }
if( memcmp(aKey, aProbe, nProbe)!=0 ) break;
rc = sqlite4KVCursorDelete(u.bt.pCur);
if( rc ) break;
rc = sqlite4KVCursorNext(u.bt.pCur);
}
sqlite4KVCursorClose(u.bt.pCur);
if( rc==SQLITE_NOTFOUND) rc = SQLITE_OK;
break;
}
/* Opcode: ParseSchema P1 * * P4 *
**
** Read and parse all entries from the SQLITE_MASTER table of database P1
** that match the WHERE clause P4.
**
** This opcode invokes the parser to create a new virtual machine,
** then runs the new virtual machine. It is thus a re-entrant opcode.
*/
case OP_ParseSchema: {
#if 0 /* local variables moved into u.bu */
int iDb;
const char *zMaster;
char *zSql;
InitData initData;
#endif /* local variables moved into u.bu */
u.bu.iDb = pOp->p1;
assert( u.bu.iDb>=0 && u.bu.iDb<db->nDb );
assert( DbHasProperty(db, u.bu.iDb, DB_SchemaLoaded) );
/* Used to be a conditional */ {
u.bu.zMaster = SCHEMA_TABLE(u.bu.iDb);
u.bu.initData.db = db;
u.bu.initData.iDb = pOp->p1;
u.bu.initData.pzErrMsg = &p->zErrMsg;
u.bu.zSql = sqlite4MPrintf(db,
"SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid",
db->aDb[u.bu.iDb].zName, u.bu.zMaster, pOp->p4.z);
if( u.bu.zSql==0 ){
rc = SQLITE_NOMEM;
}else{
assert( db->init.busy==0 );
db->init.busy = 1;
u.bu.initData.rc = SQLITE_OK;
assert( !db->mallocFailed );
rc = sqlite4_exec(db, u.bu.zSql, sqlite4InitCallback, &u.bu.initData, 0);
if( rc==SQLITE_OK ) rc = u.bu.initData.rc;
sqlite4DbFree(db, u.bu.zSql);
db->init.busy = 0;
}
}
if( rc==SQLITE_NOMEM ){
goto no_mem;
}
break;
}
#if !defined(SQLITE_OMIT_ANALYZE)
/* Opcode: LoadAnalysis P1 * * * *
**
** Read the sqlite_stat1 table for database P1 and load the content
** of that table into the internal index hash table. This will cause
** the analysis to be used when preparing all subsequent queries.
*/
case OP_LoadAnalysis: {
assert( pOp->p1>=0 && pOp->p1<db->nDb );
rc = sqlite4AnalysisLoad(db, pOp->p1);
break;
}
#endif /* !defined(SQLITE_OMIT_ANALYZE) */
/* Opcode: DropTable P1 * * P4 *
**
** Remove the internal (in-memory) data structures that describe
** the table named P4 in database P1. This is called after a table
** is dropped in order to keep the internal representation of the
** schema consistent with what is on disk.
*/
case OP_DropTable: {
sqlite4UnlinkAndDeleteTable(db, pOp->p1, pOp->p4.z);
break;
}
/* Opcode: DropIndex P1 * * P4 *
**
** Remove the internal (in-memory) data structures that describe
** the index named P4 in database P1. This is called after an index
** is dropped in order to keep the internal representation of the
** schema consistent with what is on disk.
*/
case OP_DropIndex: {
sqlite4UnlinkAndDeleteIndex(db, pOp->p1, pOp->p4.z);
break;
}
/* Opcode: DropTrigger P1 * * P4 *
**
** Remove the internal (in-memory) data structures that describe
** the trigger named P4 in database P1. This is called after a trigger
** is dropped in order to keep the internal representation of the
** schema consistent with what is on disk.
*/
case OP_DropTrigger: {
sqlite4UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p4.z);
break;
}
/* Opcode: RowSetTest P1 P2 P3 * *
**
** Register P1 contains a RowSet object. Register P3 contains a database
** key. This function checks if the RowSet already contains an equal key.
** If so, control jumps to instruction P2. Otherwise, fall through to the
** next instruction.
**
** TODO: Optimization similar to SQLite 3 using P4.
*/
case OP_RowSetTest: { /* in1, in3, jump */
#if 0 /* local variables moved into u.bv */
int iSet;
#endif /* local variables moved into u.bv */
pIn1 = &aMem[pOp->p1];
pIn3 = &aMem[pOp->p3];
u.bv.iSet = pOp->p4.i;
if( 0!=(pIn1->flags & MEM_RowSet)
&& 0!=sqlite4RowSetTest(pIn1->u.pRowSet, u.bv.iSet, (u8 *)pIn3->z, pIn3->n)
){
pc = pOp->p2-1;
break;
}
/* Fall through to RowSetAdd */
}
/* Opcode: RowSetAdd P1 P2 * * *
**
** Read the blob value from register P2 and store it in RowSet object P1.
*/
case OP_RowSetAdd: { /* in1, in3 */
pIn1 = &aMem[pOp->p1];
if( (pIn1->flags & MEM_RowSet)==0 ){
sqlite4VdbeMemSetRowSet(pIn1);
if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem;
}
pIn3 = &aMem[pOp->p3];
assert( pIn3->flags & MEM_Blob );
sqlite4RowSetInsert(pIn1->u.pRowSet, (u8 *)pIn3->z, pIn3->n);
break;
}
/* Opcode: RowSetRead P1 P2 P3 * *
**
** Remove a value from MemSet object P1 and store it in register P3.
** Or, if MemSet P1 is already empty, leave P3 unchanged and jump to
** instruction P2.
*/
case OP_RowSetRead: { /* in1 */
#if 0 /* local variables moved into u.bw */
const char *aKey;
int nKey;
#endif /* local variables moved into u.bw */
CHECK_FOR_INTERRUPT;
pIn1 = &aMem[pOp->p1];
pOut = &aMem[pOp->p3];
if( (pIn1->flags & MEM_RowSet)
&& (u.bw.aKey = sqlite4RowSetRead(pIn1->u.pRowSet, &u.bw.nKey))
){
rc = sqlite4VdbeMemSetStr(pOut, u.bw.aKey, u.bw.nKey, 0, SQLITE_TRANSIENT);
sqlite4RowSetNext(pIn1->u.pRowSet);
}else{
/* The RowSet is empty */
sqlite4VdbeMemSetNull(pIn1);
pc = pOp->p2 - 1;
}
break;
}
#ifndef SQLITE_OMIT_TRIGGER
/* Opcode: Program P1 P2 P3 P4 *
**
** Execute the trigger program passed as P4 (type P4_SUBPROGRAM).
**
** P1 contains the address of the memory cell that contains the first memory
** cell in an array of values used as arguments to the sub-program. P2
** contains the address to jump to if the sub-program throws an IGNORE
** exception using the RAISE() function. Register P3 contains the address
** of a memory cell in this (the parent) VM that is used to allocate the
** memory required by the sub-vdbe at runtime.
**
** P4 is a pointer to the VM containing the trigger program.
*/
case OP_Program: { /* jump */
#if 0 /* local variables moved into u.bx */
int nMem; /* Number of memory registers for sub-program */
int nByte; /* Bytes of runtime space required for sub-program */
Mem *pRt; /* Register to allocate runtime space */
Mem *pMem; /* Used to iterate through memory cells */
Mem *pEnd; /* Last memory cell in new array */
VdbeFrame *pFrame; /* New vdbe frame to execute in */
SubProgram *pProgram; /* Sub-program to execute */
#endif /* local variables moved into u.bx */
u.bx.pProgram = pOp->p4.pProgram;
u.bx.pRt = &aMem[pOp->p3];
assert( u.bx.pProgram->nOp>0 );
if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){
rc = SQLITE_ERROR;
sqlite4SetString(&p->zErrMsg, db, "too many levels of trigger recursion");
break;
}
/* Register u.bx.pRt is used to store the memory required to save the state
** of the current program, and the memory required at runtime to execute
** the trigger program. If this trigger has been fired before, then u.bx.pRt
** is already allocated. Otherwise, it must be initialized. */
if( (u.bx.pRt->flags&MEM_Frame)==0 ){
/* SubProgram.nMem is set to the number of memory cells used by the
** program stored in SubProgram.aOp. As well as these, one memory
** cell is required for each cursor used by the program. Set local
** variable u.bx.nMem (and later, VdbeFrame.nChildMem) to this value.
*/
u.bx.nMem = u.bx.pProgram->nMem + u.bx.pProgram->nCsr;
u.bx.nByte = ROUND8(sizeof(VdbeFrame))
+ u.bx.nMem * sizeof(Mem)
+ u.bx.pProgram->nCsr * sizeof(VdbeCursor *)
+ u.bx.pProgram->nOnce * sizeof(u8);
u.bx.pFrame = sqlite4DbMallocZero(db, u.bx.nByte);
if( !u.bx.pFrame ){
goto no_mem;
}
sqlite4VdbeMemRelease(u.bx.pRt);
u.bx.pRt->flags = MEM_Frame;
u.bx.pRt->u.pFrame = u.bx.pFrame;
u.bx.pFrame->v = p;
u.bx.pFrame->nChildMem = u.bx.nMem;
u.bx.pFrame->nChildCsr = u.bx.pProgram->nCsr;
u.bx.pFrame->pc = pc;
u.bx.pFrame->aMem = p->aMem;
u.bx.pFrame->nMem = p->nMem;
u.bx.pFrame->apCsr = p->apCsr;
u.bx.pFrame->nCursor = p->nCursor;
u.bx.pFrame->aOp = p->aOp;
u.bx.pFrame->nOp = p->nOp;
u.bx.pFrame->token = u.bx.pProgram->token;
u.bx.pFrame->aOnceFlag = p->aOnceFlag;
u.bx.pFrame->nOnceFlag = p->nOnceFlag;
u.bx.pEnd = &VdbeFrameMem(u.bx.pFrame)[u.bx.pFrame->nChildMem];
for(u.bx.pMem=VdbeFrameMem(u.bx.pFrame); u.bx.pMem!=u.bx.pEnd; u.bx.pMem++){
u.bx.pMem->flags = MEM_Invalid;
u.bx.pMem->db = db;
}
}else{
u.bx.pFrame = u.bx.pRt->u.pFrame;
assert( u.bx.pProgram->nMem+u.bx.pProgram->nCsr==u.bx.pFrame->nChildMem );
assert( u.bx.pProgram->nCsr==u.bx.pFrame->nChildCsr );
assert( pc==u.bx.pFrame->pc );
}
p->nFrame++;
u.bx.pFrame->pParent = p->pFrame;
u.bx.pFrame->lastRowid = lastRowid;
u.bx.pFrame->nChange = p->nChange;
p->nChange = 0;
p->pFrame = u.bx.pFrame;
p->aMem = aMem = &VdbeFrameMem(u.bx.pFrame)[-1];
p->nMem = u.bx.pFrame->nChildMem;
p->nCursor = (u16)u.bx.pFrame->nChildCsr;
p->apCsr = (VdbeCursor **)&aMem[p->nMem+1];
p->aOp = aOp = u.bx.pProgram->aOp;
p->nOp = u.bx.pProgram->nOp;
p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor];
p->nOnceFlag = u.bx.pProgram->nOnce;
pc = -1;
memset(p->aOnceFlag, 0, p->nOnceFlag);
break;
}
/* Opcode: Param P1 P2 * * *
**
** This opcode is only ever present in sub-programs called via the
** OP_Program instruction. Copy a value currently stored in a memory
** cell of the calling (parent) frame to cell P2 in the current frames
** address space. This is used by trigger programs to access the new.*
** and old.* values.
**
** The address of the cell in the parent frame is determined by adding
** the value of the P1 argument to the value of the P1 argument to the
** calling OP_Program instruction.
*/
case OP_Param: { /* out2-prerelease */
#if 0 /* local variables moved into u.by */
VdbeFrame *pFrame;
Mem *pIn;
#endif /* local variables moved into u.by */
u.by.pFrame = p->pFrame;
u.by.pIn = &u.by.pFrame->aMem[pOp->p1 + u.by.pFrame->aOp[u.by.pFrame->pc].p1];
assert( memIsValid(u.by.pIn) );
sqlite4VdbeMemShallowCopy(pOut, u.by.pIn, MEM_Ephem);
break;
}
#endif /* #ifndef SQLITE_OMIT_TRIGGER */
#ifndef SQLITE_OMIT_FOREIGN_KEY
/* Opcode: FkCounter P1 P2 * * *
**
** Increment a "constraint counter" by P2 (P2 may be negative or positive).
** If P1 is non-zero, the database constraint counter is incremented
** (deferred foreign key constraints). Otherwise, if P1 is zero, the
** statement counter is incremented (immediate foreign key constraints).
*/
case OP_FkCounter: {
if( pOp->p1 ){
db->nDeferredCons += pOp->p2;
}else{
p->nFkConstraint += pOp->p2;
}
break;
}
/* Opcode: FkIfZero P1 P2 * * *
**
** This opcode tests if a foreign key constraint-counter is currently zero.
** If so, jump to instruction P2. Otherwise, fall through to the next
** instruction.
**
** If P1 is non-zero, then the jump is taken if the database constraint-counter
** is zero (the one that counts deferred constraint violations). If P1 is
** zero, the jump is taken if the statement constraint-counter is zero
** (immediate foreign key constraint violations).
*/
case OP_FkIfZero: { /* jump */
if( pOp->p1 ){
if( db->nDeferredCons==0 ) pc = pOp->p2-1;
}else{
if( p->nFkConstraint==0 ) pc = pOp->p2-1;
}
break;
}
#endif /* #ifndef SQLITE_OMIT_FOREIGN_KEY */
#ifndef SQLITE_OMIT_AUTOINCREMENT
/* Opcode: MemMax P1 P2 * * *
**
** P1 is a register in the root frame of this VM (the root frame is
** different from the current frame if this instruction is being executed
** within a sub-program). Set the value of register P1 to the maximum of
** its current value and the value in register P2.
**
** This instruction throws an error if the memory cell is not initially
** an integer.
*/
case OP_MemMax: { /* in2 */
#if 0 /* local variables moved into u.bz */
Mem *pIn1;
VdbeFrame *pFrame;
#endif /* local variables moved into u.bz */
if( p->pFrame ){
for(u.bz.pFrame=p->pFrame; u.bz.pFrame->pParent; u.bz.pFrame=u.bz.pFrame->pParent);
u.bz.pIn1 = &u.bz.pFrame->aMem[pOp->p1];
}else{
u.bz.pIn1 = &aMem[pOp->p1];
}
assert( memIsValid(u.bz.pIn1) );
sqlite4VdbeMemIntegerify(u.bz.pIn1);
pIn2 = &aMem[pOp->p2];
sqlite4VdbeMemIntegerify(pIn2);
if( u.bz.pIn1->u.i<pIn2->u.i){
u.bz.pIn1->u.i = pIn2->u.i;
}
break;
}
#endif /* SQLITE_OMIT_AUTOINCREMENT */
/* Opcode: IfPos P1 P2 * * *
**
** If the value of register P1 is 1 or greater, jump to P2.
**
** It is illegal to use this instruction on a register that does
** not contain an integer. An assertion fault will result if you try.
*/
case OP_IfPos: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int );
if( pIn1->u.i>0 ){
pc = pOp->p2 - 1;
}
break;
}
/* Opcode: IfNeg P1 P2 * * *
**
** If the value of register P1 is less than zero, jump to P2.
**
** It is illegal to use this instruction on a register that does
** not contain an integer. An assertion fault will result if you try.
*/
case OP_IfNeg: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int );
if( pIn1->u.i<0 ){
pc = pOp->p2 - 1;
}
break;
}
/* Opcode: IfZero P1 P2 P3 * *
**
** The register P1 must contain an integer. Add literal P3 to the
** value in register P1. If the result is exactly 0, jump to P2.
**
** It is illegal to use this instruction on a register that does
** not contain an integer. An assertion fault will result if you try.
*/
case OP_IfZero: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int );
pIn1->u.i += pOp->p3;
if( pIn1->u.i==0 ){
pc = pOp->p2 - 1;
}
break;
}
/* Opcode: AggStep * P2 P3 P4 P5
**
** Execute the step function for an aggregate. The
** function has P5 arguments. P4 is a pointer to the FuncDef
** structure that specifies the function. Use register
** P3 as the accumulator.
**
** The P5 arguments are taken from register P2 and its
** successors.
*/
case OP_AggStep: {
#if 0 /* local variables moved into u.ca */
int n;
int i;
Mem *pMem;
Mem *pRec;
sqlite4_context ctx;
sqlite4_value **apVal;
#endif /* local variables moved into u.ca */
u.ca.n = pOp->p5;
assert( u.ca.n>=0 );
u.ca.pRec = &aMem[pOp->p2];
u.ca.apVal = p->apArg;
assert( u.ca.apVal || u.ca.n==0 );
for(u.ca.i=0; u.ca.i<u.ca.n; u.ca.i++, u.ca.pRec++){
assert( memIsValid(u.ca.pRec) );
u.ca.apVal[u.ca.i] = u.ca.pRec;
memAboutToChange(p, u.ca.pRec);
sqlite4VdbeMemStoreType(u.ca.pRec);
}
u.ca.ctx.pFunc = pOp->p4.pFunc;
assert( pOp->p3>0 && pOp->p3<=p->nMem );
u.ca.ctx.pMem = u.ca.pMem = &aMem[pOp->p3];
u.ca.pMem->n++;
u.ca.ctx.s.flags = MEM_Null;
u.ca.ctx.s.z = 0;
u.ca.ctx.s.zMalloc = 0;
u.ca.ctx.s.xDel = 0;
u.ca.ctx.s.db = db;
u.ca.ctx.isError = 0;
u.ca.ctx.pColl = 0;
if( u.ca.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
assert( pOp>p->aOp );
assert( pOp[-1].p4type==P4_COLLSEQ );
assert( pOp[-1].opcode==OP_CollSeq );
u.ca.ctx.pColl = pOp[-1].p4.pColl;
}
(u.ca.ctx.pFunc->xStep)(&u.ca.ctx, u.ca.n, u.ca.apVal); /* IMP: R-24505-23230 */
if( u.ca.ctx.isError ){
sqlite4SetString(&p->zErrMsg, db, "%s", sqlite4_value_text(&u.ca.ctx.s));
rc = u.ca.ctx.isError;
}
sqlite4VdbeMemRelease(&u.ca.ctx.s);
break;
}
/* Opcode: AggFinal P1 P2 * P4 *
**
** Execute the finalizer function for an aggregate. P1 is
** the memory location that is the accumulator for the aggregate.
**
** P2 is the number of arguments that the step function takes and
** P4 is a pointer to the FuncDef for this function. The P2
** argument is not used by this opcode. It is only there to disambiguate
** functions that can take varying numbers of arguments. The
** P4 argument is only needed for the degenerate case where
** the step function was not previously called.
*/
case OP_AggFinal: {
#if 0 /* local variables moved into u.cb */
Mem *pMem;
#endif /* local variables moved into u.cb */
assert( pOp->p1>0 && pOp->p1<=p->nMem );
u.cb.pMem = &aMem[pOp->p1];
assert( (u.cb.pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
rc = sqlite4VdbeMemFinalize(u.cb.pMem, pOp->p4.pFunc);
if( rc ){
sqlite4SetString(&p->zErrMsg, db, "%s", sqlite4_value_text(u.cb.pMem));
}
sqlite4VdbeChangeEncoding(u.cb.pMem, encoding);
UPDATE_MAX_BLOBSIZE(u.cb.pMem);
if( sqlite4VdbeMemTooBig(u.cb.pMem) ){
goto too_big;
}
break;
}
#ifndef SQLITE_OMIT_PRAGMA
/* Opcode: JournalMode P1 P2 P3 * P5
**
** Change the journal mode of database P1 to P3. P3 must be one of the
** PAGER_JOURNALMODE_XXX values. If changing between the various rollback
** modes (delete, truncate, persist, off and memory), this is a simple
** operation. No IO is required.
**
** If changing into or out of WAL mode the procedure is more complicated.
**
** Write a string containing the final journal-mode to register P2.
*/
case OP_JournalMode: { /* out2-prerelease */
break;
};
#endif /* SQLITE_OMIT_PRAGMA */
/* Opcode: Expire P1 * * * *
**
** Cause precompiled statements to become expired. An expired statement
** fails with an error code of SQLITE_SCHEMA if it is ever executed
** (via sqlite4_step()).
**
** If P1 is 0, then all SQL statements become expired. If P1 is non-zero,
** then only the currently executing statement is affected.
*/
case OP_Expire: {
if( !pOp->p1 ){
sqlite4ExpirePreparedStatements(db);
}else{
p->expired = 1;
}
break;
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VBegin * * * P4 *
**
** P4 may be a pointer to an sqlite4_vtab structure. If so, call the
** xBegin method for that table.
**
** Also, whether or not P4 is set, check that this is not being called from
** within a callback to a virtual table xSync() method. If it is, the error
** code will be set to SQLITE_LOCKED.
*/
case OP_VBegin: {
#if 0 /* local variables moved into u.cc */
VTable *pVTab;
#endif /* local variables moved into u.cc */
u.cc.pVTab = pOp->p4.pVtab;
rc = sqlite4VtabBegin(db, u.cc.pVTab);
if( u.cc.pVTab ) importVtabErrMsg(p, u.cc.pVTab->pVtab);
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VCreate P1 * * P4 *
**
** P4 is the name of a virtual table in database P1. Call the xCreate method
** for that table.
*/
case OP_VCreate: {
rc = sqlite4VtabCallCreate(db, pOp->p1, pOp->p4.z, &p->zErrMsg);
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VDestroy P1 * * P4 *
**
** P4 is the name of a virtual table in database P1. Call the xDestroy method
** of that table.
*/
case OP_VDestroy: {
p->inVtabMethod = 2;
rc = sqlite4VtabCallDestroy(db, pOp->p1, pOp->p4.z);
p->inVtabMethod = 0;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VOpen P1 * * P4 *
**
** P4 is a pointer to a virtual table object, an sqlite4_vtab structure.
** P1 is a cursor number. This opcode opens a cursor to the virtual
** table and stores that cursor in P1.
*/
case OP_VOpen: {
#if 0 /* local variables moved into u.cd */
VdbeCursor *pCur;
sqlite4_vtab_cursor *pVtabCursor;
sqlite4_vtab *pVtab;
sqlite4_module *pModule;
#endif /* local variables moved into u.cd */
u.cd.pCur = 0;
u.cd.pVtabCursor = 0;
u.cd.pVtab = pOp->p4.pVtab->pVtab;
u.cd.pModule = (sqlite4_module *)u.cd.pVtab->pModule;
assert(u.cd.pVtab && u.cd.pModule);
rc = u.cd.pModule->xOpen(u.cd.pVtab, &u.cd.pVtabCursor);
importVtabErrMsg(p, u.cd.pVtab);
if( SQLITE_OK==rc ){
/* Initialize sqlite4_vtab_cursor base class */
u.cd.pVtabCursor->pVtab = u.cd.pVtab;
/* Initialise vdbe cursor object */
u.cd.pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
if( u.cd.pCur ){
u.cd.pCur->pVtabCursor = u.cd.pVtabCursor;
u.cd.pCur->pModule = u.cd.pVtabCursor->pVtab->pModule;
}else{
db->mallocFailed = 1;
u.cd.pModule->xClose(u.cd.pVtabCursor);
}
}
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VFilter P1 P2 P3 P4 *
**
** P1 is a cursor opened using VOpen. P2 is an address to jump to if
** the filtered result set is empty.
**
** P4 is either NULL or a string that was generated by the xBestIndex
** method of the module. The interpretation of the P4 string is left
** to the module implementation.
**
** This opcode invokes the xFilter method on the virtual table specified
** by P1. The integer query plan parameter to xFilter is stored in register
** P3. Register P3+1 stores the argc parameter to be passed to the
** xFilter method. Registers P3+2..P3+1+argc are the argc
** additional parameters which are passed to
** xFilter as argv. Register P3+2 becomes argv[0] when passed to xFilter.
**
** A jump is made to P2 if the result set after filtering would be empty.
*/
case OP_VFilter: { /* jump */
#if 0 /* local variables moved into u.ce */
int nArg;
int iQuery;
const sqlite4_module *pModule;
Mem *pQuery;
Mem *pArgc;
sqlite4_vtab_cursor *pVtabCursor;
sqlite4_vtab *pVtab;
VdbeCursor *pCur;
int res;
int i;
Mem **apArg;
#endif /* local variables moved into u.ce */
u.ce.pQuery = &aMem[pOp->p3];
u.ce.pArgc = &u.ce.pQuery[1];
u.ce.pCur = p->apCsr[pOp->p1];
assert( memIsValid(u.ce.pQuery) );
REGISTER_TRACE(pOp->p3, u.ce.pQuery);
assert( u.ce.pCur->pVtabCursor );
u.ce.pVtabCursor = u.ce.pCur->pVtabCursor;
u.ce.pVtab = u.ce.pVtabCursor->pVtab;
u.ce.pModule = u.ce.pVtab->pModule;
/* Grab the index number and argc parameters */
assert( (u.ce.pQuery->flags&MEM_Int)!=0 && u.ce.pArgc->flags==MEM_Int );
u.ce.nArg = (int)u.ce.pArgc->u.i;
u.ce.iQuery = (int)u.ce.pQuery->u.i;
/* Invoke the xFilter method */
{
u.ce.res = 0;
u.ce.apArg = p->apArg;
for(u.ce.i = 0; u.ce.i<u.ce.nArg; u.ce.i++){
u.ce.apArg[u.ce.i] = &u.ce.pArgc[u.ce.i+1];
sqlite4VdbeMemStoreType(u.ce.apArg[u.ce.i]);
}
p->inVtabMethod = 1;
rc = u.ce.pModule->xFilter(u.ce.pVtabCursor, u.ce.iQuery, pOp->p4.z, u.ce.nArg, u.ce.apArg);
p->inVtabMethod = 0;
importVtabErrMsg(p, u.ce.pVtab);
if( rc==SQLITE_OK ){
u.ce.res = u.ce.pModule->xEof(u.ce.pVtabCursor);
}
if( u.ce.res ){
pc = pOp->p2 - 1;
}
}
u.ce.pCur->nullRow = 0;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VColumn P1 P2 P3 * *
**
** Store the value of the P2-th column of
** the row of the virtual-table that the
** P1 cursor is pointing to into register P3.
*/
case OP_VColumn: {
#if 0 /* local variables moved into u.cf */
sqlite4_vtab *pVtab;
const sqlite4_module *pModule;
Mem *pDest;
sqlite4_context sContext;
#endif /* local variables moved into u.cf */
VdbeCursor *pCur = p->apCsr[pOp->p1];
assert( pCur->pVtabCursor );
assert( pOp->p3>0 && pOp->p3<=p->nMem );
u.cf.pDest = &aMem[pOp->p3];
memAboutToChange(p, u.cf.pDest);
if( pCur->nullRow ){
sqlite4VdbeMemSetNull(u.cf.pDest);
break;
}
u.cf.pVtab = pCur->pVtabCursor->pVtab;
u.cf.pModule = u.cf.pVtab->pModule;
assert( u.cf.pModule->xColumn );
memset(&u.cf.sContext, 0, sizeof(u.cf.sContext));
/* The output cell may already have a buffer allocated. Move
** the current contents to u.cf.sContext.s so in case the user-function
** can use the already allocated buffer instead of allocating a
** new one.
*/
sqlite4VdbeMemMove(&u.cf.sContext.s, u.cf.pDest);
MemSetTypeFlag(&u.cf.sContext.s, MEM_Null);
rc = u.cf.pModule->xColumn(pCur->pVtabCursor, &u.cf.sContext, pOp->p2);
importVtabErrMsg(p, u.cf.pVtab);
if( u.cf.sContext.isError ){
rc = u.cf.sContext.isError;
}
/* Copy the result of the function to the P3 register. We
** do this regardless of whether or not an error occurred to ensure any
** dynamic allocation in u.cf.sContext.s (a Mem struct) is released.
*/
sqlite4VdbeChangeEncoding(&u.cf.sContext.s, encoding);
sqlite4VdbeMemMove(u.cf.pDest, &u.cf.sContext.s);
REGISTER_TRACE(pOp->p3, u.cf.pDest);
UPDATE_MAX_BLOBSIZE(u.cf.pDest);
if( sqlite4VdbeMemTooBig(u.cf.pDest) ){
goto too_big;
}
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VNext P1 P2 * * *
**
** Advance virtual table P1 to the next row in its result set and
** jump to instruction P2. Or, if the virtual table has reached
** the end of its result set, then fall through to the next instruction.
*/
case OP_VNext: { /* jump */
#if 0 /* local variables moved into u.cg */
sqlite4_vtab *pVtab;
const sqlite4_module *pModule;
int res;
VdbeCursor *pCur;
#endif /* local variables moved into u.cg */
u.cg.res = 0;
u.cg.pCur = p->apCsr[pOp->p1];
assert( u.cg.pCur->pVtabCursor );
if( u.cg.pCur->nullRow ){
break;
}
u.cg.pVtab = u.cg.pCur->pVtabCursor->pVtab;
u.cg.pModule = u.cg.pVtab->pModule;
assert( u.cg.pModule->xNext );
/* Invoke the xNext() method of the module. There is no way for the
** underlying implementation to return an error if one occurs during
** xNext(). Instead, if an error occurs, true is returned (indicating that
** data is available) and the error code returned when xColumn or
** some other method is next invoked on the save virtual table cursor.
*/
p->inVtabMethod = 1;
rc = u.cg.pModule->xNext(u.cg.pCur->pVtabCursor);
p->inVtabMethod = 0;
importVtabErrMsg(p, u.cg.pVtab);
if( rc==SQLITE_OK ){
u.cg.res = u.cg.pModule->xEof(u.cg.pCur->pVtabCursor);
}
if( !u.cg.res ){
/* If there is data, jump to P2 */
pc = pOp->p2 - 1;
}
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VRename P1 * * P4 *
**
** P4 is a pointer to a virtual table object, an sqlite4_vtab structure.
** This opcode invokes the corresponding xRename method. The value
** in register P1 is passed as the zName argument to the xRename method.
*/
case OP_VRename: {
#if 0 /* local variables moved into u.ch */
sqlite4_vtab *pVtab;
Mem *pName;
#endif /* local variables moved into u.ch */
u.ch.pVtab = pOp->p4.pVtab->pVtab;
u.ch.pName = &aMem[pOp->p1];
assert( u.ch.pVtab->pModule->xRename );
assert( memIsValid(u.ch.pName) );
REGISTER_TRACE(pOp->p1, u.ch.pName);
assert( u.ch.pName->flags & MEM_Str );
testcase( u.ch.pName->enc==SQLITE_UTF8 );
testcase( u.ch.pName->enc==SQLITE_UTF16BE );
testcase( u.ch.pName->enc==SQLITE_UTF16LE );
rc = sqlite4VdbeChangeEncoding(u.ch.pName, SQLITE_UTF8);
if( rc==SQLITE_OK ){
rc = u.ch.pVtab->pModule->xRename(u.ch.pVtab, u.ch.pName->z);
importVtabErrMsg(p, u.ch.pVtab);
p->expired = 0;
}
break;
}
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VUpdate P1 P2 P3 P4 *
**
** P4 is a pointer to a virtual table object, an sqlite4_vtab structure.
** This opcode invokes the corresponding xUpdate method. P2 values
** are contiguous memory cells starting at P3 to pass to the xUpdate
** invocation. The value in register (P3+P2-1) corresponds to the
** p2th element of the argv array passed to xUpdate.
**
** The xUpdate method will do a DELETE or an INSERT or both.
** The argv[0] element (which corresponds to memory cell P3)
** is the rowid of a row to delete. If argv[0] is NULL then no
** deletion occurs. The argv[1] element is the rowid of the new
** row. This can be NULL to have the virtual table select the new
** rowid for itself. The subsequent elements in the array are
** the values of columns in the new row.
**
** If P2==1 then no insert is performed. argv[0] is the rowid of
** a row to delete.
**
** P1 is a boolean flag. If it is set to true and the xUpdate call
** is successful, then the value returned by sqlite4_last_insert_rowid()
** is set to the value of the rowid for the row just inserted.
*/
case OP_VUpdate: {
#if 0 /* local variables moved into u.ci */
sqlite4_vtab *pVtab;
sqlite4_module *pModule;
int nArg;
int i;
sqlite_int64 rowid;
Mem **apArg;
Mem *pX;
#endif /* local variables moved into u.ci */
assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback
|| pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace
);
u.ci.pVtab = pOp->p4.pVtab->pVtab;
u.ci.pModule = (sqlite4_module *)u.ci.pVtab->pModule;
u.ci.nArg = pOp->p2;
assert( pOp->p4type==P4_VTAB );
if( ALWAYS(u.ci.pModule->xUpdate) ){
u8 vtabOnConflict = db->vtabOnConflict;
u.ci.apArg = p->apArg;
u.ci.pX = &aMem[pOp->p3];
for(u.ci.i=0; u.ci.i<u.ci.nArg; u.ci.i++){
assert( memIsValid(u.ci.pX) );
memAboutToChange(p, u.ci.pX);
sqlite4VdbeMemStoreType(u.ci.pX);
u.ci.apArg[u.ci.i] = u.ci.pX;
u.ci.pX++;
}
db->vtabOnConflict = pOp->p5;
rc = u.ci.pModule->xUpdate(u.ci.pVtab, u.ci.nArg, u.ci.apArg, &u.ci.rowid);
db->vtabOnConflict = vtabOnConflict;
importVtabErrMsg(p, u.ci.pVtab);
if( rc==SQLITE_OK && pOp->p1 ){
assert( u.ci.nArg>1 && u.ci.apArg[0] && (u.ci.apArg[0]->flags&MEM_Null) );
db->lastRowid = lastRowid = u.ci.rowid;
}
if( rc==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){
if( pOp->p5==OE_Ignore ){
rc = SQLITE_OK;
}else{
p->errorAction = ((pOp->p5==OE_Replace) ? OE_Abort : pOp->p5);
}
}else{
p->nChange++;
}
}
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_TRACE
/* Opcode: Trace * * * P4 *
**
** If tracing is enabled (by the sqlite4_trace()) interface, then
** the UTF-8 string contained in P4 is emitted on the trace callback.
*/
case OP_Trace: {
#if 0 /* local variables moved into u.cj */
char *zTrace;
char *z;
#endif /* local variables moved into u.cj */
if( db->xTrace && (u.cj.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){
u.cj.z = sqlite4VdbeExpandSql(p, u.cj.zTrace);
db->xTrace(db->pTraceArg, u.cj.z);
sqlite4DbFree(db, u.cj.z);
}
#ifdef SQLITE_DEBUG
if( (db->flags & SQLITE_SqlTrace)!=0
&& (u.cj.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
){
sqlite4DebugPrintf("SQL-trace: %s\n", u.cj.zTrace);
}
#endif /* SQLITE_DEBUG */
break;
}
#endif
/* Opcode: Noop * * * * *
**
** Do nothing. This instruction is often useful as a jump
** destination.
*/
/*
** The magic Explain opcode are only inserted when explain==2 (which
** is to say when the EXPLAIN QUERY PLAN syntax is used.)
** This opcode records information from the optimizer. It is the
** the same as a no-op. This opcodesnever appears in a real VM program.
*/
default: { /* This is really OP_Noop and OP_Explain */
assert( pOp->opcode==OP_Noop || pOp->opcode==OP_Explain );
break;
}
/*****************************************************************************
** The cases of the switch statement above this line should all be indented
** by 6 spaces. But the left-most 6 spaces have been removed to improve the
** readability. From this point on down, the normal indentation rules are
** restored.
*****************************************************************************/
}
#ifdef VDBE_PROFILE
{
u64 elapsed = sqlite4Hwtime() - start;
pOp->cycles += elapsed;
pOp->cnt++;
#if 0
fprintf(stdout, "%10llu ", elapsed);
sqlite4VdbePrintOp(stdout, origPc, &aOp[origPc]);
#endif
}
#endif
/* The following code adds nothing to the actual functionality
** of the program. It is only here for testing and debugging.
** On the other hand, it does burn CPU cycles every time through
** the evaluator loop. So we can leave it out when NDEBUG is defined.
*/
#ifndef NDEBUG
assert( pc>=-1 && pc<p->nOp );
#ifdef SQLITE_DEBUG
if( p->trace ){
if( rc!=0 ) fprintf(p->trace,"rc=%d\n",rc);
if( pOp->opflags & (OPFLG_OUT2_PRERELEASE|OPFLG_OUT2) ){
registerTrace(p->trace, pOp->p2, &aMem[pOp->p2]);
}
if( pOp->opflags & OPFLG_OUT3 ){
registerTrace(p->trace, pOp->p3, &aMem[pOp->p3]);
}
}
#endif /* SQLITE_DEBUG */
#endif /* NDEBUG */
} /* The end of the for(;;) loop the loops through opcodes */
/* If we reach this point, it means that execution is finished with
** an error of some kind.
*/
vdbe_error_halt:
assert( rc );
p->rc = rc;
testcase( sqlite4DefaultEnv.xLog!=0 );
sqlite4_log(db->pEnv, rc, "statement aborts at %d: [%s] %s",
pc, p->zSql, p->zErrMsg);
sqlite4VdbeHalt(p);
if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1;
rc = SQLITE_ERROR;
if( resetSchemaOnFault>0 ){
sqlite4ResetInternalSchema(db, resetSchemaOnFault-1);
}
/* This is the only way out of this procedure. We have to
** release the mutexes on btrees that were acquired at the
** top. */
vdbe_return:
db->lastRowid = lastRowid;
return rc;
/* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH
** is encountered.
*/
too_big:
sqlite4SetString(&p->zErrMsg, db, "string or blob too big");
rc = SQLITE_TOOBIG;
goto vdbe_error_halt;
/* Jump to here if a malloc() fails.
*/
no_mem:
db->mallocFailed = 1;
sqlite4SetString(&p->zErrMsg, db, "out of memory");
rc = SQLITE_NOMEM;
goto vdbe_error_halt;
/* Jump to here for any other kind of fatal error. The "rc" variable
** should hold the error number.
*/
abort_due_to_error:
assert( p->zErrMsg==0 );
if( db->mallocFailed ) rc = SQLITE_NOMEM;
if( rc!=SQLITE_IOERR_NOMEM ){
sqlite4SetString(&p->zErrMsg, db, "%s", sqlite4ErrStr(rc));
}
goto vdbe_error_halt;
/* Jump to here if the sqlite4_interrupt() API sets the interrupt
** flag.
*/
abort_due_to_interrupt:
assert( db->u1.isInterrupted );
rc = SQLITE_INTERRUPT;
p->rc = rc;
sqlite4SetString(&p->zErrMsg, db, "%s", sqlite4ErrStr(rc));
goto vdbe_error_halt;
}
/************** End of vdbe.c ************************************************/
/************** Begin file walker.c ******************************************/
/*
** 2008 August 16
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for walking the parser tree for
** an SQL statement.
*/
/* #include <stdlib.h> */
/* #include <string.h> */
/*
** Walk an expression tree. Invoke the callback once for each node
** of the expression, while decending. (In other words, the callback
** is invoked before visiting children.)
**
** The return value from the callback should be one of the WRC_*
** constants to specify how to proceed with the walk.
**
** WRC_Continue Continue descending down the tree.
**
** 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 the top-level walk call.
**
** The return value from this routine is WRC_Abort to abandon the tree walk
** and WRC_Continue to continue.
*/
SQLITE_PRIVATE int sqlite4WalkExpr(Walker *pWalker, Expr *pExpr){
int rc;
if( pExpr==0 ) return WRC_Continue;
testcase( ExprHasProperty(pExpr, EP_TokenOnly) );
testcase( ExprHasProperty(pExpr, EP_Reduced) );
rc = pWalker->xExprCallback(pWalker, pExpr);
if( rc==WRC_Continue
&& !ExprHasAnyProperty(pExpr,EP_TokenOnly) ){
if( sqlite4WalkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
if( sqlite4WalkExpr(pWalker, pExpr->pRight) ) return WRC_Abort;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
if( sqlite4WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
}else{
if( sqlite4WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
}
}
return rc & WRC_Abort;
}
/*
** Call sqlite4WalkExpr() for every expression in list p or until
** an abort request is seen.
*/
SQLITE_PRIVATE int sqlite4WalkExprList(Walker *pWalker, ExprList *p){
int i;
struct ExprList_item *pItem;
if( p ){
for(i=p->nExpr, pItem=p->a; i>0; i--, pItem++){
if( sqlite4WalkExpr(pWalker, pItem->pExpr) ) return WRC_Abort;
}
}
return WRC_Continue;
}
/*
** Walk all expressions associated with SELECT statement p. Do
** not invoke the SELECT callback on p, but do (of course) invoke
** any expr callbacks and SELECT callbacks that come from subqueries.
** Return WRC_Abort or WRC_Continue.
*/
SQLITE_PRIVATE int sqlite4WalkSelectExpr(Walker *pWalker, Select *p){
if( sqlite4WalkExprList(pWalker, p->pEList) ) return WRC_Abort;
if( sqlite4WalkExpr(pWalker, p->pWhere) ) return WRC_Abort;
if( sqlite4WalkExprList(pWalker, p->pGroupBy) ) return WRC_Abort;
if( sqlite4WalkExpr(pWalker, p->pHaving) ) return WRC_Abort;
if( sqlite4WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort;
if( sqlite4WalkExpr(pWalker, p->pLimit) ) return WRC_Abort;
if( sqlite4WalkExpr(pWalker, p->pOffset) ) return WRC_Abort;
return WRC_Continue;
}
/*
** Walk the parse trees associated with all subqueries in the
** FROM clause of SELECT statement p. Do not invoke the select
** callback on p, but do invoke it on each FROM clause subquery
** and on any subqueries further down in the tree. Return
** WRC_Abort or WRC_Continue;
*/
SQLITE_PRIVATE int sqlite4WalkSelectFrom(Walker *pWalker, Select *p){
SrcList *pSrc;
int i;
struct SrcList_item *pItem;
pSrc = p->pSrc;
if( ALWAYS(pSrc) ){
for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
if( sqlite4WalkSelect(pWalker, pItem->pSelect) ){
return WRC_Abort;
}
}
}
return WRC_Continue;
}
/*
** Call sqlite4WalkExpr() for every expression in Select statement p.
** Invoke sqlite4WalkSelect() for subqueries in the FROM clause and
** on the compound select chain, p->pPrior.
**
** Return WRC_Continue under normal conditions. Return WRC_Abort if
** there is an abort request.
**
** If the Walker does not have an xSelectCallback() then this routine
** is a no-op returning WRC_Continue.
*/
SQLITE_PRIVATE int sqlite4WalkSelect(Walker *pWalker, Select *p){
int rc;
if( p==0 || pWalker->xSelectCallback==0 ) return WRC_Continue;
rc = WRC_Continue;
while( p ){
rc = pWalker->xSelectCallback(pWalker, p);
if( rc ) break;
if( sqlite4WalkSelectExpr(pWalker, p) ) return WRC_Abort;
if( sqlite4WalkSelectFrom(pWalker, p) ) return WRC_Abort;
p = p->pPrior;
}
return rc & WRC_Abort;
}
/************** End of walker.c **********************************************/
/************** Begin file resolve.c *****************************************/
/*
** 2008 August 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 routines used for walking the parser tree and
** resolve all identifiers by associating them with a particular
** table and column.
*/
/* #include <stdlib.h> */
/* #include <string.h> */
/*
** Turn the pExpr expression into an alias for the iCol-th column of the
** result set in pEList.
**
** If the result set column is a simple column reference, then this routine
** makes an exact copy. But for any other kind of expression, this
** routine make a copy of the result set column as the argument to the
** TK_AS operator. The TK_AS operator causes the expression to be
** evaluated just once and then reused for each alias.
**
** The reason for suppressing the TK_AS term when the expression is a simple
** column reference is so that the column reference will be recognized as
** usable by indices within the WHERE clause processing logic.
**
** Hack: The TK_AS operator is inhibited if zType[0]=='G'. This means
** that in a GROUP BY clause, the expression is evaluated twice. Hence:
**
** SELECT random()%5 AS x, count(*) FROM tab GROUP BY x
**
** Is equivalent to:
**
** SELECT random()%5 AS x, count(*) FROM tab GROUP BY random()%5
**
** The result of random()%5 in the GROUP BY clause is probably different
** from the result in the result-set. We might fix this someday. Or
** then again, we might not...
*/
static void resolveAlias(
Parse *pParse, /* Parsing context */
ExprList *pEList, /* A result set */
int iCol, /* A column in the result set. 0..pEList->nExpr-1 */
Expr *pExpr, /* Transform this into an alias to the result set */
const char *zType /* "GROUP" or "ORDER" or "" */
){
Expr *pOrig; /* The iCol-th column of the result set */
Expr *pDup; /* Copy of pOrig */
sqlite4 *db; /* The database connection */
assert( iCol>=0 && iCol<pEList->nExpr );
pOrig = pEList->a[iCol].pExpr;
assert( pOrig!=0 );
assert( pOrig->flags & EP_Resolved );
db = pParse->db;
if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){
pDup = sqlite4ExprDup(db, pOrig, 0);
pDup = sqlite4PExpr(pParse, TK_AS, pDup, 0, 0);
if( pDup==0 ) return;
if( pEList->a[iCol].iAlias==0 ){
pEList->a[iCol].iAlias = (u16)(++pParse->nAlias);
}
pDup->iTable = pEList->a[iCol].iAlias;
}else if( ExprHasProperty(pOrig, EP_IntValue) || pOrig->u.zToken==0 ){
pDup = sqlite4ExprDup(db, pOrig, 0);
if( pDup==0 ) return;
}else{
char *zToken = pOrig->u.zToken;
assert( zToken!=0 );
pOrig->u.zToken = 0;
pDup = sqlite4ExprDup(db, pOrig, 0);
pOrig->u.zToken = zToken;
if( pDup==0 ) return;
assert( (pDup->flags & (EP_Reduced|EP_TokenOnly))==0 );
pDup->flags2 |= EP2_MallocedToken;
pDup->u.zToken = sqlite4DbStrDup(db, zToken);
}
if( pExpr->flags & EP_ExpCollate ){
pDup->pColl = pExpr->pColl;
pDup->flags |= EP_ExpCollate;
}
/* Before calling sqlite4ExprDelete(), set the EP_Static flag. This
** prevents ExprDelete() from deleting the Expr structure itself,
** allowing it to be repopulated by the memcpy() on the following line.
*/
ExprSetProperty(pExpr, EP_Static);
sqlite4ExprDelete(db, pExpr);
memcpy(pExpr, pDup, sizeof(*pExpr));
sqlite4DbFree(db, pDup);
}
/*
** Return TRUE if the name zCol occurs anywhere in the USING clause.
**
** Return FALSE if the USING clause is NULL or if it does not contain
** zCol.
*/
static int nameInUsingClause(IdList *pUsing, const char *zCol){
if( pUsing ){
int k;
for(k=0; k<pUsing->nId; k++){
if( sqlite4StrICmp(pUsing->a[k].zName, zCol)==0 ) return 1;
}
}
return 0;
}
/*
** Return true if table pTab has an implicit primary key, and zCol points
** to a column name that resolves to the implicit primary key (i.e. "rowid").
*/
int isRowidReference(Table *pTab, const char *zCol){
int ret = 0;
if( 0==sqlite4StrICmp(zCol, "ROWID") ){
/* If the call to FindPrimaryKey() returns NULL, then pTab must be a
** sub-select or a view. Neither of these have an IPK. */
Index *pPk = sqlite4FindPrimaryKey(pTab, 0);
if( pPk && pPk->aiColumn[0]==-1 ) ret = 1;
}
return ret;
}
/*
** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
** that name in the set of source tables in pSrcList and make the pExpr
** expression node refer back to that source column. The following changes
** are made to pExpr:
**
** pExpr->iDb Set the index in db->aDb[] of the database X
** (even if X is implied).
** pExpr->iTable Set to the cursor number for the table obtained
** from pSrcList.
** pExpr->pTab Points to the Table structure of X.Y (even if
** X and/or Y are implied.)
** pExpr->iColumn Set to the column number within the table.
** pExpr->op Set to TK_COLUMN.
** pExpr->pLeft Any expression this points to is deleted
** pExpr->pRight Any expression this points to is deleted.
**
** The zDb variable is the name of the database (the "X"). This value may be
** NULL meaning that name is of the form Y.Z or Z. Any available database
** can be used. The zTable variable is the name of the table (the "Y"). This
** value can be NULL if zDb is also NULL. If zTable is NULL it
** means that the form of the name is Z and that columns from any table
** can be used.
**
** If the name cannot be resolved unambiguously, leave an error message
** in pParse and return WRC_Abort. Return WRC_Prune on success.
*/
static int lookupName(
Parse *pParse, /* The parsing context */
const char *zDb, /* Name of the database containing table, or NULL */
const char *zTab, /* Name of table containing column, or NULL */
const char *zCol, /* Name of the column. */
NameContext *pNC, /* The name context used to resolve the name */
Expr *pExpr /* Make this EXPR node point to the selected column */
){
int i, j; /* Loop counters */
int cnt = 0; /* Number of matching column names */
int cntTab = 0; /* Number of matching table names */
sqlite4 *db = pParse->db; /* The database connection */
struct SrcList_item *pItem; /* Use for looping over pSrcList items */
struct SrcList_item *pMatch = 0; /* The matching pSrcList item */
NameContext *pTopNC = pNC; /* First namecontext in the list */
Schema *pSchema = 0; /* Schema of the expression */
int isTrigger = 0;
assert( pNC ); /* the name context cannot be NULL. */
assert( zCol ); /* The Z in X.Y.Z cannot be NULL */
assert( ~ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
/* Initialize the node to no-match */
pExpr->iTable = -1;
pExpr->pTab = 0;
ExprSetIrreducible(pExpr);
/* Start at the inner-most context and move outward until a match is found */
while( pNC && cnt==0 ){
ExprList *pEList;
SrcList *pSrcList = pNC->pSrcList;
if( pSrcList ){
for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
Table *pTab;
int iDb;
Column *pCol;
pTab = pItem->pTab;
assert( pTab!=0 && pTab->zName!=0 );
iDb = sqlite4SchemaToIndex(db, pTab->pSchema);
assert( pTab->nCol>0 );
if( zTab ){
if( pItem->zAlias ){
char *zTabName = pItem->zAlias;
if( sqlite4StrICmp(zTabName, zTab)!=0 ) continue;
}else{
char *zTabName = pTab->zName;
if( NEVER(zTabName==0) || sqlite4StrICmp(zTabName, zTab)!=0 ){
continue;
}
if( zDb!=0 && sqlite4StrICmp(db->aDb[iDb].zName, zDb)!=0 ){
continue;
}
}
}
if( 0==(cntTab++) ){
pExpr->iTable = pItem->iCursor;
pExpr->pTab = pTab;
pSchema = pTab->pSchema;
pMatch = pItem;
}
for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
if( sqlite4StrICmp(pCol->zName, zCol)==0 ){
/* If there has been exactly one prior match and this match
** is for the right-hand table of a NATURAL JOIN or is in a
** USING clause, then skip this match.
*/
if( cnt==1 ){
if( pItem->jointype & JT_NATURAL ) continue;
if( nameInUsingClause(pItem->pUsing, zCol) ) continue;
}
cnt++;
pExpr->iTable = pItem->iCursor;
pExpr->pTab = pTab;
pMatch = pItem;
pSchema = pTab->pSchema;
pExpr->iColumn = (i16)j;
break;
}
}
}
}
#ifndef SQLITE_OMIT_TRIGGER
/* If we have not already resolved the name, then maybe
** it is a new.* or old.* trigger argument reference
*/
if( zDb==0 && zTab!=0 && cnt==0 && pParse->pTriggerTab!=0 ){
int op = pParse->eTriggerOp;
Table *pTab = 0;
assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT );
if( op!=TK_DELETE && sqlite4StrICmp("new",zTab) == 0 ){
pExpr->iTable = 1;
pTab = pParse->pTriggerTab;
}else if( op!=TK_INSERT && sqlite4StrICmp("old",zTab)==0 ){
pExpr->iTable = 0;
pTab = pParse->pTriggerTab;
}
if( pTab ){
int iCol;
pSchema = pTab->pSchema;
cntTab++;
for(iCol=0; iCol<pTab->nCol; iCol++){
Column *pCol = &pTab->aCol[iCol];
if( sqlite4StrICmp(pCol->zName, zCol)==0 ){
break;
}
}
if( iCol>=pTab->nCol && isRowidReference(pTab, zCol) ){
iCol = -1; /* IMP: R-44911-55124 */
}
if( iCol<pTab->nCol ){
cnt++;
if( iCol<0 ){
pExpr->affinity = SQLITE_AFF_INTEGER;
}else if( pExpr->iTable==0 ){
testcase( iCol==31 );
testcase( iCol==32 );
pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
}else{
testcase( iCol==31 );
testcase( iCol==32 );
pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
}
pExpr->iColumn = (i16)iCol;
isTrigger = 1;
}
pExpr->pTab = pTab;
}
}
#endif /* !defined(SQLITE_OMIT_TRIGGER) */
/*
** Perhaps the name is a reference to the ROWID
*/
if( cnt==0 && cntTab==1 && isRowidReference(pExpr->pTab, zCol) ){
cnt = 1;
pExpr->iColumn = -1; /* IMP: R-44911-55124 */
pExpr->affinity = SQLITE_AFF_INTEGER;
}
/*
** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z
** might refer to an result-set alias. This happens, for example, when
** we are resolving names in the WHERE clause of the following command:
**
** SELECT a+b AS x FROM table WHERE x<10;
**
** In cases like this, replace pExpr with a copy of the expression that
** forms the result set entry ("a+b" in the example) and return immediately.
** Note that the expression in the result set should have already been
** resolved by the time the WHERE clause is resolved.
*/
if( cnt==0 && (pEList = pNC->pEList)!=0 && zTab==0 ){
for(j=0; j<pEList->nExpr; j++){
char *zAs = pEList->a[j].zName;
if( zAs!=0 && sqlite4StrICmp(zAs, zCol)==0 ){
Expr *pOrig;
assert( pExpr->pLeft==0 && pExpr->pRight==0 );
assert( pExpr->x.pList==0 );
assert( pExpr->x.pSelect==0 );
pOrig = pEList->a[j].pExpr;
if( !pNC->allowAgg && ExprHasProperty(pOrig, EP_Agg) ){
sqlite4ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
return WRC_Abort;
}
resolveAlias(pParse, pEList, j, pExpr, "");
cnt = 1;
pMatch = 0;
assert( zTab==0 && zDb==0 );
goto lookupname_end;
}
}
}
/* 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==0 ){
pNC = pNC->pNext;
}
}
/*
** 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
** Z is a string literal if it doesn't match any column names. In that
** case, we need to return right away and not make any changes to
** pExpr.
**
** Because no reference was made to outer contexts, the pNC->nRef
** fields are not changed in any context.
*/
if( cnt==0 && zTab==0 && ExprHasProperty(pExpr,EP_DblQuoted) ){
pExpr->op = TK_STRING;
pExpr->pTab = 0;
return WRC_Prune;
}
/*
** cnt==0 means there was not match. cnt>1 means there were two or
** more matches. Either way, we have an error.
*/
if( cnt!=1 ){
const char *zErr;
zErr = cnt==0 ? "no such column" : "ambiguous column name";
if( zDb ){
sqlite4ErrorMsg(pParse, "%s: %s.%s.%s", zErr, zDb, zTab, zCol);
}else if( zTab ){
sqlite4ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol);
}else{
sqlite4ErrorMsg(pParse, "%s: %s", zErr, zCol);
}
pParse->checkSchema = 1;
pTopNC->nErr++;
}
/* If a column from a table in pSrcList is referenced, then record
** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes
** bit 0 to be set. Column 1 sets bit 1. And so forth. If the
** column number is greater than the number of bits in the bitmask
** then set the high-order bit of the bitmask.
*/
if( pExpr->iColumn>=0 && pMatch!=0 ){
int n = pExpr->iColumn;
testcase( n==BMS-1 );
if( n>=BMS ){
n = BMS-1;
}
assert( pMatch->iCursor==pExpr->iTable );
pMatch->colUsed |= ((Bitmask)1)<<n;
}
/* Clean up and return
*/
sqlite4ExprDelete(db, pExpr->pLeft);
pExpr->pLeft = 0;
sqlite4ExprDelete(db, pExpr->pRight);
pExpr->pRight = 0;
pExpr->op = (isTrigger ? TK_TRIGGER : TK_COLUMN);
lookupname_end:
if( cnt==1 ){
assert( pNC!=0 );
sqlite4AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
/* Increment the nRef value on all name contexts from TopNC up to
** the point where the name matched. */
for(;;){
assert( pTopNC!=0 );
pTopNC->nRef++;
if( pTopNC==pNC ) break;
pTopNC = pTopNC->pNext;
}
return WRC_Prune;
} else {
return WRC_Abort;
}
}
/*
** Allocate and return a pointer to an expression to load the column iCol
** from datasource iSrc in SrcList pSrc.
*/
SQLITE_PRIVATE Expr *sqlite4CreateColumnExpr(sqlite4 *db, SrcList *pSrc, int iSrc, int iCol){
Expr *p = sqlite4ExprAlloc(db, TK_COLUMN, 0, 0);
if( p ){
struct SrcList_item *pItem = &pSrc->a[iSrc];
p->pTab = pItem->pTab;
p->iTable = pItem->iCursor;
p->iColumn = (ynVar)iCol;
testcase( iCol==BMS );
testcase( iCol==BMS-1 );
pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol);
ExprSetProperty(p, EP_Resolved);
}
return p;
}
/*
** This routine is callback for sqlite4WalkExpr().
**
** Resolve symbolic names into TK_COLUMN operators for the current
** node in the expression tree. Return 0 to continue the search down
** the tree or 2 to abort the tree walk.
**
** This routine also does error checking and name resolution for
** function names. The operator for aggregate functions is changed
** to TK_AGG_FUNCTION.
*/
static int resolveExprStep(Walker *pWalker, Expr *pExpr){
NameContext *pNC;
Parse *pParse;
pNC = pWalker->u.pNC;
assert( pNC!=0 );
pParse = pNC->pParse;
assert( pParse==pWalker->pParse );
if( ExprHasAnyProperty(pExpr, EP_Resolved) ) return WRC_Prune;
ExprSetProperty(pExpr, EP_Resolved);
#ifndef NDEBUG
if( pNC->pSrcList && pNC->pSrcList->nAlloc>0 ){
SrcList *pSrcList = pNC->pSrcList;
int i;
for(i=0; i<pNC->pSrcList->nSrc; i++){
assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursor<pParse->nTab);
}
}
#endif
switch( pExpr->op ){
#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
/* The special operator TK_ROW means use the rowid for the first
** column in the FROM clause. This is used by the LIMIT and ORDER BY
** clause processing on UPDATE and DELETE statements.
*/
case TK_ROW: {
SrcList *pSrcList = pNC->pSrcList;
struct SrcList_item *pItem;
assert( pSrcList && pSrcList->nSrc==1 );
pItem = pSrcList->a;
pExpr->op = TK_COLUMN;
pExpr->pTab = pItem->pTab;
pExpr->iTable = pItem->iCursor;
pExpr->iColumn = -1;
pExpr->affinity = SQLITE_AFF_INTEGER;
break;
}
#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */
/* A lone identifier is the name of a column.
*/
case TK_ID: {
return lookupName(pParse, 0, 0, pExpr->u.zToken, pNC, pExpr);
}
/* A table name and column name: ID.ID
** Or a database, table and column: ID.ID.ID
*/
case TK_DOT: {
const char *zColumn;
const char *zTable;
const char *zDb;
Expr *pRight;
/* if( pSrcList==0 ) break; */
pRight = pExpr->pRight;
if( pRight->op==TK_ID ){
zDb = 0;
zTable = pExpr->pLeft->u.zToken;
zColumn = pRight->u.zToken;
}else{
assert( pRight->op==TK_DOT );
zDb = pExpr->pLeft->u.zToken;
zTable = pRight->pLeft->u.zToken;
zColumn = pRight->pRight->u.zToken;
}
return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr);
}
/* Resolve function names
*/
case TK_CONST_FUNC:
case TK_FUNCTION: {
ExprList *pList = pExpr->x.pList; /* The argument list */
int n = pList ? pList->nExpr : 0; /* Number of arguments */
int no_such_func = 0; /* True if no such function exists */
int wrong_num_args = 0; /* True if wrong number of arguments */
int is_agg = 0; /* True if is an aggregate function */
int auth; /* Authorization to use the function */
int nId; /* Number of characters in function name */
const char *zId; /* The function name. */
FuncDef *pDef; /* Information about the function */
u8 enc = ENC(pParse->db); /* The database encoding */
testcase( pExpr->op==TK_CONST_FUNC );
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
zId = pExpr->u.zToken;
nId = sqlite4Strlen30(zId);
pDef = sqlite4FindFunction(pParse->db, zId, nId, n, enc, 0);
if( pDef==0 ){
pDef = sqlite4FindFunction(pParse->db, zId, nId, -1, enc, 0);
if( pDef==0 ){
no_such_func = 1;
}else{
wrong_num_args = 1;
}
}else{
is_agg = pDef->xFunc==0;
}
#ifndef SQLITE_OMIT_AUTHORIZATION
if( pDef ){
auth = sqlite4AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0);
if( auth!=SQLITE_OK ){
if( auth==SQLITE_DENY ){
sqlite4ErrorMsg(pParse, "not authorized to use function: %s",
pDef->zName);
pNC->nErr++;
}
pExpr->op = TK_NULL;
return WRC_Prune;
}
}
#endif
if( is_agg && !pNC->allowAgg ){
sqlite4ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
pNC->nErr++;
is_agg = 0;
}else if( no_such_func ){
sqlite4ErrorMsg(pParse, "no such function: %.*s", nId, zId);
pNC->nErr++;
}else if( wrong_num_args ){
sqlite4ErrorMsg(pParse,"wrong number of arguments to function %.*s()",
nId, zId);
pNC->nErr++;
}
if( is_agg ){
pExpr->op = TK_AGG_FUNCTION;
pNC->hasAgg = 1;
}
if( is_agg ) pNC->allowAgg = 0;
sqlite4WalkExprList(pWalker, pList);
if( is_agg ) pNC->allowAgg = 1;
/* FIX ME: Compute pExpr->affinity based on the expected return
** type of the function
*/
return WRC_Prune;
}
#ifndef SQLITE_OMIT_SUBQUERY
case TK_SELECT:
case TK_EXISTS: testcase( pExpr->op==TK_EXISTS );
#endif
case TK_IN: {
testcase( pExpr->op==TK_IN );
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
int nRef = pNC->nRef;
#ifndef SQLITE_OMIT_CHECK
if( pNC->isCheck ){
sqlite4ErrorMsg(pParse,"subqueries prohibited in CHECK constraints");
}
#endif
sqlite4WalkSelect(pWalker, pExpr->x.pSelect);
assert( pNC->nRef>=nRef );
if( nRef!=pNC->nRef ){
ExprSetProperty(pExpr, EP_VarSelect);
}
}
break;
}
#ifndef SQLITE_OMIT_CHECK
case TK_VARIABLE: {
if( pNC->isCheck ){
sqlite4ErrorMsg(pParse,"parameters prohibited in CHECK constraints");
}
break;
}
#endif
}
return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue;
}
/*
** pEList is a list of expressions which are really the result set of the
** a SELECT statement. pE is a term in an ORDER BY or GROUP BY clause.
** This routine checks to see if pE is a simple identifier which corresponds
** to the AS-name of one of the terms of the expression list. If it is,
** this routine return an integer between 1 and N where N is the number of
** elements in pEList, corresponding to the matching entry. If there is
** no match, or if pE is not a simple identifier, then this routine
** return 0.
**
** pEList has been resolved. pE has not.
*/
static int resolveAsName(
Parse *pParse, /* Parsing context for error messages */
ExprList *pEList, /* List of expressions to scan */
Expr *pE /* Expression we are trying to match */
){
int i; /* Loop counter */
UNUSED_PARAMETER(pParse);
if( pE->op==TK_ID ){
char *zCol = pE->u.zToken;
for(i=0; i<pEList->nExpr; i++){
char *zAs = pEList->a[i].zName;
if( zAs!=0 && sqlite4StrICmp(zAs, zCol)==0 ){
return i+1;
}
}
}
return 0;
}
/*
** pE is a pointer to an expression which is a single term in the
** ORDER BY of a compound SELECT. The expression has not been
** name resolved.
**
** At the point this routine is called, we already know that the
** ORDER BY term is not an integer index into the result set. That
** case is handled by the calling routine.
**
** Attempt to match pE against result set columns in the left-most
** SELECT statement. Return the index i of the matching column,
** as an indication to the caller that it should sort by the i-th column.
** The left-most column is 1. In other words, the value returned is the
** same integer value that would be used in the SQL statement to indicate
** the column.
**
** If there is no match, return 0. Return -1 if an error occurs.
*/
static int resolveOrderByTermToExprList(
Parse *pParse, /* Parsing context for error messages */
Select *pSelect, /* The SELECT statement with the ORDER BY clause */
Expr *pE /* The specific ORDER BY term */
){
int i; /* Loop counter */
ExprList *pEList; /* The columns of the result set */
NameContext nc; /* Name context for resolving pE */
sqlite4 *db; /* Database connection */
int rc; /* Return code from subprocedures */
u8 savedSuppErr; /* Saved value of db->suppressErr */
assert( sqlite4ExprIsInteger(pE, &i)==0 );
pEList = pSelect->pEList;
/* Resolve all names in the ORDER BY term expression
*/
memset(&nc, 0, sizeof(nc));
nc.pParse = pParse;
nc.pSrcList = pSelect->pSrc;
nc.pEList = pEList;
nc.allowAgg = 1;
nc.nErr = 0;
db = pParse->db;
savedSuppErr = db->suppressErr;
db->suppressErr = 1;
rc = sqlite4ResolveExprNames(&nc, pE);
db->suppressErr = savedSuppErr;
if( rc ) return 0;
/* Try to match the ORDER BY expression against an expression
** in the result set. Return an 1-based index of the matching
** result-set entry.
*/
for(i=0; i<pEList->nExpr; i++){
if( sqlite4ExprCompare(pEList->a[i].pExpr, pE)<2 ){
return i+1;
}
}
/* If no match, return 0. */
return 0;
}
/*
** Generate an ORDER BY or GROUP BY term out-of-range error.
*/
static void resolveOutOfRangeError(
Parse *pParse, /* The error context into which to write the error */
const char *zType, /* "ORDER" or "GROUP" */
int i, /* The index (1-based) of the term out of range */
int mx /* Largest permissible value of i */
){
sqlite4ErrorMsg(pParse,
"%r %s BY term out of range - should be "
"between 1 and %d", i, zType, mx);
}
/*
** Analyze the ORDER BY clause in a compound SELECT statement. Modify
** each term of the ORDER BY clause is a constant integer between 1
** and N where N is the number of columns in the compound SELECT.
**
** ORDER BY terms that are already an integer between 1 and N are
** unmodified. ORDER BY terms that are integers outside the range of
** 1 through N generate an error. ORDER BY terms that are expressions
** are matched against result set expressions of compound SELECT
** beginning with the left-most SELECT and working toward the right.
** At the first match, the ORDER BY expression is transformed into
** the integer column number.
**
** Return the number of errors seen.
*/
static int resolveCompoundOrderBy(
Parse *pParse, /* Parsing context. Leave error messages here */
Select *pSelect /* The SELECT statement containing the ORDER BY */
){
int i;
ExprList *pOrderBy;
ExprList *pEList;
sqlite4 *db;
int moreToDo = 1;
pOrderBy = pSelect->pOrderBy;
if( pOrderBy==0 ) return 0;
db = pParse->db;
#if SQLITE_MAX_COLUMN
if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
sqlite4ErrorMsg(pParse, "too many terms in ORDER BY clause");
return 1;
}
#endif
for(i=0; i<pOrderBy->nExpr; i++){
pOrderBy->a[i].done = 0;
}
pSelect->pNext = 0;
while( pSelect->pPrior ){
pSelect->pPrior->pNext = pSelect;
pSelect = pSelect->pPrior;
}
while( pSelect && moreToDo ){
struct ExprList_item *pItem;
moreToDo = 0;
pEList = pSelect->pEList;
assert( pEList!=0 );
for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
int iCol = -1;
Expr *pE, *pDup;
if( pItem->done ) continue;
pE = pItem->pExpr;
if( sqlite4ExprIsInteger(pE, &iCol) ){
if( iCol<=0 || iCol>pEList->nExpr ){
resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr);
return 1;
}
}else{
iCol = resolveAsName(pParse, pEList, pE);
if( iCol==0 ){
pDup = sqlite4ExprDup(db, pE, 0);
if( !db->mallocFailed ){
assert(pDup);
iCol = resolveOrderByTermToExprList(pParse, pSelect, pDup);
}
sqlite4ExprDelete(db, pDup);
}
}
if( iCol>0 ){
CollSeq *pColl = pE->pColl;
int flags = pE->flags & EP_ExpCollate;
sqlite4ExprDelete(db, pE);
pItem->pExpr = pE = sqlite4Expr(db, TK_INTEGER, 0);
if( pE==0 ) return 1;
pE->pColl = pColl;
pE->flags |= EP_IntValue | flags;
pE->u.iValue = iCol;
pItem->iOrderByCol = (u16)iCol;
pItem->done = 1;
}else{
moreToDo = 1;
}
}
pSelect = pSelect->pNext;
}
for(i=0; i<pOrderBy->nExpr; i++){
if( pOrderBy->a[i].done==0 ){
sqlite4ErrorMsg(pParse, "%r ORDER BY term does not match any "
"column in the result set", i+1);
return 1;
}
}
return 0;
}
/*
** Check every term in the ORDER BY or GROUP BY clause pOrderBy of
** the SELECT statement pSelect. If any term is reference to a
** result set expression (as determined by the ExprList.a.iCol field)
** then convert that term into a copy of the corresponding result set
** column.
**
** If any errors are detected, add an error message to pParse and
** return non-zero. Return zero if no errors are seen.
*/
SQLITE_PRIVATE int sqlite4ResolveOrderGroupBy(
Parse *pParse, /* Parsing context. Leave error messages here */
Select *pSelect, /* The SELECT statement containing the clause */
ExprList *pOrderBy, /* The ORDER BY or GROUP BY clause to be processed */
const char *zType /* "ORDER" or "GROUP" */
){
int i;
sqlite4 *db = pParse->db;
ExprList *pEList;
struct ExprList_item *pItem;
if( pOrderBy==0 || pParse->db->mallocFailed ) return 0;
#if SQLITE_MAX_COLUMN
if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
sqlite4ErrorMsg(pParse, "too many terms in %s BY clause", zType);
return 1;
}
#endif
pEList = pSelect->pEList;
assert( pEList!=0 ); /* sqlite4SelectNew() guarantees this */
for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
if( pItem->iOrderByCol ){
if( pItem->iOrderByCol>pEList->nExpr ){
resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr);
return 1;
}
resolveAlias(pParse, pEList, pItem->iOrderByCol-1, pItem->pExpr, zType);
}
}
return 0;
}
/*
** pOrderBy is an ORDER BY or GROUP BY clause in SELECT statement pSelect.
** The Name context of the SELECT statement is pNC. zType is either
** "ORDER" or "GROUP" depending on which type of clause pOrderBy is.
**
** This routine resolves each term of the clause into an expression.
** If the order-by term is an integer I between 1 and N (where N is the
** number of columns in the result set of the SELECT) then the expression
** in the resolution is a copy of the I-th result-set expression. If
** the order-by term is an identify that corresponds to the AS-name of
** a result-set expression, then the term resolves to a copy of the
** result-set expression. Otherwise, the expression is resolved in
** the usual way - using sqlite4ResolveExprNames().
**
** This routine returns the number of errors. If errors occur, then
** an appropriate error message might be left in pParse. (OOM errors
** excepted.)
*/
static int resolveOrderGroupBy(
NameContext *pNC, /* The name context of the SELECT statement */
Select *pSelect, /* The SELECT statement holding pOrderBy */
ExprList *pOrderBy, /* An ORDER BY or GROUP BY clause to resolve */
const char *zType /* Either "ORDER" or "GROUP", as appropriate */
){
int i; /* Loop counter */
int iCol; /* Column number */
struct ExprList_item *pItem; /* A term of the ORDER BY clause */
Parse *pParse; /* Parsing context */
int nResult; /* Number of terms in the result set */
if( pOrderBy==0 ) return 0;
nResult = pSelect->pEList->nExpr;
pParse = pNC->pParse;
for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
Expr *pE = pItem->pExpr;
iCol = resolveAsName(pParse, pSelect->pEList, pE);
if( iCol>0 ){
/* If an AS-name match is found, mark this ORDER BY column as being
** a copy of the iCol-th result-set column. The subsequent call to
** sqlite4ResolveOrderGroupBy() will convert the expression to a
** copy of the iCol-th result-set expression. */
pItem->iOrderByCol = (u16)iCol;
continue;
}
if( sqlite4ExprIsInteger(pE, &iCol) ){
/* The ORDER BY term is an integer constant. Again, set the column
** number so that sqlite4ResolveOrderGroupBy() will convert the
** order-by term to a copy of the result-set expression */
if( iCol<1 ){
resolveOutOfRangeError(pParse, zType, i+1, nResult);
return 1;
}
pItem->iOrderByCol = (u16)iCol;
continue;
}
/* Otherwise, treat the ORDER BY term as an ordinary expression */
pItem->iOrderByCol = 0;
if( sqlite4ResolveExprNames(pNC, pE) ){
return 1;
}
}
return sqlite4ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType);
}
/*
** Resolve names in the SELECT statement p and all of its descendents.
*/
static int resolveSelectStep(Walker *pWalker, Select *p){
NameContext *pOuterNC; /* Context that contains this SELECT */
NameContext sNC; /* Name context of this SELECT */
int isCompound; /* True if p is a compound select */
int nCompound; /* Number of compound terms processed so far */
Parse *pParse; /* Parsing context */
ExprList *pEList; /* Result set expression list */
int i; /* Loop counter */
ExprList *pGroupBy; /* The GROUP BY clause */
Select *pLeftmost; /* Left-most of SELECT of a compound */
sqlite4 *db; /* Database connection */
assert( p!=0 );
if( p->selFlags & SF_Resolved ){
return WRC_Prune;
}
pOuterNC = pWalker->u.pNC;
pParse = pWalker->pParse;
db = pParse->db;
/* Normally sqlite4SelectExpand() will be called first and will have
** already expanded this SELECT. However, if this is a subquery within
** an expression, sqlite4ResolveExprNames() will be called without a
** prior call to sqlite4SelectExpand(). When that happens, let
** sqlite4SelectPrep() do all of the processing for this SELECT.
** sqlite4SelectPrep() will invoke both sqlite4SelectExpand() and
** this routine in the correct order.
*/
if( (p->selFlags & SF_Expanded)==0 ){
sqlite4SelectPrep(pParse, p, pOuterNC);
return (pParse->nErr || db->mallocFailed) ? WRC_Abort : WRC_Prune;
}
isCompound = p->pPrior!=0;
nCompound = 0;
pLeftmost = p;
while( p ){
assert( (p->selFlags & SF_Expanded)!=0 );
assert( (p->selFlags & SF_Resolved)==0 );
p->selFlags |= SF_Resolved;
/* Resolve the expressions in the LIMIT and OFFSET clauses. These
** are not allowed to refer to any names, so pass an empty NameContext.
*/
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = pParse;
if( sqlite4ResolveExprNames(&sNC, p->pLimit) ||
sqlite4ResolveExprNames(&sNC, p->pOffset) ){
return WRC_Abort;
}
/* Set up the local name-context to pass to sqlite4ResolveExprNames() to
** resolve the result-set expression list.
*/
sNC.allowAgg = 1;
sNC.pSrcList = p->pSrc;
sNC.pNext = pOuterNC;
/* Resolve names in the result set. */
pEList = p->pEList;
assert( pEList!=0 );
for(i=0; i<pEList->nExpr; i++){
Expr *pX = pEList->a[i].pExpr;
if( sqlite4ResolveExprNames(&sNC, pX) ){
return WRC_Abort;
}
}
/* Recursively resolve names in all subqueries
*/
for(i=0; i<p->pSrc->nSrc; i++){
struct SrcList_item *pItem = &p->pSrc->a[i];
if( pItem->pSelect ){
NameContext *pNC; /* Used to iterate name contexts */
int nRef = 0; /* Refcount for pOuterNC and outer contexts */
const char *zSavedContext = pParse->zAuthContext;
/* Count the total number of references to pOuterNC and all of its
** parent contexts. After resolving references to expressions in
** pItem->pSelect, check if this value has changed. If so, then
** SELECT statement pItem->pSelect must be correlated. Set the
** pItem->isCorrelated flag if this is the case. */
for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef += pNC->nRef;
if( pItem->zName ) pParse->zAuthContext = pItem->zName;
sqlite4ResolveSelectNames(pParse, pItem->pSelect, pOuterNC);
pParse->zAuthContext = zSavedContext;
if( pParse->nErr || db->mallocFailed ) return WRC_Abort;
for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef -= pNC->nRef;
assert( pItem->isCorrelated==0 && nRef<=0 );
pItem->isCorrelated = (nRef!=0);
}
}
/* If there are no aggregate functions in the result-set, and no GROUP BY
** expression, do not allow aggregates in any of the other expressions.
*/
assert( (p->selFlags & SF_Aggregate)==0 );
pGroupBy = p->pGroupBy;
if( pGroupBy || sNC.hasAgg ){
p->selFlags |= SF_Aggregate;
}else{
sNC.allowAgg = 0;
}
/* If a HAVING clause is present, then there must be a GROUP BY clause.
*/
if( p->pHaving && !pGroupBy ){
sqlite4ErrorMsg(pParse, "a GROUP BY clause is required before HAVING");
return WRC_Abort;
}
/* Add the expression list to the name-context before parsing the
** other expressions in the SELECT statement. This is so that
** expressions in the WHERE clause (etc.) can refer to expressions by
** aliases in the result set.
**
** Minor point: If this is the case, then the expression will be
** re-evaluated for each reference to it.
*/
sNC.pEList = p->pEList;
if( sqlite4ResolveExprNames(&sNC, p->pWhere) ||
sqlite4ResolveExprNames(&sNC, p->pHaving)
){
return WRC_Abort;
}
/* The ORDER BY and GROUP BY clauses may not refer to terms in
** outer queries
*/
sNC.pNext = 0;
sNC.allowAgg = 1;
/* Process the ORDER BY clause for singleton SELECT statements.
** The ORDER BY clause for compounds SELECT statements is handled
** below, after all of the result-sets for all of the elements of
** the compound have been resolved.
*/
if( !isCompound && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER") ){
return WRC_Abort;
}
if( db->mallocFailed ){
return WRC_Abort;
}
/* Resolve the GROUP BY clause. At the same time, make sure
** the GROUP BY clause does not contain aggregate functions.
*/
if( pGroupBy ){
struct ExprList_item *pItem;
if( resolveOrderGroupBy(&sNC, p, pGroupBy, "GROUP") || db->mallocFailed ){
return WRC_Abort;
}
for(i=0, pItem=pGroupBy->a; i<pGroupBy->nExpr; i++, pItem++){
if( ExprHasProperty(pItem->pExpr, EP_Agg) ){
sqlite4ErrorMsg(pParse, "aggregate functions are not allowed in "
"the GROUP BY clause");
return WRC_Abort;
}
}
}
/* Advance to the next term of the compound
*/
p = p->pPrior;
nCompound++;
}
/* Resolve the ORDER BY on a compound SELECT after all terms of
** the compound have been resolved.
*/
if( isCompound && resolveCompoundOrderBy(pParse, pLeftmost) ){
return WRC_Abort;
}
return WRC_Prune;
}
/*
** This routine walks an expression tree and resolves references to
** table columns and result-set columns. At the same time, do error
** checking on function usage and set a flag if any aggregate functions
** are seen.
**
** To resolve table columns references we look for nodes (or subtrees) of the
** form X.Y.Z or Y.Z or just Z where
**
** X: The name of a database. Ex: "main" or "temp" or
** the symbolic name assigned to an ATTACH-ed database.
**
** Y: The name of a table in a FROM clause. Or in a trigger
** one of the special names "old" or "new".
**
** Z: The name of a column in table Y.
**
** The node at the root of the subtree is modified as follows:
**
** Expr.op Changed to TK_COLUMN
** Expr.pTab Points to the Table object for X.Y
** Expr.iColumn The column index in X.Y. -1 for the rowid.
** Expr.iTable The VDBE cursor number for X.Y
**
**
** To resolve result-set references, look for expression nodes of the
** form Z (with no X and Y prefix) where the Z matches the right-hand
** size of an AS clause in the result-set of a SELECT. The Z expression
** is replaced by a copy of the left-hand side of the result-set expression.
** Table-name and function resolution occurs on the substituted expression
** tree. For example, in:
**
** SELECT a+b AS x, c+d AS y FROM t1 ORDER BY x;
**
** The "x" term of the order by is replaced by "a+b" to render:
**
** SELECT a+b AS x, c+d AS y FROM t1 ORDER BY a+b;
**
** Function calls are checked to make sure that the function is
** defined and that the correct number of arguments are specified.
** If the function is an aggregate function, then the pNC->hasAgg is
** set and the opcode is changed from TK_FUNCTION to TK_AGG_FUNCTION.
** If an expression contains aggregate functions then the EP_Agg
** property on the expression is set.
**
** An error message is left in pParse if anything is amiss. The number
** if errors is returned.
*/
SQLITE_PRIVATE int sqlite4ResolveExprNames(
NameContext *pNC, /* Namespace to resolve expressions in. */
Expr *pExpr /* The expression to be analyzed. */
){
int savedHasAgg;
Walker w;
if( pExpr==0 ) return 0;
#if SQLITE_MAX_EXPR_DEPTH>0
{
Parse *pParse = pNC->pParse;
if( sqlite4ExprCheckHeight(pParse, pExpr->nHeight+pNC->pParse->nHeight) ){
return 1;
}
pParse->nHeight += pExpr->nHeight;
}
#endif
savedHasAgg = pNC->hasAgg;
pNC->hasAgg = 0;
w.xExprCallback = resolveExprStep;
w.xSelectCallback = resolveSelectStep;
w.pParse = pNC->pParse;
w.u.pNC = pNC;
sqlite4WalkExpr(&w, pExpr);
#if SQLITE_MAX_EXPR_DEPTH>0
pNC->pParse->nHeight -= pExpr->nHeight;
#endif
if( pNC->nErr>0 || w.pParse->nErr>0 ){
ExprSetProperty(pExpr, EP_Error);
}
if( pNC->hasAgg ){
ExprSetProperty(pExpr, EP_Agg);
}else if( savedHasAgg ){
pNC->hasAgg = 1;
}
return ExprHasProperty(pExpr, EP_Error);
}
/*
** Resolve all names in all expressions of a SELECT and in all
** decendents of the SELECT, including compounds off of p->pPrior,
** subqueries in expressions, and subqueries used as FROM clause
** terms.
**
** See sqlite4ResolveExprNames() for a description of the kinds of
** transformations that occur.
**
** All SELECT statements should have been expanded using
** sqlite4SelectExpand() prior to invoking this routine.
*/
SQLITE_PRIVATE void sqlite4ResolveSelectNames(
Parse *pParse, /* The parser context */
Select *p, /* The SELECT statement being coded. */
NameContext *pOuterNC /* Name context for parent SELECT statement */
){
Walker w;
assert( p!=0 );
w.xExprCallback = resolveExprStep;
w.xSelectCallback = resolveSelectStep;
w.pParse = pParse;
w.u.pNC = pOuterNC;
sqlite4WalkSelect(&w, p);
}
/************** End of resolve.c *********************************************/
/************** Begin file expr.c ********************************************/
/*
** 2001 September 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.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
*/
/*
** Return the 'affinity' of the expression pExpr if any.
**
** If pExpr is a column, a reference to a column via an 'AS' alias,
** or a sub-select with a column as the return value, then the
** affinity of that column is returned. Otherwise, 0x00 is returned,
** indicating no affinity for the expression.
**
** i.e. the WHERE clause expresssions in the following statements all
** have an affinity:
**
** CREATE TABLE t1(a);
** SELECT * FROM t1 WHERE a;
** SELECT a AS b FROM t1 WHERE b;
** SELECT * FROM t1 WHERE (select a from t1);
*/
SQLITE_PRIVATE char sqlite4ExprAffinity(Expr *pExpr){
int op = pExpr->op;
if( op==TK_SELECT ){
assert( pExpr->flags&EP_xIsSelect );
return sqlite4ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
}
#ifndef SQLITE_OMIT_CAST
if( op==TK_CAST ){
assert( !ExprHasProperty(pExpr, EP_IntValue) );
return sqlite4AffinityType(pExpr->u.zToken);
}
#endif
if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER)
&& pExpr->pTab!=0
){
/* op==TK_REGISTER && pExpr->pTab!=0 happens when pExpr was originally
** a TK_COLUMN but was previously evaluated and cached in a register */
int j = pExpr->iColumn;
if( j<0 ) return SQLITE_AFF_INTEGER;
assert( pExpr->pTab && j<pExpr->pTab->nCol );
return pExpr->pTab->aCol[j].affinity;
}
return pExpr->affinity;
}
/*
** Set the explicit collating sequence for an expression to the
** collating sequence supplied in the second argument.
*/
SQLITE_PRIVATE Expr *sqlite4ExprSetColl(Expr *pExpr, CollSeq *pColl){
if( pExpr && pColl ){
pExpr->pColl = pColl;
pExpr->flags |= EP_ExpCollate;
}
return pExpr;
}
/*
** Set the collating sequence for expression pExpr to be the collating
** sequence named by pToken. Return a pointer to the revised expression.
** The collating sequence is marked as "explicit" using the EP_ExpCollate
** flag. An explicit collating sequence will override implicit
** collating sequences.
*/
SQLITE_PRIVATE Expr *sqlite4ExprSetCollByToken(Parse *pParse, Expr *pExpr, Token *pCollName){
char *zColl = 0; /* Dequoted name of collation sequence */
CollSeq *pColl;
sqlite4 *db = pParse->db;
zColl = sqlite4NameFromToken(db, pCollName);
pColl = sqlite4LocateCollSeq(pParse, zColl);
sqlite4ExprSetColl(pExpr, pColl);
sqlite4DbFree(db, zColl);
return pExpr;
}
/*
** Return the default collation sequence for the expression pExpr. If
** there is no default collation type, return 0.
*/
SQLITE_PRIVATE CollSeq *sqlite4ExprCollSeq(Parse *pParse, Expr *pExpr){
CollSeq *pColl = 0;
Expr *p = pExpr;
while( p ){
int op;
pColl = p->pColl;
if( pColl ) break;
op = p->op;
if( p->pTab!=0 && (
op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER || op==TK_TRIGGER
)){
/* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
** a TK_COLUMN but was previously evaluated and cached in a register */
const char *zColl;
int j = p->iColumn;
if( j>=0 ){
sqlite4 *db = pParse->db;
zColl = p->pTab->aCol[j].zColl;
pColl = sqlite4FindCollSeq(db, ENC(db), zColl, 0);
pExpr->pColl = pColl;
}
break;
}
if( op!=TK_CAST && op!=TK_UPLUS ){
break;
}
p = p->pLeft;
}
if( sqlite4CheckCollSeq(pParse, pColl) ){
pColl = 0;
}
return pColl;
}
/*
** 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.
*/
SQLITE_PRIVATE char sqlite4CompareAffinity(Expr *pExpr, char aff2){
char aff1 = sqlite4ExprAffinity(pExpr);
if( aff1 && aff2 ){
/* Both sides of the comparison are columns. If one has numeric
** affinity, use that. Otherwise use no affinity.
*/
if( sqlite4IsNumericAffinity(aff1) || sqlite4IsNumericAffinity(aff2) ){
return SQLITE_AFF_NUMERIC;
}else{
return SQLITE_AFF_NONE;
}
}else if( !aff1 && !aff2 ){
/* Neither side of the comparison is a column. Compare the
** results directly.
*/
return SQLITE_AFF_NONE;
}else{
/* One side is a column, the other is not. Use the columns affinity. */
assert( aff1==0 || aff2==0 );
return (aff1 + aff2);
}
}
/*
** pExpr is a comparison operator. Return the type affinity that should
** be applied to both operands prior to doing the comparison.
*/
static char comparisonAffinity(Expr *pExpr){
char aff;
assert( pExpr->op==TK_EQ || pExpr->op==TK_IN || pExpr->op==TK_LT ||
pExpr->op==TK_GT || pExpr->op==TK_GE || pExpr->op==TK_LE ||
pExpr->op==TK_NE || pExpr->op==TK_IS || pExpr->op==TK_ISNOT );
assert( pExpr->pLeft );
aff = sqlite4ExprAffinity(pExpr->pLeft);
if( pExpr->pRight ){
aff = sqlite4CompareAffinity(pExpr->pRight, aff);
}else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
aff = sqlite4CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff);
}else if( !aff ){
aff = SQLITE_AFF_NONE;
}
return aff;
}
/*
** pExpr is a comparison expression, eg. '=', '<', IN(...) etc.
** idx_affinity is the affinity of an indexed column. Return true
** if the index with affinity idx_affinity may be used to implement
** the comparison in pExpr.
*/
SQLITE_PRIVATE int sqlite4IndexAffinityOk(Expr *pExpr, char idx_affinity){
char aff = comparisonAffinity(pExpr);
switch( aff ){
case SQLITE_AFF_NONE:
return 1;
case SQLITE_AFF_TEXT:
return idx_affinity==SQLITE_AFF_TEXT;
default:
return sqlite4IsNumericAffinity(idx_affinity);
}
}
/*
** Return the P5 value that should be used for a binary comparison
** opcode (OP_Eq, OP_Ge etc.) used to compare pExpr1 and pExpr2.
*/
static u8 binaryCompareP5(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){
u8 aff = (char)sqlite4ExprAffinity(pExpr2);
aff = (u8)sqlite4CompareAffinity(pExpr1, aff) | (u8)jumpIfNull;
return aff;
}
/*
** Return a pointer to the collation sequence that should be used by
** a binary comparison operator comparing pLeft and pRight.
**
** If the left hand expression has a collating sequence type, then it is
** used. Otherwise the collation sequence for the right hand expression
** is used, or the default (BINARY) if neither expression has a collating
** type.
**
** Argument pRight (but not pLeft) may be a null pointer. In this case,
** it is not considered.
*/
SQLITE_PRIVATE CollSeq *sqlite4BinaryCompareCollSeq(
Parse *pParse,
Expr *pLeft,
Expr *pRight
){
CollSeq *pColl;
assert( pLeft );
if( pLeft->flags & EP_ExpCollate ){
assert( pLeft->pColl );
pColl = pLeft->pColl;
}else if( pRight && pRight->flags & EP_ExpCollate ){
assert( pRight->pColl );
pColl = pRight->pColl;
}else{
pColl = sqlite4ExprCollSeq(pParse, pLeft);
if( !pColl ){
pColl = sqlite4ExprCollSeq(pParse, pRight);
}
}
return pColl;
}
/*
** Generate code for a comparison operator.
*/
static int codeCompare(
Parse *pParse, /* The parsing (and code generating) context */
Expr *pLeft, /* The left operand */
Expr *pRight, /* The right operand */
int opcode, /* The comparison opcode */
int in1, int in2, /* Register holding operands */
int dest, /* Jump here if true. */
int jumpIfNull /* If true, jump if either operand is NULL */
){
int p5;
int addr;
CollSeq *p4;
p4 = sqlite4BinaryCompareCollSeq(pParse, pLeft, pRight);
p5 = binaryCompareP5(pLeft, pRight, jumpIfNull);
addr = sqlite4VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1,
(void*)p4, P4_COLLSEQ);
sqlite4VdbeChangeP5(pParse->pVdbe, (u8)p5);
return addr;
}
#if SQLITE_MAX_EXPR_DEPTH>0
/*
** Check that argument nHeight is less than or equal to the maximum
** expression depth allowed. If it is not, leave an error message in
** pParse.
*/
SQLITE_PRIVATE int sqlite4ExprCheckHeight(Parse *pParse, int nHeight){
int rc = SQLITE_OK;
int mxHeight = pParse->db->aLimit[SQLITE_LIMIT_EXPR_DEPTH];
if( nHeight>mxHeight ){
sqlite4ErrorMsg(pParse,
"Expression tree is too large (maximum depth %d)", mxHeight
);
rc = SQLITE_ERROR;
}
return rc;
}
/* The following three functions, heightOfExpr(), heightOfExprList()
** and heightOfSelect(), are used to determine the maximum height
** of any expression tree referenced by the structure passed as the
** first argument.
**
** If this maximum height is greater than the current value pointed
** to by pnHeight, the second parameter, then set *pnHeight to that
** value.
*/
static void heightOfExpr(Expr *p, int *pnHeight){
if( p ){
if( p->nHeight>*pnHeight ){
*pnHeight = p->nHeight;
}
}
}
static void heightOfExprList(ExprList *p, int *pnHeight){
if( p ){
int i;
for(i=0; i<p->nExpr; i++){
heightOfExpr(p->a[i].pExpr, pnHeight);
}
}
}
static void heightOfSelect(Select *p, int *pnHeight){
if( p ){
heightOfExpr(p->pWhere, pnHeight);
heightOfExpr(p->pHaving, pnHeight);
heightOfExpr(p->pLimit, pnHeight);
heightOfExpr(p->pOffset, pnHeight);
heightOfExprList(p->pEList, pnHeight);
heightOfExprList(p->pGroupBy, pnHeight);
heightOfExprList(p->pOrderBy, pnHeight);
heightOfSelect(p->pPrior, pnHeight);
}
}
/*
** Set the Expr.nHeight variable in the structure passed as an
** argument. An expression with no children, Expr.pList or
** Expr.pSelect member has a height of 1. Any other expression
** has a height equal to the maximum height of any other
** referenced Expr plus one.
*/
static void exprSetHeight(Expr *p){
int nHeight = 0;
heightOfExpr(p->pLeft, &nHeight);
heightOfExpr(p->pRight, &nHeight);
if( ExprHasProperty(p, EP_xIsSelect) ){
heightOfSelect(p->x.pSelect, &nHeight);
}else{
heightOfExprList(p->x.pList, &nHeight);
}
p->nHeight = nHeight + 1;
}
/*
** Set the Expr.nHeight variable using the exprSetHeight() function. If
** the height is greater than the maximum allowed expression depth,
** leave an error in pParse.
*/
SQLITE_PRIVATE void sqlite4ExprSetHeight(Parse *pParse, Expr *p){
exprSetHeight(p);
sqlite4ExprCheckHeight(pParse, p->nHeight);
}
/*
** Return the maximum height of any expression tree referenced
** by the select statement passed as an argument.
*/
SQLITE_PRIVATE int sqlite4SelectExprHeight(Select *p){
int nHeight = 0;
heightOfSelect(p, &nHeight);
return nHeight;
}
#else
#define exprSetHeight(y)
#endif /* SQLITE_MAX_EXPR_DEPTH>0 */
/*
** This routine is the core allocator for Expr nodes.
**
** Construct a new expression node and return a pointer to it. Memory
** for this node and for the pToken argument is a single allocation
** obtained from sqlite4DbMalloc(). The calling function
** 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 performance. 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.
**
** Special case: If op==TK_INTEGER and pToken points to a string that
** can be translated into a 32-bit integer, then the token is not
** stored in u.zToken. Instead, the integer values is written
** into u.iValue and the EP_IntValue flag is set. No extra storage
** is allocated to hold the integer text and the dequote flag is ignored.
*/
SQLITE_PRIVATE Expr *sqlite4ExprAlloc(
sqlite4 *db, /* Handle for sqlite4DbMallocZero() (may be null) */
int op, /* Expression opcode */
const Token *pToken, /* Token argument. Might be NULL */
int dequote /* True to dequote */
){
Expr *pNew;
int nExtra = 0;
int iValue = 0;
if( pToken ){
if( op!=TK_INTEGER || pToken->z==0
|| sqlite4GetInt32(pToken->z, &iValue)==0 ){
nExtra = pToken->n+1;
assert( iValue>=0 );
}
}
pNew = sqlite4DbMallocZero(db, sizeof(Expr)+nExtra);
if( pNew ){
pNew->op = (u8)op;
pNew->iAgg = -1;
if( pToken ){
if( nExtra==0 ){
pNew->flags |= EP_IntValue;
pNew->u.iValue = iValue;
}else{
int c;
pNew->u.zToken = (char*)&pNew[1];
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 && nExtra>=3
&& ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){
sqlite4Dequote(pNew->u.zToken);
if( c=='"' ) pNew->flags |= EP_DblQuoted;
}
}
}
#if SQLITE_MAX_EXPR_DEPTH>0
pNew->nHeight = 1;
#endif
}
return pNew;
}
/*
** Allocate a new expression node from a zero-terminated token that has
** already been dequoted.
*/
SQLITE_PRIVATE Expr *sqlite4Expr(
sqlite4 *db, /* Handle for sqlite4DbMallocZero() (may be null) */
int op, /* Expression opcode */
const char *zToken /* Token argument. Might be NULL */
){
Token x;
x.z = zToken;
x.n = zToken ? sqlite4Strlen30(zToken) : 0;
return sqlite4ExprAlloc(db, op, &x, 0);
}
/*
** Attach subtrees pLeft and pRight to the Expr node pRoot.
**
** If pRoot==NULL that means that a memory allocation error has occurred.
** In that case, delete the subtrees pLeft and pRight.
*/
SQLITE_PRIVATE void sqlite4ExprAttachSubtrees(
sqlite4 *db,
Expr *pRoot,
Expr *pLeft,
Expr *pRight
){
if( pRoot==0 ){
assert( db->mallocFailed );
sqlite4ExprDelete(db, pLeft);
sqlite4ExprDelete(db, pRight);
}else{
if( pRight ){
pRoot->pRight = pRight;
if( pRight->flags & EP_ExpCollate ){
pRoot->flags |= EP_ExpCollate;
pRoot->pColl = pRight->pColl;
}
}
if( pLeft ){
pRoot->pLeft = pLeft;
if( pLeft->flags & EP_ExpCollate ){
pRoot->flags |= EP_ExpCollate;
pRoot->pColl = pLeft->pColl;
}
}
exprSetHeight(pRoot);
}
}
/*
** Allocate a Expr node which joins as many as two subtrees.
**
** One or both of the subtrees can be NULL. Return a pointer to the new
** Expr node. Or, if an OOM error occurs, set pParse->db->mallocFailed,
** free the subtrees and return NULL.
*/
SQLITE_PRIVATE Expr *sqlite4PExpr(
Parse *pParse, /* Parsing context */
int op, /* Expression opcode */
Expr *pLeft, /* Left operand */
Expr *pRight, /* Right operand */
const Token *pToken /* Argument token */
){
Expr *p = sqlite4ExprAlloc(pParse->db, op, pToken, 1);
sqlite4ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
if( p ) {
sqlite4ExprCheckHeight(pParse, p->nHeight);
}
return p;
}
/*
** Join two expressions using an AND operator. If either expression is
** NULL, then just return the other expression.
*/
SQLITE_PRIVATE Expr *sqlite4ExprAnd(sqlite4 *db, Expr *pLeft, Expr *pRight){
if( pLeft==0 ){
return pRight;
}else if( pRight==0 ){
return pLeft;
}else{
Expr *pNew = sqlite4ExprAlloc(db, TK_AND, 0, 0);
sqlite4ExprAttachSubtrees(db, pNew, pLeft, pRight);
return pNew;
}
}
/*
** Construct a new expression node for a function with multiple
** arguments.
*/
SQLITE_PRIVATE Expr *sqlite4ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){
Expr *pNew;
sqlite4 *db = pParse->db;
assert( pToken );
pNew = sqlite4ExprAlloc(db, TK_FUNCTION, pToken, 1);
if( pNew==0 ){
sqlite4ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */
return 0;
}
pNew->x.pList = pList;
assert( !ExprHasProperty(pNew, EP_xIsSelect) );
sqlite4ExprSetHeight(pParse, pNew);
return pNew;
}
/*
** Assign a variable number to an expression that encodes a wildcard
** in the original SQL statement.
**
** Wildcards consisting of a single "?" are assigned the next sequential
** variable number.
**
** Wildcards of the form "?nnn" are assigned the number "nnn". We make
** sure "nnn" is not too be 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
** as the previous instance of the same wildcard. Or if this is the first
** instance of the wildcard, the next sequenial variable number is
** assigned.
*/
SQLITE_PRIVATE void sqlite4ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
sqlite4 *db = pParse->db;
const char *z;
if( pExpr==0 ) return;
assert( !ExprHasAnyProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) );
z = pExpr->u.zToken;
assert( z!=0 );
assert( z[0]!=0 );
if( z[1]==0 ){
/* Wildcard of the form "?". Assign the next variable number */
assert( z[0]=='?' );
pExpr->iColumn = (ynVar)(++pParse->nVar);
}else{
ynVar x = 0;
u32 n = sqlite4Strlen30(z);
if( z[0]=='?' ){
/* Wildcard of the form "?nnn". Convert "nnn" to an integer and
** use it as the variable number */
i64 i;
int bOk = 0==sqlite4Atoi64(&z[1], &i, n-1, SQLITE_UTF8);
pExpr->iColumn = x = (ynVar)i;
testcase( i==0 );
testcase( i==1 );
testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] );
if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
sqlite4ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]);
x = 0;
}
if( i>pParse->nVar ){
pParse->nVar = (int)i;
}
}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
*/
ynVar i;
for(i=0; i<pParse->nzVar; i++){
if( pParse->azVar[i] && memcmp(pParse->azVar[i],z,n+1)==0 ){
pExpr->iColumn = x = (ynVar)i+1;
break;
}
}
if( x==0 ) x = pExpr->iColumn = (ynVar)(++pParse->nVar);
}
if( x>0 ){
if( x>pParse->nzVar ){
char **a;
a = sqlite4DbRealloc(db, pParse->azVar, x*sizeof(a[0]));
if( a==0 ) return; /* Error reported through db->mallocFailed */
pParse->azVar = a;
memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0]));
pParse->nzVar = x;
}
if( z[0]!='?' || pParse->azVar[x-1]==0 ){
sqlite4DbFree(db, pParse->azVar[x-1]);
pParse->azVar[x-1] = sqlite4DbStrNDup(db, z, n);
}
}
}
if( !pParse->nErr && pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
sqlite4ErrorMsg(pParse, "too many SQL variables");
}
}
/*
** Recursively delete an expression tree.
*/
SQLITE_PRIVATE void sqlite4ExprDelete(sqlite4 *db, Expr *p){
if( p==0 ) return;
/* Sanity check: Assert that the IntValue is non-negative if it exists */
assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
if( !ExprHasAnyProperty(p, EP_TokenOnly) ){
sqlite4ExprDelete(db, p->pLeft);
sqlite4ExprDelete(db, p->pRight);
if( !ExprHasProperty(p, EP_Reduced) && (p->flags2 & EP2_MallocedToken)!=0 ){
sqlite4DbFree(db, p->u.zToken);
}
if( ExprHasProperty(p, EP_xIsSelect) ){
sqlite4SelectDelete(db, p->x.pSelect);
}else{
sqlite4ExprListDelete(db, p->x.pList);
}
}
if( !ExprHasProperty(p, EP_Static) ){
sqlite4DbFree(db, p);
}
}
/*
** Return the number of bytes allocated for the expression structure
** passed as the first argument. This is always one of EXPR_FULLSIZE,
** EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE.
*/
static int exprStructSize(Expr *p){
if( ExprHasProperty(p, EP_TokenOnly) ) return EXPR_TOKENONLYSIZE;
if( ExprHasProperty(p, EP_Reduced) ) return EXPR_REDUCEDSIZE;
return EXPR_FULLSIZE;
}
/*
** The dupedExpr*Size() routines each return the number of bytes required
** to store a copy of an expression or expression tree. They differ in
** how much of the tree is measured.
**
** dupedExprStructSize() Size of only the Expr structure
** dupedExprNodeSize() Size of Expr + space for token
** dupedExprSize() Expr + token + subtree components
**
***************************************************************************
**
** The dupedExprStructSize() function returns two values OR-ed together:
** (1) the space required for a copy of the Expr structure only and
** (2) the EP_xxx flags that indicate what the structure size should be.
** The return values is always one of:
**
** EXPR_FULLSIZE
** EXPR_REDUCEDSIZE | EP_Reduced
** EXPR_TOKENONLYSIZE | EP_TokenOnly
**
** The size of the structure can be found by masking the return value
** of this routine with 0xfff. The flags can be found by masking the
** return value with EP_Reduced|EP_TokenOnly.
**
** Note that with flags==EXPRDUP_REDUCE, this routines works on full-size
** (unreduced) Expr objects as they or originally constructed by the parser.
** During expression analysis, extra information is computed and moved into
** later parts of teh Expr object and that extra information might get chopped
** off if the expression is reduced. Note also that it does not work to
** make a EXPRDUP_REDUCE copy of a reduced expression. It is only legal
** to reduce a pristine expression tree from the parser. The implementation
** of dupedExprStructSize() contain multiple assert() statements that attempt
** to enforce this constraint.
*/
static int dupedExprStructSize(Expr *p, int flags){
int nSize;
assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
if( 0==(flags&EXPRDUP_REDUCE) ){
nSize = EXPR_FULLSIZE;
}else{
assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) );
assert( !ExprHasProperty(p, EP_FromJoin) );
assert( (p->flags2 & EP2_MallocedToken)==0 );
assert( (p->flags2 & EP2_Irreducible)==0 );
if( p->pLeft || p->pRight || p->pColl || p->x.pList ){
nSize = EXPR_REDUCEDSIZE | EP_Reduced;
}else{
nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly;
}
}
return nSize;
}
/*
** This function returns the space in bytes required to store the copy
** of the Expr structure and a copy of the Expr.u.zToken string (if that
** string is defined.)
*/
static int dupedExprNodeSize(Expr *p, int flags){
int nByte = dupedExprStructSize(p, flags) & 0xfff;
if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
nByte += sqlite4Strlen30(p->u.zToken)+1;
}
return ROUND8(nByte);
}
/*
** Return the number of bytes required to create a duplicate of the
** expression passed as the first argument. The second argument is a
** mask containing EXPRDUP_XXX flags.
**
** The value returned includes space to create a copy of the Expr struct
** itself and the buffer referred to by Expr.u.zToken, if any.
**
** If the EXPRDUP_REDUCE flag is set, then the return value includes
** space to duplicate all Expr nodes in the tree formed by Expr.pLeft
** and Expr.pRight variables (but not for any structures pointed to or
** descended from the Expr.x.pList or Expr.x.pSelect variables).
*/
static int dupedExprSize(Expr *p, int flags){
int nByte = 0;
if( p ){
nByte = dupedExprNodeSize(p, flags);
if( flags&EXPRDUP_REDUCE ){
nByte += dupedExprSize(p->pLeft, flags) + dupedExprSize(p->pRight, flags);
}
}
return nByte;
}
/*
** This function is similar to sqlite4ExprDup(), except that if pzBuffer
** is not NULL then *pzBuffer is assumed to point to a buffer large enough
** to store the copy of expression p, the copies of p->u.zToken
** (if applicable), and the copies of the p->pLeft and p->pRight expressions,
** if any. Before returning, *pzBuffer is set to the first byte passed the
** portion of the buffer copied into by this function.
*/
static Expr *exprDup(sqlite4 *db, Expr *p, int flags, u8 **pzBuffer){
Expr *pNew = 0; /* Value to return */
if( p ){
const int isReduced = (flags&EXPRDUP_REDUCE);
u8 *zAlloc;
u32 staticFlag = 0;
assert( pzBuffer==0 || isReduced );
/* Figure out where to write the new Expr structure. */
if( pzBuffer ){
zAlloc = *pzBuffer;
staticFlag = EP_Static;
}else{
zAlloc = sqlite4DbMallocRaw(db, dupedExprSize(p, flags));
}
pNew = (Expr *)zAlloc;
if( pNew ){
/* Set nNewSize to the size allocated for the structure pointed to
** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or
** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed
** by the copy of the p->u.zToken string (if any).
*/
const unsigned nStructSize = dupedExprStructSize(p, flags);
const int nNewSize = nStructSize & 0xfff;
int nToken;
if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
nToken = sqlite4Strlen30(p->u.zToken) + 1;
}else{
nToken = 0;
}
if( isReduced ){
assert( ExprHasProperty(p, EP_Reduced)==0 );
memcpy(zAlloc, p, nNewSize);
}else{
int nSize = exprStructSize(p);
memcpy(zAlloc, p, nSize);
memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize);
}
/* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */
pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static);
pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
pNew->flags |= staticFlag;
/* 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) ){
/* Fill in the pNew->x.pSelect or pNew->x.pList member. */
if( ExprHasProperty(p, EP_xIsSelect) ){
pNew->x.pSelect = sqlite4SelectDup(db, p->x.pSelect, isReduced);
}else{
pNew->x.pList = sqlite4ExprListDup(db, p->x.pList, isReduced);
}
}
/* Fill in pNew->pLeft and pNew->pRight. */
if( ExprHasAnyProperty(pNew, EP_Reduced|EP_TokenOnly) ){
zAlloc += dupedExprNodeSize(p, flags);
if( ExprHasProperty(pNew, EP_Reduced) ){
pNew->pLeft = exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc);
pNew->pRight = exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc);
}
if( pzBuffer ){
*pzBuffer = zAlloc;
}
}else{
pNew->flags2 = 0;
if( !ExprHasAnyProperty(p, EP_TokenOnly) ){
pNew->pLeft = sqlite4ExprDup(db, p->pLeft, 0);
pNew->pRight = sqlite4ExprDup(db, p->pRight, 0);
}
}
}
}
return pNew;
}
/*
** The following group of routines make deep copies of expressions,
** expression lists, ID lists, and select statements. The copies can
** be deleted (by being passed to their respective ...Delete() routines)
** without effecting the originals.
**
** The expression list, ID, and source lists return by sqlite4ExprListDup(),
** sqlite4IdListDup(), and sqlite4SrcListDup() can not be further expanded
** by subsequent calls to sqlite*ListAppend() routines.
**
** Any tables that the SrcList might point to are not duplicated.
**
** The flags parameter contains a combination of the EXPRDUP_XXX flags.
** If the EXPRDUP_REDUCE flag is set, then the structure returned is a
** truncated version of the usual Expr structure that will be stored as
** part of the in-memory representation of the database schema.
*/
SQLITE_PRIVATE Expr *sqlite4ExprDup(sqlite4 *db, Expr *p, int flags){
return exprDup(db, p, flags, 0);
}
SQLITE_PRIVATE ExprList *sqlite4ExprListDup(sqlite4 *db, ExprList *p, int flags){
ExprList *pNew;
struct ExprList_item *pItem, *pOldItem;
int i;
if( p==0 ) return 0;
pNew = sqlite4DbMallocRaw(db, sizeof(*pNew) );
if( pNew==0 ) return 0;
pNew->iECursor = 0;
pNew->nExpr = pNew->nAlloc = p->nExpr;
pNew->a = pItem = sqlite4DbMallocRaw(db, p->nExpr*sizeof(p->a[0]) );
if( pItem==0 ){
sqlite4DbFree(db, pNew);
return 0;
}
pOldItem = p->a;
for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){
Expr *pOldExpr = pOldItem->pExpr;
pItem->pExpr = sqlite4ExprDup(db, pOldExpr, flags);
pItem->zName = sqlite4DbStrDup(db, pOldItem->zName);
pItem->zSpan = sqlite4DbStrDup(db, pOldItem->zSpan);
pItem->sortOrder = pOldItem->sortOrder;
pItem->done = 0;
pItem->iOrderByCol = pOldItem->iOrderByCol;
pItem->iAlias = pOldItem->iAlias;
}
return pNew;
}
/*
** If cursors, triggers, views and subqueries are all omitted from
** the build, then none of the following routines, except for
** sqlite4SelectDup(), can be called. sqlite4SelectDup() is sometimes
** called with a NULL argument.
*/
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \
|| !defined(SQLITE_OMIT_SUBQUERY)
SQLITE_PRIVATE SrcList *sqlite4SrcListDup(sqlite4 *db, SrcList *p, int flags){
SrcList *pNew;
int i;
int nByte;
if( p==0 ) return 0;
nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0);
pNew = sqlite4DbMallocRaw(db, nByte );
if( pNew==0 ) return 0;
pNew->nSrc = pNew->nAlloc = p->nSrc;
for(i=0; i<p->nSrc; i++){
struct SrcList_item *pNewItem = &pNew->a[i];
struct SrcList_item *pOldItem = &p->a[i];
Table *pTab;
pNewItem->zDatabase = sqlite4DbStrDup(db, pOldItem->zDatabase);
pNewItem->zName = sqlite4DbStrDup(db, pOldItem->zName);
pNewItem->zAlias = sqlite4DbStrDup(db, pOldItem->zAlias);
pNewItem->jointype = pOldItem->jointype;
pNewItem->iCursor = pOldItem->iCursor;
pNewItem->addrFillSub = pOldItem->addrFillSub;
pNewItem->regReturn = pOldItem->regReturn;
pNewItem->isCorrelated = pOldItem->isCorrelated;
pNewItem->zIndex = sqlite4DbStrDup(db, pOldItem->zIndex);
pNewItem->notIndexed = pOldItem->notIndexed;
pNewItem->pIndex = pOldItem->pIndex;
pTab = pNewItem->pTab = pOldItem->pTab;
if( pTab ){
pTab->nRef++;
}
pNewItem->pSelect = sqlite4SelectDup(db, pOldItem->pSelect, flags);
pNewItem->pOn = sqlite4ExprDup(db, pOldItem->pOn, flags);
pNewItem->pUsing = sqlite4IdListDup(db, pOldItem->pUsing);
pNewItem->colUsed = pOldItem->colUsed;
}
return pNew;
}
SQLITE_PRIVATE IdList *sqlite4IdListDup(sqlite4 *db, IdList *p){
IdList *pNew;
int i;
if( p==0 ) return 0;
pNew = sqlite4DbMallocRaw(db, sizeof(*pNew) );
if( pNew==0 ) return 0;
pNew->nId = pNew->nAlloc = p->nId;
pNew->a = sqlite4DbMallocRaw(db, p->nId*sizeof(p->a[0]) );
if( pNew->a==0 ){
sqlite4DbFree(db, pNew);
return 0;
}
for(i=0; i<p->nId; i++){
struct IdList_item *pNewItem = &pNew->a[i];
struct IdList_item *pOldItem = &p->a[i];
pNewItem->zName = sqlite4DbStrDup(db, pOldItem->zName);
pNewItem->idx = pOldItem->idx;
}
return pNew;
}
SQLITE_PRIVATE Select *sqlite4SelectDup(sqlite4 *db, Select *p, int flags){
Select *pNew, *pPrior;
if( p==0 ) return 0;
pNew = sqlite4DbMallocRaw(db, sizeof(*p) );
if( pNew==0 ) return 0;
pNew->pEList = sqlite4ExprListDup(db, p->pEList, flags);
pNew->pSrc = sqlite4SrcListDup(db, p->pSrc, flags);
pNew->pWhere = sqlite4ExprDup(db, p->pWhere, flags);
pNew->pGroupBy = sqlite4ExprListDup(db, p->pGroupBy, flags);
pNew->pHaving = sqlite4ExprDup(db, p->pHaving, flags);
pNew->pOrderBy = sqlite4ExprListDup(db, p->pOrderBy, flags);
pNew->op = p->op;
pNew->pPrior = pPrior = sqlite4SelectDup(db, p->pPrior, flags);
if( pPrior ) pPrior->pNext = pNew;
pNew->pNext = 0;
pNew->pLimit = sqlite4ExprDup(db, p->pLimit, flags);
pNew->pOffset = sqlite4ExprDup(db, p->pOffset, flags);
pNew->iLimit = 0;
pNew->iOffset = 0;
pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
pNew->pRightmost = 0;
pNew->addrOpenEphm[0] = -1;
pNew->addrOpenEphm[1] = -1;
pNew->addrOpenEphm[2] = -1;
return pNew;
}
#else
SQLITE_PRIVATE Select *sqlite4SelectDup(sqlite4 *db, Select *p, int flags){
assert( p==0 );
return 0;
}
#endif
/*
** Add a new element to the end of an expression list. If pList is
** initially NULL, then create a new expression list.
**
** 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.
*/
SQLITE_PRIVATE ExprList *sqlite4ExprListAppend(
Parse *pParse, /* Parsing context */
ExprList *pList, /* List to which to append. Might be NULL */
Expr *pExpr /* Expression to be appended. Might be NULL */
){
sqlite4 *db = pParse->db;
if( pList==0 ){
pList = sqlite4DbMallocZero(db, sizeof(ExprList) );
if( pList==0 ){
goto no_mem;
}
assert( pList->nAlloc==0 );
}
if( pList->nAlloc<=pList->nExpr ){
struct ExprList_item *a;
int n = pList->nAlloc*2 + 4;
a = sqlite4DbRealloc(db, pList->a, n*sizeof(pList->a[0]));
if( a==0 ){
goto no_mem;
}
pList->a = a;
pList->nAlloc = sqlite4DbMallocSize(db, a)/sizeof(a[0]);
}
assert( pList->a!=0 );
if( 1 ){
struct ExprList_item *pItem = &pList->a[pList->nExpr++];
memset(pItem, 0, sizeof(*pItem));
pItem->pExpr = pExpr;
}
return pList;
no_mem:
/* Avoid leaking memory if malloc has failed. */
sqlite4ExprDelete(db, pExpr);
sqlite4ExprListDelete(db, pList);
return 0;
}
/*
** Set the ExprList.a[].zName element of the most recently added item
** on the expression list.
**
** pList might be NULL following an OOM error. But pName should never be
** NULL. If a memory allocation fails, the pParse->db->mallocFailed flag
** is set.
*/
SQLITE_PRIVATE void sqlite4ExprListSetName(
Parse *pParse, /* Parsing context */
ExprList *pList, /* List to which to add the span. */
Token *pName, /* Name to be added */
int dequote /* True to cause the name to be dequoted */
){
assert( pList!=0 || pParse->db->mallocFailed!=0 );
if( pList ){
struct ExprList_item *pItem;
assert( pList->nExpr>0 );
pItem = &pList->a[pList->nExpr-1];
assert( pItem->zName==0 );
pItem->zName = sqlite4DbStrNDup(pParse->db, pName->z, pName->n);
if( dequote && pItem->zName ) sqlite4Dequote(pItem->zName);
}
}
/*
** Set the ExprList.a[].zSpan element of the most recently added item
** on the expression list.
**
** pList might be NULL following an OOM error. But pSpan should never be
** NULL. If a memory allocation fails, the pParse->db->mallocFailed flag
** is set.
*/
SQLITE_PRIVATE void sqlite4ExprListSetSpan(
Parse *pParse, /* Parsing context */
ExprList *pList, /* List to which to add the span. */
ExprSpan *pSpan /* The span to be added */
){
sqlite4 *db = pParse->db;
assert( pList!=0 || db->mallocFailed!=0 );
if( pList ){
struct ExprList_item *pItem = &pList->a[pList->nExpr-1];
assert( pList->nExpr>0 );
assert( db->mallocFailed || pItem->pExpr==pSpan->pExpr );
sqlite4DbFree(db, pItem->zSpan);
pItem->zSpan = sqlite4DbStrNDup(db, (char*)pSpan->zStart,
(int)(pSpan->zEnd - pSpan->zStart));
}
}
/*
** If the expression list pEList contains more than iLimit elements,
** leave an error message in pParse.
*/
SQLITE_PRIVATE void sqlite4ExprListCheckLength(
Parse *pParse,
ExprList *pEList,
const char *zObject
){
int mx = pParse->db->aLimit[SQLITE_LIMIT_COLUMN];
testcase( pEList && pEList->nExpr==mx );
testcase( pEList && pEList->nExpr==mx+1 );
if( pEList && pEList->nExpr>mx ){
sqlite4ErrorMsg(pParse, "too many columns in %s", zObject);
}
}
/*
** Delete an entire expression list.
*/
SQLITE_PRIVATE void sqlite4ExprListDelete(sqlite4 *db, ExprList *pList){
int i;
struct ExprList_item *pItem;
if( pList==0 ) return;
assert( pList->a!=0 || (pList->nExpr==0 && pList->nAlloc==0) );
assert( pList->nExpr<=pList->nAlloc );
for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
sqlite4ExprDelete(db, pItem->pExpr);
sqlite4DbFree(db, pItem->zName);
sqlite4DbFree(db, pItem->zSpan);
}
sqlite4DbFree(db, pList->a);
sqlite4DbFree(db, pList);
}
/*
** These routines are Walker callbacks. Walker.u.pi is a pointer
** to an integer. These routines are checking an expression to see
** if it is a constant. Set *Walker.u.pi to 0 if the expression is
** not constant.
**
** These callback routines are used to implement the following:
**
** sqlite4ExprIsConstant()
** sqlite4ExprIsConstantNotJoin()
** sqlite4ExprIsConstantOrFunction()
**
*/
static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
/* If pWalker->u.i is 3 then any term of the expression that comes from
** the ON or USING clauses of a join disqualifies the expression
** from being considered constant. */
if( pWalker->u.i==3 && ExprHasAnyProperty(pExpr, EP_FromJoin) ){
pWalker->u.i = 0;
return WRC_Abort;
}
switch( pExpr->op ){
/* Consider functions to be constant if all their arguments are constant
** and pWalker->u.i==2 */
case TK_FUNCTION:
if( pWalker->u.i==2 ) return 0;
/* Fall through */
case TK_ID:
case TK_COLUMN:
case TK_AGG_FUNCTION:
case TK_AGG_COLUMN:
testcase( pExpr->op==TK_ID );
testcase( pExpr->op==TK_COLUMN );
testcase( pExpr->op==TK_AGG_FUNCTION );
testcase( pExpr->op==TK_AGG_COLUMN );
pWalker->u.i = 0;
return WRC_Abort;
default:
testcase( pExpr->op==TK_SELECT ); /* selectNodeIsConstant will disallow */
testcase( pExpr->op==TK_EXISTS ); /* selectNodeIsConstant will disallow */
return WRC_Continue;
}
}
static int selectNodeIsConstant(Walker *pWalker, Select *NotUsed){
UNUSED_PARAMETER(NotUsed);
pWalker->u.i = 0;
return WRC_Abort;
}
static int exprIsConst(Expr *p, int initFlag){
Walker w;
w.u.i = initFlag;
w.xExprCallback = exprNodeIsConstant;
w.xSelectCallback = selectNodeIsConstant;
sqlite4WalkExpr(&w, p);
return w.u.i;
}
/*
** Walk an expression tree. Return 1 if the expression is constant
** and 0 if it involves variables or function calls.
**
** For the purposes of this function, a double-quoted string (ex: "abc")
** is considered a variable but a single-quoted string (ex: 'abc') is
** a constant.
*/
SQLITE_PRIVATE int sqlite4ExprIsConstant(Expr *p){
return exprIsConst(p, 1);
}
/*
** Walk an expression tree. Return 1 if the expression is constant
** that does no originate from the ON or USING clauses of a join.
** Return 0 if it involves variables or function calls or terms from
** an ON or USING clause.
*/
SQLITE_PRIVATE int sqlite4ExprIsConstantNotJoin(Expr *p){
return exprIsConst(p, 3);
}
/*
** Walk an expression tree. Return 1 if the expression is constant
** or a function call with constant arguments. Return and 0 if there
** are any variables.
**
** For the purposes of this function, a double-quoted string (ex: "abc")
** is considered a variable but a single-quoted string (ex: 'abc') is
** a constant.
*/
SQLITE_PRIVATE int sqlite4ExprIsConstantOrFunction(Expr *p){
return exprIsConst(p, 2);
}
/*
** 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
** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.
*/
SQLITE_PRIVATE int sqlite4ExprIsInteger(Expr *p, int *pValue){
int rc = 0;
/* If an expression is an integer literal that fits in a signed 32-bit
** integer, then the EP_IntValue flag will have already been set */
assert( p->op!=TK_INTEGER || (p->flags & EP_IntValue)!=0
|| sqlite4GetInt32(p->u.zToken, &rc)==0 );
if( p->flags & EP_IntValue ){
*pValue = p->u.iValue;
return 1;
}
switch( p->op ){
case TK_UPLUS: {
rc = sqlite4ExprIsInteger(p->pLeft, pValue);
break;
}
case TK_UMINUS: {
int v;
if( sqlite4ExprIsInteger(p->pLeft, &v) ){
*pValue = -v;
rc = 1;
}
break;
}
default: break;
}
return rc;
}
/*
** Return FALSE if there is no chance that the expression can be NULL.
**
** If the expression might be NULL or if the expression is too complex
** to tell return TRUE.
**
** This routine is used as an optimization, to skip OP_IsNull opcodes
** when we know that a value cannot be NULL. Hence, a false positive
** (returning TRUE when in fact the expression can never be NULL) might
** be a small performance hit but is otherwise harmless. On the other
** hand, a false negative (returning FALSE when the result could be NULL)
** will likely result in an incorrect answer. So when in doubt, return
** TRUE.
*/
SQLITE_PRIVATE int sqlite4ExprCanBeNull(const Expr *p){
u8 op;
while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ p = p->pLeft; }
op = p->op;
if( op==TK_REGISTER ) op = p->op2;
switch( op ){
case TK_INTEGER:
case TK_STRING:
case TK_FLOAT:
case TK_BLOB:
return 0;
default:
return 1;
}
}
/*
** Generate an OP_IsNull instruction that tests register iReg and jumps
** to location iDest if the value in iReg is NULL. The value in iReg
** was computed by pExpr. If we can look at pExpr at compile-time and
** determine that it can never generate a NULL, then the OP_IsNull operation
** can be omitted.
*/
SQLITE_PRIVATE void sqlite4ExprCodeIsNullJump(
Vdbe *v, /* The VDBE under construction */
const Expr *pExpr, /* Only generate OP_IsNull if this expr can be NULL */
int iReg, /* Test the value in this register for NULL */
int iDest /* Jump here if the value is null */
){
if( sqlite4ExprCanBeNull(pExpr) ){
sqlite4VdbeAddOp2(v, OP_IsNull, iReg, iDest);
}
}
/*
** Return TRUE if the given expression is a constant which would be
** unchanged by OP_Affinity with the affinity given in the second
** argument.
**
** This routine is used to determine if the OP_Affinity operation
** can be omitted. When in doubt return FALSE. A false negative
** is harmless. A false positive, however, can result in the wrong
** answer.
*/
SQLITE_PRIVATE int sqlite4ExprNeedsNoAffinityChange(const Expr *p, char aff){
u8 op;
if( aff==SQLITE_AFF_NONE ) return 1;
while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ p = p->pLeft; }
op = p->op;
if( op==TK_REGISTER ) op = p->op2;
switch( op ){
case TK_INTEGER: {
return aff==SQLITE_AFF_INTEGER || aff==SQLITE_AFF_NUMERIC;
}
case TK_FLOAT: {
return aff==SQLITE_AFF_REAL || aff==SQLITE_AFF_NUMERIC;
}
case TK_STRING: {
return aff==SQLITE_AFF_TEXT;
}
case TK_BLOB: {
return 1;
}
case TK_COLUMN: {
assert( p->iTable>=0 ); /* p cannot be part of a CHECK constraint */
return p->iColumn<0
&& (aff==SQLITE_AFF_INTEGER || aff==SQLITE_AFF_NUMERIC);
}
default: {
return 0;
}
}
}
/*
** Code an OP_Once instruction and allocate space for its flag. Return the
** address of the new instruction.
*/
SQLITE_PRIVATE int sqlite4CodeOnce(Parse *pParse){
Vdbe *v = sqlite4GetVdbe(pParse); /* Virtual machine being coded */
return sqlite4VdbeAddOp1(v, OP_Once, pParse->nOnce++);
}
/*
** Return true if we are able to the IN operator optimization on a
** query of the form
**
** x IN (SELECT ...)
**
** Where the SELECT... clause is as specified by the parameter to this
** routine.
**
** The Select object passed in has already been preprocessed and no
** errors have been found.
*/
#ifndef SQLITE_OMIT_SUBQUERY
static int isCandidateForInOpt(Select *p){
SrcList *pSrc;
ExprList *pEList;
Table *pTab;
if( p==0 ) return 0; /* right-hand side of IN is SELECT */
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 );
testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
return 0; /* No DISTINCT keyword and no aggregate functions */
}
assert( p->pGroupBy==0 ); /* Has no GROUP BY clause */
if( p->pLimit ) return 0; /* Has no LIMIT clause */
assert( p->pOffset==0 ); /* No LIMIT means no OFFSET */
if( p->pWhere ) return 0; /* Has no WHERE clause */
pSrc = p->pSrc;
assert( pSrc!=0 );
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;
if( NEVER(pTab==0) ) return 0;
assert( pTab->pSelect==0 ); /* FROM clause is not a view */
if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */
pEList = p->pEList;
if( pEList->nExpr!=1 ) return 0; /* One column in the result set */
if( pEList->a[0].pExpr->op!=TK_COLUMN ) return 0; /* Result is a column */
return 1;
}
SQLITE_PRIVATE Index *sqlite4FindExistingInIndex(Parse *pParse, Expr *pX, int bReqUnique){
Index *pIdx = 0;
Select *p;
p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){
sqlite4 *db = pParse->db;
Table *pTab = p->pSrc->a[0].pTab;
Expr *pRhs = p->pEList->a[0].pExpr;
int iCol = pRhs->iColumn;
CollSeq *pReq;
char aff;
/* The collation sequence used by the comparison. If an index is to
** be used in place of a temp-table, it must be ordered according
** to this collation sequence. */
pReq = sqlite4BinaryCompareCollSeq(pParse, pX->pLeft, pRhs);
/* Check that the affinity that will be used to perform the
** comparison is the same as the affinity of the column. If
** it is not, it is not possible to use any index. */
aff = comparisonAffinity(pX);
if( aff!=SQLITE_AFF_NONE && aff!=pTab->aCol[iCol].affinity ) return 0;
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( (pIdx->aiColumn[0]==iCol)
&& sqlite4FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq
&& (!bReqUnique || (pIdx->nColumn==1 && pIdx->onError!=OE_None))
){
break;
}
}
}
return pIdx;
}
#endif /* SQLITE_OMIT_SUBQUERY */
/*
** This function is used by the implementation of the IN (...) operator.
** It's job is to find or create a b-tree structure that may be used
** either to test for membership of the (...) set or to iterate through
** its members, skipping duplicates.
**
** The index of the cursor opened on the b-tree (database table, database index
** or ephermal table) is stored in pX->iTable before this function returns.
** The returned value of this function indicates the b-tree type, as follows:
**
** IN_INDEX_ROWID - The cursor was opened on a database table.
** IN_INDEX_INDEX - The cursor was opened on a database index.
** IN_INDEX_EPH - The cursor was opened on a specially created and
** populated epheremal table.
**
** An existing b-tree may only be used if the SELECT is of the simple
** form:
**
** SELECT <column> FROM <table>
**
** If the prNotFound parameter is 0, then the b-tree will be used to iterate
** through the set members, skipping any duplicates. In this case an
** epheremal table must be used unless the selected <column> is guaranteed
** to be unique - either because it is an INTEGER PRIMARY KEY or it
** has a UNIQUE constraint or UNIQUE index.
**
** If the prNotFound parameter is not 0, then the b-tree will be used
** for fast set membership tests. In this case an epheremal table must
** be used unless <column> is an INTEGER PRIMARY KEY or an index can
** be found with <column> as its left-most column.
**
** When the b-tree is being used for membership tests, the calling function
** needs to know whether or not the structure contains an SQL NULL
** value in order to correctly evaluate expressions like "X IN (Y, Z)".
** If there is any chance that the (...) might contain a NULL value at
** runtime, then a register is allocated and the register number written
** to *prNotFound. If there is no chance that the (...) contains a
** NULL value, then *prNotFound is left unchanged.
**
** If a register is allocated and its location stored in *prNotFound, then
** its initial value is NULL. If the (...) does not remain constant
** for the duration of the query (i.e. the SELECT within the (...)
** is a correlated subquery) then the value of the allocated register is
** reset to NULL each time the subquery is rerun. This allows the
** caller to use vdbe code equivalent to the following:
**
** if( register==NULL ){
** has_null = <test if data structure contains null>
** register = 1
** }
**
** in order to avoid running the <test if data structure contains null>
** test more often than is necessary.
*/
#ifndef SQLITE_OMIT_SUBQUERY
SQLITE_PRIVATE int sqlite4FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
Index *pIdx;
int eType = 0; /* Type of RHS table. IN_INDEX_* */
int iTab = pParse->nTab++; /* Cursor of the RHS table */
Vdbe *v = sqlite4GetVdbe(pParse); /* Virtual machine being coded */
assert( pX->op==TK_IN );
assert( prNotFound );
/* 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. */
pIdx = sqlite4FindExistingInIndex(pParse, pX, 0);
if( pIdx ){
int iAddr;
char *pKey;
int iDb; /* aDb[] Index of database containing pIdx */
iDb = sqlite4SchemaToIndex(pParse->db, pIdx->pSchema);
pKey = (char *)sqlite4IndexKeyinfo(pParse, pIdx);
iAddr = sqlite4CodeOnce(pParse);
sqlite4VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb);
sqlite4VdbeChangeP4(v, -1 , pKey, P4_KEYINFO_HANDOFF);
VdbeComment((v, "%s", pIdx->zName));
sqlite4VdbeJumpHere(v, iAddr);
*prNotFound = ++pParse->nMem;
sqlite4VdbeAddOp2(v, OP_Null, 0, *prNotFound);
pX->iTable = iTab;
}else{
/* Could not find an existing table or index to use as the RHS b-tree.
** We will have to generate an ephemeral table to do the job. */
double savedNQueryLoop = pParse->nQueryLoop;
int rMayHaveNull = 0;
eType = IN_INDEX_EPH;
*prNotFound = rMayHaveNull = ++pParse->nMem;
sqlite4VdbeAddOp2(v, OP_Null, 0, *prNotFound);
sqlite4CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID);
pParse->nQueryLoop = savedNQueryLoop;
}
return eType;
}
#endif
/*
** Generate code for scalar subqueries used as a subquery expression, EXISTS,
** or IN operators. Examples:
**
** (SELECT a FROM b) -- subquery
** EXISTS (SELECT a FROM b) -- EXISTS subquery
** x IN (4,5,11) -- IN operator with list on right-hand side
** x IN (SELECT a FROM b) -- IN operator with subquery on the right
**
** The pExpr parameter describes the expression that contains the IN
** operator or subquery.
**
** If parameter isRowid is non-zero, then expression pExpr is guaranteed
** to be of the form "<rowid> IN (?, ?, ?)", where <rowid> is a reference
** to some integer key column of a table B-Tree. In this case, use an
** intkey B-Tree to store the set of IN(...) values instead of the usual
** (slower) variable length keys B-Tree.
**
** If rMayHaveNull is non-zero, that means that the operation is an IN
** (not a SELECT or EXISTS) and that the RHS might contains NULLs.
** Furthermore, the IN is in a WHERE clause and that we really want
** to iterate over the RHS of the IN operator in order to quickly locate
** all corresponding LHS elements. All this routine does is initialize
** the register given by rMayHaveNull to NULL. Calling routines will take
** care of changing this register value to non-NULL if the RHS is NULL-free.
**
** If rMayHaveNull is zero, that means that the subquery is being used
** for membership testing only. There is no need to initialize any
** registers to indicate the presense or absence of NULLs on the RHS.
**
** For a SELECT or EXISTS operator, return the register that holds the
** result. For IN operators or if an error occurs, the return value is 0.
*/
#ifndef SQLITE_OMIT_SUBQUERY
SQLITE_PRIVATE int sqlite4CodeSubselect(
Parse *pParse, /* Parsing context */
Expr *pExpr, /* The IN, SELECT, or EXISTS operator */
int rMayHaveNull, /* Register that records whether NULLs exist in RHS */
int isRowid /* If true, LHS of IN operator is a rowid */
){
int testAddr = -1; /* One-time test address */
int rReg = 0; /* Register storing resulting */
Vdbe *v = sqlite4GetVdbe(pParse);
if( NEVER(v==0) ) return 0;
sqlite4ExprCachePush(pParse);
/* This code must be run in its entirety every time it 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
** * We are inside a trigger
**
** If all of the above are false, then we can run this code just once
** save the results, and reuse the same result on subsequent invocations.
*/
if( !ExprHasAnyProperty(pExpr, EP_VarSelect) ){
testAddr = sqlite4CodeOnce(pParse);
}
#ifndef SQLITE_OMIT_EXPLAIN
if( pParse->explain==2 ){
char *zMsg = sqlite4MPrintf(
pParse->db, "EXECUTE %s%s SUBQUERY %d", testAddr>=0?"":"CORRELATED ",
pExpr->op==TK_IN?"LIST":"SCALAR", pParse->iNextSelectId
);
sqlite4VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
}
#endif
switch( pExpr->op ){
case TK_IN: {
char affinity; /* Affinity of the LHS of the IN */
KeyInfo keyInfo; /* Keyinfo for the generated table */
int addr; /* Address of OP_OpenEphemeral instruction */
Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */
if( rMayHaveNull ){
sqlite4VdbeAddOp2(v, OP_Null, 0, rMayHaveNull);
}
affinity = sqlite4ExprAffinity(pLeft);
/* Whether this is an 'x IN(SELECT...)' or an 'x IN(<exprlist>)'
** expression it is handled the same way. An ephemeral table is
** filled with single-field index keys representing the results
** from the SELECT or the <exprlist>.
**
** If the 'x' expression is a column value, or the SELECT...
** statement returns a column value, then the affinity of that
** column is used to build the index keys. If both 'x' and the
** SELECT... statement are columns, then numeric affinity is used
** if either column has NUMERIC or INTEGER affinity. If neither
** 'x' nor the SELECT... statement are columns, then numeric affinity
** is used.
*/
pExpr->iTable = pParse->nTab++;
addr = sqlite4VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid);
memset(&keyInfo, 0, sizeof(keyInfo));
keyInfo.nField = 1;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
/* Case 1: expr IN (SELECT ...)
**
** Generate code to write the results of the select into the temporary
** table allocated and opened above.
*/
SelectDest dest;
ExprList *pEList;
assert( !isRowid );
sqlite4SelectDestInit(&dest, SRT_Set, pExpr->iTable);
dest.affinity = (u8)affinity;
assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
pExpr->x.pSelect->iLimit = 0;
if( sqlite4Select(pParse, pExpr->x.pSelect, &dest) ){
return 0;
}
pEList = pExpr->x.pSelect->pEList;
if( ALWAYS(pEList!=0 && pEList->nExpr>0) ){
keyInfo.aColl[0] = sqlite4BinaryCompareCollSeq(pParse, pExpr->pLeft,
pEList->a[0].pExpr);
}
}else if( ALWAYS(pExpr->x.pList!=0) ){
/* Case 2: expr IN (exprlist)
**
** For each expression, build an index key from the evaluation and
** store it in the temporary table. If <expr> is a column, then use
** that columns affinity when building index keys. If <expr> is not
** a column, use numeric affinity.
*/
int i;
ExprList *pList = pExpr->x.pList;
struct ExprList_item *pItem;
int r1, r2, r3;
if( !affinity ){
affinity = SQLITE_AFF_NONE;
}
keyInfo.aColl[0] = sqlite4ExprCollSeq(pParse, pExpr->pLeft);
/* Loop through each expression in <exprlist>. */
r1 = sqlite4GetTempReg(pParse);
r2 = sqlite4GetTempReg(pParse);
sqlite4VdbeAddOp2(v, OP_Null, 0, r2);
for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
Expr *pE2 = pItem->pExpr;
int iValToIns;
/* If the expression is not constant then we will need to
** disable the test that was generated above that makes sure
** this code only executes once. Because for a non-constant
** expression we need to rerun this code each time.
*/
if( testAddr>=0 && !sqlite4ExprIsConstant(pE2) ){
sqlite4VdbeChangeToNoop(v, testAddr);
testAddr = -1;
}
/* Evaluate the expression and insert it into the temp table */
if( isRowid && sqlite4ExprIsInteger(pE2, &iValToIns) ){
sqlite4VdbeAddOp3(v, OP_InsertInt, pExpr->iTable, r2, iValToIns);
}else{
r3 = sqlite4ExprCodeTarget(pParse, pE2, r1);
if( isRowid ){
sqlite4VdbeAddOp2(v, OP_MustBeInt, r3,
sqlite4VdbeCurrentAddr(v)+2);
sqlite4VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3);
}else{
int r4 = sqlite4GetTempReg(pParse);
sqlite4VdbeAddOp2(v, OP_MakeKey, pExpr->iTable, r4);
sqlite4VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
sqlite4ExprCacheAffinityChange(pParse, r3, 1);
sqlite4VdbeAddOp3(v, OP_IdxInsert, pExpr->iTable, r2, r4);
sqlite4ReleaseTempReg(pParse, r4);
}
}
}
sqlite4ReleaseTempReg(pParse, r1);
sqlite4ReleaseTempReg(pParse, r2);
}
if( !isRowid ){
sqlite4VdbeChangeP4(v, addr, (void *)&keyInfo, P4_KEYINFO);
}
break;
}
case TK_EXISTS:
case TK_SELECT:
default: {
/* If this has to be a scalar SELECT. Generate code to put the
** value of this select in a memory cell and record the number
** of the memory cell in iColumn. If this is an EXISTS, write
** an integer 0 (not exists) or 1 (exists) into a memory cell
** and record that memory cell in iColumn.
*/
Select *pSel; /* SELECT statement to encode */
SelectDest dest; /* How to deal with SELECt result */
testcase( pExpr->op==TK_EXISTS );
testcase( pExpr->op==TK_SELECT );
assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
assert( ExprHasProperty(pExpr, EP_xIsSelect) );
pSel = pExpr->x.pSelect;
sqlite4SelectDestInit(&dest, 0, ++pParse->nMem);
if( pExpr->op==TK_SELECT ){
dest.eDest = SRT_Mem;
sqlite4VdbeAddOp2(v, OP_Null, 0, dest.iParm);
VdbeComment((v, "Init subquery result"));
}else{
dest.eDest = SRT_Exists;
sqlite4VdbeAddOp2(v, OP_Integer, 0, dest.iParm);
VdbeComment((v, "Init EXISTS result"));
}
sqlite4ExprDelete(pParse->db, pSel->pLimit);
pSel->pLimit = sqlite4PExpr(pParse, TK_INTEGER, 0, 0,
&sqlite4IntTokens[1]);
pSel->iLimit = 0;
if( sqlite4Select(pParse, pSel, &dest) ){
return 0;
}
rReg = dest.iParm;
ExprSetIrreducible(pExpr);
break;
}
}
if( testAddr>=0 ){
sqlite4VdbeJumpHere(v, testAddr);
}
sqlite4ExprCachePop(pParse, 1);
return rReg;
}
#endif /* SQLITE_OMIT_SUBQUERY */
#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 expression. The right-hand side (RHS)
** is an array of zero or more values. The expression is true if the LHS is
** contained within the RHS. The value of the expression is unknown (NULL)
** if the LHS is NULL or if the LHS is not contained within the RHS and the
** RHS contains one or more NULL values.
**
** This routine generates code will jump 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.
*/
static void sqlite4ExprCodeIN(
Parse *pParse, /* Parsing and code generating context */
Expr *pExpr, /* The IN expression */
int destIfFalse, /* Jump here if LHS is not contained in the RHS */
int destIfNull /* Jump here if the results are unknown due to NULLs */
){
int rRhsHasNull = 0; /* Register that is true if RHS contains NULL values */
char affinity; /* Comparison affinity to use */
int eType; /* Type of the RHS */
int r1; /* Temporary use register */
Vdbe *v; /* Statement under construction */
/* Compute the RHS. After this step, the table with cursor
** pExpr->iTable will contains the values that make up the RHS.
*/
v = pParse->pVdbe;
assert( v!=0 ); /* OOM detected prior to this routine */
VdbeNoopComment((v, "begin IN expr"));
eType = sqlite4FindInIndex(pParse, pExpr, &rRhsHasNull);
/* Figure out the affinity to use to create a key from the results
** of the expression. affinityStr stores a static string suitable for
** P4 of OP_MakeRecord.
*/
affinity = comparisonAffinity(pExpr);
/* Code the LHS, the <expr> from "<expr> IN (...)".
*/
sqlite4ExprCachePush(pParse);
r1 = sqlite4GetTempReg(pParse);
sqlite4ExprCode(pParse, pExpr->pLeft, r1);
/* If the LHS is NULL, then the result is either false or NULL depending
** on whether the RHS is empty or not, respectively.
*/
if( destIfNull==destIfFalse ){
/* Shortcut for the common case where the false and NULL outcomes are
** the same. */
sqlite4VdbeAddOp2(v, OP_IsNull, r1, destIfNull);
}else{
int addr1 = sqlite4VdbeAddOp1(v, OP_NotNull, r1);
sqlite4VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse);
sqlite4VdbeAddOp2(v, OP_Goto, 0, destIfNull);
sqlite4VdbeJumpHere(v, addr1);
}
if( eType==IN_INDEX_ROWID ){
/* In this case, the RHS is the ROWID of table b-tree
*/
sqlite4VdbeAddOp2(v, OP_MustBeInt, r1, destIfFalse);
sqlite4VdbeAddOp3(v, OP_NotExists, pExpr->iTable, destIfFalse, r1);
}else{
/* In this case, the RHS is an index b-tree.
*/
sqlite4VdbeAddOp4(v, OP_Affinity, r1, 1, 0, &affinity, 1);
/* If the set membership test fails, then the result of the
** "x IN (...)" expression must be either 0 or NULL. If the set
** contains no NULL values, then the result is 0. If the set
** contains one or more NULL values, then the result of the
** expression is also NULL.
*/
if( rRhsHasNull==0 || destIfFalse==destIfNull ){
/* This branch runs if it is known at compile time that the RHS
** cannot contain NULL values. This happens as the result
** of a "NOT NULL" constraint in the database schema.
**
** Also run this branch if NULL is equivalent to FALSE
** for this particular IN operator.
*/
sqlite4VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse, r1, 1);
}else{
/* In this branch, the RHS of the IN might contain a NULL and
** the presence of a NULL on the RHS makes a difference in the
** outcome.
*/
int j1, j2, j3;
/* First check to see if the LHS is contained in the RHS. If so,
** then the presence of NULLs in the RHS does not matter, so jump
** over all of the code that follows.
*/
j1 = sqlite4VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, r1, 1);
/* Here we begin generating code that runs if the LHS is not
** contained within the RHS. Generate additional code that
** tests the RHS for NULLs. If the RHS contains a NULL then
** jump to destIfNull. If there are no NULLs in the RHS then
** jump to destIfFalse.
*/
j2 = sqlite4VdbeAddOp1(v, OP_NotNull, rRhsHasNull);
j3 = sqlite4VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, rRhsHasNull, 1);
sqlite4VdbeAddOp2(v, OP_Integer, -1, rRhsHasNull);
sqlite4VdbeJumpHere(v, j3);
sqlite4VdbeAddOp2(v, OP_AddImm, rRhsHasNull, 1);
sqlite4VdbeJumpHere(v, j2);
/* Jump to the appropriate target depending on whether or not
** the RHS contains a NULL
*/
sqlite4VdbeAddOp2(v, OP_If, rRhsHasNull, destIfNull);
sqlite4VdbeAddOp2(v, OP_Goto, 0, destIfFalse);
/* The OP_Found at the top of this branch jumps here when true,
** causing the overall IN expression evaluation to fall through.
*/
sqlite4VdbeJumpHere(v, j1);
}
}
sqlite4ReleaseTempReg(pParse, r1);
sqlite4ExprCachePop(pParse, 1);
VdbeComment((v, "end IN expr"));
}
#endif /* SQLITE_OMIT_SUBQUERY */
/*
** Duplicate an 8-byte value
*/
static char *dup8bytes(Vdbe *v, const char *in){
char *out = sqlite4DbMallocRaw(sqlite4VdbeDb(v), 8);
if( out ){
memcpy(out, in, 8);
}
return out;
}
#ifndef SQLITE_OMIT_FLOATING_POINT
/*
** Generate an instruction that will put the floating point
** value described by z[0..n-1] into register iMem.
**
** The z[] string will probably not be zero-terminated. But the
** z[n] character is guaranteed to be something that does not look
** like the continuation of the number.
*/
static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){
if( ALWAYS(z!=0) ){
double value;
char *zV;
sqlite4AtoF(z, &value, sqlite4Strlen30(z), SQLITE_UTF8);
assert( !sqlite4IsNaN(value) ); /* The new AtoF never returns NaN */
if( negateFlag ) value = -value;
zV = dup8bytes(v, (char*)&value);
sqlite4VdbeAddOp4(v, OP_Real, 0, iMem, 0, zV, P4_REAL);
}
}
#endif
/*
** Generate an instruction that will put the integer describe by
** text z[0..n-1] into register iMem.
**
** Expr.u.zToken is always UTF8 and zero-terminated.
*/
static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){
Vdbe *v = pParse->pVdbe;
if( pExpr->flags & EP_IntValue ){
int i = pExpr->u.iValue;
assert( i>=0 );
if( negFlag ) i = -i;
sqlite4VdbeAddOp2(v, OP_Integer, i, iMem);
}else{
int c;
i64 value;
const char *z = pExpr->u.zToken;
assert( z!=0 );
c = sqlite4Atoi64(z, &value, sqlite4Strlen30(z), SQLITE_UTF8);
if( c==0 || (c==2 && negFlag) ){
char *zV;
if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; }
zV = dup8bytes(v, (char*)&value);
sqlite4VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64);
}else{
#ifdef SQLITE_OMIT_FLOATING_POINT
sqlite4ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z);
#else
codeReal(v, z, negFlag, iMem);
#endif
}
}
}
/*
** Clear a cache entry.
*/
static void cacheEntryClear(Parse *pParse, struct yColCache *p){
if( p->tempReg ){
if( pParse->nTempReg<ArraySize(pParse->aTempReg) ){
pParse->aTempReg[pParse->nTempReg++] = p->iReg;
}
p->tempReg = 0;
}
}
/*
** Record in the column cache that a particular column from a
** particular table is stored in a particular register.
*/
SQLITE_PRIVATE void sqlite4ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){
int i;
int minLru;
int idxLru;
struct yColCache *p;
assert( iReg>0 ); /* Register numbers are always positive */
assert( iCol>=-1 && iCol<32768 ); /* Finite column numbers */
/* The SQLITE_ColumnCache flag disables the column cache. This is used
** for testing only - to verify that SQLite always gets the same answer
** with and without the column cache.
*/
if( pParse->db->flags & SQLITE_ColumnCache ) return;
/* First replace any existing entry.
**
** Actually, the way the column cache is currently used, we are guaranteed
** that the object will never already be in cache. Verify this guarantee.
*/
#ifndef NDEBUG
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
#if 0 /* This code wold remove the entry from the cache if it existed */
if( p->iReg && p->iTable==iTab && p->iColumn==iCol ){
cacheEntryClear(pParse, p);
p->iLevel = pParse->iCacheLevel;
p->iReg = iReg;
p->lru = pParse->iCacheCnt++;
return;
}
#endif
assert( p->iReg==0 || p->iTable!=iTab || p->iColumn!=iCol );
}
#endif
/* Find an empty slot and replace it */
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
if( p->iReg==0 ){
p->iLevel = pParse->iCacheLevel;
p->iTable = iTab;
p->iColumn = iCol;
p->iReg = iReg;
p->tempReg = 0;
p->lru = pParse->iCacheCnt++;
return;
}
}
/* Replace the last recently used */
minLru = 0x7fffffff;
idxLru = -1;
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
if( p->lru<minLru ){
idxLru = i;
minLru = p->lru;
}
}
if( ALWAYS(idxLru>=0) ){
p = &pParse->aColCache[idxLru];
p->iLevel = pParse->iCacheLevel;
p->iTable = iTab;
p->iColumn = iCol;
p->iReg = iReg;
p->tempReg = 0;
p->lru = pParse->iCacheCnt++;
return;
}
}
/*
** Indicate that registers between iReg..iReg+nReg-1 are being overwritten.
** Purge the range of registers from the column cache.
*/
SQLITE_PRIVATE void sqlite4ExprCacheRemove(Parse *pParse, int iReg, int nReg){
int i;
int iLast = iReg + nReg - 1;
struct yColCache *p;
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
int r = p->iReg;
if( r>=iReg && r<=iLast ){
cacheEntryClear(pParse, p);
p->iReg = 0;
}
}
}
/*
** Remember the current column cache context. Any new entries added
** added to the column cache after this call are removed when the
** corresponding pop occurs.
*/
SQLITE_PRIVATE void sqlite4ExprCachePush(Parse *pParse){
pParse->iCacheLevel++;
}
/*
** Remove from the column cache any entries that were added since the
** the previous N Push operations. In other words, restore the cache
** to the state it was in N Pushes ago.
*/
SQLITE_PRIVATE void sqlite4ExprCachePop(Parse *pParse, int N){
int i;
struct yColCache *p;
assert( N>0 );
assert( pParse->iCacheLevel>=N );
pParse->iCacheLevel -= N;
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
if( p->iReg && p->iLevel>pParse->iCacheLevel ){
cacheEntryClear(pParse, p);
p->iReg = 0;
}
}
}
/*
** When a cached column is reused, make sure that its register is
** no longer available as a temp register. ticket #3879: that same
** register might be in the cache in multiple places, so be sure to
** get them all.
*/
static void sqlite4ExprCachePinRegister(Parse *pParse, int iReg){
int i;
struct yColCache *p;
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
if( p->iReg==iReg ){
p->tempReg = 0;
}
}
}
/*
** Generate code to extract the value of the iCol-th column of a table.
*/
SQLITE_PRIVATE void sqlite4ExprCodeGetColumnOfTable(
Vdbe *v, /* The VDBE under construction */
Table *pTab, /* The table containing the value */
int iTabCur, /* The cursor for this table */
int iCol, /* Index of the column to extract */
int regOut /* Extract the valud into this register */
){
if( iCol<0 ){
sqlite4VdbeAddOp2(v, OP_Rowid, iTabCur, regOut);
}else{
int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;
sqlite4VdbeAddOp3(v, op, iTabCur, iCol, regOut);
}
if( iCol>=0 ){
sqlite4ColumnDefault(v, pTab, iCol, regOut);
}
}
/*
** Generate code that will extract the iColumn-th column from
** table pTab and store the column value in a register. An effort
** is made to store the column value in register iReg, but this is
** not guaranteed. The location of the column value is returned.
**
** There must be an open cursor to pTab in iTable when this routine
** is called. If iColumn<0 then code is generated that extracts the rowid.
*/
SQLITE_PRIVATE int sqlite4ExprCodeGetColumn(
Parse *pParse, /* Parsing and code generating context */
Table *pTab, /* Description of the table we are reading from */
int iColumn, /* Index of the table column */
int iTable, /* The cursor pointing to the table */
int iReg /* Store results here */
){
Vdbe *v = pParse->pVdbe;
int i;
struct yColCache *p;
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
if( p->iReg>0 && p->iTable==iTable && p->iColumn==iColumn ){
p->lru = pParse->iCacheCnt++;
sqlite4ExprCachePinRegister(pParse, p->iReg);
return p->iReg;
}
}
assert( v!=0 );
sqlite4ExprCodeGetColumnOfTable(v, pTab, iTable, iColumn, iReg);
sqlite4ExprCacheStore(pParse, iTable, iColumn, iReg);
return iReg;
}
/*
** Clear all column cache entries.
*/
SQLITE_PRIVATE void sqlite4ExprCacheClear(Parse *pParse){
int i;
struct yColCache *p;
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
if( p->iReg ){
cacheEntryClear(pParse, p);
p->iReg = 0;
}
}
}
/*
** Record the fact that an affinity change has occurred on iCount
** registers starting with iStart.
*/
SQLITE_PRIVATE void sqlite4ExprCacheAffinityChange(Parse *pParse, int iStart, int iCount){
sqlite4ExprCacheRemove(pParse, iStart, iCount);
}
/*
** Generate code to move content from registers iFrom...iFrom+nReg-1
** over to iTo..iTo+nReg-1. Keep the column cache up-to-date.
*/
SQLITE_PRIVATE void sqlite4ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
int i;
struct yColCache *p;
if( NEVER(iFrom==iTo) ) return;
sqlite4VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg);
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
int x = p->iReg;
if( x>=iFrom && x<iFrom+nReg ){
p->iReg += iTo-iFrom;
}
}
}
/*
** Generate code to copy content from registers iFrom...iFrom+nReg-1
** over to iTo..iTo+nReg-1.
*/
SQLITE_PRIVATE void sqlite4ExprCodeCopy(Parse *pParse, int iFrom, int iTo, int nReg){
int i;
if( NEVER(iFrom==iTo) ) return;
for(i=0; i<nReg; i++){
sqlite4VdbeAddOp2(pParse->pVdbe, OP_Copy, iFrom+i, iTo+i);
}
}
#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
/*
** Return true if any register in the range iFrom..iTo (inclusive)
** is used as part of the column cache.
**
** This routine is used within assert() and testcase() macros only
** and does not appear in a normal build.
*/
static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){
int i;
struct yColCache *p;
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
int r = p->iReg;
if( r>=iFrom && r<=iTo ) return 1; /*NO_TEST*/
}
return 0;
}
#endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */
/*
** Generate code into the current Vdbe to evaluate the given
** expression. Attempt to store the results in register "target".
** Return the register where results are stored.
**
** With this routine, there is no guarantee that results will
** be stored in target. The result might be stored in some other
** register if it is convenient to do so. The calling function
** must check the return code and move the results to the desired
** register.
*/
SQLITE_PRIVATE int sqlite4ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
Vdbe *v = pParse->pVdbe; /* The VM under construction */
int op; /* The opcode being coded */
int inReg = target; /* Results stored in register inReg */
int regFree1 = 0; /* If non-zero free this temporary register */
int regFree2 = 0; /* If non-zero free this temporary register */
int r1, r2, r3, r4; /* Various register numbers */
sqlite4 *db = pParse->db; /* The database connection */
assert( target>0 && target<=pParse->nMem );
if( v==0 ){
assert( pParse->db->mallocFailed );
return 0;
}
if( pExpr==0 ){
op = TK_NULL;
}else{
op = pExpr->op;
}
switch( op ){
case TK_AGG_COLUMN: {
AggInfo *pAggInfo = pExpr->pAggInfo;
struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg];
if( !pAggInfo->directMode ){
assert( pCol->iMem>0 );
inReg = pCol->iMem;
break;
}else if( pAggInfo->useSortingIdx ){
sqlite4VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdx,
pExpr->iAgg, target);
break;
}
/* Otherwise, fall thru into the TK_COLUMN case */
}
case TK_COLUMN: {
if( pExpr->iTable<0 ){
/* This only happens when coding check constraints */
assert( pParse->ckBase>0 );
inReg = pExpr->iColumn + pParse->ckBase;
}else{
inReg = sqlite4ExprCodeGetColumn(pParse, pExpr->pTab,
pExpr->iColumn, pExpr->iTable, target);
}
break;
}
case TK_INTEGER: {
codeInteger(pParse, pExpr, 0, target);
break;
}
#ifndef SQLITE_OMIT_FLOATING_POINT
case TK_FLOAT: {
assert( !ExprHasProperty(pExpr, EP_IntValue) );
codeReal(v, pExpr->u.zToken, 0, target);
break;
}
#endif
case TK_STRING: {
assert( !ExprHasProperty(pExpr, EP_IntValue) );
sqlite4VdbeAddOp4(v, OP_String8, 0, target, 0, pExpr->u.zToken, 0);
break;
}
case TK_NULL: {
sqlite4VdbeAddOp2(v, OP_Null, 0, target);
break;
}
#ifndef SQLITE_OMIT_BLOB_LITERAL
case TK_BLOB: {
int n;
const char *z;
char *zBlob;
assert( !ExprHasProperty(pExpr, EP_IntValue) );
assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' );
assert( pExpr->u.zToken[1]=='\'' );
z = &pExpr->u.zToken[2];
n = sqlite4Strlen30(z) - 1;
assert( z[n]=='\'' );
zBlob = sqlite4HexToBlob(sqlite4VdbeDb(v), z, n);
sqlite4VdbeAddOp4(v, OP_Blob, n/2, target, 0, zBlob, P4_DYNAMIC);
break;
}
#endif
case TK_VARIABLE: {
assert( !ExprHasProperty(pExpr, EP_IntValue) );
assert( pExpr->u.zToken!=0 );
assert( pExpr->u.zToken[0]!=0 );
sqlite4VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target);
if( pExpr->u.zToken[1]!=0 ){
assert( pExpr->u.zToken[0]=='?'
|| strcmp(pExpr->u.zToken, pParse->azVar[pExpr->iColumn-1])==0 );
sqlite4VdbeChangeP4(v, -1, pParse->azVar[pExpr->iColumn-1], P4_STATIC);
}
break;
}
case TK_REGISTER: {
inReg = pExpr->iTable;
break;
}
case TK_AS: {
inReg = sqlite4ExprCodeTarget(pParse, pExpr->pLeft, target);
break;
}
#ifndef SQLITE_OMIT_CAST
case TK_CAST: {
/* Expressions of the form: CAST(pLeft AS token) */
int aff, to_op;
inReg = sqlite4ExprCodeTarget(pParse, pExpr->pLeft, target);
assert( !ExprHasProperty(pExpr, EP_IntValue) );
aff = sqlite4AffinityType(pExpr->u.zToken);
to_op = aff - SQLITE_AFF_TEXT + OP_ToText;
assert( to_op==OP_ToText || aff!=SQLITE_AFF_TEXT );
assert( to_op==OP_ToBlob || aff!=SQLITE_AFF_NONE );
assert( to_op==OP_ToNumeric || aff!=SQLITE_AFF_NUMERIC );
assert( to_op==OP_ToInt || aff!=SQLITE_AFF_INTEGER );
assert( to_op==OP_ToReal || aff!=SQLITE_AFF_REAL );
testcase( to_op==OP_ToText );
testcase( to_op==OP_ToBlob );
testcase( to_op==OP_ToNumeric );
testcase( to_op==OP_ToInt );
testcase( to_op==OP_ToReal );
if( inReg!=target ){
sqlite4VdbeAddOp2(v, OP_SCopy, inReg, target);
inReg = target;
}
sqlite4VdbeAddOp1(v, to_op, inReg);
testcase( usedAsColumnCache(pParse, inReg, inReg) );
sqlite4ExprCacheAffinityChange(pParse, inReg, 1);
break;
}
#endif /* SQLITE_OMIT_CAST */
case TK_LT:
case TK_LE:
case TK_GT:
case TK_GE:
case TK_NE:
case TK_EQ: {
assert( TK_LT==OP_Lt );
assert( TK_LE==OP_Le );
assert( TK_GT==OP_Gt );
assert( TK_GE==OP_Ge );
assert( TK_EQ==OP_Eq );
assert( TK_NE==OP_Ne );
testcase( op==TK_LT );
testcase( op==TK_LE );
testcase( op==TK_GT );
testcase( op==TK_GE );
testcase( op==TK_EQ );
testcase( op==TK_NE );
r1 = sqlite4ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
r2 = sqlite4ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
r1, r2, inReg, SQLITE_STOREP2);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
}
case TK_IS:
case TK_ISNOT: {
testcase( op==TK_IS );
testcase( op==TK_ISNOT );
r1 = sqlite4ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
r2 = sqlite4ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
op = (op==TK_IS) ? TK_EQ : TK_NE;
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
r1, r2, inReg, SQLITE_STOREP2 | SQLITE_NULLEQ);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
}
case TK_AND:
case TK_OR:
case TK_PLUS:
case TK_STAR:
case TK_MINUS:
case TK_REM:
case TK_BITAND:
case TK_BITOR:
case TK_SLASH:
case TK_LSHIFT:
case TK_RSHIFT:
case TK_CONCAT: {
assert( TK_AND==OP_And );
assert( TK_OR==OP_Or );
assert( TK_PLUS==OP_Add );
assert( TK_MINUS==OP_Subtract );
assert( TK_REM==OP_Remainder );
assert( TK_BITAND==OP_BitAnd );
assert( TK_BITOR==OP_BitOr );
assert( TK_SLASH==OP_Divide );
assert( TK_LSHIFT==OP_ShiftLeft );
assert( TK_RSHIFT==OP_ShiftRight );
assert( TK_CONCAT==OP_Concat );
testcase( op==TK_AND );
testcase( op==TK_OR );
testcase( op==TK_PLUS );
testcase( op==TK_MINUS );
testcase( op==TK_REM );
testcase( op==TK_BITAND );
testcase( op==TK_BITOR );
testcase( op==TK_SLASH );
testcase( op==TK_LSHIFT );
testcase( op==TK_RSHIFT );
testcase( op==TK_CONCAT );
r1 = sqlite4ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
r2 = sqlite4ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
sqlite4VdbeAddOp3(v, op, r2, r1, target);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
}
case TK_UMINUS: {
Expr *pLeft = pExpr->pLeft;
assert( pLeft );
if( pLeft->op==TK_INTEGER ){
codeInteger(pParse, pLeft, 1, target);
#ifndef SQLITE_OMIT_FLOATING_POINT
}else if( pLeft->op==TK_FLOAT ){
assert( !ExprHasProperty(pExpr, EP_IntValue) );
codeReal(v, pLeft->u.zToken, 1, target);
#endif
}else{
regFree1 = r1 = sqlite4GetTempReg(pParse);
sqlite4VdbeAddOp2(v, OP_Integer, 0, r1);
r2 = sqlite4ExprCodeTemp(pParse, pExpr->pLeft, ®Free2);
sqlite4VdbeAddOp3(v, OP_Subtract, r2, r1, target);
testcase( regFree2==0 );
}
inReg = target;
break;
}
case TK_BITNOT:
case TK_NOT: {
assert( TK_BITNOT==OP_BitNot );
assert( TK_NOT==OP_Not );
testcase( op==TK_BITNOT );
testcase( op==TK_NOT );
r1 = sqlite4ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
testcase( regFree1==0 );
inReg = target;
sqlite4VdbeAddOp2(v, op, r1, inReg);
break;
}
case TK_ISNULL:
case TK_NOTNULL: {
int addr;
assert( TK_ISNULL==OP_IsNull );
assert( TK_NOTNULL==OP_NotNull );
testcase( op==TK_ISNULL );
testcase( op==TK_NOTNULL );
sqlite4VdbeAddOp2(v, OP_Integer, 1, target);
r1 = sqlite4ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
testcase( regFree1==0 );
addr = sqlite4VdbeAddOp1(v, op, r1);
sqlite4VdbeAddOp2(v, OP_AddImm, target, -1);
sqlite4VdbeJumpHere(v, addr);
break;
}
case TK_AGG_FUNCTION: {
AggInfo *pInfo = pExpr->pAggInfo;
if( pInfo==0 ){
assert( !ExprHasProperty(pExpr, EP_IntValue) );
sqlite4ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken);
}else{
inReg = pInfo->aFunc[pExpr->iAgg].iMem;
}
break;
}
case TK_CONST_FUNC:
case TK_FUNCTION: {
ExprList *pFarg; /* List of function arguments */
int nFarg; /* Number of function arguments */
FuncDef *pDef; /* The function definition object */
int nId; /* Length of the function name in bytes */
const char *zId; /* The function name */
int constMask = 0; /* Mask of function arguments that are constant */
int i; /* Loop counter */
u8 enc = ENC(db); /* The text encoding used by this database */
CollSeq *pColl = 0; /* A collating sequence */
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
testcase( op==TK_CONST_FUNC );
testcase( op==TK_FUNCTION );
if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ){
pFarg = 0;
}else{
pFarg = pExpr->x.pList;
}
nFarg = pFarg ? pFarg->nExpr : 0;
assert( !ExprHasProperty(pExpr, EP_IntValue) );
zId = pExpr->u.zToken;
nId = sqlite4Strlen30(zId);
pDef = sqlite4FindFunction(db, zId, nId, nFarg, enc, 0);
if( pDef==0 ){
sqlite4ErrorMsg(pParse, "unknown function: %.*s()", nId, zId);
break;
}
/* Attempt a direct implementation of the built-in COALESCE() and
** IFNULL() functions. This avoids unnecessary evalation of
** arguments past the first non-NULL argument.
*/
if( pDef->flags & SQLITE_FUNC_COALESCE ){
int endCoalesce = sqlite4VdbeMakeLabel(v);
assert( nFarg>=2 );
sqlite4ExprCode(pParse, pFarg->a[0].pExpr, target);
for(i=1; i<nFarg; i++){
sqlite4VdbeAddOp2(v, OP_NotNull, target, endCoalesce);
sqlite4ExprCacheRemove(pParse, target, 1);
sqlite4ExprCachePush(pParse);
sqlite4ExprCode(pParse, pFarg->a[i].pExpr, target);
sqlite4ExprCachePop(pParse, 1);
}
sqlite4VdbeResolveLabel(v, endCoalesce);
break;
}
if( pFarg ){
r1 = sqlite4GetTempRange(pParse, nFarg);
sqlite4ExprCachePush(pParse); /* Ticket 2ea2425d34be */
sqlite4ExprCodeExprList(pParse, pFarg, r1, 1);
sqlite4ExprCachePop(pParse, 1); /* Ticket 2ea2425d34be */
}else{
r1 = 0;
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Possibly overload the function if the first argument is
** a virtual table column.
**
** For infix functions (LIKE, GLOB, REGEXP, and MATCH) use the
** second argument, not the first, as the argument to test to
** see if it is a column in a virtual table. This is done because
** the left operand of infix functions (the operand we want to
** control overloading) ends up as the second argument to the
** function. The expression "A glob B" is equivalent to
** "glob(B,A). We want to use the A in "A glob B" to test
** for function overloading. But we use the B term in "glob(B,A)".
*/
if( nFarg>=2 && (pExpr->flags & EP_InfixFunc) ){
pDef = sqlite4VtabOverloadFunction(db, pDef, nFarg, pFarg->a[1].pExpr);
}else if( nFarg>0 ){
pDef = sqlite4VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr);
}
#endif
for(i=0; i<nFarg; i++){
if( i<32 && sqlite4ExprIsConstant(pFarg->a[i].pExpr) ){
constMask |= (1<<i);
}
if( (pDef->flags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){
pColl = sqlite4ExprCollSeq(pParse, pFarg->a[i].pExpr);
}
}
if( pDef->flags & SQLITE_FUNC_NEEDCOLL ){
if( !pColl ) pColl = db->pDfltColl;
sqlite4VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
}
sqlite4VdbeAddOp4(v, OP_Function, constMask, r1, target,
(char*)pDef, P4_FUNCDEF);
sqlite4VdbeChangeP5(v, (u8)nFarg);
if( nFarg ){
sqlite4ReleaseTempRange(pParse, r1, nFarg);
}
break;
}
#ifndef SQLITE_OMIT_SUBQUERY
case TK_EXISTS:
case TK_SELECT: {
testcase( op==TK_EXISTS );
testcase( op==TK_SELECT );
inReg = sqlite4CodeSubselect(pParse, pExpr, 0, 0);
break;
}
case TK_IN: {
int destIfFalse = sqlite4VdbeMakeLabel(v);
int destIfNull = sqlite4VdbeMakeLabel(v);
sqlite4VdbeAddOp2(v, OP_Null, 0, target);
sqlite4ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);
sqlite4VdbeAddOp2(v, OP_Integer, 1, target);
sqlite4VdbeResolveLabel(v, destIfFalse);
sqlite4VdbeAddOp2(v, OP_AddImm, target, 0);
sqlite4VdbeResolveLabel(v, destIfNull);
break;
}
#endif /* SQLITE_OMIT_SUBQUERY */
/*
** x BETWEEN y AND z
**
** This is equivalent to
**
** x>=y AND x<=z
**
** X is stored in pExpr->pLeft.
** Y is stored in pExpr->pList->a[0].pExpr.
** Z is stored in pExpr->pList->a[1].pExpr.
*/
case TK_BETWEEN: {
Expr *pLeft = pExpr->pLeft;
struct ExprList_item *pLItem = pExpr->x.pList->a;
Expr *pRight = pLItem->pExpr;
r1 = sqlite4ExprCodeTemp(pParse, pLeft, ®Free1);
r2 = sqlite4ExprCodeTemp(pParse, pRight, ®Free2);
testcase( regFree1==0 );
testcase( regFree2==0 );
r3 = sqlite4GetTempReg(pParse);
r4 = sqlite4GetTempReg(pParse);
codeCompare(pParse, pLeft, pRight, OP_Ge,
r1, r2, r3, SQLITE_STOREP2);
pLItem++;
pRight = pLItem->pExpr;
sqlite4ReleaseTempReg(pParse, regFree2);
r2 = sqlite4ExprCodeTemp(pParse, pRight, ®Free2);
testcase( regFree2==0 );
codeCompare(pParse, pLeft, pRight, OP_Le, r1, r2, r4, SQLITE_STOREP2);
sqlite4VdbeAddOp3(v, OP_And, r3, r4, target);
sqlite4ReleaseTempReg(pParse, r3);
sqlite4ReleaseTempReg(pParse, r4);
break;
}
case TK_UPLUS: {
inReg = sqlite4ExprCodeTarget(pParse, pExpr->pLeft, target);
break;
}
case TK_TRIGGER: {
/* If the opcode is TK_TRIGGER, then the expression is a reference
** to a column in the new.* or old.* pseudo-tables available to
** trigger programs. In this case Expr.iTable is set to 1 for the
** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn
** is set to the column of the pseudo-table to read, or to -1 to
** read the rowid field (if applicable - see below).
**
** The expression is implemented using an OP_Param opcode. The p1
** parameter is set to 0 for an old.rowid reference, or to (i+1)
** to reference another column of the old.* pseudo-table, where
** i is the index of the column. For a new.rowid reference, p1 is
** set to (n+1), where n is the number of columns in each pseudo-table.
** For a reference to any other column in the new.* pseudo-table, p1
** is set to (n+2+i), where n and i are as defined previously. For
** example, if the table on which triggers are being fired is
** declared as:
**
** CREATE TABLE t1(a, b);
**
** Then p1 is interpreted as follows:
**
** p1==0 -> old.rowid p1==3 -> new.rowid
** p1==1 -> old.a p1==4 -> new.a
** p1==2 -> old.b p1==5 -> new.b
**
** As of SQLite 4, the rowid references are only valid if the table is
** declared without an explicit PRIMARY KEY (as it is in the example
** above). If the table does have an explicit PRIMARY KEY, the contents
** of the old.rowid and new.rowid registers are not defined.
*/
Table *pTab = pExpr->pTab;
int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn;
assert( pExpr->iTable==0 || pExpr->iTable==1 );
assert( pExpr->iColumn>=-1 && pExpr->iColumn<pTab->nCol );
assert( p1>=0 && p1<(pTab->nCol*2+2) );
sqlite4VdbeAddOp2(v, OP_Param, p1, target);
VdbeComment((v, "%s.%s -> $%d",
(pExpr->iTable ? "new" : "old"),
(pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName),
target
));
#ifndef SQLITE_OMIT_FLOATING_POINT
/* If the column has REAL affinity, it may currently be stored as an
** integer. Use OP_RealAffinity to make sure it is really real. */
if( pExpr->iColumn>=0
&& pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL
){
sqlite4VdbeAddOp1(v, OP_RealAffinity, target);
}
#endif
break;
}
/*
** Form A:
** CASE x WHEN e1 THEN r1 WHEN e2 THEN r2 ... WHEN eN THEN rN ELSE y END
**
** Form B:
** CASE WHEN e1 THEN r1 WHEN e2 THEN r2 ... WHEN eN THEN rN ELSE y END
**
** Form A is can be transformed into the equivalent form B as follows:
** CASE WHEN x=e1 THEN r1 WHEN x=e2 THEN r2 ...
** WHEN x=eN THEN rN ELSE y END
**
** X (if it exists) is in pExpr->pLeft.
** Y is in pExpr->pRight. The Y is also optional. If there is no
** ELSE clause and no other term matches, then the result of the
** exprssion is NULL.
** Ei is in pExpr->pList->a[i*2] and Ri is pExpr->pList->a[i*2+1].
**
** The result of the expression is the Ri for the first matching Ei,
** or if there is no matching Ei, the ELSE term Y, or if there is
** no ELSE term, NULL.
*/
default: assert( op==TK_CASE ); {
int endLabel; /* GOTO label for end of CASE stmt */
int nextCase; /* GOTO label for next WHEN clause */
int nExpr; /* 2x number of WHEN terms */
int i; /* Loop counter */
ExprList *pEList; /* List of WHEN terms */
struct ExprList_item *aListelem; /* Array of WHEN terms */
Expr opCompare; /* The X==Ei expression */
Expr cacheX; /* Cached expression X */
Expr *pX; /* The X expression */
Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */
VVA_ONLY( int iCacheLevel = pParse->iCacheLevel; )
assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList );
assert((pExpr->x.pList->nExpr % 2) == 0);
assert(pExpr->x.pList->nExpr > 0);
pEList = pExpr->x.pList;
aListelem = pEList->a;
nExpr = pEList->nExpr;
endLabel = sqlite4VdbeMakeLabel(v);
if( (pX = pExpr->pLeft)!=0 ){
cacheX = *pX;
testcase( pX->op==TK_COLUMN );
testcase( pX->op==TK_REGISTER );
cacheX.iTable = sqlite4ExprCodeTemp(pParse, pX, ®Free1);
testcase( regFree1==0 );
cacheX.op = TK_REGISTER;
opCompare.op = TK_EQ;
opCompare.pLeft = &cacheX;
pTest = &opCompare;
/* Ticket b351d95f9cd5ef17e9d9dbae18f5ca8611190001:
** The value in regFree1 might get SCopy-ed into the file result.
** So make sure that the regFree1 register is not reused for other
** purposes and possibly overwritten. */
regFree1 = 0;
}
for(i=0; i<nExpr; i=i+2){
sqlite4ExprCachePush(pParse);
if( pX ){
assert( pTest!=0 );
opCompare.pRight = aListelem[i].pExpr;
}else{
pTest = aListelem[i].pExpr;
}
nextCase = sqlite4VdbeMakeLabel(v);
testcase( pTest->op==TK_COLUMN );
sqlite4ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL);
testcase( aListelem[i+1].pExpr->op==TK_COLUMN );
testcase( aListelem[i+1].pExpr->op==TK_REGISTER );
sqlite4ExprCode(pParse, aListelem[i+1].pExpr, target);
sqlite4VdbeAddOp2(v, OP_Goto, 0, endLabel);
sqlite4ExprCachePop(pParse, 1);
sqlite4VdbeResolveLabel(v, nextCase);
}
if( pExpr->pRight ){
sqlite4ExprCachePush(pParse);
sqlite4ExprCode(pParse, pExpr->pRight, target);
sqlite4ExprCachePop(pParse, 1);
}else{
sqlite4VdbeAddOp2(v, OP_Null, 0, target);
}
assert( db->mallocFailed || pParse->nErr>0
|| pParse->iCacheLevel==iCacheLevel );
sqlite4VdbeResolveLabel(v, endLabel);
break;
}
#ifndef SQLITE_OMIT_TRIGGER
case TK_RAISE: {
assert( pExpr->affinity==OE_Rollback
|| pExpr->affinity==OE_Abort
|| pExpr->affinity==OE_Fail
|| pExpr->affinity==OE_Ignore
);
if( !pParse->pTriggerTab ){
sqlite4ErrorMsg(pParse,
"RAISE() may only be used within a trigger-program");
return 0;
}
if( pExpr->affinity==OE_Abort ){
sqlite4MayAbort(pParse);
}
assert( !ExprHasProperty(pExpr, EP_IntValue) );
if( pExpr->affinity==OE_Ignore ){
sqlite4VdbeAddOp4(
v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
}else{
sqlite4HaltConstraint(pParse, pExpr->affinity, pExpr->u.zToken, 0);
}
break;
}
#endif
}
sqlite4ReleaseTempReg(pParse, regFree1);
sqlite4ReleaseTempReg(pParse, regFree2);
return inReg;
}
/*
** Generate code to evaluate an expression and store the results
** into a register. Return the register number where the results
** are stored.
**
** If the register is a temporary register that can be deallocated,
** then write its number into *pReg. If the result register is not
** a temporary, then set *pReg to zero.
*/
SQLITE_PRIVATE int sqlite4ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){
int r1 = sqlite4GetTempReg(pParse);
int r2 = sqlite4ExprCodeTarget(pParse, pExpr, r1);
if( r2==r1 ){
*pReg = r1;
}else{
sqlite4ReleaseTempReg(pParse, r1);
*pReg = 0;
}
return r2;
}
/*
** Generate code that will evaluate expression pExpr and store the
** results in register target. The results are guaranteed to appear
** in register target.
*/
SQLITE_PRIVATE int sqlite4ExprCode(Parse *pParse, Expr *pExpr, int target){
int inReg;
assert( target>0 && target<=pParse->nMem );
if( pExpr && pExpr->op==TK_REGISTER ){
sqlite4VdbeAddOp2(pParse->pVdbe, OP_Copy, pExpr->iTable, target);
}else{
inReg = sqlite4ExprCodeTarget(pParse, pExpr, target);
assert( pParse->pVdbe || pParse->db->mallocFailed );
if( inReg!=target && pParse->pVdbe ){
sqlite4VdbeAddOp2(pParse->pVdbe, OP_SCopy, inReg, target);
}
}
return target;
}
/*
** Generate code that evalutes the given expression and puts the result
** in register target.
**
** Also make a copy of the expression results into another "cache" register
** and modify the expression so that the next time it is evaluated,
** the result is a copy of the cache register.
**
** This routine is used for expressions that are used multiple
** times. They are evaluated once and the results of the expression
** are reused.
*/
SQLITE_PRIVATE int sqlite4ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){
Vdbe *v = pParse->pVdbe;
int inReg;
inReg = sqlite4ExprCode(pParse, pExpr, target);
assert( target>0 );
if( pExpr->op!=TK_REGISTER ){
int iMem;
iMem = ++pParse->nMem;
sqlite4VdbeAddOp2(v, OP_Copy, inReg, iMem);
pExpr->iTable = iMem;
pExpr->op2 = pExpr->op;
pExpr->op = TK_REGISTER;
}
return inReg;
}
#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
/*
** Generate a human-readable explanation of an expression tree.
*/
SQLITE_PRIVATE void sqlite4ExplainExpr(Vdbe *pOut, Expr *pExpr){
int op; /* The opcode being coded */
const char *zBinOp = 0; /* Binary operator */
const char *zUniOp = 0; /* Unary operator */
if( pExpr==0 ){
op = TK_NULL;
}else{
op = pExpr->op;
}
switch( op ){
case TK_AGG_COLUMN: {
sqlite4ExplainPrintf(pOut, "AGG{%d:%d}",
pExpr->iTable, pExpr->iColumn);
break;
}
case TK_COLUMN: {
if( pExpr->iTable<0 ){
/* This only happens when coding check constraints */
sqlite4ExplainPrintf(pOut, "COLUMN(%d)", pExpr->iColumn);
}else{
sqlite4ExplainPrintf(pOut, "{%d:%d}",
pExpr->iTable, pExpr->iColumn);
}
break;
}
case TK_INTEGER: {
if( pExpr->flags & EP_IntValue ){
sqlite4ExplainPrintf(pOut, "%d", pExpr->u.iValue);
}else{
sqlite4ExplainPrintf(pOut, "%s", pExpr->u.zToken);
}
break;
}
#ifndef SQLITE_OMIT_FLOATING_POINT
case TK_FLOAT: {
sqlite4ExplainPrintf(pOut,"%s", pExpr->u.zToken);
break;
}
#endif
case TK_STRING: {
sqlite4ExplainPrintf(pOut,"%Q", pExpr->u.zToken);
break;
}
case TK_NULL: {
sqlite4ExplainPrintf(pOut,"NULL");
break;
}
#ifndef SQLITE_OMIT_BLOB_LITERAL
case TK_BLOB: {
sqlite4ExplainPrintf(pOut,"%s", pExpr->u.zToken);
break;
}
#endif
case TK_VARIABLE: {
sqlite4ExplainPrintf(pOut,"VARIABLE(%s,%d)",
pExpr->u.zToken, pExpr->iColumn);
break;
}
case TK_REGISTER: {
sqlite4ExplainPrintf(pOut,"REGISTER(%d)", pExpr->iTable);
break;
}
case TK_AS: {
sqlite4ExplainExpr(pOut, pExpr->pLeft);
break;
}
#ifndef SQLITE_OMIT_CAST
case TK_CAST: {
/* Expressions of the form: CAST(pLeft AS token) */
const char *zAff = "unk";
switch( sqlite4AffinityType(pExpr->u.zToken) ){
case SQLITE_AFF_TEXT: zAff = "TEXT"; break;
case SQLITE_AFF_NONE: zAff = "NONE"; break;
case SQLITE_AFF_NUMERIC: zAff = "NUMERIC"; break;
case SQLITE_AFF_INTEGER: zAff = "INTEGER"; break;
case SQLITE_AFF_REAL: zAff = "REAL"; break;
}
sqlite4ExplainPrintf(pOut, "CAST-%s(", zAff);
sqlite4ExplainExpr(pOut, pExpr->pLeft);
sqlite4ExplainPrintf(pOut, ")");
break;
}
#endif /* SQLITE_OMIT_CAST */
case TK_LT: zBinOp = "LT"; break;
case TK_LE: zBinOp = "LE"; break;
case TK_GT: zBinOp = "GT"; break;
case TK_GE: zBinOp = "GE"; break;
case TK_NE: zBinOp = "NE"; break;
case TK_EQ: zBinOp = "EQ"; break;
case TK_IS: zBinOp = "IS"; break;
case TK_ISNOT: zBinOp = "ISNOT"; break;
case TK_AND: zBinOp = "AND"; break;
case TK_OR: zBinOp = "OR"; break;
case TK_PLUS: zBinOp = "ADD"; break;
case TK_STAR: zBinOp = "MUL"; break;
case TK_MINUS: zBinOp = "SUB"; break;
case TK_REM: zBinOp = "REM"; break;
case TK_BITAND: zBinOp = "BITAND"; break;
case TK_BITOR: zBinOp = "BITOR"; break;
case TK_SLASH: zBinOp = "DIV"; break;
case TK_LSHIFT: zBinOp = "LSHIFT"; break;
case TK_RSHIFT: zBinOp = "RSHIFT"; break;
case TK_CONCAT: zBinOp = "CONCAT"; break;
case TK_UMINUS: zUniOp = "UMINUS"; break;
case TK_UPLUS: zUniOp = "UPLUS"; break;
case TK_BITNOT: zUniOp = "BITNOT"; break;
case TK_NOT: zUniOp = "NOT"; break;
case TK_ISNULL: zUniOp = "ISNULL"; break;
case TK_NOTNULL: zUniOp = "NOTNULL"; break;
case TK_AGG_FUNCTION:
case TK_CONST_FUNC:
case TK_FUNCTION: {
ExprList *pFarg; /* List of function arguments */
if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ){
pFarg = 0;
}else{
pFarg = pExpr->x.pList;
}
sqlite4ExplainPrintf(pOut, "%sFUNCTION:%s(",
op==TK_AGG_FUNCTION ? "AGG_" : "",
pExpr->u.zToken);
if( pFarg ){
sqlite4ExplainExprList(pOut, pFarg);
}
sqlite4ExplainPrintf(pOut, ")");
break;
}
#ifndef SQLITE_OMIT_SUBQUERY
case TK_EXISTS: {
sqlite4ExplainPrintf(pOut, "EXISTS(");
sqlite4ExplainSelect(pOut, pExpr->x.pSelect);
sqlite4ExplainPrintf(pOut,")");
break;
}
case TK_SELECT: {
sqlite4ExplainPrintf(pOut, "(");
sqlite4ExplainSelect(pOut, pExpr->x.pSelect);
sqlite4ExplainPrintf(pOut, ")");
break;
}
case TK_IN: {
sqlite4ExplainPrintf(pOut, "IN(");
sqlite4ExplainExpr(pOut, pExpr->pLeft);
sqlite4ExplainPrintf(pOut, ",");
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
sqlite4ExplainSelect(pOut, pExpr->x.pSelect);
}else{
sqlite4ExplainExprList(pOut, pExpr->x.pList);
}
sqlite4ExplainPrintf(pOut, ")");
break;
}
#endif /* SQLITE_OMIT_SUBQUERY */
/*
** x BETWEEN y AND z
**
** This is equivalent to
**
** x>=y AND x<=z
**
** X is stored in pExpr->pLeft.
** Y is stored in pExpr->pList->a[0].pExpr.
** Z is stored in pExpr->pList->a[1].pExpr.
*/
case TK_BETWEEN: {
Expr *pX = pExpr->pLeft;
Expr *pY = pExpr->x.pList->a[0].pExpr;
Expr *pZ = pExpr->x.pList->a[1].pExpr;
sqlite4ExplainPrintf(pOut, "BETWEEN(");
sqlite4ExplainExpr(pOut, pX);
sqlite4ExplainPrintf(pOut, ",");
sqlite4ExplainExpr(pOut, pY);
sqlite4ExplainPrintf(pOut, ",");
sqlite4ExplainExpr(pOut, pZ);
sqlite4ExplainPrintf(pOut, ")");
break;
}
case TK_TRIGGER: {
/* If the opcode is TK_TRIGGER, then the expression is a reference
** to a column in the new.* or old.* pseudo-tables available to
** trigger programs. In this case Expr.iTable is set to 1 for the
** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn
** is set to the column of the pseudo-table to read, or to -1 to
** read the rowid field.
*/
sqlite4ExplainPrintf(pOut, "%s(%d)",
pExpr->iTable ? "NEW" : "OLD", pExpr->iColumn);
break;
}
case TK_CASE: {
sqlite4ExplainPrintf(pOut, "CASE(");
sqlite4ExplainExpr(pOut, pExpr->pLeft);
sqlite4ExplainPrintf(pOut, ",");
sqlite4ExplainExprList(pOut, pExpr->x.pList);
break;
}
#ifndef SQLITE_OMIT_TRIGGER
case TK_RAISE: {
const char *zType = "unk";
switch( pExpr->affinity ){
case OE_Rollback: zType = "rollback"; break;
case OE_Abort: zType = "abort"; break;
case OE_Fail: zType = "fail"; break;
case OE_Ignore: zType = "ignore"; break;
}
sqlite4ExplainPrintf(pOut, "RAISE-%s(%s)", zType, pExpr->u.zToken);
break;
}
#endif
}
if( zBinOp ){
sqlite4ExplainPrintf(pOut,"%s(", zBinOp);
sqlite4ExplainExpr(pOut, pExpr->pLeft);
sqlite4ExplainPrintf(pOut,",");
sqlite4ExplainExpr(pOut, pExpr->pRight);
sqlite4ExplainPrintf(pOut,")");
}else if( zUniOp ){
sqlite4ExplainPrintf(pOut,"%s(", zUniOp);
sqlite4ExplainExpr(pOut, pExpr->pLeft);
sqlite4ExplainPrintf(pOut,")");
}
}
#endif /* defined(SQLITE_ENABLE_TREE_EXPLAIN) */
#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
/*
** Generate a human-readable explanation of an expression list.
*/
SQLITE_PRIVATE void sqlite4ExplainExprList(Vdbe *pOut, ExprList *pList){
int i;
if( pList==0 || pList->nExpr==0 ){
sqlite4ExplainPrintf(pOut, "(empty-list)");
return;
}else if( pList->nExpr==1 ){
sqlite4ExplainExpr(pOut, pList->a[0].pExpr);
}else{
sqlite4ExplainPush(pOut);
for(i=0; i<pList->nExpr; i++){
sqlite4ExplainPrintf(pOut, "item[%d] = ", i);
sqlite4ExplainPush(pOut);
sqlite4ExplainExpr(pOut, pList->a[i].pExpr);
sqlite4ExplainPop(pOut);
if( i<pList->nExpr-1 ){
sqlite4ExplainNL(pOut);
}
}
sqlite4ExplainPop(pOut);
}
}
#endif /* SQLITE_DEBUG */
/*
** Return TRUE if pExpr is an constant expression that is appropriate
** for factoring out of a loop. Appropriate expressions are:
**
** * Any expression that evaluates to two or more opcodes.
**
** * Any OP_Integer, OP_Real, OP_String, OP_Blob, OP_Null,
** or OP_Variable that does not need to be placed in a
** specific register.
**
** There is no point in factoring out single-instruction constant
** expressions that need to be placed in a particular register.
** We could factor them out, but then we would end up adding an
** OP_SCopy instruction to move the value into the correct register
** later. We might as well just use the original instruction and
** avoid the OP_SCopy.
*/
static int isAppropriateForFactoring(Expr *p){
if( !sqlite4ExprIsConstantNotJoin(p) ){
return 0; /* Only constant expressions are appropriate for factoring */
}
if( (p->flags & EP_FixedDest)==0 ){
return 1; /* Any constant without a fixed destination is appropriate */
}
while( p->op==TK_UPLUS ) p = p->pLeft;
switch( p->op ){
#ifndef SQLITE_OMIT_BLOB_LITERAL
case TK_BLOB:
#endif
case TK_VARIABLE:
case TK_INTEGER:
case TK_FLOAT:
case TK_NULL:
case TK_STRING: {
testcase( p->op==TK_BLOB );
testcase( p->op==TK_VARIABLE );
testcase( p->op==TK_INTEGER );
testcase( p->op==TK_FLOAT );
testcase( p->op==TK_NULL );
testcase( p->op==TK_STRING );
/* Single-instruction constants with a fixed destination are
** better done in-line. If we factor them, they will just end
** up generating an OP_SCopy to move the value to the destination
** register. */
return 0;
}
case TK_UMINUS: {
if( p->pLeft->op==TK_FLOAT || p->pLeft->op==TK_INTEGER ){
return 0;
}
break;
}
default: {
break;
}
}
return 1;
}
/*
** If pExpr is a constant expression that is appropriate for
** factoring out of a loop, then evaluate the expression
** into a register and convert the expression into a TK_REGISTER
** expression.
*/
static int evalConstExpr(Walker *pWalker, Expr *pExpr){
Parse *pParse = pWalker->pParse;
switch( pExpr->op ){
case TK_IN:
case TK_REGISTER: {
return WRC_Prune;
}
case TK_FUNCTION:
case TK_AGG_FUNCTION:
case TK_CONST_FUNC: {
/* The arguments to a function have a fixed destination.
** Mark them this way to avoid generated unneeded OP_SCopy
** instructions.
*/
ExprList *pList = pExpr->x.pList;
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
if( pList ){
int i = pList->nExpr;
struct ExprList_item *pItem = pList->a;
for(; i>0; i--, pItem++){
if( ALWAYS(pItem->pExpr) ) pItem->pExpr->flags |= EP_FixedDest;
}
}
break;
}
}
if( isAppropriateForFactoring(pExpr) ){
int r1 = ++pParse->nMem;
int r2;
r2 = sqlite4ExprCodeTarget(pParse, pExpr, r1);
if( NEVER(r1!=r2) ) sqlite4ReleaseTempReg(pParse, r1);
pExpr->op2 = pExpr->op;
pExpr->op = TK_REGISTER;
pExpr->iTable = r2;
return WRC_Prune;
}
return WRC_Continue;
}
/*
** Preevaluate constant subexpressions within pExpr and store the
** results in registers. Modify pExpr so that the constant subexpresions
** are TK_REGISTER opcodes that refer to the precomputed values.
**
** This routine is a no-op if the jump to the cookie-check code has
** already occur. Since the cookie-check jump is generated prior to
** any other serious processing, this check ensures that there is no
** way to accidently bypass the constant initializations.
**
** This routine is also a no-op if the SQLITE_FactorOutConst optimization
** is disabled via the sqlite4_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS)
** interface. This allows test logic to verify that the same answer is
** obtained for queries regardless of whether or not constants are
** precomputed into registers or if they are inserted in-line.
*/
SQLITE_PRIVATE void sqlite4ExprCodeConstants(Parse *pParse, Expr *pExpr){
Walker w;
if( pParse->cookieGoto ) return;
if( (pParse->db->flags & SQLITE_FactorOutConst)!=0 ) return;
w.xExprCallback = evalConstExpr;
w.xSelectCallback = 0;
w.pParse = pParse;
sqlite4WalkExpr(&w, pExpr);
}
/*
** 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.
*/
SQLITE_PRIVATE int sqlite4ExprCodeExprList(
Parse *pParse, /* Parsing context */
ExprList *pList, /* The expression list to be coded */
int target, /* Where to write results */
int doHardCopy /* Make a hard copy of every element */
){
struct ExprList_item *pItem;
int i, n;
assert( pList!=0 );
assert( target>0 );
assert( pParse->pVdbe!=0 ); /* Never gets this far otherwise */
n = pList->nExpr;
for(pItem=pList->a, i=0; i<n; i++, pItem++){
Expr *pExpr = pItem->pExpr;
int inReg = sqlite4ExprCodeTarget(pParse, pExpr, target+i);
if( inReg!=target+i ){
sqlite4VdbeAddOp2(pParse->pVdbe, doHardCopy ? OP_Copy : OP_SCopy,
inReg, target+i);
}
}
return n;
}
/*
** Generate code for a BETWEEN operator.
**
** x BETWEEN y AND z
**
** The above is equivalent to
**
** x>=y AND x<=z
**
** Code it as such, taking care to do the common subexpression
** elementation of x.
*/
static void exprCodeBetween(
Parse *pParse, /* Parsing and code generating context */
Expr *pExpr, /* The BETWEEN expression */
int dest, /* Jump here if the jump is taken */
int jumpIfTrue, /* Take the jump if the BETWEEN is true */
int jumpIfNull /* Take the jump if the BETWEEN is NULL */
){
Expr exprAnd; /* The AND operator in x>=y AND x<=z */
Expr compLeft; /* The x>=y term */
Expr compRight; /* The x<=z term */
Expr exprX; /* The x subexpression */
int regFree1 = 0; /* Temporary use register */
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
exprX = *pExpr->pLeft;
exprAnd.op = TK_AND;
exprAnd.pLeft = &compLeft;
exprAnd.pRight = &compRight;
compLeft.op = TK_GE;
compLeft.pLeft = &exprX;
compLeft.pRight = pExpr->x.pList->a[0].pExpr;
compRight.op = TK_LE;
compRight.pLeft = &exprX;
compRight.pRight = pExpr->x.pList->a[1].pExpr;
exprX.iTable = sqlite4ExprCodeTemp(pParse, &exprX, ®Free1);
exprX.op = TK_REGISTER;
if( jumpIfTrue ){
sqlite4ExprIfTrue(pParse, &exprAnd, dest, jumpIfNull);
}else{
sqlite4ExprIfFalse(pParse, &exprAnd, dest, jumpIfNull);
}
sqlite4ReleaseTempReg(pParse, regFree1);
/* Ensure adequate test coverage */
testcase( jumpIfTrue==0 && jumpIfNull==0 && regFree1==0 );
testcase( jumpIfTrue==0 && jumpIfNull==0 && regFree1!=0 );
testcase( jumpIfTrue==0 && jumpIfNull!=0 && regFree1==0 );
testcase( jumpIfTrue==0 && jumpIfNull!=0 && regFree1!=0 );
testcase( jumpIfTrue!=0 && jumpIfNull==0 && regFree1==0 );
testcase( jumpIfTrue!=0 && jumpIfNull==0 && regFree1!=0 );
testcase( jumpIfTrue!=0 && jumpIfNull!=0 && regFree1==0 );
testcase( jumpIfTrue!=0 && jumpIfNull!=0 && regFree1!=0 );
}
/*
** Generate code for a boolean expression such that a jump is made
** to the label "dest" if the expression is true but execution
** continues straight thru if the expression is false.
**
** If the expression evaluates to NULL (neither true nor false), then
** take the jump if the jumpIfNull flag is SQLITE_JUMPIFNULL.
**
** This code depends on the fact that certain token values (ex: TK_EQ)
** are the same as opcode values (ex: OP_Eq) that implement the corresponding
** operation. Special comments in vdbe.c and the mkopcodeh.awk script in
** the make process cause these values to align. Assert()s in the code
** below verify that the numbers are aligned correctly.
*/
SQLITE_PRIVATE void sqlite4ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
Vdbe *v = pParse->pVdbe;
int op = 0;
int regFree1 = 0;
int regFree2 = 0;
int r1, r2;
assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
if( NEVER(v==0) ) return; /* Existance of VDBE checked by caller */
if( NEVER(pExpr==0) ) return; /* No way this can happen */
op = pExpr->op;
switch( op ){
case TK_AND: {
int d2 = sqlite4VdbeMakeLabel(v);
testcase( jumpIfNull==0 );
sqlite4ExprCachePush(pParse);
sqlite4ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL);
sqlite4ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
sqlite4VdbeResolveLabel(v, d2);
sqlite4ExprCachePop(pParse, 1);
break;
}
case TK_OR: {
testcase( jumpIfNull==0 );
sqlite4ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
sqlite4ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
break;
}
case TK_NOT: {
testcase( jumpIfNull==0 );
sqlite4ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
break;
}
case TK_LT:
case TK_LE:
case TK_GT:
case TK_GE:
case TK_NE:
case TK_EQ: {
assert( TK_LT==OP_Lt );
assert( TK_LE==OP_Le );
assert( TK_GT==OP_Gt );
assert( TK_GE==OP_Ge );
assert( TK_EQ==OP_Eq );
assert( TK_NE==OP_Ne );
testcase( op==TK_LT );
testcase( op==TK_LE );
testcase( op==TK_GT );
testcase( op==TK_GE );
testcase( op==TK_EQ );
testcase( op==TK_NE );
testcase( jumpIfNull==0 );
r1 = sqlite4ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
r2 = sqlite4ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
r1, r2, dest, jumpIfNull);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
}
case TK_IS:
case TK_ISNOT: {
testcase( op==TK_IS );
testcase( op==TK_ISNOT );
r1 = sqlite4ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
r2 = sqlite4ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
op = (op==TK_IS) ? TK_EQ : TK_NE;
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
r1, r2, dest, SQLITE_NULLEQ);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
}
case TK_ISNULL:
case TK_NOTNULL: {
assert( TK_ISNULL==OP_IsNull );
assert( TK_NOTNULL==OP_NotNull );
testcase( op==TK_ISNULL );
testcase( op==TK_NOTNULL );
r1 = sqlite4ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
sqlite4VdbeAddOp2(v, op, r1, dest);
testcase( regFree1==0 );
break;
}
case TK_BETWEEN: {
testcase( jumpIfNull==0 );
exprCodeBetween(pParse, pExpr, dest, 1, jumpIfNull);
break;
}
#ifndef SQLITE_OMIT_SUBQUERY
case TK_IN: {
int destIfFalse = sqlite4VdbeMakeLabel(v);
int destIfNull = jumpIfNull ? dest : destIfFalse;
sqlite4ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);
sqlite4VdbeAddOp2(v, OP_Goto, 0, dest);
sqlite4VdbeResolveLabel(v, destIfFalse);
break;
}
#endif
default: {
r1 = sqlite4ExprCodeTemp(pParse, pExpr, ®Free1);
sqlite4VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0);
testcase( regFree1==0 );
testcase( jumpIfNull==0 );
break;
}
}
sqlite4ReleaseTempReg(pParse, regFree1);
sqlite4ReleaseTempReg(pParse, regFree2);
}
/*
** Generate code for a boolean expression such that a jump is made
** to the label "dest" if the expression is false but execution
** continues straight thru if the expression is true.
**
** If the expression evaluates to NULL (neither true nor false) then
** jump if jumpIfNull is SQLITE_JUMPIFNULL or fall through if jumpIfNull
** is 0.
*/
SQLITE_PRIVATE void sqlite4ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
Vdbe *v = pParse->pVdbe;
int op = 0;
int regFree1 = 0;
int regFree2 = 0;
int r1, r2;
assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
if( NEVER(v==0) ) return; /* Existance of VDBE checked by caller */
if( pExpr==0 ) return;
/* The value of pExpr->op and op are related as follows:
**
** pExpr->op op
** --------- ----------
** TK_ISNULL OP_NotNull
** TK_NOTNULL OP_IsNull
** TK_NE OP_Eq
** TK_EQ OP_Ne
** TK_GT OP_Le
** TK_LE OP_Gt
** TK_GE OP_Lt
** TK_LT OP_Ge
**
** For other values of pExpr->op, op is undefined and unused.
** The value of TK_ and OP_ constants are arranged such that we
** can compute the mapping above using the following expression.
** Assert()s verify that the computation is correct.
*/
op = ((pExpr->op+(TK_ISNULL&1))^1)-(TK_ISNULL&1);
/* Verify correct alignment of TK_ and OP_ constants
*/
assert( pExpr->op!=TK_ISNULL || op==OP_NotNull );
assert( pExpr->op!=TK_NOTNULL || op==OP_IsNull );
assert( pExpr->op!=TK_NE || op==OP_Eq );
assert( pExpr->op!=TK_EQ || op==OP_Ne );
assert( pExpr->op!=TK_LT || op==OP_Ge );
assert( pExpr->op!=TK_LE || op==OP_Gt );
assert( pExpr->op!=TK_GT || op==OP_Le );
assert( pExpr->op!=TK_GE || op==OP_Lt );
switch( pExpr->op ){
case TK_AND: {
testcase( jumpIfNull==0 );
sqlite4ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
sqlite4ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
break;
}
case TK_OR: {
int d2 = sqlite4VdbeMakeLabel(v);
testcase( jumpIfNull==0 );
sqlite4ExprCachePush(pParse);
sqlite4ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL);
sqlite4ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
sqlite4VdbeResolveLabel(v, d2);
sqlite4ExprCachePop(pParse, 1);
break;
}
case TK_NOT: {
testcase( jumpIfNull==0 );
sqlite4ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
break;
}
case TK_LT:
case TK_LE:
case TK_GT:
case TK_GE:
case TK_NE:
case TK_EQ: {
testcase( op==TK_LT );
testcase( op==TK_LE );
testcase( op==TK_GT );
testcase( op==TK_GE );
testcase( op==TK_EQ );
testcase( op==TK_NE );
testcase( jumpIfNull==0 );
r1 = sqlite4ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
r2 = sqlite4ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
r1, r2, dest, jumpIfNull);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
}
case TK_IS:
case TK_ISNOT: {
testcase( pExpr->op==TK_IS );
testcase( pExpr->op==TK_ISNOT );
r1 = sqlite4ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
r2 = sqlite4ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ;
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
r1, r2, dest, SQLITE_NULLEQ);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
}
case TK_ISNULL:
case TK_NOTNULL: {
testcase( op==TK_ISNULL );
testcase( op==TK_NOTNULL );
r1 = sqlite4ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
sqlite4VdbeAddOp2(v, op, r1, dest);
testcase( regFree1==0 );
break;
}
case TK_BETWEEN: {
testcase( jumpIfNull==0 );
exprCodeBetween(pParse, pExpr, dest, 0, jumpIfNull);
break;
}
#ifndef SQLITE_OMIT_SUBQUERY
case TK_IN: {
if( jumpIfNull ){
sqlite4ExprCodeIN(pParse, pExpr, dest, dest);
}else{
int destIfNull = sqlite4VdbeMakeLabel(v);
sqlite4ExprCodeIN(pParse, pExpr, dest, destIfNull);
sqlite4VdbeResolveLabel(v, destIfNull);
}
break;
}
#endif
default: {
r1 = sqlite4ExprCodeTemp(pParse, pExpr, ®Free1);
sqlite4VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0);
testcase( regFree1==0 );
testcase( jumpIfNull==0 );
break;
}
}
sqlite4ReleaseTempReg(pParse, regFree1);
sqlite4ReleaseTempReg(pParse, regFree2);
}
/*
** Do a deep comparison of two expression trees. Return 0 if the two
** expressions are completely identical. Return 1 if they differ only
** by a COLLATE operator at the top level. Return 2 if there are differences
** other than the top-level COLLATE operator.
**
** Sometimes this routine will return 2 even if the two expressions
** really are equivalent. If we cannot prove that the expressions are
** identical, we return 2 just to be safe. So if this routine
** returns 2, then you do not really know for certain if the two
** expressions are the same. But if you get a 0 or 1 return, then you
** can be sure the expressions are the same. In the places where
** 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.
*/
SQLITE_PRIVATE int sqlite4ExprCompare(Expr *pA, Expr *pB){
if( pA==0||pB==0 ){
return pB==pA ? 0 : 2;
}
assert( !ExprHasAnyProperty(pA, EP_TokenOnly|EP_Reduced) );
assert( !ExprHasAnyProperty(pB, EP_TokenOnly|EP_Reduced) );
if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){
return 2;
}
if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
if( pA->op!=pB->op ) return 2;
if( sqlite4ExprCompare(pA->pLeft, pB->pLeft) ) return 2;
if( sqlite4ExprCompare(pA->pRight, pB->pRight) ) return 2;
if( sqlite4ExprListCompare(pA->x.pList, pB->x.pList) ) return 2;
if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2;
if( ExprHasProperty(pA, EP_IntValue) ){
if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){
return 2;
}
}else if( pA->op!=TK_COLUMN && pA->u.zToken ){
if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
return 2;
}
}
if( (pA->flags & EP_ExpCollate)!=(pB->flags & EP_ExpCollate) ) return 1;
if( (pA->flags & EP_ExpCollate)!=0 && pA->pColl!=pB->pColl ) return 2;
return 0;
}
/*
** Compare two ExprList objects. Return 0 if they are identical and
** non-zero if they differ in any way.
**
** This routine might return non-zero for equivalent ExprLists. The
** only consequence will be disabled optimizations. But this routine
** must never return 0 if the two ExprList objects are different, or
** a malfunction will result.
**
** Two NULL pointers are considered to be the same. But a NULL pointer
** always differs from a non-NULL pointer.
*/
SQLITE_PRIVATE int sqlite4ExprListCompare(ExprList *pA, ExprList *pB){
int i;
if( pA==0 && pB==0 ) return 0;
if( pA==0 || pB==0 ) return 1;
if( pA->nExpr!=pB->nExpr ) return 1;
for(i=0; i<pA->nExpr; i++){
Expr *pExprA = pA->a[i].pExpr;
Expr *pExprB = pB->a[i].pExpr;
if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1;
if( sqlite4ExprCompare(pExprA, pExprB) ) return 1;
}
return 0;
}
/*
** Add a new element to the pAggInfo->aCol[] array. Return the index of
** the new element. Return a negative number if malloc fails.
*/
static int addAggInfoColumn(sqlite4 *db, AggInfo *pInfo){
int i;
pInfo->aCol = sqlite4ArrayAllocate(
db,
pInfo->aCol,
sizeof(pInfo->aCol[0]),
3,
&pInfo->nColumn,
&pInfo->nColumnAlloc,
&i
);
return i;
}
/*
** Add a new element to the pAggInfo->aFunc[] array. Return the index of
** the new element. Return a negative number if malloc fails.
*/
static int addAggInfoFunc(sqlite4 *db, AggInfo *pInfo){
int i;
pInfo->aFunc = sqlite4ArrayAllocate(
db,
pInfo->aFunc,
sizeof(pInfo->aFunc[0]),
3,
&pInfo->nFunc,
&pInfo->nFuncAlloc,
&i
);
return i;
}
/*
** This is the xExprCallback for a tree walker. It is used to
** implement sqlite4ExprAnalyzeAggregates(). See sqlite4ExprAnalyzeAggregates
** for additional information.
*/
static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
int i;
NameContext *pNC = pWalker->u.pNC;
Parse *pParse = pNC->pParse;
SrcList *pSrcList = pNC->pSrcList;
AggInfo *pAggInfo = pNC->pAggInfo;
switch( pExpr->op ){
case TK_AGG_COLUMN:
case TK_COLUMN: {
testcase( pExpr->op==TK_AGG_COLUMN );
testcase( pExpr->op==TK_COLUMN );
/* Check to see if the column is in one of the tables in the FROM
** clause of the aggregate query */
if( ALWAYS(pSrcList!=0) ){
struct SrcList_item *pItem = pSrcList->a;
for(i=0; i<pSrcList->nSrc; i++, pItem++){
struct AggInfo_col *pCol;
assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
if( pExpr->iTable==pItem->iCursor ){
/* If we reach this point, it means that pExpr refers to a table
** that is in the FROM clause of the aggregate query.
**
** Make an entry for the column in pAggInfo->aCol[] if there
** is not an entry there already.
*/
int k;
pCol = pAggInfo->aCol;
for(k=0; k<pAggInfo->nColumn; k++, pCol++){
if( pCol->iTable==pExpr->iTable &&
pCol->iColumn==pExpr->iColumn ){
break;
}
}
if( (k>=pAggInfo->nColumn)
&& (k = addAggInfoColumn(pParse->db, pAggInfo))>=0
){
pCol = &pAggInfo->aCol[k];
pCol->pTab = pExpr->pTab;
pCol->iTable = pExpr->iTable;
pCol->iColumn = pExpr->iColumn;
pCol->iMem = ++pParse->nMem;
pCol->iSorterColumn = -1;
pCol->pExpr = pExpr;
if( pAggInfo->pGroupBy ){
int j, n;
ExprList *pGB = pAggInfo->pGroupBy;
struct ExprList_item *pTerm = pGB->a;
n = pGB->nExpr;
for(j=0; j<n; j++, pTerm++){
Expr *pE = pTerm->pExpr;
if( pE->op==TK_COLUMN && pE->iTable==pExpr->iTable &&
pE->iColumn==pExpr->iColumn ){
pCol->iSorterColumn = j;
break;
}
}
}
if( pCol->iSorterColumn<0 ){
pCol->iSorterColumn = pAggInfo->nSortingColumn++;
}
}
/* There is now an entry for pExpr in pAggInfo->aCol[] (either
** because it was there before or because we just created it).
** Convert the pExpr to be a TK_AGG_COLUMN referring to that
** pAggInfo->aCol[] entry.
*/
ExprSetIrreducible(pExpr);
pExpr->pAggInfo = pAggInfo;
pExpr->op = TK_AGG_COLUMN;
pExpr->iAgg = (i16)k;
break;
} /* endif pExpr->iTable==pItem->iCursor */
} /* end loop over pSrcList */
}
return WRC_Prune;
}
case TK_AGG_FUNCTION: {
/* The pNC->nDepth==0 test causes aggregate functions in subqueries
** to be ignored */
if( pNC->nDepth==0 ){
/* Check to see if pExpr is a duplicate of another aggregate
** function that is already in the pAggInfo structure
*/
struct AggInfo_func *pItem = pAggInfo->aFunc;
for(i=0; i<pAggInfo->nFunc; i++, pItem++){
if( sqlite4ExprCompare(pItem->pExpr, pExpr)==0 ){
break;
}
}
if( i>=pAggInfo->nFunc ){
/* pExpr is original. Make a new entry in pAggInfo->aFunc[]
*/
u8 enc = ENC(pParse->db);
i = addAggInfoFunc(pParse->db, pAggInfo);
if( i>=0 ){
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
pItem = &pAggInfo->aFunc[i];
pItem->pExpr = pExpr;
pItem->iMem = ++pParse->nMem;
assert( !ExprHasProperty(pExpr, EP_IntValue) );
pItem->pFunc = sqlite4FindFunction(pParse->db,
pExpr->u.zToken, sqlite4Strlen30(pExpr->u.zToken),
pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0);
if( pExpr->flags & EP_Distinct ){
pItem->iDistinct = pParse->nTab++;
}else{
pItem->iDistinct = -1;
}
}
}
/* Make pExpr point to the appropriate pAggInfo->aFunc[] entry
*/
assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
ExprSetIrreducible(pExpr);
pExpr->iAgg = (i16)i;
pExpr->pAggInfo = pAggInfo;
return WRC_Prune;
}
}
}
return WRC_Continue;
}
static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){
NameContext *pNC = pWalker->u.pNC;
if( pNC->nDepth==0 ){
pNC->nDepth++;
sqlite4WalkSelect(pWalker, pSelect);
pNC->nDepth--;
return WRC_Prune;
}else{
return WRC_Continue;
}
}
/*
** Analyze the given expression looking for aggregate functions and
** for variables that need to be added to the pParse->aAgg[] array.
** Make additional entries to the pParse->aAgg[] array as necessary.
**
** This routine should only be called after the expression has been
** analyzed by sqlite4ResolveExprNames().
*/
SQLITE_PRIVATE void sqlite4ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
Walker w;
w.xExprCallback = analyzeAggregate;
w.xSelectCallback = analyzeAggregatesInSelect;
w.u.pNC = pNC;
assert( pNC->pSrcList!=0 );
sqlite4WalkExpr(&w, pExpr);
}
/*
** Call sqlite4ExprAnalyzeAggregates() for every expression in an
** expression list. Return the number of errors.
**
** If an error is found, the analysis is cut short.
*/
SQLITE_PRIVATE void sqlite4ExprAnalyzeAggList(NameContext *pNC, ExprList *pList){
struct ExprList_item *pItem;
int i;
if( pList ){
for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
sqlite4ExprAnalyzeAggregates(pNC, pItem->pExpr);
}
}
}
/*
** Allocate a single new register for use to hold some intermediate result.
*/
SQLITE_PRIVATE int sqlite4GetTempReg(Parse *pParse){
if( pParse->nTempReg==0 ){
return ++pParse->nMem;
}
return pParse->aTempReg[--pParse->nTempReg];
}
/*
** Deallocate a register, making available for reuse for some other
** purpose.
**
** If a register is currently being used by the column cache, then
** the dallocation is deferred until the column cache line that uses
** the register becomes stale.
*/
SQLITE_PRIVATE void sqlite4ReleaseTempReg(Parse *pParse, int iReg){
if( iReg && pParse->nTempReg<ArraySize(pParse->aTempReg) ){
int i;
struct yColCache *p;
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
if( p->iReg==iReg ){
p->tempReg = 1;
return;
}
}
pParse->aTempReg[pParse->nTempReg++] = iReg;
}
}
/*
** Allocate or deallocate a block of nReg consecutive registers
*/
SQLITE_PRIVATE int sqlite4GetTempRange(Parse *pParse, int nReg){
int i, n;
i = pParse->iRangeReg;
n = pParse->nRangeReg;
if( nReg<=n ){
assert( !usedAsColumnCache(pParse, i, i+n-1) );
pParse->iRangeReg += nReg;
pParse->nRangeReg -= nReg;
}else{
i = pParse->nMem+1;
pParse->nMem += nReg;
}
return i;
}
SQLITE_PRIVATE void sqlite4ReleaseTempRange(Parse *pParse, int iReg, int nReg){
sqlite4ExprCacheRemove(pParse, iReg, nReg);
if( nReg>pParse->nRangeReg ){
pParse->nRangeReg = nReg;
pParse->iRangeReg = iReg;
}
}
/*
** Mark all temporary registers as being unavailable for reuse.
*/
SQLITE_PRIVATE void sqlite4ClearTempRegCache(Parse *pParse){
pParse->nTempReg = 0;
pParse->nRangeReg = 0;
}
/************** End of expr.c ************************************************/
/************** Begin file alter.c *******************************************/
/*
** 2005 February 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.
**
*************************************************************************
** This file contains C code routines that used to generate VDBE code
** that implements the ALTER TABLE command.
*/
/*
** The code in this file only exists if we are not omitting the
** ALTER TABLE logic from the build.
*/
#ifndef SQLITE_OMIT_ALTERTABLE
/*
** This function is used by SQL generated to implement the
** ALTER TABLE command. The first argument is the text of a CREATE TABLE or
** CREATE INDEX command. The second is a table name. The table name in
** the CREATE TABLE or CREATE INDEX statement is replaced with the third
** argument and the result returned. Examples:
**
** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def')
** -> 'CREATE TABLE def(a, b, c)'
**
** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def')
** -> 'CREATE INDEX i ON def(a, b, c)'
*/
static void renameTableFunc(
sqlite4_context *context,
int NotUsed,
sqlite4_value **argv
){
unsigned char const *zSql = sqlite4_value_text(argv[0]);
unsigned char const *zTableName = sqlite4_value_text(argv[1]);
int token;
Token tname;
unsigned char const *zCsr = zSql;
int len = 0;
char *zRet;
sqlite4 *db = sqlite4_context_db_handle(context);
UNUSED_PARAMETER(NotUsed);
/* The principle used to locate the table name in the CREATE TABLE
** statement is that the table name is the first non-space token that
** is immediately followed by a TK_LP or TK_USING token.
*/
if( zSql ){
do {
if( !*zCsr ){
/* Ran out of input before finding an opening bracket. Return NULL. */
return;
}
/* Store the token that zCsr points to in tname. */
tname.z = (char*)zCsr;
tname.n = len;
/* Advance zCsr to the next token. Store that token type in 'token',
** and its length in 'len' (to be used next iteration of this loop).
*/
do {
zCsr += len;
len = sqlite4GetToken(zCsr, &token);
} while( token==TK_SPACE );
assert( len>0 );
} while( token!=TK_LP && token!=TK_USING );
zRet = sqlite4MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql,
zTableName, tname.z+tname.n);
sqlite4_result_text(context, zRet, -1, SQLITE_TRANSIENT);
sqlite4DbFree(db, zRet);
}
}
/*
** This C function implements an SQL user function that is used by SQL code
** generated by the ALTER TABLE ... RENAME command to modify the definition
** of any foreign key constraints that use the table being renamed as the
** parent table. It is passed three arguments:
**
** 1) The complete text of the CREATE TABLE statement being modified,
** 2) The old name of the table being renamed, and
** 3) The new name of the table being renamed.
**
** It returns the new CREATE TABLE statement. For example:
**
** sqlite_rename_parent('CREATE TABLE t1(a REFERENCES t2)', 't2', 't3')
** -> 'CREATE TABLE t1(a REFERENCES t3)'
*/
#ifndef SQLITE_OMIT_FOREIGN_KEY
static void renameParentFunc(
sqlite4_context *context,
int NotUsed,
sqlite4_value **argv
){
sqlite4 *db = sqlite4_context_db_handle(context);
char *zOutput = 0;
char *zResult;
unsigned char const *zInput = sqlite4_value_text(argv[0]);
unsigned char const *zOld = sqlite4_value_text(argv[1]);
unsigned char const *zNew = sqlite4_value_text(argv[2]);
unsigned const char *z; /* Pointer to token */
int n; /* Length of token z */
int token; /* Type of token */
UNUSED_PARAMETER(NotUsed);
for(z=zInput; *z; z=z+n){
n = sqlite4GetToken(z, &token);
if( token==TK_REFERENCES ){
char *zParent;
do {
z += n;
n = sqlite4GetToken(z, &token);
}while( token==TK_SPACE );
zParent = sqlite4DbStrNDup(db, (const char *)z, n);
if( zParent==0 ) break;
sqlite4Dequote(zParent);
if( 0==sqlite4StrICmp((const char *)zOld, zParent) ){
char *zOut = sqlite4MPrintf(db, "%s%.*s\"%w\"",
(zOutput?zOutput:""), z-zInput, zInput, (const char *)zNew
);
sqlite4DbFree(db, zOutput);
zOutput = zOut;
zInput = &z[n];
}
sqlite4DbFree(db, zParent);
}
}
zResult = sqlite4MPrintf(db, "%s%s", (zOutput?zOutput:""), zInput),
sqlite4_result_text(context, zResult, -1, SQLITE_TRANSIENT);
sqlite4DbFree(db, zOutput);
sqlite4DbFree(db, zResult);
}
#endif
#ifndef SQLITE_OMIT_TRIGGER
/* This function is used by SQL generated to implement the
** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER
** statement. The second is a table name. The table name in the CREATE
** TRIGGER statement is replaced with the third argument and the result
** returned. This is analagous to renameTableFunc() above, except for CREATE
** TRIGGER, not CREATE INDEX and CREATE TABLE.
*/
static void renameTriggerFunc(
sqlite4_context *context,
int NotUsed,
sqlite4_value **argv
){
unsigned char const *zSql = sqlite4_value_text(argv[0]);
unsigned char const *zTableName = sqlite4_value_text(argv[1]);
int token;
Token tname;
int dist = 3;
unsigned char const *zCsr = zSql;
int len = 0;
char *zRet;
sqlite4 *db = sqlite4_context_db_handle(context);
UNUSED_PARAMETER(NotUsed);
/* The principle used to locate the table name in the CREATE TRIGGER
** statement is that the table name is the first token that is immediatedly
** preceded by either TK_ON or TK_DOT and immediatedly followed by one
** of TK_WHEN, TK_BEGIN or TK_FOR.
*/
if( zSql ){
do {
if( !*zCsr ){
/* Ran out of input before finding the table name. Return NULL. */
return;
}
/* Store the token that zCsr points to in tname. */
tname.z = (char*)zCsr;
tname.n = len;
/* Advance zCsr to the next token. Store that token type in 'token',
** and its length in 'len' (to be used next iteration of this loop).
*/
do {
zCsr += len;
len = sqlite4GetToken(zCsr, &token);
}while( token==TK_SPACE );
assert( len>0 );
/* Variable 'dist' stores the number of tokens read since the most
** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN
** token is read and 'dist' equals 2, the condition stated above
** to be met.
**
** Note that ON cannot be a database, table or column name, so
** there is no need to worry about syntax like
** "CREATE TRIGGER ... ON ON.ON BEGIN ..." etc.
*/
dist++;
if( token==TK_DOT || token==TK_ON ){
dist = 0;
}
} while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) );
/* Variable tname now contains the token that is the old table-name
** in the CREATE TRIGGER statement.
*/
zRet = sqlite4MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql,
zTableName, tname.z+tname.n);
sqlite4_result_text(context, zRet, -1, SQLITE_TRANSIENT);
sqlite4DbFree(db, zRet);
}
}
#endif /* !SQLITE_OMIT_TRIGGER */
/*
** Register built-in functions used to help implement ALTER TABLE
*/
SQLITE_PRIVATE void sqlite4AlterFunctions(sqlite4_env *pEnv){
static FuncDef aAlterTableFuncs[] = {
FUNCTION(sqlite_rename_table, 2, 0, 0, renameTableFunc),
#ifndef SQLITE_OMIT_TRIGGER
FUNCTION(sqlite_rename_trigger, 2, 0, 0, renameTriggerFunc),
#endif
#ifndef SQLITE_OMIT_FOREIGN_KEY
FUNCTION(sqlite_rename_parent, 3, 0, 0, renameParentFunc),
#endif
};
int i;
FuncDefTable *pFuncTab = &pEnv->aGlobalFuncs;
FuncDef *aFunc = (FuncDef*)aAlterTableFuncs;
for(i=0; i<ArraySize(aAlterTableFuncs); i++){
sqlite4FuncDefInsert(pFuncTab, &aFunc[i], 1);
}
}
/*
** This function is used to create the text of expressions of the form:
**
** name=<constant1> OR name=<constant2> OR ...
**
** If argument zWhere is NULL, then a pointer string containing the text
** "name=<constant>" is returned, where <constant> is the quoted version
** of the string passed as argument zConstant. The returned buffer is
** allocated using sqlite4DbMalloc(). It is the responsibility of the
** caller to ensure that it is eventually freed.
**
** If argument zWhere is not NULL, then the string returned is
** "<where> OR name=<constant>", where <where> is the contents of zWhere.
** In this case zWhere is passed to sqlite4DbFree() before returning.
**
*/
static char *whereOrName(sqlite4 *db, char *zWhere, char *zConstant){
char *zNew;
if( !zWhere ){
zNew = sqlite4MPrintf(db, "name=%Q", zConstant);
}else{
zNew = sqlite4MPrintf(db, "%s OR name=%Q", zWhere, zConstant);
sqlite4DbFree(db, zWhere);
}
return zNew;
}
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
/*
** Generate the text of a WHERE expression which can be used to select all
** tables that have foreign key constraints that refer to table pTab (i.e.
** constraints for which pTab is the parent table) from the sqlite_master
** table.
*/
static char *whereForeignKeys(Parse *pParse, Table *pTab){
FKey *p;
char *zWhere = 0;
for(p=sqlite4FkReferences(pTab); p; p=p->pNextTo){
zWhere = whereOrName(pParse->db, zWhere, p->pFrom->zName);
}
return zWhere;
}
#endif
/*
** Generate the text of a WHERE expression which can be used to select all
** temporary triggers on table pTab from the sqlite_temp_master table. If
** table pTab has no temporary triggers, or is itself stored in the
** temporary database, NULL is returned.
*/
static char *whereTempTriggers(Parse *pParse, Table *pTab){
Trigger *pTrig;
char *zWhere = 0;
const Schema *pTempSchema = pParse->db->aDb[1].pSchema; /* Temp db schema */
/* If the table is not located in the temp-db (in which case NULL is
** returned, loop through the tables list of triggers. For each trigger
** that is not part of the temp-db schema, add a clause to the WHERE
** expression being built up in zWhere.
*/
if( pTab->pSchema!=pTempSchema ){
sqlite4 *db = pParse->db;
for(pTrig=sqlite4TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){
if( pTrig->pSchema==pTempSchema ){
zWhere = whereOrName(db, zWhere, pTrig->zName);
}
}
}
if( zWhere ){
char *zNew = sqlite4MPrintf(pParse->db, "type='trigger' AND (%s)", zWhere);
sqlite4DbFree(pParse->db, zWhere);
zWhere = zNew;
}
return zWhere;
}
/*
** Generate code to drop and reload the internal representation of table
** pTab from the database, including triggers and temporary triggers.
** Argument zName is the name of the table in the database schema at
** the time the generated code is executed. This can be different from
** pTab->zName if this function is being called to code part of an
** "ALTER TABLE RENAME TO" statement.
*/
static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){
Vdbe *v;
char *zWhere;
int iDb; /* Index of database containing pTab */
#ifndef SQLITE_OMIT_TRIGGER
Trigger *pTrig;
#endif
v = sqlite4GetVdbe(pParse);
if( NEVER(v==0) ) return;
iDb = sqlite4SchemaToIndex(pParse->db, pTab->pSchema);
assert( iDb>=0 );
#ifndef SQLITE_OMIT_TRIGGER
/* Drop any table triggers from the internal schema. */
for(pTrig=sqlite4TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){
int iTrigDb = sqlite4SchemaToIndex(pParse->db, pTrig->pSchema);
assert( iTrigDb==iDb || iTrigDb==1 );
sqlite4VdbeAddOp4(v, OP_DropTrigger, iTrigDb, 0, 0, pTrig->zName, 0);
}
#endif
/* Drop the table and index from the internal schema. */
sqlite4VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);
/* Reload the table, index and permanent trigger schemas. */
zWhere = sqlite4MPrintf(pParse->db, "tbl_name=%Q", zName);
if( !zWhere ) return;
sqlite4VdbeAddParseSchemaOp(v, iDb, zWhere);
#ifndef SQLITE_OMIT_TRIGGER
/* Now, if the table is not stored in the temp database, reload any temp
** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined.
*/
if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
sqlite4VdbeAddParseSchemaOp(v, 1, zWhere);
}
#endif
}
/*
** Parameter zName is the name of a table that is about to be altered
** (either with ALTER TABLE ... RENAME TO or ALTER TABLE ... ADD COLUMN).
** If the table is a system table, this function leaves an error message
** in pParse->zErr (system tables may not be altered) and returns non-zero.
**
** Or, if zName is not a system table, zero is returned.
*/
static int isSystemTable(Parse *pParse, const char *zName){
if( sqlite4Strlen30(zName)>6 && 0==sqlite4StrNICmp(zName, "sqlite_", 7) ){
sqlite4ErrorMsg(pParse, "table %s may not be altered", zName);
return 1;
}
return 0;
}
/*
** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy"
** command.
*/
SQLITE_PRIVATE void sqlite4AlterRenameTable(
Parse *pParse, /* Parser context. */
SrcList *pSrc, /* The table to rename. */
Token *pName /* The new table name. */
){
int iDb; /* Database that contains the table */
char *zDb; /* Name of database iDb */
Table *pTab; /* Table being renamed */
char *zName = 0; /* NULL-terminated version of pName */
sqlite4 *db = pParse->db; /* Database connection */
int nTabName; /* Number of UTF-8 characters in zTabName */
const char *zTabName; /* Original name of the table */
Vdbe *v;
#ifndef SQLITE_OMIT_TRIGGER
char *zWhere = 0; /* Where clause to locate temp triggers */
#endif
VTable *pVTab = 0; /* Non-zero if this is a v-tab with an xRename() */
int savedDbFlags; /* Saved value of db->flags */
savedDbFlags = db->flags;
if( NEVER(db->mallocFailed) ) goto exit_rename_table;
assert( pSrc->nSrc==1 );
pTab = sqlite4LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase);
if( !pTab ) goto exit_rename_table;
iDb = sqlite4SchemaToIndex(pParse->db, pTab->pSchema);
zDb = db->aDb[iDb].zName;
db->flags |= SQLITE_PreferBuiltin;
/* Get a NULL terminated version of the new table name. */
zName = sqlite4NameFromToken(db, pName);
if( !zName ) goto exit_rename_table;
/* Check that a table or index named 'zName' does not already exist
** in database iDb. If so, this is an error.
*/
if( sqlite4FindTable(db, zName, zDb) || sqlite4FindIndex(db, zName, zDb) ){
sqlite4ErrorMsg(pParse,
"there is already another table or index with this name: %s", zName);
goto exit_rename_table;
}
/* Make sure it is not a system table being altered, or a reserved name
** that the table is being renamed to.
*/
if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ){
goto exit_rename_table;
}
if( SQLITE_OK!=sqlite4CheckObjectName(pParse, zName) ){ goto
exit_rename_table;
}
#ifndef SQLITE_OMIT_VIEW
if( pTab->pSelect ){
sqlite4ErrorMsg(pParse, "view %s may not be altered", pTab->zName);
goto exit_rename_table;
}
#endif
#ifndef SQLITE_OMIT_AUTHORIZATION
/* Invoke the authorization callback. */
if( sqlite4AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){
goto exit_rename_table;
}
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( sqlite4ViewGetColumnNames(pParse, pTab) ){
goto exit_rename_table;
}
if( IsVirtual(pTab) ){
pVTab = sqlite4GetVTable(db, pTab);
if( pVTab->pVtab->pModule->xRename==0 ){
pVTab = 0;
}
}
#endif
/* Begin a transaction and code the VerifyCookie for database iDb.
** Then modify the schema cookie (since the ALTER TABLE modifies the
** schema). Open a statement transaction if the table is a virtual
** table.
*/
v = sqlite4GetVdbe(pParse);
if( v==0 ){
goto exit_rename_table;
}
sqlite4BeginWriteOperation(pParse, pVTab!=0, iDb);
sqlite4ChangeCookie(pParse, iDb);
/* If this is a virtual table, invoke the xRename() function if
** one is defined. The xRename() callback will modify the names
** of any resources used by the v-table implementation (including other
** SQLite tables) that are identified by the name of the virtual table.
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( pVTab ){
int i = ++pParse->nMem;
sqlite4VdbeAddOp4(v, OP_String8, 0, i, 0, zName, 0);
sqlite4VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB);
sqlite4MayAbort(pParse);
}
#endif
/* figure out how many UTF-8 characters are in zName */
zTabName = pTab->zName;
nTabName = sqlite4Utf8CharLen(zTabName, -1);
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
if( db->flags&SQLITE_ForeignKeys ){
/* If foreign-key support is enabled, rewrite the CREATE TABLE
** statements corresponding to all child tables of foreign key constraints
** for which the renamed table is the parent table. */
if( (zWhere=whereForeignKeys(pParse, pTab))!=0 ){
sqlite4NestedParse(pParse,
"UPDATE \"%w\".%s SET "
"sql = sqlite_rename_parent(sql, %Q, %Q) "
"WHERE %s;", zDb, SCHEMA_TABLE(iDb), zTabName, zName, zWhere);
sqlite4DbFree(db, zWhere);
}
}
#endif
/* Modify the sqlite_master table to use the new table name. */
sqlite4NestedParse(pParse,
"UPDATE %Q.%s SET "
#ifdef SQLITE_OMIT_TRIGGER
"sql = sqlite_rename_table(sql, %Q), "
#else
"sql = CASE "
"WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)"
"ELSE sqlite_rename_table(sql, %Q) END, "
#endif
"tbl_name = %Q, "
"name = CASE "
"WHEN type='table' THEN %Q "
"WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN "
"'sqlite_autoindex_' || %Q || substr(name,%d+18) "
"ELSE name END "
"WHERE tbl_name=%Q AND "
"(type='table' OR type='index' OR type='trigger');",
zDb, SCHEMA_TABLE(iDb), zName, zName, zName,
#ifndef SQLITE_OMIT_TRIGGER
zName,
#endif
zName, nTabName, zTabName
);
#ifndef SQLITE_OMIT_AUTOINCREMENT
/* If the sqlite_sequence table exists in this database, then update
** it with the new table name.
*/
if( sqlite4FindTable(db, "sqlite_sequence", zDb) ){
sqlite4NestedParse(pParse,
"UPDATE \"%w\".sqlite_sequence set name = %Q WHERE name = %Q",
zDb, zName, pTab->zName);
}
#endif
#ifndef SQLITE_OMIT_TRIGGER
/* If there are TEMP triggers on this table, modify the sqlite_temp_master
** table. Don't do this if the table being ALTERed is itself located in
** the temp database.
*/
if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
sqlite4NestedParse(pParse,
"UPDATE sqlite_temp_master SET "
"sql = sqlite_rename_trigger(sql, %Q), "
"tbl_name = %Q "
"WHERE %s;", zName, zName, zWhere);
sqlite4DbFree(db, zWhere);
}
#endif
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
if( db->flags&SQLITE_ForeignKeys ){
FKey *p;
for(p=sqlite4FkReferences(pTab); p; p=p->pNextTo){
Table *pFrom = p->pFrom;
if( pFrom!=pTab ){
reloadTableSchema(pParse, p->pFrom, pFrom->zName);
}
}
}
#endif
/* Drop and reload the internal table schema. */
reloadTableSchema(pParse, pTab, zName);
exit_rename_table:
sqlite4SrcListDelete(db, pSrc);
sqlite4DbFree(db, zName);
db->flags = savedDbFlags;
}
/*
** This function is called after an "ALTER TABLE ... ADD" statement
** has been parsed. Argument pColDef contains the text of the new
** column definition.
**
** The Table structure pParse->pNewTable was extended to include
** the new column during parsing.
*/
SQLITE_PRIVATE void sqlite4AlterFinishAddColumn(Parse *pParse, Token *pColDef){
Table *pNew; /* Copy of pParse->pNewTable */
Table *pTab; /* Table being altered */
int iDb; /* Database number */
const char *zDb; /* Database name */
const char *zTab; /* Table name */
char *zCol; /* Null-terminated column definition */
Column *pCol; /* The new column */
Expr *pDflt; /* Default value for the new column */
sqlite4 *db; /* The database connection; */
db = pParse->db;
if( pParse->nErr || db->mallocFailed ) return;
pNew = pParse->pNewTable;
assert( pNew );
iDb = sqlite4SchemaToIndex(db, pNew->pSchema);
zDb = db->aDb[iDb].zName;
zTab = &pNew->zName[16]; /* Skip the "sqlite_altertab_" prefix on the name */
pCol = &pNew->aCol[pNew->nCol-1];
pDflt = pCol->pDflt;
pTab = sqlite4FindTable(db, zTab, zDb);
assert( pTab );
#ifndef SQLITE_OMIT_AUTHORIZATION
/* Invoke the authorization callback. */
if( sqlite4AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){
return;
}
#endif
/* If the default value for the new column was specified with a
** literal NULL, then set pDflt to 0. This simplifies checking
** for an SQL NULL default below.
*/
if( pDflt && pDflt->op==TK_NULL ){
pDflt = 0;
}
/* Check that the new column is not specified as PRIMARY KEY or UNIQUE.
** If there is a NOT NULL constraint, then the default value for the
** column must not be NULL.
*/
if( pCol->isPrimKey ){
sqlite4ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");
return;
}
if( pNew->pIndex ){
sqlite4ErrorMsg(pParse, "Cannot add a UNIQUE column");
return;
}
if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){
sqlite4ErrorMsg(pParse,
"Cannot add a REFERENCES column with non-NULL default value");
return;
}
if( pCol->notNull && !pDflt ){
sqlite4ErrorMsg(pParse,
"Cannot add a NOT NULL column with default value NULL");
return;
}
/* Ensure the default expression is something that sqlite4ValueFromExpr()
** can handle (i.e. not CURRENT_TIME etc.)
*/
if( pDflt ){
sqlite4_value *pVal;
if( sqlite4ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){
db->mallocFailed = 1;
return;
}
if( !pVal ){
sqlite4ErrorMsg(pParse, "Cannot add a column with non-constant default");
return;
}
sqlite4ValueFree(pVal);
}
/* Modify the CREATE TABLE statement. */
zCol = sqlite4DbStrNDup(db, (char*)pColDef->z, pColDef->n);
if( zCol ){
char *zEnd = &zCol[pColDef->n-1];
int savedDbFlags = db->flags;
while( zEnd>zCol && (*zEnd==';' || sqlite4Isspace(*zEnd)) ){
*zEnd-- = '\0';
}
db->flags |= SQLITE_PreferBuiltin;
sqlite4NestedParse(pParse,
"UPDATE \"%w\".%s SET "
"sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) "
"WHERE type = 'table' AND name = %Q",
zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1,
zTab
);
sqlite4DbFree(db, zCol);
db->flags = savedDbFlags;
}
/* Reload the schema of the modified table. */
reloadTableSchema(pParse, pTab, pTab->zName);
}
/*
** This function is called by the parser after the table-name in
** an "ALTER TABLE <table-name> ADD" statement is parsed. Argument
** pSrc is the full-name of the table being altered.
**
** This routine makes a (partial) copy of the Table structure
** for the table being altered and sets Parse.pNewTable to point
** to it. Routines called by the parser as the column definition
** is parsed (i.e. sqlite4AddColumn()) add the new Column data to
** the copy. The copy of the Table structure is deleted by tokenize.c
** after parsing is finished.
**
** Routine sqlite4AlterFinishAddColumn() will be called to complete
** coding the "ALTER TABLE ... ADD" statement.
*/
SQLITE_PRIVATE void sqlite4AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
Table *pNew;
Table *pTab;
Vdbe *v;
int iDb;
int i;
int nAlloc;
sqlite4 *db = pParse->db;
/* Look up the table being altered. */
assert( pParse->pNewTable==0 );
if( db->mallocFailed ) goto exit_begin_add_column;
pTab = sqlite4LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase);
if( !pTab ) goto exit_begin_add_column;
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( IsVirtual(pTab) ){
sqlite4ErrorMsg(pParse, "virtual tables may not be altered");
goto exit_begin_add_column;
}
#endif
/* Make sure this is not an attempt to ALTER a view. */
if( pTab->pSelect ){
sqlite4ErrorMsg(pParse, "Cannot add a column to a view");
goto exit_begin_add_column;
}
if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ){
goto exit_begin_add_column;
}
assert( pTab->addColOffset>0 );
iDb = sqlite4SchemaToIndex(db, pTab->pSchema);
/* Put a copy of the Table struct in Parse.pNewTable for the
** sqlite4AddColumn() function and friends to modify. But modify
** the name by adding an "sqlite_altertab_" prefix. By adding this
** prefix, we insure that the name will not collide with an existing
** table because user table are not allowed to have the "sqlite_"
** prefix on their name.
*/
pNew = (Table*)sqlite4DbMallocZero(db, sizeof(Table));
if( !pNew ) goto exit_begin_add_column;
pParse->pNewTable = pNew;
pNew->nRef = 1;
pNew->nCol = pTab->nCol;
assert( pNew->nCol>0 );
nAlloc = (((pNew->nCol-1)/8)*8)+8;
assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 );
pNew->aCol = (Column*)sqlite4DbMallocZero(db, sizeof(Column)*nAlloc);
pNew->zName = sqlite4MPrintf(db, "sqlite_altertab_%s", pTab->zName);
if( !pNew->aCol || !pNew->zName ){
db->mallocFailed = 1;
goto exit_begin_add_column;
}
memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol);
for(i=0; i<pNew->nCol; i++){
Column *pCol = &pNew->aCol[i];
pCol->zName = sqlite4DbStrDup(db, pCol->zName);
pCol->zColl = 0;
pCol->zType = 0;
pCol->pDflt = 0;
pCol->zDflt = 0;
}
pNew->pSchema = db->aDb[iDb].pSchema;
pNew->addColOffset = pTab->addColOffset;
pNew->nRef = 1;
/* Begin a transaction and increment the schema cookie. */
sqlite4BeginWriteOperation(pParse, 0, iDb);
v = sqlite4GetVdbe(pParse);
if( !v ) goto exit_begin_add_column;
sqlite4ChangeCookie(pParse, iDb);
exit_begin_add_column:
sqlite4SrcListDelete(db, pSrc);
return;
}
#endif /* SQLITE_ALTER_TABLE */
/************** End of alter.c ***********************************************/
/************** Begin file analyze.c *****************************************/
/*
** 2005 July 8
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code associated with the ANALYZE command.
**
** The ANALYZE command gather statistics about the content of tables
** and indices. These statistics are made available to the query planner
** to help it make better decisions about how to perform queries.
**
** The following system tables are or have been supported:
**
** CREATE TABLE sqlite_stat1(tbl, idx, stat);
** CREATE TABLE sqlite_stat2(tbl, idx, sampleno, sample);
** CREATE TABLE sqlite_stat3(tbl, idx, nEq, nLt, nDLt, sample);
**
** Additional tables might be added in future releases of SQLite.
** The sqlite_stat2 table is not created or used unless the SQLite version
** is between 3.6.18 and 3.7.8, inclusive, and unless SQLite is compiled
** with SQLITE_ENABLE_STAT2. The sqlite_stat2 table is deprecated.
** The sqlite_stat2 table is superceded by sqlite_stat3, which is only
** created and used by SQLite versions 3.7.9 and later and with
** SQLITE_ENABLE_STAT3 defined. The fucntionality of sqlite_stat3
** is a superset of sqlite_stat2.
**
** Format of sqlite_stat1:
**
** There is normally one row per index, with the index identified by the
** name in the idx column. The tbl column is the name of the table to
** which the index belongs. In each such row, the stat column will be
** a string consisting of a list of integers. The first integer in this
** list is the number of rows in the index and in the table. The second
** integer is the average number of rows in the index that have the same
** value in the first column of the index. The third integer is the average
** number of rows in the index that have the same value for the first two
** columns. The N-th integer (for N>1) is the average number of rows in
** the index which have the same value for the first N-1 columns. For
** a K-column index, there will be K+1 integers in the stat column. If
** the index is unique, then the last integer will be 1.
**
** The list of integers in the stat column can optionally be followed
** by the keyword "unordered". The "unordered" keyword, if it is present,
** must be separated from the last integer by a single space. If the
** "unordered" keyword is present, then the query planner assumes that
** the index is unordered and will not use the index for a range query.
**
** If the sqlite_stat1.idx column is NULL, then the sqlite_stat1.stat
** column contains a single integer which is the (estimated) number of
** rows in the table identified by sqlite_stat1.tbl.
**
** Format of sqlite_stat2:
**
** The sqlite_stat2 is only created and is only used if SQLite is compiled
** with SQLITE_ENABLE_STAT2 and if the SQLite version number is between
** 3.6.18 and 3.7.8. The "stat2" table contains additional information
** about the distribution of keys within an index. The index is identified by
** the "idx" column and the "tbl" column is the name of the table to which
** the index belongs. There are usually 10 rows in the sqlite_stat2
** table for each index.
**
** The sqlite_stat2 entries for an index that have sampleno between 0 and 9
** inclusive are samples of the left-most key value in the index taken at
** evenly spaced points along the index. Let the number of samples be S
** (10 in the standard build) and let C be the number of rows in the index.
** Then the sampled rows are given by:
**
** rownumber = (i*C*2 + C)/(S*2)
**
** For i between 0 and S-1. Conceptually, the index space is divided into
** S uniform buckets and the samples are the middle row from each bucket.
**
** The format for sqlite_stat2 is recorded here for legacy reference. This
** version of SQLite does not support sqlite_stat2. It neither reads nor
** writes the sqlite_stat2 table. This version of SQLite only supports
** sqlite_stat3.
**
** Format for sqlite_stat3:
**
** The sqlite_stat3 is an enhancement to sqlite_stat2. A new name is
** used to avoid compatibility problems.
**
** The format of the sqlite_stat3 table is similar to the format of
** the sqlite_stat2 table. There are multiple entries for each index.
** The idx column names the index and the tbl column is the table of the
** index. If the idx and tbl columns are the same, then the sample is
** of the INTEGER PRIMARY KEY. The sample column is a value taken from
** the left-most column of the index. The nEq column is the approximate
** number of entires in the index whose left-most column exactly matches
** the sample. nLt is the approximate number of entires whose left-most
** column is less than the sample. The nDLt column is the approximate
** number of distinct left-most entries in the index that are less than
** the sample.
**
** Future versions of SQLite might change to store a string containing
** multiple integers values in the nDLt column of sqlite_stat3. The first
** integer will be the number of prior index entires that are distinct in
** the left-most column. The second integer will be the number of prior index
** entries that are distinct in the first two columns. The third integer
** will be the number of prior index entries that are distinct in the first
** three columns. And so forth. With that extension, the nDLt field is
** similar in function to the sqlite_stat1.stat field.
**
** There can be an arbitrary number of sqlite_stat3 entries per index.
** The ANALYZE command will typically generate sqlite_stat3 tables
** that contain between 10 and 40 samples which are distributed across
** the key space, though not uniformly, and which include samples with
** largest possible nEq values.
*/
#ifndef SQLITE_OMIT_ANALYZE
/*
** This routine generates code that opens the sqlite_stat1 table for
** writing with cursor iStatCur. If the library was built with the
** SQLITE_ENABLE_STAT3 macro defined, then the sqlite_stat3 table is
** opened for writing using cursor (iStatCur+1)
**
** If the sqlite_stat1 tables does not previously exist, it is created.
** Similarly, if the sqlite_stat3 table does not exist and the library
** is compiled with SQLITE_ENABLE_STAT3 defined, it is created.
**
** Argument zWhere may be a pointer to a buffer containing a table name,
** or it may be a NULL pointer. If it is not NULL, then all entries in
** the sqlite_stat1 and (if applicable) sqlite_stat3 tables associated
** with the named table are deleted. If zWhere==0, then code is generated
** to delete all stat table entries.
*/
static void openStatTable(
Parse *pParse, /* Parsing context */
int iDb, /* The database we are looking in */
int iStatCur, /* Open the sqlite_stat1 table on this cursor */
const char *zWhere, /* Delete entries for this table or index */
const char *zWhereType /* Either "tbl" or "idx" */
){
static const struct {
const char *zName;
const char *zCols;
} aTable[] = {
{ "sqlite_stat1", "tbl,idx,stat" },
#ifdef SQLITE_ENABLE_STAT3
{ "sqlite_stat3", "tbl,idx,neq,nlt,ndlt,sample" },
#endif
};
int aRoot[] = {0, 0};
u8 aCreateTbl[] = {0, 0};
int i;
sqlite4 *db = pParse->db;
Db *pDb;
Vdbe *v = sqlite4GetVdbe(pParse);
if( v==0 ) return;
assert( sqlite4VdbeDb(v)==db );
pDb = &db->aDb[iDb];
/* Create new statistic tables if they do not exist, or clear them
** if they do already exist.
*/
for(i=0; i<ArraySize(aTable); i++){
const char *zTab = aTable[i].zName;
Table *pStat;
if( (pStat = sqlite4FindTable(db, zTab, pDb->zName))==0 ){
/* The sqlite_stat[12] 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. */
sqlite4NestedParse(pParse,
"CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols
);
aRoot[i] = pParse->regRoot;
aCreateTbl[i] = 1;
}else{
/* The table already exists. If zWhere is not NULL, delete all entries
** associated with the table zWhere. If zWhere is NULL, delete the
** entire contents of the table. */
aRoot[i] = pStat->tnum;
if( zWhere ){
sqlite4NestedParse(pParse,
"DELETE FROM %Q.%s WHERE %s=%Q", pDb->zName, zTab, zWhereType, zWhere
);
}else{
/* The sqlite_stat[12] table already exists. Delete all rows. */
sqlite4VdbeAddOp2(v, OP_Clear, aRoot[i], iDb);
}
}
}
/* Open the sqlite_stat[13] tables for writing. */
for(i=0; i<ArraySize(aTable); i++){
sqlite4VdbeAddOp3(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb);
sqlite4VdbeChangeP4(v, -1, (char *)3, P4_INT32);
sqlite4VdbeChangeP5(v, aCreateTbl[i]);
}
}
/*
** Recommended number of samples for sqlite_stat3
*/
#ifndef SQLITE_STAT3_SAMPLES
# define SQLITE_STAT3_SAMPLES 24
#endif
/*
** Three SQL functions - stat3_init(), stat3_push(), and stat3_pop() -
** share an instance of the following structure to hold their state
** information.
*/
typedef struct Stat3Accum Stat3Accum;
struct Stat3Accum {
tRowcnt nRow; /* Number of rows in the entire table */
tRowcnt nPSample; /* How often to do a periodic sample */
int iMin; /* Index of entry with minimum nEq and hash */
int mxSample; /* Maximum number of samples to accumulate */
int nSample; /* Current number of samples */
u32 iPrn; /* Pseudo-random number used for sampling */
struct Stat3Sample {
i64 iRowid; /* Rowid in main table of the key */
tRowcnt nEq; /* sqlite_stat3.nEq */
tRowcnt nLt; /* sqlite_stat3.nLt */
tRowcnt nDLt; /* sqlite_stat3.nDLt */
u8 isPSample; /* True if a periodic sample */
u32 iHash; /* Tiebreaker hash */
} *a; /* An array of samples */
};
#ifdef SQLITE_ENABLE_STAT3
/*
** Implementation of the stat3_init(C,S) SQL function. The two parameters
** are the number of rows in the table or index (C) and the number of samples
** to accumulate (S).
**
** This routine allocates the Stat3Accum object.
**
** The return value is the Stat3Accum object (P).
*/
static void stat3Init(
sqlite4_context *context,
int argc,
sqlite4_value **argv
){
Stat3Accum *p;
tRowcnt nRow;
int mxSample;
int n;
sqlite4_env *pEnv = sqlite4_context_env(context);
UNUSED_PARAMETER(argc);
nRow = (tRowcnt)sqlite4_value_int64(argv[0]);
mxSample = sqlite4_value_int(argv[1]);
n = sizeof(*p) + sizeof(p->a[0])*mxSample;
p = sqlite4_malloc(pEnv, n);
if( p==0 ){
sqlite4_result_error_nomem(context);
return;
}
memset(p, 0, n);
p->a = (struct Stat3Sample*)&p[1];
p->nRow = nRow;
p->mxSample = mxSample;
p->nPSample = p->nRow/(mxSample/3+1) + 1;
sqlite4_randomness(pEnv, sizeof(p->iPrn), &p->iPrn);
sqlite4_result_blob(context, p, sizeof(p), SQLITE_DYNAMIC);
}
static const FuncDef stat3InitFuncdef = {
2, /* nArg */
SQLITE_UTF8, /* iPrefEnc */
0, /* flags */
0, /* pUserData */
0, /* pNext */
stat3Init, /* xFunc */
0, /* xStep */
0, /* xFinalize */
"stat3_init", /* zName */
0, /* pHash */
0 /* pDestructor */
};
/*
** Implementation of the stat3_push(nEq,nLt,nDLt,rowid,P) SQL function. The
** arguments describe a single key instance. This routine makes the
** decision about whether or not to retain this key for the sqlite_stat3
** table.
**
** The return value is NULL.
*/
static void stat3Push(
sqlite4_context *context,
int argc,
sqlite4_value **argv
){
Stat3Accum *p = (Stat3Accum*)sqlite4_value_blob(argv[4]);
tRowcnt nEq = sqlite4_value_int64(argv[0]);
tRowcnt nLt = sqlite4_value_int64(argv[1]);
tRowcnt nDLt = sqlite4_value_int64(argv[2]);
i64 rowid = sqlite4_value_int64(argv[3]);
u8 isPSample = 0;
u8 doInsert = 0;
int iMin = p->iMin;
struct Stat3Sample *pSample;
int i;
u32 h;
UNUSED_PARAMETER(context);
UNUSED_PARAMETER(argc);
if( nEq==0 ) return;
h = p->iPrn = p->iPrn*1103515245 + 12345;
if( (nLt/p->nPSample)!=((nEq+nLt)/p->nPSample) ){
doInsert = isPSample = 1;
}else if( p->nSample<p->mxSample ){
doInsert = 1;
}else{
if( nEq>p->a[iMin].nEq || (nEq==p->a[iMin].nEq && h>p->a[iMin].iHash) ){
doInsert = 1;
}
}
if( !doInsert ) return;
if( p->nSample==p->mxSample ){
assert( p->nSample - iMin - 1 >= 0 );
memmove(&p->a[iMin], &p->a[iMin+1], sizeof(p->a[0])*(p->nSample-iMin-1));
pSample = &p->a[p->nSample-1];
}else{
pSample = &p->a[p->nSample++];
}
pSample->iRowid = rowid;
pSample->nEq = nEq;
pSample->nLt = nLt;
pSample->nDLt = nDLt;
pSample->iHash = h;
pSample->isPSample = isPSample;
/* Find the new minimum */
if( p->nSample==p->mxSample ){
pSample = p->a;
i = 0;
while( pSample->isPSample ){
i++;
pSample++;
assert( i<p->nSample );
}
nEq = pSample->nEq;
h = pSample->iHash;
iMin = i;
for(i++, pSample++; i<p->nSample; i++, pSample++){
if( pSample->isPSample ) continue;
if( pSample->nEq<nEq
|| (pSample->nEq==nEq && pSample->iHash<h)
){
iMin = i;
nEq = pSample->nEq;
h = pSample->iHash;
}
}
p->iMin = iMin;
}
}
static const FuncDef stat3PushFuncdef = {
5, /* nArg */
SQLITE_UTF8, /* iPrefEnc */
0, /* flags */
0, /* pUserData */
0, /* pNext */
stat3Push, /* xFunc */
0, /* xStep */
0, /* xFinalize */
"stat3_push", /* zName */
0, /* pHash */
0 /* pDestructor */
};
/*
** Implementation of the stat3_get(P,N,...) SQL function. This routine is
** used to query the results. Content is returned for the Nth sqlite_stat3
** row where N is between 0 and S-1 and S is the number of samples. The
** value returned depends on the number of arguments.
**
** argc==2 result: rowid
** argc==3 result: nEq
** argc==4 result: nLt
** argc==5 result: nDLt
*/
static void stat3Get(
sqlite4_context *context,
int argc,
sqlite4_value **argv
){
int n = sqlite4_value_int(argv[1]);
Stat3Accum *p = (Stat3Accum*)sqlite4_value_blob(argv[0]);
assert( p!=0 );
if( p->nSample<=n ) return;
switch( argc ){
case 2: sqlite4_result_int64(context, p->a[n].iRowid); break;
case 3: sqlite4_result_int64(context, p->a[n].nEq); break;
case 4: sqlite4_result_int64(context, p->a[n].nLt); break;
default: sqlite4_result_int64(context, p->a[n].nDLt); break;
}
}
static const FuncDef stat3GetFuncdef = {
-1, /* nArg */
SQLITE_UTF8, /* iPrefEnc */
0, /* flags */
0, /* pUserData */
0, /* pNext */
stat3Get, /* xFunc */
0, /* xStep */
0, /* xFinalize */
"stat3_get", /* zName */
0, /* pHash */
0 /* pDestructor */
};
#endif /* SQLITE_ENABLE_STAT3 */
/*
** Generate code to do an analysis of all indices associated with
** a single table.
*/
static void analyzeOneTable(
Parse *pParse, /* Parser context */
Table *pTab, /* Table whose indices are to be analyzed */
Index *pOnlyIdx, /* If not NULL, only analyze this one index */
int iStatCur, /* Index of VdbeCursor that writes the sqlite_stat1 table */
int iMem /* Available memory locations begin here */
){
sqlite4 *db = pParse->db; /* Database handle */
Index *pIdx; /* An index to being analyzed */
int iIdxCur; /* Cursor open on index being analyzed */
Vdbe *v; /* The virtual machine being built up */
int i; /* Loop counter */
int topOfLoop; /* The top of the loop */
int endOfLoop; /* The end of the loop */
int jZeroRows = -1; /* Jump from here if number of rows is zero */
int iDb; /* Index of database containing pTab */
int regTabname = iMem++; /* Register containing table name */
int regIdxname = iMem++; /* Register containing index name */
int regStat1 = iMem++; /* The stat column of sqlite_stat1 */
#ifdef SQLITE_ENABLE_STAT3
int regNumEq = regStat1; /* Number of instances. Same as regStat1 */
int regNumLt = iMem++; /* Number of keys less than regSample */
int regNumDLt = iMem++; /* Number of distinct keys less than regSample */
int regSample = iMem++; /* The next sample value */
int regRowid = regSample; /* Rowid of a sample */
int regAccum = iMem++; /* Register to hold Stat3Accum object */
int regLoop = iMem++; /* Loop counter */
int regCount = iMem++; /* Number of rows in the table or index */
int regTemp1 = iMem++; /* Intermediate register */
int regTemp2 = iMem++; /* Intermediate register */
int once = 1; /* One-time initialization */
int shortJump = 0; /* Instruction address */
int iTabCur = pParse->nTab++; /* Table cursor */
#endif
int regCol = iMem++; /* Content of a column in analyzed table */
int regRec = iMem++; /* Register holding completed record */
int regTemp = iMem++; /* Temporary use register */
int regNewRowid = iMem++; /* Rowid for the inserted record */
v = sqlite4GetVdbe(pParse);
if( v==0 || NEVER(pTab==0) ){
return;
}
if( pTab->tnum==0 ){
/* Do not gather statistics on views or virtual tables */
return;
}
if( memcmp(pTab->zName, "sqlite_", 7)==0 ){
/* Do not gather statistics on system tables */
return;
}
iDb = sqlite4SchemaToIndex(db, pTab->pSchema);
assert( iDb>=0 );
#ifndef SQLITE_OMIT_AUTHORIZATION
if( sqlite4AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0,
db->aDb[iDb].zName ) ){
return;
}
#endif
iIdxCur = pParse->nTab++;
sqlite4VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0);
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
int nCol;
KeyInfo *pKey;
int addrIfNot = 0; /* address of OP_IfNot */
int *aChngAddr; /* Array of jump instruction addresses */
if( pOnlyIdx && pOnlyIdx!=pIdx ) continue;
VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName));
nCol = pIdx->nColumn;
aChngAddr = sqlite4DbMallocRaw(db, sizeof(int)*nCol);
if( aChngAddr==0 ) continue;
pKey = sqlite4IndexKeyinfo(pParse, pIdx);
if( iMem+1+(nCol*2)>pParse->nMem ){
pParse->nMem = iMem+1+(nCol*2);
}
/* Open a cursor to the index to be analyzed. */
assert( iDb==sqlite4SchemaToIndex(db, pIdx->pSchema) );
sqlite4VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb,
(char *)pKey, P4_KEYINFO_HANDOFF);
VdbeComment((v, "%s", pIdx->zName));
/* Populate the register containing the index name. */
sqlite4VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0);
#ifdef SQLITE_ENABLE_STAT3
if( once ){
once = 0;
sqlite4OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
}
sqlite4VdbeAddOp2(v, OP_Count, iIdxCur, regCount);
sqlite4VdbeAddOp2(v, OP_Integer, SQLITE_STAT3_SAMPLES, regTemp1);
sqlite4VdbeAddOp2(v, OP_Integer, 0, regNumEq);
sqlite4VdbeAddOp2(v, OP_Integer, 0, regNumLt);
sqlite4VdbeAddOp2(v, OP_Integer, -1, regNumDLt);
sqlite4VdbeAddOp3(v, OP_Null, 0, regSample, regAccum);
sqlite4VdbeAddOp4(v, OP_Function, 1, regCount, regAccum,
(char*)&stat3InitFuncdef, P4_FUNCDEF);
sqlite4VdbeChangeP5(v, 2);
#endif /* SQLITE_ENABLE_STAT3 */
/* The block of memory cells initialized here is used as follows.
**
** iMem:
** The total number of rows in the table.
**
** iMem+1 .. iMem+nCol:
** Number of distinct entries in index considering the
** left-most N columns only, where N is between 1 and nCol,
** inclusive.
**
** iMem+nCol+1 .. Mem+2*nCol:
** Previous value of indexed columns, from left to right.
**
** Cells iMem through iMem+nCol are initialized to 0. The others are
** initialized to contain an SQL NULL.
*/
for(i=0; i<=nCol; i++){
sqlite4VdbeAddOp2(v, OP_Integer, 0, iMem+i);
}
for(i=0; i<nCol; i++){
sqlite4VdbeAddOp2(v, OP_Null, 0, iMem+nCol+i+1);
}
/* Start the analysis loop. This loop runs through all the entries in
** the index b-tree. */
endOfLoop = sqlite4VdbeMakeLabel(v);
sqlite4VdbeAddOp2(v, OP_Rewind, iIdxCur, endOfLoop);
topOfLoop = sqlite4VdbeCurrentAddr(v);
sqlite4VdbeAddOp2(v, OP_AddImm, iMem, 1); /* Increment row counter */
for(i=0; i<nCol; i++){
CollSeq *pColl;
sqlite4VdbeAddOp3(v, OP_Column, iIdxCur, i, regCol);
if( i==0 ){
/* Always record the very first row */
addrIfNot = sqlite4VdbeAddOp1(v, OP_IfNot, iMem+1);
}
assert( pIdx->azColl!=0 );
assert( pIdx->azColl[i]!=0 );
pColl = sqlite4LocateCollSeq(pParse, pIdx->azColl[i]);
aChngAddr[i] = sqlite4VdbeAddOp4(v, OP_Ne, regCol, 0, iMem+nCol+i+1,
(char*)pColl, P4_COLLSEQ);
sqlite4VdbeChangeP5(v, SQLITE_NULLEQ);
VdbeComment((v, "jump if column %d changed", i));
#ifdef SQLITE_ENABLE_STAT3
if( i==0 ){
sqlite4VdbeAddOp2(v, OP_AddImm, regNumEq, 1);
VdbeComment((v, "incr repeat count"));
}
#endif
}
sqlite4VdbeAddOp2(v, OP_Goto, 0, endOfLoop);
for(i=0; i<nCol; i++){
sqlite4VdbeJumpHere(v, aChngAddr[i]); /* Set jump dest for the OP_Ne */
if( i==0 ){
sqlite4VdbeJumpHere(v, addrIfNot); /* Jump dest for OP_IfNot */
#ifdef SQLITE_ENABLE_STAT3
sqlite4VdbeAddOp4(v, OP_Function, 1, regNumEq, regTemp2,
(char*)&stat3PushFuncdef, P4_FUNCDEF);
sqlite4VdbeChangeP5(v, 5);
sqlite4VdbeAddOp3(v, OP_Column, iIdxCur, pIdx->nColumn, regRowid);
sqlite4VdbeAddOp3(v, OP_Add, regNumEq, regNumLt, regNumLt);
sqlite4VdbeAddOp2(v, OP_AddImm, regNumDLt, 1);
sqlite4VdbeAddOp2(v, OP_Integer, 1, regNumEq);
#endif
}
sqlite4VdbeAddOp2(v, OP_AddImm, iMem+i+1, 1);
sqlite4VdbeAddOp3(v, OP_Column, iIdxCur, i, iMem+nCol+i+1);
}
sqlite4DbFree(db, aChngAddr);
/* Always jump here after updating the iMem+1...iMem+1+nCol counters */
sqlite4VdbeResolveLabel(v, endOfLoop);
sqlite4VdbeAddOp2(v, OP_Next, iIdxCur, topOfLoop);
sqlite4VdbeAddOp1(v, OP_Close, iIdxCur);
#ifdef SQLITE_ENABLE_STAT3
sqlite4VdbeAddOp4(v, OP_Function, 1, regNumEq, regTemp2,
(char*)&stat3PushFuncdef, P4_FUNCDEF);
sqlite4VdbeChangeP5(v, 5);
sqlite4VdbeAddOp2(v, OP_Integer, -1, regLoop);
shortJump =
sqlite4VdbeAddOp2(v, OP_AddImm, regLoop, 1);
sqlite4VdbeAddOp4(v, OP_Function, 1, regAccum, regTemp1,
(char*)&stat3GetFuncdef, P4_FUNCDEF);
sqlite4VdbeChangeP5(v, 2);
sqlite4VdbeAddOp1(v, OP_IsNull, regTemp1);
sqlite4VdbeAddOp3(v, OP_NotExists, iTabCur, shortJump, regTemp1);
sqlite4VdbeAddOp3(v, OP_Column, iTabCur, pIdx->aiColumn[0], regSample);
sqlite4ColumnDefault(v, pTab, pIdx->aiColumn[0], regSample);
sqlite4VdbeAddOp4(v, OP_Function, 1, regAccum, regNumEq,
(char*)&stat3GetFuncdef, P4_FUNCDEF);
sqlite4VdbeChangeP5(v, 3);
sqlite4VdbeAddOp4(v, OP_Function, 1, regAccum, regNumLt,
(char*)&stat3GetFuncdef, P4_FUNCDEF);
sqlite4VdbeChangeP5(v, 4);
sqlite4VdbeAddOp4(v, OP_Function, 1, regAccum, regNumDLt,
(char*)&stat3GetFuncdef, P4_FUNCDEF);
sqlite4VdbeChangeP5(v, 5);
sqlite4VdbeAddOp4(v, OP_MakeRecord, regTabname, 6, regRec, "bbbbbb", 0);
sqlite4VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
sqlite4VdbeAddOp3(v, OP_Insert, iStatCur+1, regRec, regNewRowid);
sqlite4VdbeAddOp2(v, OP_Goto, 0, shortJump);
sqlite4VdbeJumpHere(v, shortJump+2);
#endif
/* Store the results in sqlite_stat1.
**
** The result is a single row of the sqlite_stat1 table. The first
** two columns are the names of the table and index. The third column
** is a string composed of a list of integer statistics about the
** index. The first integer in the list is the total number of entries
** in the index. There is one additional integer in the list for each
** column of the table. This additional integer is a guess of how many
** rows of the table the index will select. If D is the count of distinct
** values and K is the total number of rows, then the integer is computed
** as:
**
** I = (K+D-1)/D
**
** If K==0 then no entry is made into the sqlite_stat1 table.
** If K>0 then it is always the case the D>0 so division by zero
** is never possible.
*/
sqlite4VdbeAddOp2(v, OP_SCopy, iMem, regStat1);
if( jZeroRows<0 ){
jZeroRows = sqlite4VdbeAddOp1(v, OP_IfNot, iMem);
}
for(i=0; i<nCol; i++){
sqlite4VdbeAddOp4(v, OP_String8, 0, regTemp, 0, " ", 0);
sqlite4VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1);
sqlite4VdbeAddOp3(v, OP_Add, iMem, iMem+i+1, regTemp);
sqlite4VdbeAddOp2(v, OP_AddImm, regTemp, -1);
sqlite4VdbeAddOp3(v, OP_Divide, iMem+i+1, regTemp, regTemp);
sqlite4VdbeAddOp1(v, OP_ToInt, regTemp);
sqlite4VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1);
}
sqlite4VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
sqlite4VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
sqlite4VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
sqlite4VdbeChangeP5(v, OPFLAG_APPEND);
}
/* If the table has no indices, create a single sqlite_stat1 entry
** containing NULL as the index name and the row count as the content.
*/
if( pTab->pIndex==0 ){
sqlite4VdbeAddOp3(v, OP_OpenRead, iIdxCur, pTab->tnum, iDb);
VdbeComment((v, "%s", pTab->zName));
sqlite4VdbeAddOp2(v, OP_Count, iIdxCur, regStat1);
sqlite4VdbeAddOp1(v, OP_Close, iIdxCur);
jZeroRows = sqlite4VdbeAddOp1(v, OP_IfNot, regStat1);
}else{
sqlite4VdbeJumpHere(v, jZeroRows);
jZeroRows = sqlite4VdbeAddOp0(v, OP_Goto);
}
sqlite4VdbeAddOp2(v, OP_Null, 0, regIdxname);
sqlite4VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
sqlite4VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
sqlite4VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
sqlite4VdbeChangeP5(v, OPFLAG_APPEND);
if( pParse->nMem<regRec ) pParse->nMem = regRec;
sqlite4VdbeJumpHere(v, jZeroRows);
}
/*
** Generate code that will cause the most recent index analysis to
** be loaded into internal hash tables where is can be used.
*/
static void loadAnalysis(Parse *pParse, int iDb){
Vdbe *v = sqlite4GetVdbe(pParse);
if( v ){
sqlite4VdbeAddOp1(v, OP_LoadAnalysis, iDb);
}
}
/*
** Generate code that will do an analysis of an entire database
*/
static void analyzeDatabase(Parse *pParse, int iDb){
sqlite4 *db = pParse->db;
Schema *pSchema = db->aDb[iDb].pSchema; /* Schema of database iDb */
HashElem *k;
int iStatCur;
int iMem;
sqlite4BeginWriteOperation(pParse, 0, iDb);
iStatCur = pParse->nTab;
pParse->nTab += 3;
openStatTable(pParse, iDb, iStatCur, 0, 0);
iMem = pParse->nMem+1;
for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
Table *pTab = (Table*)sqliteHashData(k);
analyzeOneTable(pParse, pTab, 0, iStatCur, iMem);
}
loadAnalysis(pParse, iDb);
}
/*
** Generate code that will do an analysis of a single table in
** a database. If pOnlyIdx is not NULL then it is a single index
** in pTab that should be analyzed.
*/
static void analyzeTable(Parse *pParse, Table *pTab, Index *pOnlyIdx){
int iDb;
int iStatCur;
assert( pTab!=0 );
iDb = sqlite4SchemaToIndex(pParse->db, pTab->pSchema);
sqlite4BeginWriteOperation(pParse, 0, iDb);
iStatCur = pParse->nTab;
pParse->nTab += 3;
if( pOnlyIdx ){
openStatTable(pParse, iDb, iStatCur, pOnlyIdx->zName, "idx");
}else{
openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl");
}
analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur, pParse->nMem+1);
loadAnalysis(pParse, iDb);
}
/*
** Generate code for the ANALYZE command. The parser calls this routine
** when it recognizes an ANALYZE command.
**
** ANALYZE -- 1
** ANALYZE <database> -- 2
** ANALYZE ?<database>.?<tablename> -- 3
**
** Form 1 causes all indices in all attached databases to be analyzed.
** Form 2 analyzes all indices the single database named.
** Form 3 analyzes all indices associated with the named table.
*/
SQLITE_PRIVATE void sqlite4Analyze(Parse *pParse, Token *pName1, Token *pName2){
sqlite4 *db = pParse->db;
int iDb;
int i;
char *z, *zDb;
Table *pTab;
Index *pIdx;
Token *pTableName;
/* Read the database schema. If an error occurs, leave an error message
** and code in pParse and return NULL. */
if( SQLITE_OK!=sqlite4ReadSchema(pParse) ){
return;
}
assert( pName2!=0 || pName1==0 );
if( pName1==0 ){
/* Form 1: Analyze everything */
for(i=0; i<db->nDb; i++){
if( i==1 ) continue; /* Do not analyze the TEMP database */
analyzeDatabase(pParse, i);
}
}else if( pName2->n==0 ){
/* Form 2: Analyze the database or table named */
iDb = sqlite4FindDb(db, pName1);
if( iDb>=0 ){
analyzeDatabase(pParse, iDb);
}else{
z = sqlite4NameFromToken(db, pName1);
if( z ){
if( (pIdx = sqlite4FindIndex(db, z, 0))!=0 ){
analyzeTable(pParse, pIdx->pTable, pIdx);
}else if( (pTab = sqlite4LocateTable(pParse, 0, z, 0))!=0 ){
analyzeTable(pParse, pTab, 0);
}
sqlite4DbFree(db, z);
}
}
}else{
/* Form 3: Analyze the fully qualified table name */
iDb = sqlite4TwoPartName(pParse, pName1, pName2, &pTableName);
if( iDb>=0 ){
zDb = db->aDb[iDb].zName;
z = sqlite4NameFromToken(db, pTableName);
if( z ){
if( (pIdx = sqlite4FindIndex(db, z, zDb))!=0 ){
analyzeTable(pParse, pIdx->pTable, pIdx);
}else if( (pTab = sqlite4LocateTable(pParse, 0, z, zDb))!=0 ){
analyzeTable(pParse, pTab, 0);
}
sqlite4DbFree(db, z);
}
}
}
}
/*
** Used to pass information from the analyzer reader through to the
** callback routine.
*/
typedef struct analysisInfo analysisInfo;
struct analysisInfo {
sqlite4 *db;
const char *zDatabase;
};
/*
** This callback is invoked once for each index when reading the
** sqlite_stat1 table.
**
** argv[0] = name of the table
** argv[1] = name of the index (might be NULL)
** argv[2] = results of analysis - on integer for each column
**
** Entries for which argv[1]==NULL simply record the number of rows in
** the table.
*/
static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
analysisInfo *pInfo = (analysisInfo*)pData;
Index *pIndex;
Table *pTable;
int i, c, n;
tRowcnt v;
const char *z;
assert( argc==3 );
UNUSED_PARAMETER2(NotUsed, argc);
if( argv==0 || argv[0]==0 || argv[2]==0 ){
return 0;
}
pTable = sqlite4FindTable(pInfo->db, argv[0], pInfo->zDatabase);
if( pTable==0 ){
return 0;
}
if( argv[1] ){
pIndex = sqlite4FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
}else{
pIndex = 0;
}
n = pIndex ? pIndex->nColumn : 0;
z = argv[2];
for(i=0; *z && i<=n; i++){
v = 0;
while( (c=z[0])>='0' && c<='9' ){
v = v*10 + c - '0';
z++;
}
if( i==0 ) pTable->nRowEst = v;
if( pIndex==0 ) break;
pIndex->aiRowEst[i] = v;
if( *z==' ' ) z++;
if( memcmp(z, "unordered", 10)==0 ){
pIndex->bUnordered = 1;
break;
}
}
return 0;
}
/*
** If the Index.aSample variable is not NULL, delete the aSample[] array
** and its contents.
*/
SQLITE_PRIVATE void sqlite4DeleteIndexSamples(sqlite4 *db, Index *pIdx){
#ifdef SQLITE_ENABLE_STAT3
if( pIdx->aSample ){
int j;
for(j=0; j<pIdx->nSample; j++){
IndexSample *p = &pIdx->aSample[j];
if( p->eType==SQLITE_TEXT || p->eType==SQLITE_BLOB ){
sqlite4DbFree(db, p->u.z);
}
}
sqlite4DbFree(db, pIdx->aSample);
}
if( db && db->pnBytesFreed==0 ){
pIdx->nSample = 0;
pIdx->aSample = 0;
}
#else
UNUSED_PARAMETER(db);
UNUSED_PARAMETER(pIdx);
#endif
}
#ifdef SQLITE_ENABLE_STAT3
/*
** Load content from the sqlite_stat3 table into the Index.aSample[]
** arrays of all indices.
*/
static int loadStat3(sqlite4 *db, const char *zDb){
int rc; /* Result codes from subroutines */
sqlite4_stmt *pStmt = 0; /* An SQL statement being run */
char *zSql; /* Text of the SQL statement */
Index *pPrevIdx = 0; /* Previous index in the loop */
int idx = 0; /* slot in pIdx->aSample[] for next sample */
int eType; /* Datatype of a sample */
IndexSample *pSample; /* A slot in pIdx->aSample[] */
if( !sqlite4FindTable(db, "sqlite_stat3", zDb) ){
return SQLITE_OK;
}
zSql = sqlite4MPrintf(db,
"SELECT idx,count(*) FROM %Q.sqlite_stat3"
" GROUP BY idx", zDb);
if( !zSql ){
return SQLITE_NOMEM;
}
rc = sqlite4_prepare(db, zSql, -1, &pStmt, 0);
sqlite4DbFree(db, zSql);
if( rc ) return rc;
while( sqlite4_step(pStmt)==SQLITE_ROW ){
char *zIndex; /* Index name */
Index *pIdx; /* Pointer to the index object */
int nSample; /* Number of samples */
zIndex = (char *)sqlite4_column_text(pStmt, 0);
if( zIndex==0 ) continue;
nSample = sqlite4_column_int(pStmt, 1);
pIdx = sqlite4FindIndex(db, zIndex, zDb);
if( pIdx==0 ) continue;
assert( pIdx->nSample==0 );
pIdx->nSample = nSample;
pIdx->aSample = sqlite4MallocZero(db->pEnv, nSample*sizeof(IndexSample) );
pIdx->avgEq = pIdx->aiRowEst[1];
if( pIdx->aSample==0 ){
db->mallocFailed = 1;
sqlite4_finalize(pStmt);
return SQLITE_NOMEM;
}
}
rc = sqlite4_finalize(pStmt);
if( rc ) return rc;
zSql = sqlite4MPrintf(db,
"SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat3", zDb);
if( !zSql ){
return SQLITE_NOMEM;
}
rc = sqlite4_prepare(db, zSql, -1, &pStmt, 0);
sqlite4DbFree(db, zSql);
if( rc ) return rc;
while( sqlite4_step(pStmt)==SQLITE_ROW ){
char *zIndex; /* Index name */
Index *pIdx; /* Pointer to the index object */
int i; /* Loop counter */
tRowcnt sumEq; /* Sum of the nEq values */
zIndex = (char *)sqlite4_column_text(pStmt, 0);
if( zIndex==0 ) continue;
pIdx = sqlite4FindIndex(db, zIndex, zDb);
if( pIdx==0 ) continue;
if( pIdx==pPrevIdx ){
idx++;
}else{
pPrevIdx = pIdx;
idx = 0;
}
assert( idx<pIdx->nSample );
pSample = &pIdx->aSample[idx];
pSample->nEq = (tRowcnt)sqlite4_column_int64(pStmt, 1);
pSample->nLt = (tRowcnt)sqlite4_column_int64(pStmt, 2);
pSample->nDLt = (tRowcnt)sqlite4_column_int64(pStmt, 3);
if( idx==pIdx->nSample-1 ){
if( pSample->nDLt>0 ){
for(i=0, sumEq=0; i<=idx-1; i++) sumEq += pIdx->aSample[i].nEq;
pIdx->avgEq = (pSample->nLt - sumEq)/pSample->nDLt;
}
if( pIdx->avgEq<=0 ) pIdx->avgEq = 1;
}
eType = sqlite4_column_type(pStmt, 4);
pSample->eType = (u8)eType;
switch( eType ){
case SQLITE_INTEGER: {
pSample->u.i = sqlite4_column_int64(pStmt, 4);
break;
}
case SQLITE_FLOAT: {
pSample->u.r = sqlite4_column_double(pStmt, 4);
break;
}
case SQLITE_NULL: {
break;
}
default: assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); {
const char *z = (const char *)(
(eType==SQLITE_BLOB) ?
sqlite4_column_blob(pStmt, 4):
sqlite4_column_text(pStmt, 4)
);
int n = z ? sqlite4_column_bytes(pStmt, 4) : 0;
pSample->nByte = n;
if( n < 1){
pSample->u.z = 0;
}else{
pSample->u.z = sqlite4Malloc(db->pEnv, n);
if( pSample->u.z==0 ){
db->mallocFailed = 1;
sqlite4_finalize(pStmt);
return SQLITE_NOMEM;
}
memcpy(pSample->u.z, z, n);
}
}
}
}
return sqlite4_finalize(pStmt);
}
#endif /* SQLITE_ENABLE_STAT3 */
/*
** Load the content of the sqlite_stat1 and sqlite_stat3 tables. The
** contents of sqlite_stat1 are used to populate the Index.aiRowEst[]
** arrays. The contents of sqlite_stat3 are used to populate the
** Index.aSample[] arrays.
**
** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR
** is returned. In this case, even if SQLITE_ENABLE_STAT3 was defined
** during compilation and the sqlite_stat3 table is present, no data is
** read from it.
**
** If SQLITE_ENABLE_STAT3 was defined during compilation and the
** sqlite_stat3 table is not present in the database, SQLITE_ERROR is
** returned. However, in this case, data is read from the sqlite_stat1
** table (if it is present) before returning.
**
** If an OOM error occurs, this function always sets db->mallocFailed.
** This means if the caller does not care about other errors, the return
** code may be ignored.
*/
SQLITE_PRIVATE int sqlite4AnalysisLoad(sqlite4 *db, int iDb){
analysisInfo sInfo;
HashElem *i;
char *zSql;
int rc;
assert( iDb>=0 && iDb<db->nDb );
assert( db->aDb[iDb].pKV!=0 );
/* Clear any prior statistics */
for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
Index *pIdx = sqliteHashData(i);
sqlite4DefaultRowEst(pIdx);
#ifdef SQLITE_ENABLE_STAT3
sqlite4DeleteIndexSamples(db, pIdx);
pIdx->aSample = 0;
#endif
}
/* Check to make sure the sqlite_stat1 table exists */
sInfo.db = db;
sInfo.zDatabase = db->aDb[iDb].zName;
if( sqlite4FindTable(db, "sqlite_stat1", sInfo.zDatabase)==0 ){
return SQLITE_ERROR;
}
/* Load new statistics out of the sqlite_stat1 table */
zSql = sqlite4MPrintf(db,
"SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
if( zSql==0 ){
rc = SQLITE_NOMEM;
}else{
rc = sqlite4_exec(db, zSql, analysisLoader, &sInfo, 0);
sqlite4DbFree(db, zSql);
}
/* Load the statistics from the sqlite_stat3 table. */
#ifdef SQLITE_ENABLE_STAT3
if( rc==SQLITE_OK ){
rc = loadStat3(db, sInfo.zDatabase);
}
#endif
if( rc==SQLITE_NOMEM ){
db->mallocFailed = 1;
}
return rc;
}
#endif /* SQLITE_OMIT_ANALYZE */
/************** End of analyze.c *********************************************/
/************** Begin file attach.c ******************************************/
/*
** 2003 April 6
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
*/
#ifndef SQLITE_OMIT_ATTACH
/*
** Resolve an expression that was part of an ATTACH or DETACH statement. This
** is slightly different from resolving a normal SQL expression, because simple
** identifiers are treated as strings, not possible column names or aliases.
**
** i.e. if the parser sees:
**
** ATTACH DATABASE abc AS def
**
** it treats the two expressions as literal strings 'abc' and 'def' instead of
** looking for columns of the same name.
**
** This only applies to the root node of pExpr, so the statement:
**
** ATTACH DATABASE abc||def AS 'db2'
**
** will fail because neither abc or def can be resolved.
*/
static int resolveAttachExpr(NameContext *pName, Expr *pExpr)
{
int rc = SQLITE_OK;
if( pExpr ){
if( pExpr->op!=TK_ID ){
rc = sqlite4ResolveExprNames(pName, pExpr);
if( rc==SQLITE_OK && !sqlite4ExprIsConstant(pExpr) ){
sqlite4ErrorMsg(pName->pParse, "invalid name: \"%s\"", pExpr->u.zToken);
return SQLITE_ERROR;
}
}else{
pExpr->op = TK_STRING;
}
}
return rc;
}
/*
** An SQL user-function registered to do the work of an ATTACH statement. The
** three arguments to the function come directly from an attach statement:
**
** ATTACH DATABASE x AS y KEY z
**
** SELECT sqlite_attach(x, y, z)
**
** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the
** third argument.
*/
static void attachFunc(
sqlite4_context *context,
int NotUsed,
sqlite4_value **argv
){
int i;
int rc = 0;
sqlite4 *db = sqlite4_context_db_handle(context);
const char *zName;
const char *zFile;
char *zPath = 0;
char *zErr = 0;
unsigned int flags;
Db *aNew;
char *zErrDyn = 0;
UNUSED_PARAMETER(NotUsed);
zFile = (const char *)sqlite4_value_text(argv[0]);
zName = (const char *)sqlite4_value_text(argv[1]);
if( zFile==0 ) zFile = "";
if( zName==0 ) zName = "";
/* Check for the following errors:
**
** * Too many attached databases,
** * Transaction currently open
** * Specified database name already being used.
*/
if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){
zErrDyn = sqlite4MPrintf(db, "too many attached databases - max %d",
db->aLimit[SQLITE_LIMIT_ATTACHED]
);
goto attach_error;
}
if( db->pSavepoint ){
zErrDyn = sqlite4MPrintf(db, "cannot ATTACH database within transaction");
goto attach_error;
}
for(i=0; i<db->nDb; i++){
char *z = db->aDb[i].zName;
assert( z && zName );
if( sqlite4StrICmp(z, zName)==0 ){
zErrDyn = sqlite4MPrintf(db, "database %s is already in use", zName);
goto attach_error;
}
}
/* Allocate the new entry in the db->aDb[] array and initialise the schema
** hash tables.
*/
if( db->aDb==db->aDbStatic ){
aNew = sqlite4DbMallocRaw(db, sizeof(db->aDb[0])*3 );
if( aNew==0 ) return;
memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
}else{
aNew = sqlite4DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
if( aNew==0 ) return;
}
db->aDb = aNew;
aNew = &db->aDb[db->nDb];
memset(aNew, 0, sizeof(*aNew));
/* Open the database file. If the btree is successfully opened, use
** it to obtain the database schema. At this point the schema may
** or may not be initialised.
*/
flags = db->openFlags;
rc = sqlite4ParseUri(db->pEnv, zFile, &flags, &zPath, &zErr);
if( rc!=SQLITE_OK ){
if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
sqlite4_result_error(context, zErr, -1);
sqlite4_free(db->pEnv, zErr);
return;
}
rc = sqlite4KVStoreOpen(db, zName, zPath, &aNew->pKV, flags);
sqlite4_free(db->pEnv, zPath);
db->nDb++;
if( rc==SQLITE_CONSTRAINT ){
rc = SQLITE_ERROR;
zErrDyn = sqlite4MPrintf(db, "database is already attached");
}else if( rc==SQLITE_OK ){
aNew->pSchema = sqlite4SchemaGet(db);
if( !aNew->pSchema ){
rc = SQLITE_NOMEM;
}else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){
zErrDyn = sqlite4MPrintf(db,
"attached databases must use the same text encoding as main database");
rc = SQLITE_ERROR;
}
}
aNew->zName = sqlite4DbStrDup(db, zName);
if( rc==SQLITE_OK && aNew->zName==0 ){
rc = SQLITE_NOMEM;
}
/* If the file was opened successfully, read the schema for the new database.
** If this fails, or if opening the file failed, then close the file and
** remove the entry from the db->aDb[] array. i.e. put everything back the way
** we found it.
*/
if( rc==SQLITE_OK ){
rc = sqlite4Init(db, &zErrDyn);
}
if( rc ){
int iDb = db->nDb - 1;
assert( iDb>=2 );
if( db->aDb[iDb].pKV ){
sqlite4KVStoreClose(db->aDb[iDb].pKV);
db->aDb[iDb].pKV = 0;
db->aDb[iDb].pSchema = 0;
}
sqlite4ResetInternalSchema(db, -1);
db->nDb = iDb;
if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
db->mallocFailed = 1;
sqlite4DbFree(db, zErrDyn);
zErrDyn = sqlite4MPrintf(db, "out of memory");
}else if( zErrDyn==0 ){
zErrDyn = sqlite4MPrintf(db, "unable to open database: %s", zFile);
}
goto attach_error;
}
return;
attach_error:
/* Return an error if we get here */
if( zErrDyn ){
sqlite4_result_error(context, zErrDyn, -1);
sqlite4DbFree(db, zErrDyn);
}
if( rc ) sqlite4_result_error_code(context, rc);
}
/*
** An SQL user-function registered to do the work of an DETACH statement. The
** three arguments to the function come directly from a detach statement:
**
** DETACH DATABASE x
**
** SELECT sqlite_detach(x)
*/
static void detachFunc(
sqlite4_context *context,
int NotUsed,
sqlite4_value **argv
){
const char *zName = (const char *)sqlite4_value_text(argv[0]);
sqlite4 *db = sqlite4_context_db_handle(context);
int i;
Db *pDb = 0;
char zErr[128];
UNUSED_PARAMETER(NotUsed);
if( zName==0 ) zName = "";
for(i=0; i<db->nDb; i++){
pDb = &db->aDb[i];
if( pDb->pKV==0 ) continue;
if( sqlite4StrICmp(pDb->zName, zName)==0 ) break;
}
if( i>=db->nDb ){
sqlite4_snprintf(zErr,sizeof(zErr), "no such database: %s", zName);
goto detach_error;
}
if( i<2 ){
sqlite4_snprintf(zErr,sizeof(zErr), "cannot detach database %s", zName);
goto detach_error;
}
if( db->pSavepoint ){
sqlite4_snprintf(zErr,sizeof(zErr),
"cannot DETACH database within transaction");
goto detach_error;
}
if( pDb->pKV->iTransLevel ){
sqlite4_snprintf(zErr,sizeof(zErr), "database %s is locked", zName);
goto detach_error;
}
sqlite4KVStoreClose(pDb->pKV);
pDb->pKV = 0;
pDb->pSchema = 0;
sqlite4ResetInternalSchema(db, -1);
return;
detach_error:
sqlite4_result_error(context, zErr, -1);
}
/*
** This procedure generates VDBE code for a single invocation of either the
** sqlite_detach() or sqlite_attach() SQL user functions.
*/
static void codeAttach(
Parse *pParse, /* The parser context */
int type, /* Either SQLITE_ATTACH or SQLITE_DETACH */
FuncDef const *pFunc,/* FuncDef wrapper for detachFunc() or attachFunc() */
Expr *pAuthArg, /* Expression to pass to authorization callback */
Expr *pFilename, /* Name of database file */
Expr *pDbname, /* Name of the database to use internally */
Expr *pKey /* Database key for encryption extension */
){
int rc;
NameContext sName;
Vdbe *v;
sqlite4* db = pParse->db;
int regArgs;
memset(&sName, 0, sizeof(NameContext));
sName.pParse = pParse;
if(
SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) ||
SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) ||
SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey))
){
pParse->nErr++;
goto attach_end;
}
#ifndef SQLITE_OMIT_AUTHORIZATION
if( pAuthArg ){
char *zAuthArg;
if( pAuthArg->op==TK_STRING ){
zAuthArg = pAuthArg->u.zToken;
}else{
zAuthArg = 0;
}
rc = sqlite4AuthCheck(pParse, type, zAuthArg, 0, 0);
if(rc!=SQLITE_OK ){
goto attach_end;
}
}
#endif /* SQLITE_OMIT_AUTHORIZATION */
v = sqlite4GetVdbe(pParse);
regArgs = sqlite4GetTempRange(pParse, 4);
sqlite4ExprCode(pParse, pFilename, regArgs);
sqlite4ExprCode(pParse, pDbname, regArgs+1);
sqlite4ExprCode(pParse, pKey, regArgs+2);
assert( v || db->mallocFailed );
if( v ){
sqlite4VdbeAddOp3(v, OP_Function, 0, regArgs+3-pFunc->nArg, regArgs+3);
assert( pFunc->nArg==-1 || (pFunc->nArg&0xff)==pFunc->nArg );
sqlite4VdbeChangeP5(v, (u8)(pFunc->nArg));
sqlite4VdbeChangeP4(v, -1, (char *)pFunc, P4_FUNCDEF);
/* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this
** statement only). For DETACH, set it to false (expire all existing
** statements).
*/
sqlite4VdbeAddOp1(v, OP_Expire, (type==SQLITE_ATTACH));
}
attach_end:
sqlite4ExprDelete(db, pFilename);
sqlite4ExprDelete(db, pDbname);
sqlite4ExprDelete(db, pKey);
}
/*
** Called by the parser to compile a DETACH statement.
**
** DETACH pDbname
*/
SQLITE_PRIVATE void sqlite4Detach(Parse *pParse, Expr *pDbname){
static const FuncDef detach_func = {
1, /* nArg */
SQLITE_UTF8, /* iPrefEnc */
0, /* flags */
0, /* pUserData */
0, /* pNext */
detachFunc, /* xFunc */
0, /* xStep */
0, /* xFinalize */
"sqlite_detach", /* zName */
0, /* pHash */
0 /* pDestructor */
};
codeAttach(pParse, SQLITE_DETACH, &detach_func, pDbname, 0, 0, pDbname);
}
/*
** Called by the parser to compile an ATTACH statement.
**
** ATTACH p AS pDbname KEY pKey
*/
SQLITE_PRIVATE void sqlite4Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){
static const FuncDef attach_func = {
3, /* nArg */
SQLITE_UTF8, /* iPrefEnc */
0, /* flags */
0, /* pUserData */
0, /* pNext */
attachFunc, /* xFunc */
0, /* xStep */
0, /* xFinalize */
"sqlite_attach", /* zName */
0, /* pHash */
0 /* pDestructor */
};
codeAttach(pParse, SQLITE_ATTACH, &attach_func, p, p, pDbname, pKey);
}
#endif /* SQLITE_OMIT_ATTACH */
/*
** Initialize a DbFixer structure. This routine must be called prior
** to passing the structure to one of the sqliteFixAAAA() routines below.
**
** The return value indicates whether or not fixation is required. TRUE
** means we do need to fix the database references, FALSE means we do not.
*/
SQLITE_PRIVATE int sqlite4FixInit(
DbFixer *pFix, /* The fixer to be initialized */
Parse *pParse, /* Error messages will be written here */
int iDb, /* This is the database that must be used */
const char *zType, /* "view", "trigger", or "index" */
const Token *pName /* Name of the view, trigger, or index */
){
sqlite4 *db;
if( NEVER(iDb<0) || iDb==1 ) return 0;
db = pParse->db;
assert( db->nDb>iDb );
pFix->pParse = pParse;
pFix->zDb = db->aDb[iDb].zName;
pFix->zType = zType;
pFix->pName = pName;
return 1;
}
/*
** The following set of routines walk through the parse tree and assign
** a specific database to all table references where the database name
** was left unspecified in the original SQL statement. The pFix structure
** must have been initialized by a prior call to sqlite4FixInit().
**
** These routines are used to make sure that an index, trigger, or
** view in one database does not refer to objects in a different database.
** (Exception: indices, triggers, and views in the TEMP database are
** allowed to refer to anything.) If a reference is explicitly made
** to an object in a different database, an error message is added to
** pParse->zErrMsg and these routines return non-zero. If everything
** checks out, these routines return 0.
*/
SQLITE_PRIVATE int sqlite4FixSrcList(
DbFixer *pFix, /* Context of the fixation */
SrcList *pList /* The Source list to check and modify */
){
int i;
const char *zDb;
struct SrcList_item *pItem;
if( NEVER(pList==0) ) return 0;
zDb = pFix->zDb;
for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
if( pItem->zDatabase==0 ){
pItem->zDatabase = sqlite4DbStrDup(pFix->pParse->db, zDb);
}else if( sqlite4StrICmp(pItem->zDatabase,zDb)!=0 ){
sqlite4ErrorMsg(pFix->pParse,
"%s %T cannot reference objects in database %s",
pFix->zType, pFix->pName, pItem->zDatabase);
return 1;
}
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
if( sqlite4FixSelect(pFix, pItem->pSelect) ) return 1;
if( sqlite4FixExpr(pFix, pItem->pOn) ) return 1;
#endif
}
return 0;
}
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
SQLITE_PRIVATE int sqlite4FixSelect(
DbFixer *pFix, /* Context of the fixation */
Select *pSelect /* The SELECT statement to be fixed to one database */
){
while( pSelect ){
if( sqlite4FixExprList(pFix, pSelect->pEList) ){
return 1;
}
if( sqlite4FixSrcList(pFix, pSelect->pSrc) ){
return 1;
}
if( sqlite4FixExpr(pFix, pSelect->pWhere) ){
return 1;
}
if( sqlite4FixExpr(pFix, pSelect->pHaving) ){
return 1;
}
pSelect = pSelect->pPrior;
}
return 0;
}
SQLITE_PRIVATE int sqlite4FixExpr(
DbFixer *pFix, /* Context of the fixation */
Expr *pExpr /* The expression to be fixed to one database */
){
while( pExpr ){
if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ) break;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
if( sqlite4FixSelect(pFix, pExpr->x.pSelect) ) return 1;
}else{
if( sqlite4FixExprList(pFix, pExpr->x.pList) ) return 1;
}
if( sqlite4FixExpr(pFix, pExpr->pRight) ){
return 1;
}
pExpr = pExpr->pLeft;
}
return 0;
}
SQLITE_PRIVATE int sqlite4FixExprList(
DbFixer *pFix, /* Context of the fixation */
ExprList *pList /* The expression to be fixed to one database */
){
int i;
struct ExprList_item *pItem;
if( pList==0 ) return 0;
for(i=0, pItem=pList->a; i<pList->nExpr; i++, pItem++){
if( sqlite4FixExpr(pFix, pItem->pExpr) ){
return 1;
}
}
return 0;
}
#endif
#ifndef SQLITE_OMIT_TRIGGER
SQLITE_PRIVATE int sqlite4FixTriggerStep(
DbFixer *pFix, /* Context of the fixation */
TriggerStep *pStep /* The trigger step be fixed to one database */
){
while( pStep ){
if( sqlite4FixSelect(pFix, pStep->pSelect) ){
return 1;
}
if( sqlite4FixExpr(pFix, pStep->pWhere) ){
return 1;
}
if( sqlite4FixExprList(pFix, pStep->pExprList) ){
return 1;
}
pStep = pStep->pNext;
}
return 0;
}
#endif
/************** End of attach.c **********************************************/
/************** Begin file auth.c ********************************************/
/*
** 2003 January 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 code used to implement the sqlite4_set_authorizer()
** API. This facility is an optional feature of the library. Embedded
** systems that do not need this facility may omit it by recompiling
** the library with -DSQLITE_OMIT_AUTHORIZATION=1
*/
/*
** All of the code in this file may be omitted by defining a single
** macro.
*/
#ifndef SQLITE_OMIT_AUTHORIZATION
/*
** Set or clear the access authorization function.
**
** The access authorization function is be called during the compilation
** phase to verify that the user has read and/or write access permission on
** various fields of the database. The first argument to the auth function
** is a copy of the 3rd argument to this routine. The second argument
** to the auth function is one of these constants:
**
** SQLITE_CREATE_INDEX
** SQLITE_CREATE_TABLE
** SQLITE_CREATE_TEMP_INDEX
** SQLITE_CREATE_TEMP_TABLE
** SQLITE_CREATE_TEMP_TRIGGER
** SQLITE_CREATE_TEMP_VIEW
** SQLITE_CREATE_TRIGGER
** SQLITE_CREATE_VIEW
** SQLITE_DELETE
** SQLITE_DROP_INDEX
** SQLITE_DROP_TABLE
** SQLITE_DROP_TEMP_INDEX
** SQLITE_DROP_TEMP_TABLE
** SQLITE_DROP_TEMP_TRIGGER
** SQLITE_DROP_TEMP_VIEW
** SQLITE_DROP_TRIGGER
** SQLITE_DROP_VIEW
** SQLITE_INSERT
** SQLITE_PRAGMA
** SQLITE_READ
** SQLITE_SELECT
** SQLITE_TRANSACTION
** SQLITE_UPDATE
**
** The third and fourth arguments to the auth function are the name of
** the table and the column that are being accessed. The auth function
** should return either SQLITE_OK, SQLITE_DENY, or SQLITE_IGNORE. If
** SQLITE_OK is returned, it means that access is allowed. SQLITE_DENY
** means that the SQL statement will never-run - the sqlite4_exec() call
** will return with an error. SQLITE_IGNORE means that the SQL statement
** should run but attempts to read the specified column will return NULL
** and attempts to write the column will be ignored.
**
** Setting the auth function to NULL disables this hook. The default
** setting of the auth function is NULL.
*/
SQLITE_API int sqlite4_set_authorizer(
sqlite4 *db,
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
void *pArg
){
sqlite4_mutex_enter(db->mutex);
db->xAuth = xAuth;
db->pAuthArg = pArg;
sqlite4ExpirePreparedStatements(db);
sqlite4_mutex_leave(db->mutex);
return SQLITE_OK;
}
/*
** Write an error message into pParse->zErrMsg that explains that the
** user-supplied authorization function returned an illegal value.
*/
static void sqliteAuthBadReturnCode(Parse *pParse){
sqlite4ErrorMsg(pParse, "authorizer malfunction");
pParse->rc = SQLITE_ERROR;
}
/*
** Invoke the authorization callback for permission to read column zCol from
** table zTab in database zDb. This function assumes that an authorization
** callback has been registered (i.e. that sqlite4.xAuth is not NULL).
**
** If SQLITE_IGNORE is returned and pExpr is not NULL, then pExpr is changed
** to an SQL NULL expression. Otherwise, if pExpr is NULL, then SQLITE_IGNORE
** is treated as SQLITE_DENY. In this case an error is left in pParse.
*/
SQLITE_PRIVATE int sqlite4AuthReadCol(
Parse *pParse, /* The parser context */
const char *zTab, /* Table name */
const char *zCol, /* Column name */
int iDb /* Index of containing database. */
){
sqlite4 *db = pParse->db; /* Database handle */
char *zDb = db->aDb[iDb].zName; /* Name of attached database */
int rc; /* Auth callback return code */
rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext);
if( rc==SQLITE_DENY ){
if( db->nDb>2 || iDb!=0 ){
sqlite4ErrorMsg(pParse, "access to %s.%s.%s is prohibited",zDb,zTab,zCol);
}else{
sqlite4ErrorMsg(pParse, "access to %s.%s is prohibited", zTab, zCol);
}
pParse->rc = SQLITE_AUTH;
}else if( rc!=SQLITE_IGNORE && rc!=SQLITE_OK ){
sqliteAuthBadReturnCode(pParse);
}
return rc;
}
/*
** The pExpr should be a TK_COLUMN expression. The table referred to
** is in pTabList or else it is the NEW or OLD table of a trigger.
** Check to see if it is OK to read this particular column.
**
** If the auth function returns SQLITE_IGNORE, change the TK_COLUMN
** instruction into a TK_NULL. If the auth function returns SQLITE_DENY,
** then generate an error.
*/
SQLITE_PRIVATE void sqlite4AuthRead(
Parse *pParse, /* The parser context */
Expr *pExpr, /* The expression to check authorization on */
Schema *pSchema, /* The schema of the expression */
SrcList *pTabList /* All table that pExpr might refer to */
){
sqlite4 *db = pParse->db;
Table *pTab = 0; /* The table being read */
const char *zCol; /* Name of the column of the table */
int iSrc; /* Index in pTabList->a[] of table being read */
int iDb; /* The index of the database the expression refers to */
int iCol; /* Index of column in table */
if( db->xAuth==0 ) return;
iDb = sqlite4SchemaToIndex(pParse->db, pSchema);
if( iDb<0 ){
/* An attempt to read a column out of a subquery or other
** temporary table. */
return;
}
assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER );
if( pExpr->op==TK_TRIGGER ){
pTab = pParse->pTriggerTab;
}else{
assert( pTabList );
for(iSrc=0; ALWAYS(iSrc<pTabList->nSrc); iSrc++){
if( pExpr->iTable==pTabList->a[iSrc].iCursor ){
pTab = pTabList->a[iSrc].pTab;
break;
}
}
}
iCol = pExpr->iColumn;
if( NEVER(pTab==0) ) return;
if( iCol>=0 ){
assert( iCol<pTab->nCol );
zCol = pTab->aCol[iCol].zName;
}else{
zCol = "ROWID";
}
assert( iDb>=0 && iDb<db->nDb );
if( SQLITE_IGNORE==sqlite4AuthReadCol(pParse, pTab->zName, zCol, iDb) ){
pExpr->op = TK_NULL;
}
}
/*
** Do an authorization check using the code and arguments given. Return
** either SQLITE_OK (zero) or SQLITE_IGNORE or SQLITE_DENY. If SQLITE_DENY
** is returned, then the error count and error message in pParse are
** modified appropriately.
*/
SQLITE_PRIVATE int sqlite4AuthCheck(
Parse *pParse,
int code,
const char *zArg1,
const char *zArg2,
const char *zArg3
){
sqlite4 *db = pParse->db;
int rc;
/* Don't do any authorization checks if the database is initialising
** or if the parser is being invoked from within sqlite4_declare_vtab.
*/
if( db->init.busy || IN_DECLARE_VTAB ){
return SQLITE_OK;
}
if( db->xAuth==0 ){
return SQLITE_OK;
}
rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext);
if( rc==SQLITE_DENY ){
sqlite4ErrorMsg(pParse, "not authorized");
pParse->rc = SQLITE_AUTH;
}else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){
rc = SQLITE_DENY;
sqliteAuthBadReturnCode(pParse);
}
return rc;
}
/*
** Push an authorization context. After this routine is called, the
** zArg3 argument to authorization callbacks will be zContext until
** popped. Or if pParse==0, this routine is a no-op.
*/
SQLITE_PRIVATE void sqlite4AuthContextPush(
Parse *pParse,
AuthContext *pContext,
const char *zContext
){
assert( pParse );
pContext->pParse = pParse;
pContext->zAuthContext = pParse->zAuthContext;
pParse->zAuthContext = zContext;
}
/*
** Pop an authorization context that was previously pushed
** by sqlite4AuthContextPush
*/
SQLITE_PRIVATE void sqlite4AuthContextPop(AuthContext *pContext){
if( pContext->pParse ){
pContext->pParse->zAuthContext = pContext->zAuthContext;
pContext->pParse = 0;
}
}
#endif /* SQLITE_OMIT_AUTHORIZATION */
/************** End of auth.c ************************************************/
/************** Begin file build.c *******************************************/
/*
** 2001 September 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.
**
*************************************************************************
** This file contains C code routines that are called by the SQLite parser
** when syntax rules are reduced. The routines in this file handle the
** following kinds of SQL syntax:
**
** CREATE TABLE
** DROP TABLE
** CREATE INDEX
** DROP INDEX
** creating ID lists
** BEGIN TRANSACTION
** COMMIT
** ROLLBACK
*/
/*
** This routine is called when a new SQL statement is beginning to
** be parsed. Initialize the pParse structure as needed.
*/
SQLITE_PRIVATE void sqlite4BeginParse(Parse *pParse, int explainFlag){
pParse->explain = (u8)explainFlag;
pParse->nVar = 0;
}
/*
** This routine is called after a single SQL statement has been
** parsed and a VDBE program to execute that statement has been
** prepared. This routine puts the finishing touches on the
** VDBE program and resets the pParse structure for the next
** parse.
**
** Note that if an error occurred, it might be the case that
** no VDBE code was generated.
*/
SQLITE_PRIVATE void sqlite4FinishCoding(Parse *pParse){
sqlite4 *db;
Vdbe *v;
db = pParse->db;
if( db->mallocFailed ) return;
if( pParse->nested ) return;
if( pParse->nErr ) return;
/* Begin by generating some termination code at the end of the
** vdbe program
*/
v = sqlite4GetVdbe(pParse);
assert( !pParse->isMultiWrite
|| sqlite4VdbeAssertMayAbort(v, pParse->mayAbort));
if( v ){
sqlite4VdbeAddOp0(v, OP_Halt);
/* The cookie mask contains one bit for each database file open.
** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are
** set for each database that is used. Generate code to start a
** transaction on each used database and to verify the schema cookie
** on each used database.
*/
if( pParse->cookieGoto>0 ){
yDbMask mask;
int iDb;
sqlite4VdbeJumpHere(v, pParse->cookieGoto-1);
for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){
if( (mask & pParse->cookieMask)==0 ) continue;
sqlite4VdbeAddOp2(v,OP_Transaction, iDb, (mask & pParse->writeMask)!=0);
if( db->init.busy==0 ){
sqlite4VdbeAddOp3(v, OP_VerifyCookie,
iDb, pParse->cookieValue[iDb],
db->aDb[iDb].pSchema->iGeneration);
}
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
{
int i;
for(i=0; i<pParse->nVtabLock; i++){
char *vtab = (char *)sqlite4GetVTable(db, pParse->apVtabLock[i]);
sqlite4VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB);
}
pParse->nVtabLock = 0;
}
#endif
/* Initialize any AUTOINCREMENT data structures required.
*/
sqlite4AutoincrementBegin(pParse);
/* Finally, jump back to the beginning of the executable code. */
sqlite4VdbeAddOp2(v, OP_Goto, 0, pParse->cookieGoto);
}
}
/* Get the VDBE program ready for execution
*/
if( v && ALWAYS(pParse->nErr==0) && !db->mallocFailed ){
#ifdef SQLITE_DEBUG
FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;
sqlite4VdbeTrace(v, trace);
#endif
assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */
/* A minimum of one cursor is required if autoincrement is used
* See ticket [a696379c1f08866] */
if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1;
sqlite4VdbeMakeReady(v, pParse);
pParse->rc = SQLITE_DONE;
pParse->colNamesSet = 0;
}else{
pParse->rc = SQLITE_ERROR;
}
pParse->nTab = 0;
pParse->nMem = 0;
pParse->nSet = 0;
pParse->nVar = 0;
pParse->cookieMask = 0;
pParse->cookieGoto = 0;
}
/*
** Generate VM code to allocate a new table number. Store the new value
** in register iReg.
*/
static void allocateTableNumber(
Parse *pParse, /* Parse context */
int iDb, /* Database number to allocate for */
int iReg /* Register to store new tnum in */
){
Vdbe *v;
v = sqlite4GetVdbe(pParse);
if( pParse->iNewidxReg==0 ){
Schema *pSchema;
HashElem *p;
int maxTab = 1;
pSchema = pParse->db->aDb[iDb].pSchema;
for(p=sqliteHashFirst(&pSchema->idxHash); p;p=sqliteHashNext(p)){
Index *pIdx = (Index*)sqliteHashData(p);
if( pIdx->tnum > maxTab ) maxTab = pIdx->tnum;
}
pParse->iNewidxReg = ++pParse->nMem;
sqlite4VdbeAddOp2(v, OP_Integer, maxTab, pParse->iNewidxReg);
}
sqlite4VdbeAddOp2(v, OP_NewIdxid, pParse->iNewidxReg, iDb);
sqlite4VdbeAddOp2(v, OP_Copy, pParse->iNewidxReg, iReg);
}
/*
** Run the parser and code generator recursively in order to generate
** code for the SQL statement given onto the end of the pParse context
** currently under construction. When the parser is run recursively
** this way, the final OP_Halt is not appended and other initialization
** and finalization steps are omitted because those are handling by the
** outermost parser.
**
** Not everything is nestable. This facility is designed to permit
** INSERT, UPDATE, and DELETE operations against SQLITE_MASTER. Use
** care if you decide to try to use this routine for some other purposes.
*/
SQLITE_PRIVATE void sqlite4NestedParse(Parse *pParse, const char *zFormat, ...){
va_list ap;
char *zSql;
char *zErrMsg = 0;
sqlite4 *db = pParse->db;
# define SAVE_SZ (sizeof(Parse) - offsetof(Parse,nVar))
char saveBuf[SAVE_SZ];
if( pParse->nErr ) return;
assert( pParse->nested<10 ); /* Nesting should only be of limited depth */
va_start(ap, zFormat);
zSql = sqlite4VMPrintf(db, zFormat, ap);
va_end(ap);
if( zSql==0 ){
return; /* A malloc must have failed */
}
pParse->nested++;
memcpy(saveBuf, &pParse->nVar, SAVE_SZ);
memset(&pParse->nVar, 0, SAVE_SZ);
sqlite4RunParser(pParse, zSql, &zErrMsg);
sqlite4DbFree(db, zErrMsg);
sqlite4DbFree(db, zSql);
memcpy(&pParse->nVar, saveBuf, SAVE_SZ);
pParse->nested--;
}
/*
** Locate the in-memory structure that describes a particular database
** table given the name of that table and (optionally) the name of the
** database containing the table. Return NULL if not found.
**
** If zDatabase is 0, all databases are searched for the table and the
** first matching table is returned. (No checking for duplicate table
** names is done.) The search order is TEMP first, then MAIN, then any
** auxiliary databases added using the ATTACH command.
**
** See also sqlite4LocateTable().
*/
SQLITE_PRIVATE Table *sqlite4FindTable(sqlite4 *db, const char *zName, const char *zDatabase){
Table *p = 0;
int i;
int nName;
assert( zName!=0 );
nName = sqlite4Strlen30(zName);
/* All mutexes are required for schema access. Make sure we hold them. */
for(i=OMIT_TEMPDB; i<db->nDb; i++){
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
if( zDatabase!=0 && sqlite4StrICmp(zDatabase, db->aDb[j].zName) ) continue;
p = sqlite4HashFind(&db->aDb[j].pSchema->tblHash, zName, nName);
if( p ) break;
}
return p;
}
/*
** Locate the in-memory structure that describes a particular database
** table given the name of that table and (optionally) the name of the
** database containing the table. Return NULL if not found. Also leave an
** error message in pParse->zErrMsg.
**
** The difference between this routine and sqlite4FindTable() is that this
** routine leaves an error message in pParse->zErrMsg where
** sqlite4FindTable() does not.
*/
SQLITE_PRIVATE Table *sqlite4LocateTable(
Parse *pParse, /* context in which to report errors */
int isView, /* True if looking for a VIEW rather than a TABLE */
const char *zName, /* Name of the table we are looking for */
const char *zDbase /* Name of the database. Might be NULL */
){
Table *p;
/* Read the database schema. If an error occurs, leave an error message
** and code in pParse and return NULL. */
if( SQLITE_OK!=sqlite4ReadSchema(pParse) ){
return 0;
}
p = sqlite4FindTable(pParse->db, zName, zDbase);
if( p==0 ){
const char *zMsg = isView ? "no such view" : "no such table";
if( zDbase ){
sqlite4ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
}else{
sqlite4ErrorMsg(pParse, "%s: %s", zMsg, zName);
}
pParse->checkSchema = 1;
}
return p;
}
/*
** Locate the in-memory structure that describes
** a particular index given the name of that index
** and the name of the database that contains the index.
** Return NULL if not found.
**
** If zDatabase is 0, all databases are searched for the
** table and the first matching index is returned. (No checking
** for duplicate index names is done.) The search order is
** TEMP first, then MAIN, then any auxiliary databases added
** using the ATTACH command.
*/
SQLITE_PRIVATE Index *sqlite4FindIndex(sqlite4 *db, const char *zName, const char *zDb){
Index *p = 0;
int i;
int nName = sqlite4Strlen30(zName);
/* All mutexes are required for schema access. Make sure we hold them. */
for(i=OMIT_TEMPDB; i<db->nDb; i++){
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
Schema *pSchema = db->aDb[j].pSchema;
assert( pSchema );
if( zDb && sqlite4StrICmp(zDb, db->aDb[j].zName) ) continue;
p = sqlite4HashFind(&pSchema->idxHash, zName, nName);
if( p ) break;
}
return p;
}
/*
** Reclaim the memory used by an index
*/
static void freeIndex(sqlite4 *db, Index *p){
#ifndef SQLITE_OMIT_ANALYZE
sqlite4DeleteIndexSamples(db, p);
#endif
sqlite4DbFree(db, p->zColAff);
sqlite4DbFree(db, p);
}
/*
** For the index called zIdxName which is found in the database iDb,
** unlike that index from its Table then remove the index from
** the index hash table and free all memory structures associated
** with the index.
*/
SQLITE_PRIVATE void sqlite4UnlinkAndDeleteIndex(sqlite4 *db, int iDb, const char *zIdxName){
Index *pIndex;
int len;
Hash *pHash;
pHash = &db->aDb[iDb].pSchema->idxHash;
len = sqlite4Strlen30(zIdxName);
pIndex = sqlite4HashInsert(pHash, zIdxName, len, 0);
if( ALWAYS(pIndex) ){
if( pIndex->pTable->pIndex==pIndex ){
pIndex->pTable->pIndex = pIndex->pNext;
}else{
Index *p;
/* Justification of ALWAYS(); The index must be on the list of
** indices. */
p = pIndex->pTable->pIndex;
while( ALWAYS(p) && p->pNext!=pIndex ){ p = p->pNext; }
if( ALWAYS(p && p->pNext==pIndex) ){
p->pNext = pIndex->pNext;
}
}
freeIndex(db, pIndex);
}
db->flags |= SQLITE_InternChanges;
}
/*
** Erase all schema information from the in-memory hash tables of
** a single database. This routine is called to reclaim memory
** before the database closes. It is also called during a rollback
** if there were schema changes during the transaction or if a
** schema-cookie mismatch occurs.
**
** If iDb<0 then reset the internal schema tables for all database
** files. If iDb>=0 then reset the internal schema for only the
** single file indicated.
*/
SQLITE_PRIVATE void sqlite4ResetInternalSchema(sqlite4 *db, int iDb){
int i, j;
assert( iDb<db->nDb );
if( iDb>=0 ){
/* Case 1: Reset the single schema identified by iDb */
Db *pDb = &db->aDb[iDb];
assert( pDb->pSchema!=0 );
sqlite4SchemaClear(db->pEnv, pDb->pSchema);
/* If any database other than TEMP is reset, then also reset TEMP
** since TEMP might be holding triggers that reference tables in the
** other database.
*/
if( iDb!=1 ){
pDb = &db->aDb[1];
assert( pDb->pSchema!=0 );
sqlite4SchemaClear(db->pEnv, pDb->pSchema);
}
return;
}
/* Case 2 (from here to the end): Reset all schemas for all attached
** databases. */
assert( iDb<0 );
for(i=0; i<db->nDb; i++){
Db *pDb = &db->aDb[i];
if( pDb->pSchema ){
sqlite4SchemaClear(db->pEnv, pDb->pSchema);
}
}
db->flags &= ~SQLITE_InternChanges;
sqlite4VtabUnlockList(db);
/* If one or more of the auxiliary database files has been closed,
** then remove them from the auxiliary database list. We take the
** opportunity to do this here since we have just deleted all of the
** schema hash tables and therefore do not have to make any changes
** to any of those tables.
*/
for(i=j=2; i<db->nDb; i++){
struct Db *pDb = &db->aDb[i];
if( pDb->pKV==0 ){
sqlite4DbFree(db, pDb->zName);
pDb->zName = 0;
continue;
}
if( j<i ){
db->aDb[j] = db->aDb[i];
}
j++;
}
memset(&db->aDb[j], 0, (db->nDb-j)*sizeof(db->aDb[j]));
db->nDb = j;
if( db->nDb<=2 && db->aDb!=db->aDbStatic ){
memcpy(db->aDbStatic, db->aDb, 2*sizeof(db->aDb[0]));
sqlite4DbFree(db, db->aDb);
db->aDb = db->aDbStatic;
}
}
/*
** This routine is called when a commit occurs.
*/
SQLITE_PRIVATE void sqlite4CommitInternalChanges(sqlite4 *db){
db->flags &= ~SQLITE_InternChanges;
}
/*
** Delete memory allocated for the column names of a table or view (the
** Table.aCol[] array).
*/
static void sqliteDeleteColumnNames(sqlite4 *db, Table *pTable){
int i;
Column *pCol;
assert( pTable!=0 );
if( (pCol = pTable->aCol)!=0 ){
for(i=0; i<pTable->nCol; i++, pCol++){
sqlite4DbFree(db, pCol->zName);
sqlite4ExprDelete(db, pCol->pDflt);
sqlite4DbFree(db, pCol->zDflt);
sqlite4DbFree(db, pCol->zType);
sqlite4DbFree(db, pCol->zColl);
}
sqlite4DbFree(db, pTable->aCol);
}
}
/*
** Remove the memory data structures associated with the given
** Table. No changes are made to disk by this routine.
**
** This routine just deletes the data structure. It does not unlink
** the table data structure from the hash table. But it does destroy
** memory structures of the indices and foreign keys associated with
** the table.
*/
SQLITE_PRIVATE void sqlite4DeleteTable(sqlite4 *db, Table *pTable){
Index *pIndex, *pNext;
assert( !pTable || pTable->nRef>0 );
/* Do not delete the table until the reference count reaches zero. */
if( !pTable ) return;
if( ((!db || db->pnBytesFreed==0) && (--pTable->nRef)>0) ) return;
/* Delete all indices associated with this table. */
for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
pNext = pIndex->pNext;
assert( pIndex->pSchema==pTable->pSchema );
if( !db || db->pnBytesFreed==0 ){
char *zName = pIndex->zName;
TESTONLY ( Index *pOld = ) sqlite4HashInsert(
&pIndex->pSchema->idxHash, zName, sqlite4Strlen30(zName), 0
);
assert( pOld==pIndex || pOld==0 );
}
freeIndex(db, pIndex);
}
/* Delete any foreign keys attached to this table. */
sqlite4FkDelete(db, pTable);
/* Delete the Table structure itself.
*/
sqliteDeleteColumnNames(db, pTable);
sqlite4DbFree(db, pTable->zName);
sqlite4DbFree(db, pTable->zColAff);
sqlite4SelectDelete(db, pTable->pSelect);
#ifndef SQLITE_OMIT_CHECK
sqlite4ExprDelete(db, pTable->pCheck);
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
sqlite4VtabClear(db, pTable);
#endif
sqlite4DbFree(db, pTable);
}
/*
** Unlink the given table from the hash tables and the delete the
** table structure with all its indices and foreign keys.
*/
SQLITE_PRIVATE void sqlite4UnlinkAndDeleteTable(sqlite4 *db, int iDb, const char *zTabName){
Table *p;
Db *pDb;
assert( db!=0 );
assert( iDb>=0 && iDb<db->nDb );
assert( zTabName );
testcase( zTabName[0]==0 ); /* Zero-length table names are allowed */
pDb = &db->aDb[iDb];
p = sqlite4HashInsert(&pDb->pSchema->tblHash, zTabName,
sqlite4Strlen30(zTabName),0);
sqlite4DeleteTable(db, p);
db->flags |= SQLITE_InternChanges;
}
/*
** Given a token, return a string that consists of the text of that
** token. Space to hold the returned string
** is obtained from sqliteMalloc() and must be freed by the calling
** function.
**
** Any quotation marks (ex: "name", 'name', [name], or `name`) that
** surround the body of the token are removed.
**
** Tokens are often just pointers into the original SQL text and so
** are not \000 terminated and are not persistent. The returned string
** is \000 terminated and is persistent.
*/
SQLITE_PRIVATE char *sqlite4NameFromToken(sqlite4 *db, Token *pName){
char *zName;
if( pName ){
zName = sqlite4DbStrNDup(db, (char*)pName->z, pName->n);
sqlite4Dequote(zName);
}else{
zName = 0;
}
return zName;
}
/*
** Open the sqlite_master table stored in database number iDb for
** writing. The table is opened using cursor 0.
*/
SQLITE_PRIVATE void sqlite4OpenMasterTable(Parse *p, int iDb){
Vdbe *v = sqlite4GetVdbe(p);
sqlite4VdbeAddOp3(v, OP_OpenWrite, 0, MASTER_ROOT, iDb);
sqlite4VdbeChangeP4(v, -1, (char *)5, P4_INT32); /* 5 column table */
if( p->nTab==0 ){
p->nTab = 1;
}
}
/*
** Parameter zName points to a nul-terminated buffer containing the name
** of a database ("main", "temp" or the name of an attached db). This
** function returns the index of the named database in db->aDb[], or
** -1 if the named db cannot be found.
*/
SQLITE_PRIVATE int sqlite4FindDbName(sqlite4 *db, const char *zName){
int i = -1; /* Database number */
if( zName ){
Db *pDb;
int n = sqlite4Strlen30(zName);
for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){
if( (!OMIT_TEMPDB || i!=1 ) && n==sqlite4Strlen30(pDb->zName) &&
0==sqlite4StrICmp(pDb->zName, zName) ){
break;
}
}
}
return i;
}
/*
** The token *pName contains the name of a database (either "main" or
** "temp" or the name of an attached db). This routine returns the
** index of the named database in db->aDb[], or -1 if the named db
** does not exist.
*/
SQLITE_PRIVATE int sqlite4FindDb(sqlite4 *db, Token *pName){
int i; /* Database number */
char *zName; /* Name we are searching for */
zName = sqlite4NameFromToken(db, pName);
i = sqlite4FindDbName(db, zName);
sqlite4DbFree(db, zName);
return i;
}
/* The table or view or trigger name is passed to this routine via tokens
** pName1 and pName2. If the table name was fully qualified, for example:
**
** CREATE TABLE xxx.yyy (...);
**
** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if
** the table name is not fully qualified, i.e.:
**
** CREATE TABLE yyy(...);
**
** Then pName1 is set to "yyy" and pName2 is "".
**
** This routine sets the *ppUnqual pointer to point at the token (pName1 or
** pName2) that stores the unqualified table name. The index of the
** database "xxx" is returned.
*/
SQLITE_PRIVATE int sqlite4TwoPartName(
Parse *pParse, /* Parsing and code generating context */
Token *pName1, /* The "xxx" in the name "xxx.yyy" or "xxx" */
Token *pName2, /* The "yyy" in the name "xxx.yyy" */
Token **pUnqual /* Write the unqualified object name here */
){
int iDb; /* Database holding the object */
sqlite4 *db = pParse->db;
if( ALWAYS(pName2!=0) && pName2->n>0 ){
if( db->init.busy ) {
sqlite4ErrorMsg(pParse, "corrupt database");
pParse->nErr++;
return -1;
}
*pUnqual = pName2;
iDb = sqlite4FindDb(db, pName1);
if( iDb<0 ){
sqlite4ErrorMsg(pParse, "unknown database %T", pName1);
pParse->nErr++;
return -1;
}
}else{
assert( db->init.iDb==0 || db->init.busy );
iDb = db->init.iDb;
*pUnqual = pName1;
}
return iDb;
}
/*
** This routine is used to check if the UTF-8 string zName is a legal
** unqualified name for a new schema object (table, index, view or
** trigger). All names are legal except those that begin with the string
** "sqlite_" (in upper, lower or mixed case). This portion of the namespace
** is reserved for internal use.
*/
SQLITE_PRIVATE int sqlite4CheckObjectName(Parse *pParse, const char *zName){
if( !pParse->db->init.busy && pParse->nested==0
&& (pParse->db->flags & SQLITE_WriteSchema)==0
&& 0==sqlite4StrNICmp(zName, "sqlite_", 7) ){
sqlite4ErrorMsg(pParse, "object name reserved for internal use: %s", zName);
return SQLITE_ERROR;
}
return SQLITE_OK;
}
/*
** Begin constructing a new table representation in memory. This is
** the first of several action routines that get called in response
** to a CREATE TABLE statement. In particular, this routine is called
** after seeing tokens "CREATE" and "TABLE" and the table name. The isTemp
** flag is true if the table should be stored in the auxiliary database
** file instead of in the main database file. This is normally the case
** when the "TEMP" or "TEMPORARY" keyword occurs in between
** CREATE and TABLE.
**
** The new table record is initialized and put in pParse->pNewTable.
** As more of the CREATE TABLE statement is parsed, additional action
** routines will be called to add more information to this record.
** At the end of the CREATE TABLE statement, the sqlite4EndTable() routine
** is called to complete the construction of the new table record.
*/
SQLITE_PRIVATE void sqlite4StartTable(
Parse *pParse, /* Parser context */
Token *pName1, /* First part of the name of the table or view */
Token *pName2, /* Second part of the name of the table or view */
int isTemp, /* True if this is a TEMP table */
int isView, /* True if this is a VIEW */
int isVirtual, /* True if this is a VIRTUAL table */
int noErr /* Do nothing if table already exists */
){
Table *pTable;
char *zName = 0; /* The name of the new table */
sqlite4 *db = pParse->db;
Vdbe *v;
int iDb; /* Database number to create the table in */
Token *pName; /* Unqualified name of the table to create */
/* The table or view name to create is passed to this routine via tokens
** pName1 and pName2. If the table name was fully qualified, for example:
**
** CREATE TABLE xxx.yyy (...);
**
** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if
** the table name is not fully qualified, i.e.:
**
** CREATE TABLE yyy(...);
**
** Then pName1 is set to "yyy" and pName2 is "".
**
** The call below sets the pName pointer to point at the token (pName1 or
** pName2) that stores the unqualified table name. The variable iDb is
** set to the index of the database that the table or view is to be
** created in.
*/
iDb = sqlite4TwoPartName(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. */
sqlite4ErrorMsg(pParse, "temporary table name must be unqualified");
return;
}
if( !OMIT_TEMPDB && isTemp ) iDb = 1;
pParse->sNameToken = *pName;
zName = sqlite4NameFromToken(db, pName);
if( zName==0 ) return;
if( SQLITE_OK!=sqlite4CheckObjectName(pParse, zName) ){
goto begin_table_error;
}
if( db->init.iDb==1 ) isTemp = 1;
#ifndef SQLITE_OMIT_AUTHORIZATION
assert( (isTemp & 1)==isTemp );
{
int code;
char *zDb = db->aDb[iDb].zName;
if( sqlite4AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){
goto begin_table_error;
}
if( isView ){
if( !OMIT_TEMPDB && isTemp ){
code = SQLITE_CREATE_TEMP_VIEW;
}else{
code = SQLITE_CREATE_VIEW;
}
}else{
if( !OMIT_TEMPDB && isTemp ){
code = SQLITE_CREATE_TEMP_TABLE;
}else{
code = SQLITE_CREATE_TABLE;
}
}
if( !isVirtual && sqlite4AuthCheck(pParse, code, zName, 0, zDb) ){
goto begin_table_error;
}
}
#endif
/* Make sure the new table name does not collide with an existing
** index or table name in the same database. Issue an error message if
** it does. The exception is if the statement being parsed was passed
** to an sqlite4_declare_vtab() call. In that case only the column names
** and types will be used, so there is no need to test for namespace
** collisions.
*/
if( !IN_DECLARE_VTAB ){
char *zDb = db->aDb[iDb].zName;
if( SQLITE_OK!=sqlite4ReadSchema(pParse) ){
goto begin_table_error;
}
pTable = sqlite4FindTable(db, zName, zDb);
if( pTable ){
if( !noErr ){
sqlite4ErrorMsg(pParse, "table %T already exists", pName);
}else{
assert( !db->init.busy );
sqlite4CodeVerifySchema(pParse, iDb);
}
goto begin_table_error;
}
if( sqlite4FindIndex(db, zName, zDb)!=0 ){
sqlite4ErrorMsg(pParse, "there is already an index named %s", zName);
goto begin_table_error;
}
}
pTable = sqlite4DbMallocZero(db, sizeof(Table));
if( pTable==0 ){
db->mallocFailed = 1;
pParse->rc = SQLITE_NOMEM;
pParse->nErr++;
goto begin_table_error;
}
pTable->zName = zName;
pTable->pSchema = db->aDb[iDb].pSchema;
pTable->nRef = 1;
pTable->nRowEst = 1000000;
assert( pParse->pNewTable==0 );
pParse->pNewTable = pTable;
/* If this is the magic sqlite_sequence table used by autoincrement,
** then record a pointer to this table in the main database structure
** so that INSERT can find the table easily.
*/
#ifndef SQLITE_OMIT_AUTOINCREMENT
if( !pParse->nested && strcmp(zName, "sqlite_sequence")==0 ){
pTable->pSchema->pSeqTab = pTable;
}
#endif
/* Begin generating the code that will insert the table record into
** the SQLITE_MASTER table. Note in particular that we must go ahead
** and allocate the record number for the table entry now. Before any
** PRIMARY KEY or UNIQUE keywords are parsed. Those keywords will cause
** indices to be created and the table record must come before the
** indices. Hence, the record number for the table must be allocated
** now.
*/
if( !db->init.busy && (v = sqlite4GetVdbe(pParse))!=0 ){
int reg1, reg3;
sqlite4BeginWriteOperation(pParse, 0, iDb);
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( isVirtual ){
sqlite4VdbeAddOp0(v, OP_VBegin);
}
#endif
/* This just creates a place-holder record in the sqlite_master table.
** The record created does not contain anything yet. It will be replaced
** by the real entry in code generated at sqlite4EndTable().
**
** The rowid for the new entry is left in register pParse->regRowid.
** The root page number of the new table is left in reg pParse->regRoot.
** The rowid and root page number values are needed by the code that
** sqlite4EndTable will generate.
*/
reg1 = pParse->regRowid = ++pParse->nMem;
reg3 = ++pParse->nMem;
#if 0
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
if( isView || isVirtual ){
sqlite4VdbeAddOp2(v, OP_Integer, 0, reg2);
}else
#endif
{
int tnum = firstAvailableTableNumber(db, iDb);
sqlite4VdbeAddOp2(v, OP_Integer, tnum, reg2);
}
#endif
sqlite4OpenMasterTable(pParse, iDb);
sqlite4VdbeAddOp2(v, OP_NewRowid, 0, reg1);
sqlite4VdbeAddOp2(v, OP_Null, 0, reg3);
sqlite4VdbeAddOp3(v, OP_Insert, 0, reg3, reg1);
sqlite4VdbeChangeP5(v, OPFLAG_APPEND);
sqlite4VdbeAddOp0(v, OP_Close);
}
/* Normal (non-error) return. */
return;
/* If an error occurs, we jump here */
begin_table_error:
sqlite4DbFree(db, zName);
return;
}
/*
** This macro is used to compare two strings in a case-insensitive manner.
** It is slightly faster than calling sqlite4StrICmp() directly, but
** produces larger code.
**
** WARNING: This macro is not compatible with the strcmp() family. It
** returns true if the two strings are equal, otherwise false.
*/
#define STRICMP(x, y) (\
sqlite4UpperToLower[*(unsigned char *)(x)]== \
sqlite4UpperToLower[*(unsigned char *)(y)] \
&& sqlite4StrICmp((x)+1,(y)+1)==0 )
/*
** Add a new column to the table currently being constructed.
**
** The parser calls this routine once for each column declaration
** in a CREATE TABLE statement. sqlite4StartTable() gets called
** first to get things going. Then this routine is called for each
** column.
*/
SQLITE_PRIVATE void sqlite4AddColumn(Parse *pParse, Token *pName){
Table *p;
int i;
char *z;
Column *pCol;
sqlite4 *db = pParse->db;
if( (p = pParse->pNewTable)==0 ) return;
#if SQLITE_MAX_COLUMN
if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){
sqlite4ErrorMsg(pParse, "too many columns on %s", p->zName);
return;
}
#endif
z = sqlite4NameFromToken(db, pName);
if( z==0 ) return;
for(i=0; i<p->nCol; i++){
if( STRICMP(z, p->aCol[i].zName) ){
sqlite4ErrorMsg(pParse, "duplicate column name: %s", z);
sqlite4DbFree(db, z);
return;
}
}
if( (p->nCol & 0x7)==0 ){
Column *aNew;
aNew = sqlite4DbRealloc(db,p->aCol,(p->nCol+8)*sizeof(p->aCol[0]));
if( aNew==0 ){
sqlite4DbFree(db, z);
return;
}
p->aCol = aNew;
}
pCol = &p->aCol[p->nCol];
memset(pCol, 0, sizeof(p->aCol[0]));
pCol->zName = z;
/* If there is no type specified, columns have the default affinity
** 'NONE'. If there is a type specified, then sqlite4AddColumnType() will
** be called next to set pCol->affinity correctly.
*/
pCol->affinity = SQLITE_AFF_NONE;
p->nCol++;
}
/*
** This routine is called by the parser while in the middle of
** parsing a CREATE TABLE statement. A "NOT NULL" constraint has
** been seen on a column. This routine sets the notNull flag on
** the column currently under construction.
*/
SQLITE_PRIVATE void sqlite4AddNotNull(Parse *pParse, int onError){
Table *p;
p = pParse->pNewTable;
if( p==0 || NEVER(p->nCol<1) ) return;
p->aCol[p->nCol-1].notNull = (u8)onError;
}
/*
** Scan the column type name zType (length nType) and return the
** associated affinity type.
**
** This routine does a case-independent search of zType for the
** substrings in the following table. If one of the substrings is
** found, the corresponding affinity is returned. If zType contains
** more than one of the substrings, entries toward the top of
** the table take priority. For example, if zType is 'BLOBINT',
** SQLITE_AFF_INTEGER is returned.
**
** Substring | Affinity
** --------------------------------
** 'INT' | SQLITE_AFF_INTEGER
** 'CHAR' | SQLITE_AFF_TEXT
** 'CLOB' | SQLITE_AFF_TEXT
** 'TEXT' | SQLITE_AFF_TEXT
** 'BLOB' | SQLITE_AFF_NONE
** 'REAL' | SQLITE_AFF_REAL
** 'FLOA' | SQLITE_AFF_REAL
** 'DOUB' | SQLITE_AFF_REAL
**
** If none of the substrings in the above table are found,
** SQLITE_AFF_NUMERIC is returned.
*/
SQLITE_PRIVATE char sqlite4AffinityType(const char *zIn){
u32 h = 0;
char aff = SQLITE_AFF_NUMERIC;
if( zIn ) while( zIn[0] ){
h = (h<<8) + sqlite4UpperToLower[(*zIn)&0xff];
zIn++;
if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){ /* CHAR */
aff = SQLITE_AFF_TEXT;
}else if( h==(('c'<<24)+('l'<<16)+('o'<<8)+'b') ){ /* CLOB */
aff = SQLITE_AFF_TEXT;
}else if( h==(('t'<<24)+('e'<<16)+('x'<<8)+'t') ){ /* TEXT */
aff = SQLITE_AFF_TEXT;
}else if( h==(('b'<<24)+('l'<<16)+('o'<<8)+'b') /* BLOB */
&& (aff==SQLITE_AFF_NUMERIC || aff==SQLITE_AFF_REAL) ){
aff = SQLITE_AFF_NONE;
#ifndef SQLITE_OMIT_FLOATING_POINT
}else if( h==(('r'<<24)+('e'<<16)+('a'<<8)+'l') /* REAL */
&& aff==SQLITE_AFF_NUMERIC ){
aff = SQLITE_AFF_REAL;
}else if( h==(('f'<<24)+('l'<<16)+('o'<<8)+'a') /* FLOA */
&& aff==SQLITE_AFF_NUMERIC ){
aff = SQLITE_AFF_REAL;
}else if( h==(('d'<<24)+('o'<<16)+('u'<<8)+'b') /* DOUB */
&& aff==SQLITE_AFF_NUMERIC ){
aff = SQLITE_AFF_REAL;
#endif
}else if( (h&0x00FFFFFF)==(('i'<<16)+('n'<<8)+'t') ){ /* INT */
aff = SQLITE_AFF_INTEGER;
break;
}
}
return aff;
}
/*
** This routine is called by the parser while in the middle of
** parsing a CREATE TABLE statement. The pFirst token is the first
** token in the sequence of tokens that describe the type of the
** column currently under construction. pLast is the last token
** in the sequence. Use this information to construct a string
** that contains the typename of the column and store that string
** in zType.
*/
SQLITE_PRIVATE void sqlite4AddColumnType(Parse *pParse, Token *pType){
Table *p;
Column *pCol;
p = pParse->pNewTable;
if( p==0 || NEVER(p->nCol<1) ) return;
pCol = &p->aCol[p->nCol-1];
assert( pCol->zType==0 );
pCol->zType = sqlite4NameFromToken(pParse->db, pType);
pCol->affinity = sqlite4AffinityType(pCol->zType);
}
/*
** The expression is the default value for the most recently added column
** of the table currently under construction.
**
** Default value expressions must be constant. Raise an exception if this
** is not the case.
**
** This routine is called by the parser while in the middle of
** parsing a CREATE TABLE statement.
*/
SQLITE_PRIVATE void sqlite4AddDefaultValue(Parse *pParse, ExprSpan *pSpan){
Table *p;
Column *pCol;
sqlite4 *db = pParse->db;
p = pParse->pNewTable;
if( p!=0 ){
pCol = &(p->aCol[p->nCol-1]);
if( !sqlite4ExprIsConstantOrFunction(pSpan->pExpr) ){
sqlite4ErrorMsg(pParse, "default value of column [%s] is not constant",
pCol->zName);
}else{
/* A copy of pExpr is used instead of the original, as pExpr contains
** tokens that point to volatile memory. The 'span' of the expression
** is required by pragma table_info.
*/
sqlite4ExprDelete(db, pCol->pDflt);
pCol->pDflt = sqlite4ExprDup(db, pSpan->pExpr, EXPRDUP_REDUCE);
sqlite4DbFree(db, pCol->zDflt);
pCol->zDflt = sqlite4DbStrNDup(db, (char*)pSpan->zStart,
(int)(pSpan->zEnd - pSpan->zStart));
}
}
sqlite4ExprDelete(db, pSpan->pExpr);
}
/*
** Designate the PRIMARY KEY for the table. pList is a list of names
** of columns that form the primary key. If pList is NULL, then the
** most recently added column of the table is the primary key.
**
** A table can have at most one primary key. If the table already has
** a primary key (and this is the second primary key) then create an
** error.
**
** If the PRIMARY KEY is on a single column whose datatype is INTEGER,
** then we will try to use that column as the rowid. Set the Table.iPKey
** field of the table under construction to be the index of the
** INTEGER PRIMARY KEY column. Table.iPKey is set to -1 if there is
** no INTEGER PRIMARY KEY.
**
** If the key is not an INTEGER PRIMARY KEY, then create a unique
** index for the key. No index is created for INTEGER PRIMARY KEYs.
*/
SQLITE_PRIVATE void sqlite4AddPrimaryKey(
Parse *pParse, /* Parsing context */
ExprList *pList, /* List of field names to be indexed */
int onError, /* What to do with a uniqueness conflict */
int autoInc, /* True if the AUTOINCREMENT keyword is present */
int sortOrder /* SQLITE_SO_ASC or SQLITE_SO_DESC */
){
Table *pTab = pParse->pNewTable;
#if 0
char *zType = 0;
#endif
int iCol = -1, i;
if( pTab==0 || IN_DECLARE_VTAB ) goto primary_key_exit;
if( pTab->tabFlags & TF_HasPrimaryKey ){
sqlite4ErrorMsg(pParse,
"table \"%s\" has more than one primary key", pTab->zName);
goto primary_key_exit;
}
pTab->tabFlags |= TF_HasPrimaryKey;
if( pList==0 ){
iCol = pTab->nCol - 1;
pTab->aCol[iCol].isPrimKey = 1;
pTab->aCol[iCol].notNull = 1;
}else{
for(i=0; i<pList->nExpr; i++){
for(iCol=0; iCol<pTab->nCol; iCol++){
if( sqlite4StrICmp(pList->a[i].zName, pTab->aCol[iCol].zName)==0 ){
break;
}
}
if( iCol<pTab->nCol ){
pTab->aCol[iCol].isPrimKey = 1;
pTab->aCol[iCol].notNull = 1;
}
}
if( pList->nExpr>1 ) iCol = -1;
}
#if 0
if( iCol>=0 && iCol<pTab->nCol ){
zType = pTab->aCol[iCol].zType;
}
if( zType && sqlite4StrICmp(zType, "INTEGER")==0
&& sortOrder==SQLITE_SO_ASC ){
pTab->iPKey = iCol;
pTab->keyConf = (u8)onError;
assert( autoInc==0 || autoInc==1 );
pTab->tabFlags |= autoInc*TF_Autoincrement;
}else if( autoInc ){
#ifndef SQLITE_OMIT_AUTOINCREMENT
sqlite4ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
"INTEGER PRIMARY KEY");
#endif
}else
#endif
{
Index *p;
p = sqlite4CreateIndex(
pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0, 1
);
pList = 0;
}
primary_key_exit:
sqlite4ExprListDelete(pParse->db, pList);
return;
}
/*
** Add a new CHECK constraint to the table currently under construction.
*/
SQLITE_PRIVATE void sqlite4AddCheckConstraint(
Parse *pParse, /* Parsing context */
Expr *pCheckExpr /* The check expression */
){
sqlite4 *db = pParse->db;
#ifndef SQLITE_OMIT_CHECK
Table *pTab = pParse->pNewTable;
if( pTab && !IN_DECLARE_VTAB ){
pTab->pCheck = sqlite4ExprAnd(db, pTab->pCheck, pCheckExpr);
}else
#endif
{
sqlite4ExprDelete(db, pCheckExpr);
}
}
/*
** Set the collation function of the most recently parsed table column
** to the CollSeq given.
*/
SQLITE_PRIVATE void sqlite4AddCollateType(Parse *pParse, Token *pToken){
Table *p;
int i;
char *zColl; /* Dequoted name of collation sequence */
sqlite4 *db;
if( (p = pParse->pNewTable)==0 ) return;
i = p->nCol-1;
db = pParse->db;
zColl = sqlite4NameFromToken(db, pToken);
if( !zColl ) return;
if( sqlite4LocateCollSeq(pParse, zColl) ){
Index *pIdx;
p->aCol[i].zColl = zColl;
/* If the column is declared as "<name> PRIMARY KEY COLLATE <type>",
** then an index may have been created on this column before the
** collation type was added. Correct this if it is the case.
*/
for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){
assert( pIdx->nColumn==1 );
if( pIdx->aiColumn[0]==i ){
pIdx->azColl[0] = p->aCol[i].zColl;
}
}
}else{
sqlite4DbFree(db, zColl);
}
}
/*
** This function returns the collation sequence for database native text
** encoding identified by the string zName, length nName.
**
** If the requested collation sequence is not available, or not available
** in the database native encoding, the collation factory is invoked to
** request it. If the collation factory does not supply such a sequence,
** and the sequence is available in another text encoding, then that is
** returned instead.
**
** If no versions of the requested collations sequence are available, or
** another error occurs, NULL is returned and an error message written into
** pParse.
**
** This routine is a wrapper around sqlite4FindCollSeq(). This routine
** invokes the collation factory if the named collation cannot be found
** and generates an error message.
**
** See also: sqlite4FindCollSeq(), sqlite4GetCollSeq()
*/
SQLITE_PRIVATE CollSeq *sqlite4LocateCollSeq(Parse *pParse, const char *zName){
sqlite4 *db = pParse->db;
u8 enc = ENC(db);
u8 initbusy = db->init.busy;
CollSeq *pColl;
pColl = sqlite4FindCollSeq(db, enc, zName, initbusy);
if( !initbusy && (!pColl || !pColl->xCmp) ){
pColl = sqlite4GetCollSeq(db, enc, pColl, zName);
if( !pColl ){
sqlite4ErrorMsg(pParse, "no such collation sequence: %s", zName);
}
}
return pColl;
}
/*
** Generate code that will increment the schema cookie.
**
** The schema cookie is used to determine when the schema for the
** database changes. After each schema change, the cookie value
** changes. When a process first reads the schema it records the
** cookie. Thereafter, whenever it goes to access the database,
** it checks the cookie to make sure the schema has not changed
** since it was last read.
**
** This plan is not completely bullet-proof. It is possible for
** the schema to change multiple times and for the cookie to be
** 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.
*/
SQLITE_PRIVATE void sqlite4ChangeCookie(Parse *pParse, int iDb){
int r1 = sqlite4GetTempReg(pParse);
sqlite4 *db = pParse->db;
Vdbe *v = pParse->pVdbe;
sqlite4VdbeAddOp2(v, OP_Integer, db->aDb[iDb].pSchema->schema_cookie+1, r1);
sqlite4VdbeAddOp3(v, OP_SetCookie, iDb, 0, r1);
sqlite4ReleaseTempReg(pParse, r1);
}
/*
** Measure the number of characters needed to output the given
** identifier. The number returned includes any quotes used
** but does not include the null terminator.
**
** The estimate is conservative. It might be larger that what is
** really needed.
*/
static int identLength(const char *z){
int n;
for(n=0; *z; n++, z++){
if( *z=='"' ){ n++; }
}
return n + 2;
}
/*
** The first parameter is a pointer to an output buffer. The second
** parameter is a pointer to an integer that contains the offset at
** which to write into the output buffer. This function copies the
** nul-terminated string pointed to by the third parameter, zSignedIdent,
** to the specified offset in the buffer and updates *pIdx to refer
** to the first byte after the last byte written before returning.
**
** If the string zSignedIdent consists entirely of alpha-numeric
** characters, does not begin with a digit and is not an SQL keyword,
** then it is copied to the output buffer exactly as it is. Otherwise,
** it is quoted using double-quotes.
*/
static void identPut(char *z, int *pIdx, char *zSignedIdent){
unsigned char *zIdent = (unsigned char*)zSignedIdent;
int i, j, needQuote;
i = *pIdx;
for(j=0; zIdent[j]; j++){
if( !sqlite4Isalnum(zIdent[j]) && zIdent[j]!='_' ) break;
}
needQuote = sqlite4Isdigit(zIdent[0]) || sqlite4KeywordCode(zIdent, j)!=TK_ID;
if( !needQuote ){
needQuote = zIdent[j];
}
if( needQuote ) z[i++] = '"';
for(j=0; zIdent[j]; j++){
z[i++] = zIdent[j];
if( zIdent[j]=='"' ) z[i++] = '"';
}
if( needQuote ) z[i++] = '"';
z[i] = 0;
*pIdx = i;
}
/*
** Generate a CREATE TABLE statement appropriate for the given
** table. Memory to hold the text of the statement is obtained
** from sqliteMalloc() and must be freed by the calling function.
*/
static char *createTableStmt(sqlite4 *db, Table *p){
int i, k, n;
char *zStmt;
char *zSep, *zSep2, *zEnd;
Column *pCol;
n = 0;
for(pCol = p->aCol, i=0; i<p->nCol; i++, pCol++){
n += identLength(pCol->zName) + 5;
}
n += identLength(p->zName);
if( n<50 ){
zSep = "";
zSep2 = ",";
zEnd = ")";
}else{
zSep = "\n ";
zSep2 = ",\n ";
zEnd = "\n)";
}
n += 35 + 6*p->nCol;
zStmt = sqlite4DbMallocRaw(0, n);
if( zStmt==0 ){
db->mallocFailed = 1;
return 0;
}
k = sqlite4_snprintf(zStmt, n, "CREATE TABLE ");
identPut(zStmt, &k, p->zName);
zStmt[k++] = '(';
for(pCol=p->aCol, i=0; i<p->nCol; i++, pCol++){
static const char * const azType[] = {
/* SQLITE_AFF_TEXT */ " TEXT",
/* SQLITE_AFF_NONE */ "",
/* SQLITE_AFF_NUMERIC */ " NUM",
/* SQLITE_AFF_INTEGER */ " INT",
/* SQLITE_AFF_REAL */ " REAL"
};
int len;
const char *zType;
k += sqlite4_snprintf(&zStmt[k], n-k, zSep);
zSep = zSep2;
identPut(zStmt, &k, pCol->zName);
assert( pCol->affinity-SQLITE_AFF_TEXT >= 0 );
assert( pCol->affinity-SQLITE_AFF_TEXT < ArraySize(azType) );
testcase( pCol->affinity==SQLITE_AFF_TEXT );
testcase( pCol->affinity==SQLITE_AFF_NONE );
testcase( pCol->affinity==SQLITE_AFF_NUMERIC );
testcase( pCol->affinity==SQLITE_AFF_INTEGER );
testcase( pCol->affinity==SQLITE_AFF_REAL );
zType = azType[pCol->affinity - SQLITE_AFF_TEXT];
len = sqlite4Strlen30(zType);
assert( pCol->affinity==SQLITE_AFF_NONE
|| pCol->affinity==sqlite4AffinityType(zType) );
memcpy(&zStmt[k], zType, len);
k += len;
assert( k<=n );
}
sqlite4_snprintf(&zStmt[k], n-k, "%s", zEnd);
return zStmt;
}
static Index *newIndex(
Parse *pParse, /* Parse context for current statement */
Table *pTab, /* Table index is created on */
const char *zName, /* Name of index object to create */
int nCol, /* Number of columns in index */
int onError, /* One of OE_Abort, OE_Replace etc. */
int nExtra, /* Bytes of extra space to allocate */
char **pzExtra /* OUT: Pointer to extra space */
){
sqlite4 *db = pParse->db; /* Database handle */
Index *pIndex; /* Return value */
char *zExtra = 0; /* nExtra bytes of extra space allocated */
int nName; /* Length of zName in bytes */
/* Allocate the index structure. */
nName = sqlite4Strlen30(zName);
pIndex = sqlite4DbMallocZero(db,
ROUND8(sizeof(Index)) + /* Index structure */
ROUND8(sizeof(tRowcnt)*(nCol+1)) + /* Index.aiRowEst */
sizeof(char *)*nCol + /* Index.azColl */
sizeof(int)*nCol + /* Index.aiColumn */
sizeof(u8)*nCol + /* Index.aSortOrder */
nName + 1 + /* Index.zName */
nExtra /* Collation sequence names */
);
assert( pIndex || db->mallocFailed );
if( pIndex ){
zExtra = (char*)pIndex;
pIndex->aiRowEst = (tRowcnt*)&zExtra[ROUND8(sizeof(Index))];
pIndex->azColl = (char**)
((char*)pIndex->aiRowEst + ROUND8(sizeof(tRowcnt)*nCol+1));
assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowEst) );
assert( EIGHT_BYTE_ALIGNMENT(pIndex->azColl) );
pIndex->aiColumn = (int *)(&pIndex->azColl[nCol]);
pIndex->aSortOrder = (u8 *)(&pIndex->aiColumn[nCol]);
pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]);
zExtra = (char *)(&pIndex->zName[nName+1]);
memcpy(pIndex->zName, zName, nName+1);
pIndex->pTable = pTab;
pIndex->nColumn = nCol;
pIndex->onError = (u8)onError;
pIndex->pSchema = pTab->pSchema;
if( db->init.busy ){
Hash *pIdxHash = &pIndex->pSchema->idxHash;
Index *p;
p = sqlite4HashInsert(pIdxHash, pIndex->zName, nName, pIndex);
if( p ){
assert( p==pIndex );
db->mallocFailed = 1;
sqlite4DbFree(db, pIndex);
pIndex = 0;
}
}
}
*pzExtra = zExtra;
return pIndex;
}
/*
** Allocate and populate an Index structure representing an implicit
** primary key. In implicit primary key behaves similarly to the built-in
** INTEGER PRIMARY KEY columns in SQLite 3.
*/
static void addImplicitPrimaryKey(
Parse *pParse, /* Parse context */
Table *pTab, /* Table to add implicit PRIMARY KEY to */
int iDb
){
Index *pIndex; /* New index */
char *zExtra;
assert( !pTab->pIndex || pTab->pIndex->eIndexType!=SQLITE_INDEX_PRIMARYKEY );
assert( sqlite4Strlen30("binary")==6 );
pIndex = newIndex(pParse, pTab, pTab->zName, 1, OE_Abort, 1+6, &zExtra);
if( pIndex ){
sqlite4 *db = pParse->db;
pIndex->aiColumn[0] = -1;
pIndex->azColl[0] = zExtra;
memcpy(zExtra, "binary", 7);
pIndex->eIndexType = SQLITE_INDEX_PRIMARYKEY;
pIndex->pNext = pTab->pIndex;
pTab->pIndex = pIndex;
sqlite4DefaultRowEst(pIndex);
pTab->tabFlags |= TF_HasPrimaryKey;
if( db->init.busy ){
pIndex->tnum = db->init.newTnum;
}else{
pIndex->tnum = ++pParse->nMem;
allocateTableNumber(pParse, iDb, pIndex->tnum);
}
}
}
/*
** This routine is called to report the final ")" that terminates
** a CREATE TABLE statement.
**
** The table structure that other action routines have been building
** is added to the internal hash tables, assuming no errors have
** occurred.
**
** An entry for the table is made in the master table on disk, unless
** this is a temporary table or db->init.busy==1. When db->init.busy==1
** it means we are reading the sqlite_master table because we just
** connected to the database or because the sqlite_master table has
** recently changed, so the entry for this table already exists in
** the sqlite_master table. We do not want to create it again.
**
** If the pSelect argument is not NULL, it means that this routine
** was called to create a table generated from a
** "CREATE TABLE ... AS SELECT ..." statement. The column names of
** the new table will match the result set of the SELECT.
*/
SQLITE_PRIVATE void sqlite4EndTable(
Parse *pParse, /* Parse context */
Token *pCons, /* The ',' token after the last column defn. */
Token *pEnd, /* The final ')' token in the CREATE TABLE */
Select *pSelect /* Select from a "CREATE ... AS SELECT" */
){
Table *p;
sqlite4 *db = pParse->db;
int iDb;
int iPkRoot = 0; /* Root page of primary key index */
if( (pEnd==0 && pSelect==0) || db->mallocFailed ){
return;
}
p = pParse->pNewTable;
if( p==0 ) return;
assert( !db->init.busy || !pSelect );
iDb = sqlite4SchemaToIndex(db, p->pSchema);
if( !IsView(p) ){
Index *pPk; /* PRIMARY KEY index of table p */
if( 0==(p->tabFlags & TF_HasPrimaryKey) ){
/* If no explicit PRIMARY KEY has been created, add an implicit
** primary key here. An implicit primary key works the way "rowid"
** did in SQLite 3. */
addImplicitPrimaryKey(pParse, p, iDb);
}
pPk = sqlite4FindPrimaryKey(p, 0);
assert( pPk || pParse->nErr || db->mallocFailed );
if( pPk ) iPkRoot = pPk->tnum;
}
#ifndef SQLITE_OMIT_CHECK
/* Resolve names in all CHECK constraint expressions.
*/
if( p->pCheck ){
SrcList sSrc; /* Fake SrcList for pParse->pNewTable */
NameContext sNC; /* Name context for pParse->pNewTable */
memset(&sNC, 0, sizeof(sNC));
memset(&sSrc, 0, sizeof(sSrc));
sSrc.nSrc = 1;
sSrc.a[0].zName = p->zName;
sSrc.a[0].pTab = p;
sSrc.a[0].iCursor = -1;
sNC.pParse = pParse;
sNC.pSrcList = &sSrc;
sNC.isCheck = 1;
if( sqlite4ResolveExprNames(&sNC, p->pCheck) ){
return;
}
}
#endif /* !defined(SQLITE_OMIT_CHECK) */
/* If not initializing, then create a record for the new table
** in the SQLITE_MASTER table of the database.
**
** If this is a TEMPORARY table, write the entry into the auxiliary
** file instead of into the main database file.
*/
if( !db->init.busy ){
int n;
Vdbe *v;
char *zType; /* "view" or "table" */
char *zType2; /* "VIEW" or "TABLE" */
char *zStmt; /* Text of the CREATE TABLE or CREATE VIEW statement */
v = sqlite4GetVdbe(pParse);
if( NEVER(v==0) ) return;
sqlite4VdbeAddOp1(v, OP_Close, 0);
/*
** Initialize zType for the new view or table.
*/
if( p->pSelect==0 ){
/* A regular table */
zType = "table";
zType2 = "TABLE";
#ifndef SQLITE_OMIT_VIEW
}else{
/* A view */
zType = "view";
zType2 = "VIEW";
#endif
}
/* If this is a CREATE TABLE xx AS SELECT ..., execute the SELECT
** statement to populate the new table. The root-page number for the
** new table is in register pParse->regRoot.
**
** Once the SELECT has been coded by sqlite4Select(), it is in a
** suitable state to query for the column names and types to be used
** by the new table.
*/
if( pSelect ){
SelectDest dest;
Table *pSelTab;
assert(pParse->nTab==1);
sqlite4VdbeAddOp3(v, OP_OpenWrite, 1, iPkRoot, iDb);
sqlite4VdbeChangeP5(v, 1);
pParse->nTab = 2;
sqlite4SelectDestInit(&dest, SRT_Table, 1);
sqlite4Select(pParse, pSelect, &dest);
sqlite4VdbeAddOp1(v, OP_Close, 1);
if( pParse->nErr==0 ){
pSelTab = sqlite4ResultSetOfSelect(pParse, pSelect);
if( pSelTab==0 ) return;
assert( p->aCol==0 );
p->nCol = pSelTab->nCol;
p->aCol = pSelTab->aCol;
pSelTab->nCol = 0;
pSelTab->aCol = 0;
sqlite4DeleteTable(db, pSelTab);
}
}
/* Compute the complete text of the CREATE statement */
if( pSelect ){
zStmt = createTableStmt(db, p);
}else{
n = (int)(pEnd->z - pParse->sNameToken.z) + 1;
zStmt = sqlite4MPrintf(db,
"CREATE %s %.*s", zType2, n, pParse->sNameToken.z
);
}
/* A slot for the record has already been allocated in the
** SQLITE_MASTER table. We just need to update that slot with all
** the information we've collected.
*/
sqlite4NestedParse(pParse,
"UPDATE %Q.%s "
"SET type='%s', name=%Q, tbl_name=%Q, rootpage=%s%d, sql=%Q "
"WHERE rowid=#%d",
db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
zType,
p->zName,
p->zName,
(iPkRoot ? "#" : ""), iPkRoot,
zStmt,
pParse->regRowid
);
sqlite4DbFree(db, zStmt);
sqlite4ChangeCookie(pParse, iDb);
#ifndef SQLITE_OMIT_AUTOINCREMENT
/* Check to see if we need to create an sqlite_sequence table for
** keeping track of autoincrement keys.
*/
if( p->tabFlags & TF_Autoincrement ){
Db *pDb = &db->aDb[iDb];
if( pDb->pSchema->pSeqTab==0 ){
sqlite4NestedParse(pParse,
"CREATE TABLE %Q.sqlite_sequence(name,seq)",
pDb->zName
);
}
}
#endif
/* Reparse everything to update our internal data structures */
sqlite4VdbeAddParseSchemaOp(v, iDb,
sqlite4MPrintf(db, "tbl_name='%q'", p->zName));
}
/* Add the table to the in-memory representation of the database.
*/
if( db->init.busy ){
Table *pOld;
Schema *pSchema = p->pSchema;
pOld = sqlite4HashInsert(&pSchema->tblHash, p->zName,
sqlite4Strlen30(p->zName),p);
if( pOld ){
assert( p==pOld ); /* Malloc must have failed inside HashInsert() */
db->mallocFailed = 1;
return;
}
pParse->pNewTable = 0;
db->nTable++;
db->flags |= SQLITE_InternChanges;
#ifndef SQLITE_OMIT_ALTERTABLE
if( !p->pSelect ){
const char *zName = (const char *)pParse->sNameToken.z;
int nName;
assert( !pSelect && pCons && pEnd );
if( pCons->z==0 ){
pCons = pEnd;
}
nName = (int)((const char *)pCons->z - zName);
p->addColOffset = 13 + sqlite4Utf8CharLen(zName, nName);
}
#endif
}
}
#ifndef SQLITE_OMIT_VIEW
/*
** The parser calls this routine in order to create a new VIEW
*/
SQLITE_PRIVATE void sqlite4CreateView(
Parse *pParse, /* The parsing context */
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 */
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 */
){
Table *p;
int n;
const char *z;
Token sEnd;
DbFixer sFix;
Token *pName = 0;
int iDb;
sqlite4 *db = pParse->db;
if( pParse->nVar>0 ){
sqlite4ErrorMsg(pParse, "parameters are not allowed in views");
sqlite4SelectDelete(db, pSelect);
return;
}
sqlite4StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr);
p = pParse->pNewTable;
if( p==0 || pParse->nErr ){
sqlite4SelectDelete(db, pSelect);
return;
}
sqlite4TwoPartName(pParse, pName1, pName2, &pName);
iDb = sqlite4SchemaToIndex(db, p->pSchema);
if( sqlite4FixInit(&sFix, pParse, iDb, "view", pName)
&& sqlite4FixSelect(&sFix, pSelect)
){
sqlite4SelectDelete(db, pSelect);
return;
}
/* Make a copy of the entire SELECT statement that defines the view.
** This will force all the Expr.token.z values to be dynamically
** allocated rather than point to the input string - which means that
** they will persist after the current sqlite4_exec() call returns.
*/
p->pSelect = sqlite4SelectDup(db, pSelect, EXPRDUP_REDUCE);
sqlite4SelectDelete(db, pSelect);
if( db->mallocFailed ){
return;
}
if( !db->init.busy ){
sqlite4ViewGetColumnNames(pParse, p);
}
/* Locate the end of the CREATE VIEW statement. Make sEnd point to
** the end.
*/
sEnd = pParse->sLastToken;
if( ALWAYS(sEnd.z[0]!=0) && sEnd.z[0]!=';' ){
sEnd.z += sEnd.n;
}
sEnd.n = 0;
n = (int)(sEnd.z - pBegin->z);
z = pBegin->z;
while( ALWAYS(n>0) && sqlite4Isspace(z[n-1]) ){ n--; }
sEnd.z = &z[n-1];
sEnd.n = 1;
/* Use sqlite4EndTable() to add the view to the SQLITE_MASTER table */
sqlite4EndTable(pParse, 0, &sEnd, 0);
return;
}
#endif /* SQLITE_OMIT_VIEW */
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
/*
** The Table structure pTable is really a VIEW. Fill in the names of
** the columns of the view in the pTable structure. Return the number
** of errors. If an error is seen leave an error message in pParse->zErrMsg.
*/
SQLITE_PRIVATE int sqlite4ViewGetColumnNames(Parse *pParse, Table *pTable){
Table *pSelTab; /* A fake table from which we get the result set */
Select *pSel; /* Copy of the SELECT that implements the view */
int nErr = 0; /* Number of errors encountered */
int n; /* Temporarily holds the number of cursors assigned */
sqlite4 *db = pParse->db; /* Database connection for malloc errors */
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
assert( pTable );
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( sqlite4VtabCallConnect(pParse, pTable) ){
return SQLITE_ERROR;
}
if( IsVirtual(pTable) ) return 0;
#endif
#ifndef SQLITE_OMIT_VIEW
/* A positive nCol means the columns names for this view are
** already known.
*/
if( pTable->nCol>0 ) return 0;
/* A negative nCol is a special marker meaning that we are currently
** trying to compute the column names. If we enter this routine with
** a negative nCol, it means two or more views form a loop, like this:
**
** CREATE VIEW one AS SELECT * FROM two;
** CREATE VIEW two AS SELECT * FROM one;
**
** Actually, the error above is now caught prior to reaching this point.
** But the following test is still important as it does come up
** in the following:
**
** CREATE TABLE main.ex1(a);
** CREATE TEMP VIEW ex1 AS SELECT a FROM ex1;
** SELECT * FROM temp.ex1;
*/
if( pTable->nCol<0 ){
sqlite4ErrorMsg(pParse, "view %s is circularly defined", pTable->zName);
return 1;
}
assert( pTable->nCol>=0 );
/* If we get this far, it means we need to compute the table names.
** Note that the call to sqlite4ResultSetOfSelect() will expand any
** "*" elements in the results set of the view and will assign cursors
** to the elements of the FROM clause. But we do not want these changes
** to be permanent. So the computation is done on a copy of the SELECT
** statement that defines the view.
*/
assert( pTable->pSelect );
pSel = sqlite4SelectDup(db, pTable->pSelect, 0);
if( pSel ){
u8 enableLookaside = db->lookaside.bEnabled;
n = pParse->nTab;
sqlite4SrcListAssignCursors(pParse, pSel->pSrc);
pTable->nCol = -1;
db->lookaside.bEnabled = 0;
#ifndef SQLITE_OMIT_AUTHORIZATION
xAuth = db->xAuth;
db->xAuth = 0;
pSelTab = sqlite4ResultSetOfSelect(pParse, pSel);
db->xAuth = xAuth;
#else
pSelTab = sqlite4ResultSetOfSelect(pParse, pSel);
#endif
db->lookaside.bEnabled = enableLookaside;
pParse->nTab = n;
if( pSelTab ){
assert( pTable->aCol==0 );
pTable->nCol = pSelTab->nCol;
pTable->aCol = pSelTab->aCol;
pSelTab->nCol = 0;
pSelTab->aCol = 0;
sqlite4DeleteTable(db, pSelTab);
pTable->pSchema->flags |= DB_UnresetViews;
}else{
pTable->nCol = 0;
nErr++;
}
sqlite4SelectDelete(db, pSel);
} else {
nErr++;
}
#endif /* SQLITE_OMIT_VIEW */
return nErr;
}
#endif /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */
#ifndef SQLITE_OMIT_VIEW
/*
** Clear the column names from every VIEW in database idx.
*/
static void sqliteViewResetAll(sqlite4 *db, int idx){
HashElem *i;
if( !DbHasProperty(db, idx, DB_UnresetViews) ) return;
for(i=sqliteHashFirst(&db->aDb[idx].pSchema->tblHash); i;i=sqliteHashNext(i)){
Table *pTab = sqliteHashData(i);
if( pTab->pSelect ){
sqliteDeleteColumnNames(db, pTab);
pTab->aCol = 0;
pTab->nCol = 0;
}
}
DbClearProperty(db, idx, DB_UnresetViews);
}
#else
# define sqliteViewResetAll(A,B)
#endif /* SQLITE_OMIT_VIEW */
/*
** Write code to erase the table with root-page iTable from database iDb.
** Also write code to modify the sqlite_master table and internal schema
** if a root-page of another table is moved by the btree-layer whilst
** erasing iTable (this can happen with an auto-vacuum database).
*/
static void destroyRootPage(Parse *pParse, int iTable, int iDb){
Vdbe *v = sqlite4GetVdbe(pParse);
sqlite4VdbeAddOp2(v, OP_Clear, iTable, iDb);
#if 0
sqlite4MayAbort(pParse);
#endif
}
/*
** Write VDBE code to erase table pTab and all associated indices on disk.
** Code to update the sqlite_master tables and internal schema definitions
** in case a root-page belonging to another table is moved by the btree layer
** is also added (this can happen with an auto-vacuum database).
*/
static void destroyTable(Parse *pParse, Table *pTab){
Index *pIdx;
int iDb = sqlite4SchemaToIndex(pParse->db, pTab->pSchema);
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
destroyRootPage(pParse, pIdx->tnum, iDb);
}
}
/*
** Remove entries from the sqlite_statN tables (for N in (1,2,3))
** after a DROP INDEX or DROP TABLE command.
*/
static void sqlite4ClearStatTables(
Parse *pParse, /* The parsing context */
int iDb, /* The database number */
const char *zType, /* "idx" or "tbl" */
const char *zName /* Name of index or table */
){
int i;
const char *zDbName = pParse->db->aDb[iDb].zName;
for(i=1; i<=3; i++){
char zTab[24];
sqlite4_snprintf(zTab,sizeof(zTab),"sqlite_stat%d",i);
if( sqlite4FindTable(pParse->db, zTab, zDbName) ){
sqlite4NestedParse(pParse,
"DELETE FROM %Q.%s WHERE %s=%Q",
zDbName, zTab, zType, zName
);
}
}
}
/*
** Generate code to drop a table.
*/
SQLITE_PRIVATE void sqlite4CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){
Vdbe *v;
sqlite4 *db = pParse->db;
Trigger *pTrigger;
Db *pDb = &db->aDb[iDb];
v = sqlite4GetVdbe(pParse);
assert( v!=0 );
sqlite4BeginWriteOperation(pParse, 1, iDb);
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( IsVirtual(pTab) ){
sqlite4VdbeAddOp0(v, OP_VBegin);
}
#endif
/* Drop all triggers associated with the table being dropped. Code
** is generated to remove entries from sqlite_master and/or
** sqlite_temp_master if required.
*/
pTrigger = sqlite4TriggerList(pParse, pTab);
while( pTrigger ){
assert( pTrigger->pSchema==pTab->pSchema ||
pTrigger->pSchema==db->aDb[1].pSchema );
sqlite4DropTriggerPtr(pParse, pTrigger);
pTrigger = pTrigger->pNext;
}
#ifndef SQLITE_OMIT_AUTOINCREMENT
/* Remove any entries of the sqlite_sequence table associated with
** the table being dropped. This is done before the table is dropped
** at the btree level, in case the sqlite_sequence table needs to
** move as a result of the drop (can happen in auto-vacuum mode).
*/
if( pTab->tabFlags & TF_Autoincrement ){
sqlite4NestedParse(pParse,
"DELETE FROM %Q.sqlite_sequence WHERE name=%Q",
pDb->zName, pTab->zName
);
}
#endif
/* Drop all SQLITE_MASTER table and index entries that refer to the
** table. The program name loops through the master table and deletes
** every row that refers to a table of the same name as the one being
** dropped. Triggers are handled seperately because a trigger can be
** created in the temp database that refers to a table in another
** database.
*/
sqlite4NestedParse(pParse,
"DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'",
pDb->zName, SCHEMA_TABLE(iDb), pTab->zName);
if( !isView && !IsVirtual(pTab) ){
destroyTable(pParse, pTab);
}
/* Remove the table entry from SQLite's internal schema and modify
** the schema cookie.
*/
if( IsVirtual(pTab) ){
sqlite4VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0);
}
sqlite4VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);
sqlite4ChangeCookie(pParse, iDb);
sqliteViewResetAll(db, iDb);
}
/*
** This routine is called to do the work of a DROP TABLE statement.
** pName is the name of the table to be dropped.
*/
SQLITE_PRIVATE void sqlite4DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
Table *pTab;
Vdbe *v;
sqlite4 *db = pParse->db;
int iDb;
if( db->mallocFailed ){
goto exit_drop_table;
}
assert( pParse->nErr==0 );
assert( pName->nSrc==1 );
if( noErr ) db->suppressErr++;
pTab = sqlite4LocateTable(pParse, isView,
pName->a[0].zName, pName->a[0].zDatabase);
if( noErr ) db->suppressErr--;
if( pTab==0 ){
if( noErr ) sqlite4CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
goto exit_drop_table;
}
iDb = sqlite4SchemaToIndex(db, pTab->pSchema);
assert( iDb>=0 && iDb<db->nDb );
/* If pTab is a virtual table, call ViewGetColumnNames() to ensure
** it is initialized.
*/
if( IsVirtual(pTab) && sqlite4ViewGetColumnNames(pParse, pTab) ){
goto exit_drop_table;
}
#ifndef SQLITE_OMIT_AUTHORIZATION
{
int code;
const char *zTab = SCHEMA_TABLE(iDb);
const char *zDb = db->aDb[iDb].zName;
const char *zArg2 = 0;
if( sqlite4AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){
goto exit_drop_table;
}
if( isView ){
if( !OMIT_TEMPDB && iDb==1 ){
code = SQLITE_DROP_TEMP_VIEW;
}else{
code = SQLITE_DROP_VIEW;
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
}else if( IsVirtual(pTab) ){
code = SQLITE_DROP_VTABLE;
zArg2 = sqlite4GetVTable(db, pTab)->pMod->zName;
#endif
}else{
if( !OMIT_TEMPDB && iDb==1 ){
code = SQLITE_DROP_TEMP_TABLE;
}else{
code = SQLITE_DROP_TABLE;
}
}
if( sqlite4AuthCheck(pParse, code, pTab->zName, zArg2, zDb) ){
goto exit_drop_table;
}
if( sqlite4AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
goto exit_drop_table;
}
}
#endif
if( sqlite4StrNICmp(pTab->zName, "sqlite_", 7)==0
&& sqlite4StrNICmp(pTab->zName, "sqlite_stat", 11)!=0 ){
sqlite4ErrorMsg(pParse, "table %s may not be dropped", pTab->zName);
goto exit_drop_table;
}
#ifndef SQLITE_OMIT_VIEW
/* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used
** on a table.
*/
if( isView && pTab->pSelect==0 ){
sqlite4ErrorMsg(pParse, "use DROP TABLE to delete table %s", pTab->zName);
goto exit_drop_table;
}
if( !isView && pTab->pSelect ){
sqlite4ErrorMsg(pParse, "use DROP VIEW to delete view %s", pTab->zName);
goto exit_drop_table;
}
#endif
/* Generate code to remove the table from the master table
** on disk.
*/
v = sqlite4GetVdbe(pParse);
if( v ){
sqlite4BeginWriteOperation(pParse, 1, iDb);
sqlite4ClearStatTables(pParse, iDb, "tbl", pTab->zName);
sqlite4FkDropTable(pParse, pName, pTab);
sqlite4CodeDropTable(pParse, pTab, iDb, isView);
}
exit_drop_table:
sqlite4SrcListDelete(db, pName);
}
/*
** This routine is called to create a new foreign key on the table
** currently under construction. pFromCol determines which columns
** in the current table point to the foreign key. If pFromCol==0 then
** connect the key to the last column inserted. pTo is the name of
** the table referred to. pToCol is a list of tables in the other
** pTo table that the foreign key points to. flags contains all
** information about the conflict resolution algorithms specified
** in the ON DELETE, ON UPDATE and ON INSERT clauses.
**
** An FKey structure is created and added to the table currently
** under construction in the pParse->pNewTable field.
**
** The foreign key is set for IMMEDIATE processing. A subsequent call
** to sqlite4DeferForeignKey() might change this to DEFERRED.
*/
SQLITE_PRIVATE void sqlite4CreateForeignKey(
Parse *pParse, /* Parsing context */
ExprList *pFromCol, /* Columns in this table that point to other table */
Token *pTo, /* Name of the other table */
ExprList *pToCol, /* Columns in the other table */
int flags /* Conflict resolution algorithms. */
){
sqlite4 *db = pParse->db;
#ifndef SQLITE_OMIT_FOREIGN_KEY
FKey *pFKey = 0;
FKey *pNextTo;
Table *p = pParse->pNewTable;
int nByte;
int i;
int nCol;
char *z;
assert( pTo!=0 );
if( p==0 || IN_DECLARE_VTAB ) goto fk_end;
if( pFromCol==0 ){
int iCol = p->nCol-1;
if( NEVER(iCol<0) ) goto fk_end;
if( pToCol && pToCol->nExpr!=1 ){
sqlite4ErrorMsg(pParse, "foreign key on %s"
" should reference only one column of table %T",
p->aCol[iCol].zName, pTo);
goto fk_end;
}
nCol = 1;
}else if( pToCol && pToCol->nExpr!=pFromCol->nExpr ){
sqlite4ErrorMsg(pParse,
"number of columns in foreign key does not match the number of "
"columns in the referenced table");
goto fk_end;
}else{
nCol = pFromCol->nExpr;
}
nByte = sizeof(*pFKey) + (nCol-1)*sizeof(pFKey->aCol[0]) + pTo->n + 1;
if( pToCol ){
for(i=0; i<pToCol->nExpr; i++){
nByte += sqlite4Strlen30(pToCol->a[i].zName) + 1;
}
}
pFKey = sqlite4DbMallocZero(db, nByte );
if( pFKey==0 ){
goto fk_end;
}
pFKey->pFrom = p;
pFKey->pNextFrom = p->pFKey;
z = (char*)&pFKey->aCol[nCol];
pFKey->zTo = z;
memcpy(z, pTo->z, pTo->n);
z[pTo->n] = 0;
sqlite4Dequote(z);
z += pTo->n+1;
pFKey->nCol = nCol;
if( pFromCol==0 ){
pFKey->aCol[0].iFrom = p->nCol-1;
}else{
for(i=0; i<nCol; i++){
int j;
for(j=0; j<p->nCol; j++){
if( sqlite4StrICmp(p->aCol[j].zName, pFromCol->a[i].zName)==0 ){
pFKey->aCol[i].iFrom = j;
break;
}
}
if( j>=p->nCol ){
sqlite4ErrorMsg(pParse,
"unknown column \"%s\" in foreign key definition",
pFromCol->a[i].zName);
goto fk_end;
}
}
}
if( pToCol ){
for(i=0; i<nCol; i++){
int n = sqlite4Strlen30(pToCol->a[i].zName);
pFKey->aCol[i].zCol = z;
memcpy(z, pToCol->a[i].zName, n);
z[n] = 0;
z += n+1;
}
}
pFKey->isDeferred = 0;
pFKey->aAction[0] = (u8)(flags & 0xff); /* ON DELETE action */
pFKey->aAction[1] = (u8)((flags >> 8 ) & 0xff); /* ON UPDATE action */
pNextTo = (FKey *)sqlite4HashInsert(&p->pSchema->fkeyHash,
pFKey->zTo, sqlite4Strlen30(pFKey->zTo), (void *)pFKey
);
if( pNextTo==pFKey ){
db->mallocFailed = 1;
goto fk_end;
}
if( pNextTo ){
assert( pNextTo->pPrevTo==0 );
pFKey->pNextTo = pNextTo;
pNextTo->pPrevTo = pFKey;
}
/* Link the foreign key to the table as the last step.
*/
p->pFKey = pFKey;
pFKey = 0;
fk_end:
sqlite4DbFree(db, pFKey);
#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
sqlite4ExprListDelete(db, pFromCol);
sqlite4ExprListDelete(db, pToCol);
}
/*
** This routine is called when an INITIALLY IMMEDIATE or INITIALLY DEFERRED
** clause is seen as part of a foreign key definition. The isDeferred
** parameter is 1 for INITIALLY DEFERRED and 0 for INITIALLY IMMEDIATE.
** The behavior of the most recently created foreign key is adjusted
** accordingly.
*/
SQLITE_PRIVATE void sqlite4DeferForeignKey(Parse *pParse, int isDeferred){
#ifndef SQLITE_OMIT_FOREIGN_KEY
Table *pTab;
FKey *pFKey;
if( (pTab = pParse->pNewTable)==0 || (pFKey = pTab->pFKey)==0 ) return;
assert( isDeferred==0 || isDeferred==1 ); /* EV: R-30323-21917 */
pFKey->isDeferred = (u8)isDeferred;
#endif
}
/*
** Generate code that will erase and refill index *pIdx. This is
** used to initialize a newly created index or to recompute the
** content of an index in response to a REINDEX command.
*/
static void sqlite4RefillIndex(Parse *pParse, Index *pIdx, int bCreate){
Table *pTab = pIdx->pTable; /* The table that is indexed */
int iTab = pParse->nTab++; /* Cursor used for PK of pTab */
int iIdx = pParse->nTab++; /* Cursor used for pIdx */
int addr1; /* Address of top of loop */
Vdbe *v; /* Generate code into this virtual machine */
int regKey; /* Registers containing the index key */
int regRecord; /* Register holding assemblied index record */
sqlite4 *db = pParse->db; /* The database connection */
int iDb = sqlite4SchemaToIndex(db, pIdx->pSchema);
Index *pPk;
#ifndef SQLITE_OMIT_AUTHORIZATION
if( sqlite4AuthCheck(pParse, SQLITE_REINDEX, pIdx->zName, 0,
db->aDb[iDb].zName ) ){
return;
}
#endif
pPk = sqlite4FindPrimaryKey(pTab, 0);
v = sqlite4GetVdbe(pParse);
if( v==0 ) return;
/* A write-lock on the table is required to perform this operation. Easiest
** way to do this is to open a write-cursor on the PK - even though this
** operation only requires read access. */
sqlite4OpenPrimaryKey(pParse, iTab, iDb, pTab, OP_OpenWrite);
/* Delete the current contents (if any) of the index. Then open a write
** cursor on it. */
if( bCreate==0 ){
sqlite4VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb);
}
sqlite4OpenIndex(pParse, iIdx, iDb, pIdx, OP_OpenWrite);
if( bCreate ) sqlite4VdbeChangeP5(v, 1);
/* Loop through the contents of the PK index. At each row, insert the
** corresponding entry into the auxiliary index. */
addr1 = sqlite4VdbeAddOp2(v, OP_Rewind, iTab, 0);
regRecord = sqlite4GetTempRange(pParse,2);
regKey = sqlite4GetTempReg(pParse);
sqlite4EncodeIndexKey(pParse, pPk, iTab, pIdx, iIdx, 0, regKey);
if( pIdx->onError!=OE_None ){
const char *zErr = "indexed columns are not unique";
int addrTest;
addrTest = sqlite4VdbeAddOp4Int(v, OP_IsUnique, iIdx, 0, regKey, 0);
sqlite4HaltConstraint(pParse, OE_Abort, (char *)zErr, P4_STATIC);
sqlite4VdbeJumpHere(v, addrTest);
}
sqlite4VdbeAddOp3(v, OP_IdxInsert, iIdx, 0, regKey);
sqlite4VdbeAddOp2(v, OP_Next, iTab, addr1+1);
sqlite4VdbeJumpHere(v, addr1);
sqlite4ReleaseTempReg(pParse, regKey);
sqlite4VdbeAddOp1(v, OP_Close, iTab);
sqlite4VdbeAddOp1(v, OP_Close, iIdx);
}
/*
** Create a new index for an SQL table. pName1.pName2 is the name of the index
** and pTblList is the name of the table that is to be indexed. Both will
** be NULL for a primary key or an index that is created to satisfy a
** UNIQUE constraint. If pTable and pIndex are NULL, use pParse->pNewTable
** as the table to be indexed. pParse->pNewTable is a table that is
** currently being constructed by a CREATE TABLE statement.
**
** pList is a list of columns to be indexed. pList will be NULL if this
** is a primary key or unique-constraint on the most recent column added
** to the table currently under construction.
**
** If the index is created successfully, return a pointer to the new Index
** structure. This is used by sqlite4AddPrimaryKey() to mark the index
** as the tables primary key (Index.autoIndex==2).
*/
SQLITE_PRIVATE Index *sqlite4CreateIndex(
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 */
SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */
ExprList *pList, /* A list of columns to be indexed */
int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
Token *pStart, /* The CREATE token that begins this statement */
Token *pEnd, /* The ")" that closes the CREATE INDEX statement */
int sortOrder, /* Sort order of primary key when pList==NULL */
int ifNotExist, /* Omit error if index already exists */
int bPrimaryKey /* True to create the tables primary key */
){
Index *pRet = 0; /* Pointer to return */
Table *pTab = 0; /* Table to be indexed */
Index *pIndex = 0; /* The index to be created */
char *zName = 0; /* Name of the index */
int i, j;
Token nullId; /* Fake token for an empty ID list */
DbFixer sFix; /* For assigning database names to pTable */
sqlite4 *db = pParse->db;
Db *pDb; /* The specific table containing the indexed database */
int iDb; /* Index of the database that is being written */
Token *pName = 0; /* Unqualified name of the index to create */
struct ExprList_item *pListItem; /* For looping over pList */
int nExtra = 0;
char *zExtra;
assert( pStart==0 || pEnd!=0 ); /* pEnd must be non-NULL if pStart is */
assert( pParse->nErr==0 ); /* Never called with prior errors */
if( db->mallocFailed || IN_DECLARE_VTAB ){
goto exit_create_index;
}
if( SQLITE_OK!=sqlite4ReadSchema(pParse) ){
goto exit_create_index;
}
/*
** Find the table that is to be indexed. Return early if not found.
*/
if( pTblName!=0 ){
/* Use the two-part index name to determine the database
** to search for the table. 'Fix' the table name to this db
** before looking up the table.
*/
assert( !bPrimaryKey );
assert( pName1 && pName2 );
iDb = sqlite4TwoPartName(pParse, pName1, pName2, &pName);
if( iDb<0 ) goto exit_create_index;
assert( pName && pName->z );
#ifndef SQLITE_OMIT_TEMPDB
/* If the index name was unqualified, check if the the table
** is a temp table. If so, set the database to 1. Do not do this
** if initialising a database schema.
*/
if( !db->init.busy ){
pTab = sqlite4SrcListLookup(pParse, pTblName);
if( pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){
iDb = 1;
}
}
#endif
if( sqlite4FixInit(&sFix, pParse, iDb, "index", pName) &&
sqlite4FixSrcList(&sFix, pTblName)
){
/* Because the parser constructs pTblName from a single identifier,
** sqlite4FixSrcList can never fail. */
assert(0);
}
pTab = sqlite4LocateTable(pParse, 0, pTblName->a[0].zName,
pTblName->a[0].zDatabase);
if( !pTab || db->mallocFailed ) goto exit_create_index;
assert( db->aDb[iDb].pSchema==pTab->pSchema );
}else{
assert( pName==0 );
assert( pStart==0 );
pTab = pParse->pNewTable;
if( !pTab ) goto exit_create_index;
iDb = sqlite4SchemaToIndex(db, pTab->pSchema);
}
pDb = &db->aDb[iDb];
assert( pTab!=0 );
assert( pParse->nErr==0 );
/* TODO: We will need to reinstate this block when sqlite_master is
** modified to use an implicit primary key. */
#if 0
if( sqlite4StrNICmp(pTab->zName, "sqlite_", 7)==0
&& memcmp(&pTab->zName[7],"altertab_",9)!=0 ){
sqlite4ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
goto exit_create_index;
}
#endif
#ifndef SQLITE_OMIT_VIEW
if( pTab->pSelect ){
assert( !bPrimaryKey );
sqlite4ErrorMsg(pParse, "views may not be indexed");
goto exit_create_index;
}
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( IsVirtual(pTab) ){
assert( !bPrimaryKey );
sqlite4ErrorMsg(pParse, "virtual tables may not be indexed");
goto exit_create_index;
}
#endif
/*
** Find the name of the index. Make sure there is not already another
** index or table with the same name.
**
** Exception: If we are reading the names of permanent indices from the
** sqlite_master table (because some other process changed the schema) and
** one of the index names collides with the name of a temporary table or
** index, then we will continue to process this index.
**
** If pName==0 it means that we are
** dealing with a primary key or UNIQUE constraint. We have to invent our
** own name.
*/
if( pName ){
assert( !bPrimaryKey );
zName = sqlite4NameFromToken(db, pName);
if( zName==0 ) goto exit_create_index;
assert( pName->z!=0 );
if( SQLITE_OK!=sqlite4CheckObjectName(pParse, zName) ){
goto exit_create_index;
}
if( !db->init.busy ){
if( sqlite4FindTable(db, zName, 0)!=0 ){
sqlite4ErrorMsg(pParse, "there is already a table named %s", zName);
goto exit_create_index;
}
}
if( sqlite4FindIndex(db, zName, pDb->zName)!=0 ){
if( !ifNotExist ){
sqlite4ErrorMsg(pParse, "index %s already exists", zName);
}else{
assert( !db->init.busy );
sqlite4CodeVerifySchema(pParse, iDb);
}
goto exit_create_index;
}
}else if( !bPrimaryKey ){
int n;
Index *pLoop;
for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){}
zName = sqlite4MPrintf(db, "sqlite_autoindex_%s_%d", pTab->zName, n);
}else{
zName = sqlite4MPrintf(db, "%s", pTab->zName);
}
if( zName==0 ){
goto exit_create_index;
}
/* Check for authorization to create an index.
*/
#ifndef SQLITE_OMIT_AUTHORIZATION
if( bPrimaryKey==0 ){
const char *zDb = pDb->zName;
if( sqlite4AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){
goto exit_create_index;
}
i = SQLITE_CREATE_INDEX;
if( !OMIT_TEMPDB && iDb==1 ) i = SQLITE_CREATE_TEMP_INDEX;
if( sqlite4AuthCheck(pParse, i, zName, pTab->zName, zDb) ){
goto exit_create_index;
}
}
#endif
/* If pList==0, it means this routine was called as a result of a PRIMARY
** KEY or UNIQUE constraint attached to the last column added to the table
** under construction. So create a fake list to simulate this.
**
** TODO: This 'fake list' could be created by the caller to reduce the
** number of parameters passed to this function.
*/
if( pList==0 ){
nullId.z = pTab->aCol[pTab->nCol-1].zName;
nullId.n = sqlite4Strlen30((char*)nullId.z);
pList = sqlite4ExprListAppend(pParse, 0, 0);
if( pList==0 ) goto exit_create_index;
sqlite4ExprListSetName(pParse, pList, &nullId, 0);
pList->a[0].sortOrder = (u8)sortOrder;
}
/* Figure out how many bytes of space are required to store explicitly
** specified collation sequence names.
*/
for(i=0; i<pList->nExpr; i++){
Expr *pExpr = pList->a[i].pExpr;
if( pExpr ){
CollSeq *pColl = pExpr->pColl;
/* Either pColl!=0 or there was an OOM failure. But if an OOM
** failure we have quit before reaching this point. */
if( ALWAYS(pColl) ){
nExtra += (1 + sqlite4Strlen30(pColl->zName));
}
}
}
/* Allocate the new Index structure. */
pIndex = newIndex(pParse, pTab, zName, pList->nExpr, onError, nExtra,&zExtra);
if( !pIndex ) goto exit_create_index;
assert( pIndex->eIndexType==SQLITE_INDEX_USER );
if( pName==0 ){
if( bPrimaryKey ){
pIndex->eIndexType = SQLITE_INDEX_PRIMARYKEY;
}else{
pIndex->eIndexType = SQLITE_INDEX_UNIQUE;
}
}
/* Scan the names of the columns of the table to be indexed and
** load the column indices into the Index structure. Report an error
** if any column is not found.
**
** TODO: Add a test to make sure that the same column is not named
** more than once within the same index. Only the first instance of
** the column will ever be used by the optimizer. Note that using the
** same column more than once cannot be an error because that would
** break backwards compatibility - it needs to be a warning.
*/
for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){
const char *zColName = pListItem->zName;
Column *pTabCol;
char *zColl; /* Collation sequence name */
for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){
if( sqlite4StrICmp(zColName, pTabCol->zName)==0 ) break;
}
if( j>=pTab->nCol ){
sqlite4ErrorMsg(pParse, "table %s has no column named %s",
pTab->zName, zColName);
pParse->checkSchema = 1;
goto exit_create_index;
}
pIndex->aiColumn[i] = j;
/* Justification of the ALWAYS(pListItem->pExpr->pColl): Because of
** the way the "idxlist" non-terminal is constructed by the parser,
** if pListItem->pExpr is not null then either pListItem->pExpr->pColl
** must exist or else there must have been an OOM error. But if there
** was an OOM error, we would never reach this point. */
if( pListItem->pExpr && ALWAYS(pListItem->pExpr->pColl) ){
int nColl;
zColl = pListItem->pExpr->pColl->zName;
nColl = sqlite4Strlen30(zColl) + 1;
assert( nExtra>=nColl );
memcpy(zExtra, zColl, nColl);
zColl = zExtra;
zExtra += nColl;
nExtra -= nColl;
}else{
zColl = pTab->aCol[j].zColl;
if( !zColl ){
zColl = db->pDfltColl->zName;
}
}
if( !db->init.busy && !sqlite4LocateCollSeq(pParse, zColl) ){
goto exit_create_index;
}
pIndex->azColl[i] = zColl;
pIndex->aSortOrder[i] = (u8)pListItem->sortOrder;
}
sqlite4DefaultRowEst(pIndex);
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
** a PRIMARY KEY or UNIQUE clause following the column definitions.
** i.e. one of:
**
** CREATE TABLE t(x PRIMARY KEY, y);
** CREATE TABLE t(x, y, UNIQUE(x, y));
**
** Either way, check to see if the table already has such an index. If
** so, don't bother creating this one. This only applies to
** automatically created indices. Users can do as they wish with
** explicit indices.
**
** Two UNIQUE or PRIMARY KEY constraints are considered equivalent
** (and thus suppressing the second one) even if they have different
** sort orders.
**
** If there are different collating sequences or if the columns of
** the constraint occur in different orders, then the constraints are
** considered distinct and both result in separate indices.
*/
Index *pIdx;
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
int k;
assert( pIdx->onError!=OE_None );
assert( pIdx->eIndexType!=SQLITE_INDEX_USER );
assert( pIndex->onError!=OE_None );
if( pIdx->nColumn!=pIndex->nColumn ) continue;
for(k=0; k<pIdx->nColumn; k++){
const char *z1;
const char *z2;
if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
z1 = pIdx->azColl[k];
z2 = pIndex->azColl[k];
if( z1!=z2 && sqlite4StrICmp(z1, z2) ) break;
}
if( k==pIdx->nColumn ){
if( pIdx->onError!=pIndex->onError ){
/* This constraint creates the same index as a previous
** constraint specified somewhere in the CREATE TABLE statement.
** However the ON CONFLICT clauses are different. If both this
** constraint and the previous equivalent constraint have explicit
** ON CONFLICT clauses this is an error. Otherwise, use the
** explicitly specified behaviour for the index.
*/
if( !(pIdx->onError==OE_Default || pIndex->onError==OE_Default) ){
sqlite4ErrorMsg(pParse,
"conflicting ON CONFLICT clauses specified", 0);
}
if( pIdx->onError==OE_Default ){
pIdx->onError = pIndex->onError;
}
}
/* If this index was to be the PRIMARY KEY, mark the UNIQUE index
** that makes it redundant as the PRIMARY KEY instead. */
if( bPrimaryKey ){
assert( pIdx->eIndexType==SQLITE_INDEX_UNIQUE );
pIdx->eIndexType = SQLITE_INDEX_PRIMARYKEY;
}
goto exit_create_index;
}
}
}
/* Link the new Index structure to its table and to the other
** in-memory database structures.
*/
if( db->init.busy ){
db->flags |= SQLITE_InternChanges;
if( pTblName!=0 || bPrimaryKey ){
pIndex->tnum = db->init.newTnum;
}
}
/* If the db->init.busy is 0 then create the index on disk. This
** involves writing the index into the master table and filling in the
** index with the current table contents.
**
** The db->init.busy is 0 when the user first enters a CREATE INDEX
** command. db->init.busy is 1 when a database is opened and
** CREATE INDEX statements are read out of the master table. In
** the latter case the index already exists on disk, which is why
** we don't want to recreate it.
**
** If pTblName==0 it means this index is generated as a primary key
** or UNIQUE constraint of a CREATE TABLE statement. Since the table
** has just been created, it contains no data and the index initialization
** step can be skipped.
*/
else{
pIndex->tnum = ++pParse->nMem;
allocateTableNumber(pParse, iDb, pIndex->tnum);
if( bPrimaryKey==0 ){
Vdbe *v;
char *zStmt;
v = sqlite4GetVdbe(pParse);
if( v==0 ) goto exit_create_index;
/* Create the rootpage for the index
*/
sqlite4BeginWriteOperation(pParse, 1, iDb);
/* Gather the complete text of the CREATE INDEX statement into
** the zStmt variable
*/
if( pStart ){
assert( pEnd!=0 );
/* A named index with an explicit CREATE INDEX statement */
zStmt = sqlite4MPrintf(db, "CREATE%s INDEX %.*s",
onError==OE_None ? "" : " UNIQUE",
(int)(pEnd->z - pName->z) + 1,
pName->z);
}else{
/* An automatic index created by a PRIMARY KEY or UNIQUE constraint */
/* zStmt = sqlite4MPrintf(""); */
zStmt = 0;
}
/* Add an entry in sqlite_master for this index
*/
sqlite4NestedParse(pParse,
"INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);",
db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
pIndex->zName,
pTab->zName,
pIndex->tnum,
zStmt
);
sqlite4DbFree(db, zStmt);
/* Fill the index with data and reparse the schema. Code an OP_Expire
** to invalidate all pre-compiled statements.
*/
if( pTblName ){
sqlite4RefillIndex(pParse, pIndex, 1);
sqlite4ChangeCookie(pParse, iDb);
sqlite4VdbeAddParseSchemaOp(v, iDb,
sqlite4MPrintf(db, "name='%q' AND type='index'", pIndex->zName));
sqlite4VdbeAddOp1(v, OP_Expire, 0);
}
}
}
/* When adding an index to the list of indices for a table, make
** sure all indices labeled OE_Replace come after all those labeled
** OE_Ignore. This is necessary for the correct constraint check
** processing (in sqlite4GenerateConstraintChecks()) as part of
** UPDATE and INSERT statements.
*/
if( db->init.busy || pTblName==0 ){
if( onError!=OE_Replace || pTab->pIndex==0
|| pTab->pIndex->onError==OE_Replace){
pIndex->pNext = pTab->pIndex;
pTab->pIndex = pIndex;
}else{
Index *pOther = pTab->pIndex;
while( pOther->pNext && pOther->pNext->onError!=OE_Replace ){
pOther = pOther->pNext;
}
pIndex->pNext = pOther->pNext;
pOther->pNext = pIndex;
}
pRet = pIndex;
pIndex = 0;
}
/* Clean up before exiting */
exit_create_index:
if( pIndex ){
sqlite4DbFree(db, pIndex->zColAff);
sqlite4DbFree(db, pIndex);
}
sqlite4ExprListDelete(db, pList);
sqlite4SrcListDelete(db, pTblName);
sqlite4DbFree(db, zName);
return pRet;
}
/*
** Fill the Index.aiRowEst[] array with default information - information
** to be used when we have not run the ANALYZE command.
**
** aiRowEst[0] is suppose to contain the number of elements in the index.
** Since we do not know, guess 1 million. aiRowEst[1] is an estimate of the
** number of rows in the table that match any particular value of the
** first column of the index. aiRowEst[2] is an estimate of the number
** of rows that match any particular combiniation of the first 2 columns
** of the index. And so forth. It must always be the case that
**
** aiRowEst[N]<=aiRowEst[N-1]
** aiRowEst[N]>=1
**
** Apart from that, we have little to go on besides intuition as to
** how aiRowEst[] should be initialized. The numbers generated here
** are based on typical values found in actual indices.
*/
SQLITE_PRIVATE void sqlite4DefaultRowEst(Index *pIdx){
tRowcnt *a = pIdx->aiRowEst;
int i;
tRowcnt n;
assert( a!=0 );
a[0] = pIdx->pTable->nRowEst;
if( a[0]<10 ) a[0] = 10;
n = 10;
for(i=1; i<=pIdx->nColumn; i++){
a[i] = n;
if( n>5 ) n--;
}
if( pIdx->onError!=OE_None ){
a[pIdx->nColumn] = 1;
}
}
/*
** This routine will drop an existing named index. This routine
** implements the DROP INDEX statement.
*/
SQLITE_PRIVATE void sqlite4DropIndex(Parse *pParse, SrcList *pName, int ifExists){
Index *pIndex;
Vdbe *v;
sqlite4 *db = pParse->db;
int iDb;
assert( pParse->nErr==0 ); /* Never called with prior errors */
if( db->mallocFailed ){
goto exit_drop_index;
}
assert( pName->nSrc==1 );
if( SQLITE_OK!=sqlite4ReadSchema(pParse) ){
goto exit_drop_index;
}
pIndex = sqlite4FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
if( pIndex==0 ){
if( !ifExists ){
sqlite4ErrorMsg(pParse, "no such index: %S", pName, 0);
}else{
sqlite4CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
}
pParse->checkSchema = 1;
goto exit_drop_index;
}
if( pIndex->eIndexType!=SQLITE_INDEX_USER ){
sqlite4ErrorMsg(pParse, "index associated with UNIQUE "
"or PRIMARY KEY constraint cannot be dropped", 0);
goto exit_drop_index;
}
iDb = sqlite4SchemaToIndex(db, pIndex->pSchema);
#ifndef SQLITE_OMIT_AUTHORIZATION
{
int code = SQLITE_DROP_INDEX;
Table *pTab = pIndex->pTable;
const char *zDb = db->aDb[iDb].zName;
const char *zTab = SCHEMA_TABLE(iDb);
if( sqlite4AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
goto exit_drop_index;
}
if( !OMIT_TEMPDB && iDb ) code = SQLITE_DROP_TEMP_INDEX;
if( sqlite4AuthCheck(pParse, code, pIndex->zName, pTab->zName, zDb) ){
goto exit_drop_index;
}
}
#endif
/* Generate code to remove the index and from the master table */
v = sqlite4GetVdbe(pParse);
if( v ){
sqlite4BeginWriteOperation(pParse, 1, iDb);
sqlite4NestedParse(pParse,
"DELETE FROM %Q.%s WHERE name=%Q AND type='index'",
db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pIndex->zName
);
sqlite4ClearStatTables(pParse, iDb, "idx", pIndex->zName);
sqlite4ChangeCookie(pParse, iDb);
destroyRootPage(pParse, pIndex->tnum, iDb);
sqlite4VdbeAddOp4(v, OP_DropIndex, iDb, 0, 0, pIndex->zName, 0);
}
exit_drop_index:
sqlite4SrcListDelete(db, pName);
}
/*
** pArray is a pointer to an array of objects. Each object in the
** array is szEntry bytes in size. This routine allocates a new
** object on the end of the array.
**
** *pnEntry is the number of entries already in use. *pnAlloc is
** the previously allocated size of the array. initSize is the
** suggested initial array size allocation.
**
** The index of the new entry is returned in *pIdx.
**
** This routine returns a pointer to the array of objects. This
** might be the same as the pArray parameter or it might be a different
** pointer if the array was resized.
*/
SQLITE_PRIVATE void *sqlite4ArrayAllocate(
sqlite4 *db, /* Connection to notify of malloc failures */
void *pArray, /* Array of objects. Might be reallocated */
int szEntry, /* Size of each object in the array */
int initSize, /* Suggested initial allocation, in elements */
int *pnEntry, /* Number of objects currently in use */
int *pnAlloc, /* Current size of the allocation, in elements */
int *pIdx /* Write the index of a new slot here */
){
char *z;
if( *pnEntry >= *pnAlloc ){
void *pNew;
int newSize;
newSize = (*pnAlloc)*2 + initSize;
pNew = sqlite4DbRealloc(db, pArray, newSize*szEntry);
if( pNew==0 ){
*pIdx = -1;
return pArray;
}
*pnAlloc = sqlite4DbMallocSize(db, pNew)/szEntry;
pArray = pNew;
}
z = (char*)pArray;
memset(&z[*pnEntry * szEntry], 0, szEntry);
*pIdx = *pnEntry;
++*pnEntry;
return pArray;
}
/*
** Append a new element to the given IdList. Create a new IdList if
** need be.
**
** A new IdList is returned, or NULL if malloc() fails.
*/
SQLITE_PRIVATE IdList *sqlite4IdListAppend(sqlite4 *db, IdList *pList, Token *pToken){
int i;
if( pList==0 ){
pList = sqlite4DbMallocZero(db, sizeof(IdList) );
if( pList==0 ) return 0;
pList->nAlloc = 0;
}
pList->a = sqlite4ArrayAllocate(
db,
pList->a,
sizeof(pList->a[0]),
5,
&pList->nId,
&pList->nAlloc,
&i
);
if( i<0 ){
sqlite4IdListDelete(db, pList);
return 0;
}
pList->a[i].zName = sqlite4NameFromToken(db, pToken);
return pList;
}
/*
** Delete an IdList.
*/
SQLITE_PRIVATE void sqlite4IdListDelete(sqlite4 *db, IdList *pList){
int i;
if( pList==0 ) return;
for(i=0; i<pList->nId; i++){
sqlite4DbFree(db, pList->a[i].zName);
}
sqlite4DbFree(db, pList->a);
sqlite4DbFree(db, pList);
}
/*
** Return the index in pList of the identifier named zId. Return -1
** if not found.
*/
SQLITE_PRIVATE int sqlite4IdListIndex(IdList *pList, const char *zName){
int i;
if( pList==0 ) return -1;
for(i=0; i<pList->nId; i++){
if( sqlite4StrICmp(pList->a[i].zName, zName)==0 ) return i;
}
return -1;
}
/*
** Expand the space allocated for the given SrcList object by
** creating nExtra new slots beginning at iStart. iStart is zero based.
** New slots are zeroed.
**
** For example, suppose a SrcList initially contains two entries: A,B.
** To append 3 new entries onto the end, do this:
**
** sqlite4SrcListEnlarge(db, pSrclist, 3, 2);
**
** After the call above it would contain: A, B, nil, nil, nil.
** If the iStart argument had been 1 instead of 2, then the result
** would have been: A, nil, nil, nil, B. To prepend the new slots,
** the iStart value would be 0. The result then would
** be: nil, nil, nil, A, B.
**
** If a memory allocation fails the SrcList is unchanged. The
** db->mallocFailed flag will be set to true.
*/
SQLITE_PRIVATE SrcList *sqlite4SrcListEnlarge(
sqlite4 *db, /* Database connection to notify of OOM errors */
SrcList *pSrc, /* The SrcList to be enlarged */
int nExtra, /* Number of new slots to add to pSrc->a[] */
int iStart /* Index in pSrc->a[] of first new slot */
){
int i;
/* Sanity checking on calling parameters */
assert( iStart>=0 );
assert( nExtra>=1 );
assert( pSrc!=0 );
assert( iStart<=pSrc->nSrc );
/* Allocate additional space if needed */
if( pSrc->nSrc+nExtra>pSrc->nAlloc ){
SrcList *pNew;
int nAlloc = pSrc->nSrc+nExtra;
int nGot;
pNew = sqlite4DbRealloc(db, pSrc,
sizeof(*pSrc) + (nAlloc-1)*sizeof(pSrc->a[0]) );
if( pNew==0 ){
assert( db->mallocFailed );
return pSrc;
}
pSrc = pNew;
nGot = (sqlite4DbMallocSize(db, pNew) - sizeof(*pSrc))/sizeof(pSrc->a[0])+1;
pSrc->nAlloc = (u16)nGot;
}
/* Move existing slots that come after the newly inserted slots
** out of the way */
for(i=pSrc->nSrc-1; i>=iStart; i--){
pSrc->a[i+nExtra] = pSrc->a[i];
}
pSrc->nSrc += (i16)nExtra;
/* Zero the newly allocated slots */
memset(&pSrc->a[iStart], 0, sizeof(pSrc->a[0])*nExtra);
for(i=iStart; i<iStart+nExtra; i++){
pSrc->a[i].iCursor = -1;
}
/* Return a pointer to the enlarged SrcList */
return pSrc;
}
/*
** Append a new table name to the given SrcList. Create a new SrcList if
** need be. A new entry is created in the SrcList even if pTable is NULL.
**
** A SrcList is returned, or NULL if there is an OOM error. The returned
** SrcList might be the same as the SrcList that was input or it might be
** a new one. If an OOM error does occurs, then the prior value of pList
** that is input to this routine is automatically freed.
**
** If pDatabase is not null, it means that the table has an optional
** database name prefix. Like this: "database.table". The pDatabase
** points to the table name and the pTable points to the database name.
** The SrcList.a[].zName field is filled with the table name which might
** come from pTable (if pDatabase is NULL) or from pDatabase.
** SrcList.a[].zDatabase is filled with the database name from pTable,
** or with NULL if no database is specified.
**
** In other words, if call like this:
**
** sqlite4SrcListAppend(D,A,B,0);
**
** Then B is a table name and the database name is unspecified. If called
** like this:
**
** sqlite4SrcListAppend(D,A,B,C);
**
** Then C is the table name and B is the database name. If C is defined
** then so is B. In other words, we never have a case where:
**
** sqlite4SrcListAppend(D,A,0,C);
**
** Both pTable and pDatabase are assumed to be quoted. They are dequoted
** before being added to the SrcList.
*/
SQLITE_PRIVATE SrcList *sqlite4SrcListAppend(
sqlite4 *db, /* Connection to notify of malloc failures */
SrcList *pList, /* Append to this SrcList. NULL creates a new SrcList */
Token *pTable, /* Table to append */
Token *pDatabase /* Database of the table */
){
struct SrcList_item *pItem;
assert( pDatabase==0 || pTable!=0 ); /* Cannot have C without B */
if( pList==0 ){
pList = sqlite4DbMallocZero(db, sizeof(SrcList) );
if( pList==0 ) return 0;
pList->nAlloc = 1;
}
pList = sqlite4SrcListEnlarge(db, pList, 1, pList->nSrc);
if( db->mallocFailed ){
sqlite4SrcListDelete(db, pList);
return 0;
}
pItem = &pList->a[pList->nSrc-1];
if( pDatabase && pDatabase->z==0 ){
pDatabase = 0;
}
if( pDatabase ){
Token *pTemp = pDatabase;
pDatabase = pTable;
pTable = pTemp;
}
pItem->zName = sqlite4NameFromToken(db, pTable);
pItem->zDatabase = sqlite4NameFromToken(db, pDatabase);
return pList;
}
/*
** Assign VdbeCursor index numbers to all tables in a SrcList
*/
SQLITE_PRIVATE void sqlite4SrcListAssignCursors(Parse *pParse, SrcList *pList){
int i;
struct SrcList_item *pItem;
assert(pList || pParse->db->mallocFailed );
if( pList ){
for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
if( pItem->iCursor>=0 ) break;
pItem->iCursor = pParse->nTab++;
if( pItem->pSelect ){
sqlite4SrcListAssignCursors(pParse, pItem->pSelect->pSrc);
}
}
}
}
/*
** Delete an entire SrcList including all its substructure.
*/
SQLITE_PRIVATE void sqlite4SrcListDelete(sqlite4 *db, SrcList *pList){
int i;
struct SrcList_item *pItem;
if( pList==0 ) return;
for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){
sqlite4DbFree(db, pItem->zDatabase);
sqlite4DbFree(db, pItem->zName);
sqlite4DbFree(db, pItem->zAlias);
sqlite4DbFree(db, pItem->zIndex);
sqlite4DeleteTable(db, pItem->pTab);
sqlite4SelectDelete(db, pItem->pSelect);
sqlite4ExprDelete(db, pItem->pOn);
sqlite4IdListDelete(db, pItem->pUsing);
}
sqlite4DbFree(db, pList);
}
/*
** This routine is called by the parser to add a new term to the
** end of a growing FROM clause. The "p" parameter is the part of
** the FROM clause that has already been constructed. "p" is NULL
** if this is the first term of the FROM clause. pTable and pDatabase
** are the name of the table and database named in the FROM clause term.
** pDatabase is NULL if the database name qualifier is missing - the
** usual case. If the term has a alias, then pAlias points to the
** alias token. If the term is a subquery, then pSubquery is the
** SELECT statement that the subquery encodes. The pTable and
** pDatabase parameters are NULL for subqueries. The pOn and pUsing
** parameters are the content of the ON and USING clauses.
**
** Return a new SrcList which encodes is the FROM with the new
** term added.
*/
SQLITE_PRIVATE SrcList *sqlite4SrcListAppendFromTerm(
Parse *pParse, /* Parsing context */
SrcList *p, /* The left part of the FROM clause already seen */
Token *pTable, /* Name of the table to add to the FROM clause */
Token *pDatabase, /* Name of the database containing pTable */
Token *pAlias, /* The right-hand side of the AS subexpression */
Select *pSubquery, /* A subquery used in place of a table name */
Expr *pOn, /* The ON clause of a join */
IdList *pUsing /* The USING clause of a join */
){
struct SrcList_item *pItem;
sqlite4 *db = pParse->db;
if( !p && (pOn || pUsing) ){
sqlite4ErrorMsg(pParse, "a JOIN clause is required before %s",
(pOn ? "ON" : "USING")
);
goto append_from_error;
}
p = sqlite4SrcListAppend(db, p, pTable, pDatabase);
if( p==0 || NEVER(p->nSrc==0) ){
goto append_from_error;
}
pItem = &p->a[p->nSrc-1];
assert( pAlias!=0 );
if( pAlias->n ){
pItem->zAlias = sqlite4NameFromToken(db, pAlias);
}
pItem->pSelect = pSubquery;
pItem->pOn = pOn;
pItem->pUsing = pUsing;
return p;
append_from_error:
assert( p==0 );
sqlite4ExprDelete(db, pOn);
sqlite4IdListDelete(db, pUsing);
sqlite4SelectDelete(db, pSubquery);
return 0;
}
/*
** Add an INDEXED BY or NOT INDEXED clause to the most recently added
** element of the source-list passed as the second argument.
*/
SQLITE_PRIVATE void sqlite4SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){
assert( pIndexedBy!=0 );
if( p && ALWAYS(p->nSrc>0) ){
struct SrcList_item *pItem = &p->a[p->nSrc-1];
assert( pItem->notIndexed==0 && pItem->zIndex==0 );
if( pIndexedBy->n==1 && !pIndexedBy->z ){
/* A "NOT INDEXED" clause was supplied. See parse.y
** construct "indexed_opt" for details. */
pItem->notIndexed = 1;
}else{
pItem->zIndex = sqlite4NameFromToken(pParse->db, pIndexedBy);
}
}
}
/*
** 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
** Shifts all join operators from left to right for an entire FROM
** clause.
**
** Example: Suppose the join is like this:
**
** A natural cross join B
**
** The operator is "natural cross join". The A and B operands are stored
** in p->a[0] and p->a[1], respectively. The parser initially stores the
** operator with A. This routine shifts that operator over to B.
*/
SQLITE_PRIVATE void sqlite4SrcListShiftJoinType(SrcList *p){
if( p ){
int i;
assert( p->a || p->nSrc==0 );
for(i=p->nSrc-1; i>0; i--){
p->a[i].jointype = p->a[i-1].jointype;
}
p->a[0].jointype = 0;
}
}
/*
** Begin a transaction
*/
SQLITE_PRIVATE void sqlite4BeginTransaction(Parse *pParse, int type){
sqlite4 *db;
Vdbe *v;
int i;
assert( pParse!=0 );
db = pParse->db;
assert( db!=0 );
if( sqlite4AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ){
return;
}
v = sqlite4GetVdbe(pParse);
if( !v ) return;
if( type!=TK_DEFERRED ){
for(i=0; i<db->nDb; i++){
sqlite4VdbeAddOp2(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1);
sqlite4VdbeUsesStorage(v, i);
}
}
sqlite4VdbeAddOp1(v, OP_Savepoint, SAVEPOINT_BEGIN);
}
/*
** Write VDBE code for either a "COMMIT" or "ROLLBACK" statement.
**
** For COMMIT, the second argument should be SAVEPOINT_RELEASE. For a
** ROLLBACK, the second argument to this function should be
** SAVEPOINT_ROLLBACK.
*/
SQLITE_PRIVATE void sqlite4EndTransaction(Parse *pParse, int op){
Vdbe *v;
/* Invoke the authorization callback */
#ifndef SQLITE_OMIT_AUTHORIZATION
const char *azCmd[] = { "COMMIT", "ROLLBACK" };
assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK );
assert( SAVEPOINT_RELEASE==1 && SAVEPOINT_ROLLBACK==2 );
if( sqlite4AuthCheck(pParse, SQLITE_TRANSACTION, azCmd[op-1], 0, 0) ) return;
#endif
/* Code the OP_Savepoint instruction. */
v = sqlite4GetVdbe(pParse);
if( v ) sqlite4VdbeAddOp1(v, OP_Savepoint, op);
}
/*
** This function is called by the parser when it parses a command to create,
** release or rollback an SQL savepoint.
*/
SQLITE_PRIVATE void sqlite4Savepoint(Parse *pParse, int op, Token *pName){
char *zName = sqlite4NameFromToken(pParse->db, pName);
if( zName ){
Vdbe *v = sqlite4GetVdbe(pParse);
#ifndef SQLITE_OMIT_AUTHORIZATION
static const char * const az[] = { "BEGIN", "RELEASE", "ROLLBACK" };
assert( !SAVEPOINT_BEGIN && SAVEPOINT_RELEASE==1 && SAVEPOINT_ROLLBACK==2 );
#endif
if( !v || sqlite4AuthCheck(pParse, SQLITE_SAVEPOINT, az[op], zName, 0) ){
sqlite4DbFree(pParse->db, zName);
return;
}
sqlite4VdbeAddOp4(v, OP_Savepoint, op, 0, 0, zName, P4_DYNAMIC);
}
}
/*
** Make sure the TEMP database is open and available for use. Return
** the number of errors. Leave any error messages in the pParse structure.
*/
SQLITE_PRIVATE int sqlite4OpenTempDatabase(Parse *pParse){
sqlite4 *db = pParse->db;
if( db->aDb[1].pKV==0 && !pParse->explain ){
int rc;
rc = sqlite4KVStoreOpen(db, "temp", ":memory:", &db->aDb[1].pKV,
SQLITE_KVOPEN_TEMPORARY);
if( rc!=SQLITE_OK ){
sqlite4ErrorMsg(pParse, "unable to open a temporary database "
"file for storing temporary tables");
pParse->rc = rc;
return 1;
}
assert( db->aDb[1].pSchema );
}
return 0;
}
/*
** Generate VDBE code that will verify the schema cookie and start
** a read-transaction for all named database files.
**
** It is important that all schema cookies be verified and all
** read transactions be started before anything else happens in
** the VDBE program. But this routine can be called after much other
** code has been generated. So here is what we do:
**
** The first time this routine is called, we code an OP_Goto that
** will jump to a subroutine at the end of the program. Then we
** record every database that needs its schema verified in the
** pParse->cookieMask field. Later, after all other code has been
** generated, the subroutine that does the cookie verifications and
** starts the transactions will be coded and the OP_Goto P2 value
** will be made to point to that subroutine. The generation of the
** cookie verification subroutine code happens in sqlite4FinishCoding().
**
** If iDb<0 then code the OP_Goto only - don't set flag to verify the
** schema on any databases. This can be used to position the OP_Goto
** early in the code, before we know if any database tables will be used.
*/
SQLITE_PRIVATE void sqlite4CodeVerifySchema(Parse *pParse, int iDb){
Parse *pToplevel = sqlite4ParseToplevel(pParse);
if( pToplevel->cookieGoto==0 ){
Vdbe *v = sqlite4GetVdbe(pToplevel);
if( v==0 ) return; /* This only happens if there was a prior error */
pToplevel->cookieGoto = sqlite4VdbeAddOp2(v, OP_Goto, 0, 0)+1;
}
if( iDb>=0 ){
sqlite4 *db = pToplevel->db;
yDbMask mask;
assert( iDb<db->nDb );
assert( db->aDb[iDb].pKV!=0 || iDb==1 );
assert( iDb<SQLITE_MAX_ATTACHED+2 );
mask = ((yDbMask)1)<<iDb;
if( (pToplevel->cookieMask & mask)==0 ){
pToplevel->cookieMask |= mask;
pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
if( !OMIT_TEMPDB && iDb==1 ){
sqlite4OpenTempDatabase(pToplevel);
}
}
}
}
/*
** If argument zDb is NULL, then call sqlite4CodeVerifySchema() for each
** attached database. Otherwise, invoke it for the database named zDb only.
*/
SQLITE_PRIVATE void sqlite4CodeVerifyNamedSchema(Parse *pParse, const char *zDb){
sqlite4 *db = pParse->db;
int i;
for(i=0; i<db->nDb; i++){
Db *pDb = &db->aDb[i];
if( pDb->pKV && (!zDb || 0==sqlite4StrICmp(zDb, pDb->zName)) ){
sqlite4CodeVerifySchema(pParse, i);
}
}
}
/*
** Generate VDBE code that prepares for doing an operation that
** might change the database.
**
** This routine starts a new transaction if we are not already within
** a transaction. If we are already within a transaction, then a checkpoint
** is set if the setStatement parameter is true. A checkpoint should
** be set for operations that might fail (due to a constraint) part of
** the way through and which will need to undo some writes without having to
** rollback the whole transaction. For operations where all constraints
** can be checked before any changes are made to the database, it is never
** necessary to undo a write and the checkpoint should not be set.
*/
SQLITE_PRIVATE void sqlite4BeginWriteOperation(Parse *pParse, int setStatement, int iDb){
Parse *pToplevel = sqlite4ParseToplevel(pParse);
sqlite4CodeVerifySchema(pParse, iDb);
pToplevel->writeMask |= ((yDbMask)1)<<iDb;
pToplevel->isMultiWrite |= setStatement;
}
/*
** Indicate that the statement currently under construction might write
** more than one entry (example: deleting one row then inserting another,
** inserting multiple rows in a table, or inserting a row and index entries.)
** If an abort occurs after some of these writes have completed, then it will
** be necessary to undo the completed writes.
*/
SQLITE_PRIVATE void sqlite4MultiWrite(Parse *pParse){
Parse *pToplevel = sqlite4ParseToplevel(pParse);
pToplevel->isMultiWrite = 1;
}
/*
** The code generator calls this routine if is discovers that it is
** possible to abort a statement prior to completion. In order to
** perform this abort without corrupting the database, we need to make
** sure that the statement is protected by a statement transaction.
**
** Technically, we only need to set the mayAbort flag if the
** isMultiWrite flag was previously set. There is a time dependency
** such that the abort must occur after the multiwrite. This makes
** some statements involving the REPLACE conflict resolution algorithm
** go a little faster. But taking advantage of this time dependency
** makes it more difficult to prove that the code is correct (in
** particular, it prevents us from writing an effective
** implementation of sqlite4AssertMayAbort()) and so we have chosen
** to take the safe route and skip the optimization.
*/
SQLITE_PRIVATE void sqlite4MayAbort(Parse *pParse){
Parse *pToplevel = sqlite4ParseToplevel(pParse);
pToplevel->mayAbort = 1;
}
/*
** Code an OP_Halt that causes the vdbe to return an SQLITE_CONSTRAINT
** error. The onError parameter determines which (if any) of the statement
** and/or current transaction is rolled back.
*/
SQLITE_PRIVATE void sqlite4HaltConstraint(Parse *pParse, int onError, char *p4, int p4type){
Vdbe *v = sqlite4GetVdbe(pParse);
if( onError==OE_Abort ){
sqlite4MayAbort(pParse);
}
sqlite4VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0, p4, p4type);
}
/*
** Check to see if pIndex uses the collating sequence pColl. Return
** true if it does and false if it does not.
*/
#ifndef SQLITE_OMIT_REINDEX
static int collationMatch(const char *zColl, Index *pIndex){
int i;
assert( zColl!=0 );
for(i=0; i<pIndex->nColumn; i++){
const char *z = pIndex->azColl[i];
assert( z!=0 );
if( 0==sqlite4StrICmp(z, zColl) ){
return 1;
}
}
return 0;
}
#endif
/*
** Recompute all indices of pTab that use the collating sequence pColl.
** If pColl==0 then recompute all indices of pTab.
*/
#ifndef SQLITE_OMIT_REINDEX
static void reindexTable(Parse *pParse, Table *pTab, char const *zColl){
Index *pIndex; /* An index associated with pTab */
for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){
if( pIndex->eIndexType==SQLITE_INDEX_PRIMARYKEY ) continue;
if( zColl==0 || collationMatch(zColl, pIndex) ){
int iDb = sqlite4SchemaToIndex(pParse->db, pTab->pSchema);
sqlite4BeginWriteOperation(pParse, 0, iDb);
sqlite4RefillIndex(pParse, pIndex, 0);
}
}
}
#endif
/*
** Recompute all indices of all tables in all databases where the
** indices use the collating sequence pColl. If pColl==0 then recompute
** all indices everywhere.
*/
#ifndef SQLITE_OMIT_REINDEX
static void reindexDatabases(Parse *pParse, char const *zColl){
Db *pDb; /* A single database */
int iDb; /* The database index number */
sqlite4 *db = pParse->db; /* The database connection */
HashElem *k; /* For looping over tables in pDb */
Table *pTab; /* A table in the database */
for(iDb=0, pDb=db->aDb; iDb<db->nDb; iDb++, pDb++){
assert( pDb!=0 );
for(k=sqliteHashFirst(&pDb->pSchema->tblHash); k; k=sqliteHashNext(k)){
pTab = (Table*)sqliteHashData(k);
reindexTable(pParse, pTab, zColl);
}
}
}
#endif
/*
** Generate code for the REINDEX command.
**
** REINDEX -- 1
** REINDEX <collation> -- 2
** REINDEX ?<database>.?<tablename> -- 3
** REINDEX ?<database>.?<indexname> -- 4
**
** Form 1 causes all indices in all attached databases to be rebuilt.
** Form 2 rebuilds all indices in all databases that use the named
** collating function. Forms 3 and 4 rebuild the named index or all
** indices associated with the named table.
*/
#ifndef SQLITE_OMIT_REINDEX
SQLITE_PRIVATE void sqlite4Reindex(Parse *pParse, Token *pName1, Token *pName2){
CollSeq *pColl; /* Collating sequence to be reindexed, or NULL */
char *z; /* Name of a table or index */
const char *zDb; /* Name of the database */
Table *pTab; /* A table in the database */
Index *pIndex; /* An index associated with pTab */
int iDb; /* The database index number */
sqlite4 *db = pParse->db; /* The database connection */
Token *pObjName; /* Name of the table or index to be reindexed */
/* Read the database schema. If an error occurs, leave an error message
** and code in pParse and return NULL. */
if( SQLITE_OK!=sqlite4ReadSchema(pParse) ){
return;
}
if( pName1==0 ){
reindexDatabases(pParse, 0);
return;
}else if( NEVER(pName2==0) || pName2->z==0 ){
char *zColl;
assert( pName1->z );
zColl = sqlite4NameFromToken(pParse->db, pName1);
if( !zColl ) return;
pColl = sqlite4FindCollSeq(db, ENC(db), zColl, 0);
if( pColl ){
reindexDatabases(pParse, zColl);
sqlite4DbFree(db, zColl);
return;
}
sqlite4DbFree(db, zColl);
}
iDb = sqlite4TwoPartName(pParse, pName1, pName2, &pObjName);
if( iDb<0 ) return;
z = sqlite4NameFromToken(db, pObjName);
if( z==0 ) return;
zDb = db->aDb[iDb].zName;
pTab = sqlite4FindTable(db, z, zDb);
if( pTab ){
reindexTable(pParse, pTab, 0);
sqlite4DbFree(db, z);
return;
}
pIndex = sqlite4FindIndex(db, z, zDb);
sqlite4DbFree(db, z);
if( pIndex && pIndex->eIndexType!=SQLITE_INDEX_PRIMARYKEY ){
sqlite4BeginWriteOperation(pParse, 0, iDb);
sqlite4RefillIndex(pParse, pIndex, 0);
return;
}
sqlite4ErrorMsg(pParse, "unable to identify the object to be reindexed");
}
#endif
/*
** Return a dynamicly allocated KeyInfo structure that can be used
** with OP_OpenRead or OP_OpenWrite to access database index pIdx.
**
** If successful, a pointer to the new structure is returned. In this case
** the caller is responsible for calling sqlite4DbFree(db, ) on the returned
** pointer. If an error occurs (out of memory or missing collation
** sequence), NULL is returned and the state of pParse updated to reflect
** the error.
*/
SQLITE_PRIVATE KeyInfo *sqlite4IndexKeyinfo(Parse *pParse, Index *pIdx){
Index *pPk; /* Primary key index on same table */
int i;
int nCol;
int nBytes;
sqlite4 *db = pParse->db;
KeyInfo *pKey;
if( pIdx->eIndexType==SQLITE_INDEX_PRIMARYKEY
|| pIdx->eIndexType==SQLITE_INDEX_TEMP
){
pPk = 0;
}else{
pPk = sqlite4FindPrimaryKey(pIdx->pTable, 0);
}
nCol = pIdx->nColumn + (pPk ? pPk->nColumn : 0);
nBytes = sizeof(KeyInfo) + (nCol-1)*sizeof(CollSeq*) + nCol;
pKey = (KeyInfo *)sqlite4DbMallocZero(db, nBytes);
if( pKey ){
pKey->db = pParse->db;
pKey->aSortOrder = (u8 *)&(pKey->aColl[nCol]);
assert( &pKey->aSortOrder[nCol]==&(((u8 *)pKey)[nBytes]) );
for(i=0; i<pIdx->nColumn; i++){
char *zColl = pIdx->azColl[i];
assert( zColl );
pKey->aColl[i] = sqlite4LocateCollSeq(pParse, zColl);
pKey->aSortOrder[i] = pIdx->aSortOrder[i];
}
if( pPk ){
for(i=0; i<pPk->nColumn; i++){
char *zColl = pPk->azColl[i];
assert( zColl );
pKey->aColl[i+pIdx->nColumn] = sqlite4LocateCollSeq(pParse, zColl);
pKey->aSortOrder[i+pIdx->nColumn] = pPk->aSortOrder[i];
}
}
pKey->nField = (u16)nCol;
if( pPk ){
pKey->nPK = pPk->nColumn;
}else{
pKey->nData = pIdx->pTable->nCol;
}
}
if( pParse->nErr ){
sqlite4DbFree(db, pKey);
pKey = 0;
}
return pKey;
}
/************** End of build.c ***********************************************/
/************** Begin file callback.c ****************************************/
/*
** 2005 May 23
**
** 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 functions used to access the internal hash tables
** of user defined functions and collation sequences.
*/
/*
** Invoke the 'collation needed' callback to request a collation sequence
** in the encoding enc of name zName, length nName.
*/
static void callCollNeeded(sqlite4 *db, int enc, const char *zName){
assert( !db->xCollNeeded || !db->xCollNeeded16 );
if( db->xCollNeeded ){
char *zExternal = sqlite4DbStrDup(db, zName);
if( !zExternal ) return;
db->xCollNeeded(db->pCollNeededArg, db, enc, zExternal);
sqlite4DbFree(db, zExternal);
}
#ifndef SQLITE_OMIT_UTF16
if( db->xCollNeeded16 ){
char const *zExternal;
sqlite4_value *pTmp = sqlite4ValueNew(db);
sqlite4ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC);
zExternal = sqlite4ValueText(pTmp, SQLITE_UTF16NATIVE);
if( zExternal ){
db->xCollNeeded16(db->pCollNeededArg, db, (int)ENC(db), zExternal);
}
sqlite4ValueFree(pTmp);
}
#endif
}
/*
** This routine is called if the collation factory fails to deliver a
** collation function in the best encoding but there may be other versions
** of this collation function (for other text encodings) available. Use one
** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if
** possible.
*/
static int synthCollSeq(sqlite4 *db, CollSeq *pColl){
CollSeq *pColl2;
char *z = pColl->zName;
int i;
static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 };
for(i=0; i<3; i++){
pColl2 = sqlite4FindCollSeq(db, aEnc[i], z, 0);
if( pColl2->xCmp!=0 ){
memcpy(pColl, pColl2, sizeof(CollSeq));
pColl->xDel = 0; /* Do not copy the destructor */
return SQLITE_OK;
}
}
return SQLITE_ERROR;
}
/*
** This function is responsible for invoking the collation factory callback
** or substituting a collation sequence of a different encoding when the
** requested collation sequence is not available in the desired encoding.
**
** If it is not NULL, then pColl must point to the database native encoding
** collation sequence with name zName, length nName.
**
** The return value is either the collation sequence to be used in database
** db for collation type name zName, length nName, or NULL, if no collation
** sequence can be found.
**
** See also: sqlite4LocateCollSeq(), sqlite4FindCollSeq()
*/
SQLITE_PRIVATE CollSeq *sqlite4GetCollSeq(
sqlite4* db, /* The database connection */
u8 enc, /* The desired encoding for the collating sequence */
CollSeq *pColl, /* Collating sequence with native encoding, or NULL */
const char *zName /* Collating sequence name */
){
CollSeq *p;
p = pColl;
if( !p ){
p = sqlite4FindCollSeq(db, enc, zName, 0);
}
if( !p || !p->xCmp ){
/* No collation sequence of this type for this encoding is registered.
** Call the collation factory to see if it can supply us with one.
*/
callCollNeeded(db, enc, zName);
p = sqlite4FindCollSeq(db, enc, zName, 0);
}
if( p && !p->xCmp && synthCollSeq(db, p) ){
p = 0;
}
assert( !p || p->xCmp );
return p;
}
/*
** This routine is called on a collation sequence before it is used to
** check that it is defined. An undefined collation sequence exists when
** a database is loaded that contains references to collation sequences
** that have not been defined by sqlite4_create_collation() etc.
**
** If required, this routine calls the 'collation needed' callback to
** request a definition of the collating sequence. If this doesn't work,
** an equivalent collating sequence that uses a text encoding different
** from the main database is substituted, if one is available.
*/
SQLITE_PRIVATE int sqlite4CheckCollSeq(Parse *pParse, CollSeq *pColl){
if( pColl ){
const char *zName = pColl->zName;
sqlite4 *db = pParse->db;
CollSeq *p = sqlite4GetCollSeq(db, ENC(db), pColl, zName);
if( !p ){
sqlite4ErrorMsg(pParse, "no such collation sequence: %s", zName);
pParse->nErr++;
return SQLITE_ERROR;
}
assert( p==pColl );
}
return SQLITE_OK;
}
/*
** Locate and return an entry from the db.aCollSeq hash table. If the entry
** specified by zName and nName is not found and parameter 'create' is
** true, then create a new entry. Otherwise return NULL.
**
** Each pointer stored in the sqlite4.aCollSeq hash table contains an
** array of three CollSeq structures. The first is the collation sequence
** prefferred for UTF-8, the second UTF-16le, and the third UTF-16be.
**
** Stored immediately after the three collation sequences is a copy of
** the collation sequence name. A pointer to this string is stored in
** each collation sequence structure.
*/
static CollSeq *findCollSeqEntry(
sqlite4 *db, /* Database connection */
const char *zName, /* Name of the collating sequence */
int create /* Create a new entry if true */
){
CollSeq *pColl;
int nName = sqlite4Strlen30(zName);
pColl = sqlite4HashFind(&db->aCollSeq, zName, nName);
if( 0==pColl && create ){
pColl = sqlite4DbMallocZero(db, 3*sizeof(*pColl) + nName + 1 );
if( pColl ){
CollSeq *pDel = 0;
pColl[0].zName = (char*)&pColl[3];
pColl[0].enc = SQLITE_UTF8;
pColl[1].zName = (char*)&pColl[3];
pColl[1].enc = SQLITE_UTF16LE;
pColl[2].zName = (char*)&pColl[3];
pColl[2].enc = SQLITE_UTF16BE;
memcpy(pColl[0].zName, zName, nName);
pColl[0].zName[nName] = 0;
pDel = sqlite4HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl);
/* If a malloc() failure occurred in sqlite4HashInsert(), it will
** return the pColl pointer to be deleted (because it wasn't added
** to the hash table).
*/
assert( pDel==0 || pDel==pColl );
if( pDel!=0 ){
db->mallocFailed = 1;
sqlite4DbFree(db, pDel);
pColl = 0;
}
}
}
return pColl;
}
/*
** Parameter zName points to a UTF-8 encoded string nName bytes long.
** Return the CollSeq* pointer for the collation sequence named zName
** for the encoding 'enc' from the database 'db'.
**
** If the entry specified is not found and 'create' is true, then create a
** new entry. Otherwise return NULL.
**
** A separate function sqlite4LocateCollSeq() is a wrapper around
** this routine. sqlite4LocateCollSeq() invokes the collation factory
** if necessary and generates an error message if the collating sequence
** cannot be found.
**
** See also: sqlite4LocateCollSeq(), sqlite4GetCollSeq()
*/
SQLITE_PRIVATE CollSeq *sqlite4FindCollSeq(
sqlite4 *db,
u8 enc,
const char *zName,
int create
){
CollSeq *pColl;
if( zName ){
pColl = findCollSeqEntry(db, zName, create);
}else{
pColl = db->pDfltColl;
}
assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE );
if( pColl ) pColl += enc-1;
return pColl;
}
/* During the search for the best function definition, this procedure
** is called to test how well the function passed as the first argument
** matches the request for a function with nArg arguments in a system
** that uses encoding enc. The value returned indicates how well the
** request is matched. A higher value indicates a better match.
**
** The returned value is always between 0 and 6, as follows:
**
** 0: Not a match, or if nArg<0 and the function is has no implementation.
** 1: A variable arguments function that prefers UTF-8 when a UTF-16
** encoding is requested, or vice versa.
** 2: A variable arguments function that uses UTF-16BE when UTF-16LE is
** requested, or vice versa.
** 3: A variable arguments function using the same text encoding.
** 4: A function with the exact number of arguments requested that
** prefers UTF-8 when a UTF-16 encoding is requested, or vice versa.
** 5: A function with the exact number of arguments requested that
** prefers UTF-16LE when UTF-16BE is requested, or vice versa.
** 6: An exact match.
**
*/
static int matchQuality(FuncDef *p, int nArg, u8 enc){
int match = 0;
if( p->nArg==-1 || p->nArg==nArg
|| (nArg==-1 && (p->xFunc!=0 || p->xStep!=0))
){
match = 1;
if( p->nArg==nArg || nArg==-1 ){
match = 4;
}
if( enc==p->iPrefEnc ){
match += 2;
}
else if( (enc==SQLITE_UTF16LE && p->iPrefEnc==SQLITE_UTF16BE) ||
(enc==SQLITE_UTF16BE && p->iPrefEnc==SQLITE_UTF16LE) ){
match += 1;
}
}
return match;
}
/*
** Search a FuncDefTable for a function with the given name. Return
** a pointer to the matching FuncDef if found, or 0 if there is no match.
*/
static FuncDef *functionSearch(
FuncDefTable *pFuncTab, /* Lookup table to search */
const char *zFunc, /* Name of function */
int nFunc /* Number of bytes in zFunc */
){
FuncDef *p;
if( nFunc<0 ) nFunc = sqlite4Strlen30(zFunc);
for(p=pFuncTab->pFirst; p; p=p->pNextName){
if( sqlite4StrNICmp(p->zName, zFunc, nFunc)==0 && p->zName[nFunc]==0 ){
return p;
}
}
return 0;
}
/*
** Insert a new FuncDef into a FuncDefTable.
**
** The pDef is private to a single database connection if isBuiltIn==0 but
** is a global public function if isBuiltIn==1. In the case of isBuiltIn==1,
** any changes to pDef are made in a way that is threadsafe, so that if two
** threads attempt to build the global function table at the same time, the
** trailing thread will perform harmless no-op assignments.
*/
SQLITE_PRIVATE void sqlite4FuncDefInsert(
FuncDefTable *pFuncTab, /* The lookup table into which to insert */
FuncDef *pDef, /* The function definition to insert */
int isBuiltIn /* True if pDef is one of the built-in functions */
){
FuncDef *pOther;
assert( pDef->pSameName==0 || isBuiltIn );
assert( pDef->pNextName==0 || isBuiltIn );
if( pFuncTab->pFirst==0 ){
pFuncTab->pFirst = pDef;
pFuncTab->pLast = pDef;
pFuncTab->pSame = pDef;
}else if( isBuiltIn
&& sqlite4StrICmp(pDef->zName, pFuncTab->pLast->zName)==0 ){
assert( pFuncTab->pSame->pSameName==0 || pFuncTab->pSame->pSameName==pDef );
pFuncTab->pSame->pSameName = pDef;
pFuncTab->pSame = pDef;
}else if( !isBuiltIn && (pOther=functionSearch(pFuncTab,pDef->zName,-1))!=0 ){
pDef->pSameName = pOther->pSameName;
pOther->pSameName = pDef;
}else{
assert( pFuncTab->pLast->pNextName==0 || pFuncTab->pLast->pNextName==pDef );
pFuncTab->pLast->pNextName = pDef;
pFuncTab->pLast = pDef;
pFuncTab->pSame = pDef;
}
}
/*
** Locate a user function given a name, a number of arguments and a flag
** indicating whether the function prefers UTF-16 over UTF-8. Return a
** pointer to the FuncDef structure that defines that function, or return
** NULL if the function does not exist.
**
** If the createFlag argument is true, then a new (blank) FuncDef
** structure is created and liked into the "db" structure if a
** no matching function previously existed. When createFlag is true
** and the nArg parameter is -1, then only a function that accepts
** any number of arguments will be returned.
**
** If createFlag is false and nArg is -1, then the first valid
** function found is returned. A function is valid if either xFunc
** or xStep is non-zero.
**
** If createFlag is false, then a function with the required name and
** number of arguments may be returned even if the eTextRep flag does not
** match that requested.
*/
SQLITE_PRIVATE FuncDef *sqlite4FindFunction(
sqlite4 *db, /* An open database */
const char *zName, /* Name of the function. Not null-terminated */
int nName, /* Number of characters in the name */
int nArg, /* Number of arguments. -1 means any number */
u8 enc, /* Preferred text encoding */
int createFlag /* Create new entry if true and does not otherwise exist */
){
FuncDef *p; /* Iterator variable */
FuncDef *pBest = 0; /* Best match found so far */
int bestScore = 0; /* Score of best match */
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
/* First search for a match amongst the application-defined functions.
*/
p = functionSearch(&db->aFunc, zName, nName);
while( p ){
int score = matchQuality(p, nArg, enc);
if( score>bestScore ){
pBest = p;
bestScore = score;
}
p = p->pSameName;
}
/* If no match is found, search the built-in functions.
**
** If the SQLITE_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.
**
** Except, if createFlag is true, that means that we are trying to
** install a new function. Whatever FuncDef structure is returned it will
** have fields overwritten with new information appropriate for the
** 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->flags & SQLITE_PreferBuiltin)!=0) ){
FuncDefTable *pFuncTab = &db->pEnv->aGlobalFuncs;
bestScore = 0;
p = functionSearch(pFuncTab, zName, nName);
while( p ){
int score = matchQuality(p, nArg, enc);
if( score>bestScore ){
pBest = p;
bestScore = score;
}
p = p->pSameName;
}
}
/* If the createFlag parameter is true and the search did not reveal an
** exact match for the name, number of arguments and encoding, then add a
** new entry to the hash table and return it.
*/
if( createFlag && (bestScore<6 || pBest->nArg!=nArg) &&
(pBest = sqlite4DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){
pBest->zName = (char *)&pBest[1];
pBest->nArg = (u16)nArg;
pBest->iPrefEnc = enc;
memcpy(pBest->zName, zName, nName);
pBest->zName[nName] = 0;
sqlite4FuncDefInsert(&db->aFunc, pBest, 0);
}
if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){
return pBest;
}
return 0;
}
/*
** Free all resources held by the schema structure. The void* argument points
** at a Schema struct. This function does not call sqlite4DbFree(db, ) on the
** pointer itself, it just cleans up subsidiary resources (i.e. the contents
** of the schema hash tables).
**
** The Schema.cache_size variable is not cleared.
*/
SQLITE_PRIVATE void sqlite4SchemaClear(sqlite4_env *pEnv, Schema *pSchema){
Hash temp1;
Hash temp2;
HashElem *pElem;
temp1 = pSchema->tblHash;
temp2 = pSchema->trigHash;
sqlite4HashInit(pEnv, &pSchema->trigHash);
sqlite4HashClear(&pSchema->idxHash);
for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
sqlite4DeleteTrigger(0, (Trigger*)sqliteHashData(pElem));
}
sqlite4HashClear(&temp2);
sqlite4HashInit(pEnv, &pSchema->tblHash);
for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
Table *pTab = sqliteHashData(pElem);
sqlite4DeleteTable(0, pTab);
}
sqlite4HashClear(&temp1);
sqlite4HashClear(&pSchema->fkeyHash);
pSchema->pSeqTab = 0;
if( pSchema->flags & DB_SchemaLoaded ){
pSchema->iGeneration++;
pSchema->flags &= ~DB_SchemaLoaded;
}
}
/*
** Find and return the schema associated with a BTree. Create
** a new one if necessary.
*/
SQLITE_PRIVATE Schema *sqlite4SchemaGet(sqlite4 *db){
Schema * p;
p = (Schema *)sqlite4DbMallocZero(0, sizeof(Schema));
if( !p ){
db->mallocFailed = 1;
}else if ( 0==p->file_format ){
sqlite4HashInit(db->pEnv, &p->tblHash);
sqlite4HashInit(db->pEnv, &p->idxHash);
sqlite4HashInit(db->pEnv, &p->trigHash);
sqlite4HashInit(db->pEnv, &p->fkeyHash);
p->enc = SQLITE_UTF8;
}
return p;
}
/************** End of callback.c ********************************************/
/************** Begin file delete.c ******************************************/
/*
** 2001 September 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.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** in order to generate code for DELETE FROM statements.
*/
/*
** While a SrcList can in general represent multiple tables and subqueries
** (as in the FROM clause of a SELECT statement) in this case it contains
** the name of a single table, as one might find in an INSERT, DELETE,
** or UPDATE statement. Look up that table in the symbol table and
** return a pointer. Set an error message and return NULL if the table
** name is not found or if any other error occurs.
**
** The following fields are initialized appropriate in pSrc:
**
** pSrc->a[0].pTab Pointer to the Table object
** pSrc->a[0].pIndex Pointer to the INDEXED BY index, if there is one
*/
SQLITE_PRIVATE Table *sqlite4SrcListLookup(Parse *pParse, SrcList *pSrc){
struct SrcList_item *pItem = pSrc->a;
Table *pTab;
assert( pItem && pSrc->nSrc==1 );
pTab = sqlite4LocateTable(pParse, 0, pItem->zName, pItem->zDatabase);
sqlite4DeleteTable(pParse->db, pItem->pTab);
pItem->pTab = pTab;
if( pTab ){
pTab->nRef++;
}
if( sqlite4IndexedByLookup(pParse, pItem) ){
pTab = 0;
}
return pTab;
}
/*
** Check to make sure the given table is writable. If it is not
** writable, generate an error message and return 1. If it is
** writable return 0;
*/
SQLITE_PRIVATE int sqlite4IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
/* A table is not writable under the following circumstances:
**
** 1) It is a virtual table and no implementation of the xUpdate method
** has been provided, or
** 2) It is a system table (i.e. sqlite_master), this call is not
** part of a nested parse and writable_schema pragma has not
** been specified.
**
** In either case leave an error message in pParse and return non-zero.
*/
if( ( IsVirtual(pTab)
&& sqlite4GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 )
|| ( (pTab->tabFlags & TF_Readonly)!=0
&& (pParse->db->flags & SQLITE_WriteSchema)==0
&& pParse->nested==0 )
){
sqlite4ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
return 1;
}
#ifndef SQLITE_OMIT_VIEW
if( !viewOk && pTab->pSelect ){
sqlite4ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
return 1;
}
#endif
return 0;
}
#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
/*
** Evaluate a view and store its result in an ephemeral table. The
** pWhere argument is an optional WHERE clause that restricts the
** set of rows in the view that are to be added to the ephemeral table.
*/
SQLITE_PRIVATE void sqlite4MaterializeView(
Parse *pParse, /* Parsing context */
Table *pView, /* View definition */
Expr *pWhere, /* Optional WHERE clause to be added */
int iCur /* Cursor number for ephemerial table */
){
SelectDest dest;
Select *pDup;
sqlite4 *db = pParse->db;
pDup = sqlite4SelectDup(db, pView->pSelect, 0);
if( pWhere ){
SrcList *pFrom;
pWhere = sqlite4ExprDup(db, pWhere, 0);
pFrom = sqlite4SrcListAppend(db, 0, 0, 0);
if( pFrom ){
assert( pFrom->nSrc==1 );
pFrom->a[0].zAlias = sqlite4DbStrDup(db, pView->zName);
pFrom->a[0].pSelect = pDup;
assert( pFrom->a[0].pOn==0 );
assert( pFrom->a[0].pUsing==0 );
}else{
sqlite4SelectDelete(db, pDup);
}
pDup = sqlite4SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0);
}
sqlite4SelectDestInit(&dest, SRT_EphemTab, iCur);
sqlite4Select(pParse, pDup, &dest);
sqlite4SelectDelete(db, pDup);
}
#endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */
#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
/*
** Generate an expression tree to implement the WHERE, ORDER BY,
** and LIMIT/OFFSET portion of DELETE and UPDATE statements.
**
** DELETE FROM table_wxyz WHERE a<5 ORDER BY a LIMIT 1;
** \__________________________/
** pLimitWhere (pInClause)
*/
SQLITE_PRIVATE Expr *sqlite4LimitWhere(
Parse *pParse, /* The parser context */
SrcList *pSrc, /* the FROM clause -- which tables to scan */
Expr *pWhere, /* The WHERE clause. May be null */
ExprList *pOrderBy, /* The ORDER BY clause. May be null */
Expr *pLimit, /* The LIMIT clause. May be null */
Expr *pOffset, /* The OFFSET clause. May be null */
char *zStmtType /* Either DELETE or UPDATE. For error messages. */
){
Expr *pWhereRowid = NULL; /* WHERE rowid .. */
Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */
Expr *pSelectRowid = NULL; /* SELECT rowid ... */
ExprList *pEList = NULL; /* Expression list contaning only pSelectRowid */
SrcList *pSelectSrc = NULL; /* SELECT rowid FROM x ... (dup of pSrc) */
Select *pSelect = NULL; /* Complete SELECT tree */
/* Check that there isn't an ORDER BY without a LIMIT clause.
*/
if( pOrderBy && (pLimit == 0) ) {
sqlite4ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType);
goto limit_where_cleanup_2;
}
/* We only need to generate a select expression if there
** is a limit/offset term to enforce.
*/
if( pLimit == 0 ) {
/* if pLimit is null, pOffset will always be null as well. */
assert( pOffset == 0 );
return pWhere;
}
/* Generate a select expression tree to enforce the limit/offset
** term for the DELETE or UPDATE statement. For example:
** DELETE FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1
** becomes:
** DELETE FROM table_a WHERE rowid IN (
** SELECT rowid FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1
** );
*/
pSelectRowid = sqlite4PExpr(pParse, TK_ROW, 0, 0, 0);
if( pSelectRowid == 0 ) goto limit_where_cleanup_2;
pEList = sqlite4ExprListAppend(pParse, 0, pSelectRowid);
if( pEList == 0 ) goto limit_where_cleanup_2;
/* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
** and the SELECT subtree. */
pSelectSrc = sqlite4SrcListDup(pParse->db, pSrc, 0);
if( pSelectSrc == 0 ) {
sqlite4ExprListDelete(pParse->db, pEList);
goto limit_where_cleanup_2;
}
/* generate the SELECT expression tree. */
pSelect = sqlite4SelectNew(pParse,pEList,pSelectSrc,pWhere,0,0,
pOrderBy,0,pLimit,pOffset);
if( pSelect == 0 ) return 0;
/* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */
pWhereRowid = sqlite4PExpr(pParse, TK_ROW, 0, 0, 0);
if( pWhereRowid == 0 ) goto limit_where_cleanup_1;
pInClause = sqlite4PExpr(pParse, TK_IN, pWhereRowid, 0, 0);
if( pInClause == 0 ) goto limit_where_cleanup_1;
pInClause->x.pSelect = pSelect;
pInClause->flags |= EP_xIsSelect;
sqlite4ExprSetHeight(pParse, pInClause);
return pInClause;
/* something went wrong. clean up anything allocated. */
limit_where_cleanup_1:
sqlite4SelectDelete(pParse->db, pSelect);
return 0;
limit_where_cleanup_2:
sqlite4ExprDelete(pParse->db, pWhere);
sqlite4ExprListDelete(pParse->db, pOrderBy);
sqlite4ExprDelete(pParse->db, pLimit);
sqlite4ExprDelete(pParse->db, pOffset);
return 0;
}
#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */
/*
** Generate code for a DELETE FROM statement.
**
** DELETE FROM table_wxyz WHERE a<5 AND b NOT NULL;
** \________/ \________________/
** pTabList pWhere
*/
SQLITE_PRIVATE void sqlite4DeleteFrom(
Parse *pParse, /* The parser context */
SrcList *pTabList, /* The table from which we should delete things */
Expr *pWhere /* The WHERE clause. May be null */
){
sqlite4 *db = pParse->db; /* Main database structure */
Vdbe *v; /* The virtual database engine */
Table *pTab; /* Table to delete from */
const char *zDb; /* Name of database holding pTab */
AuthContext sContext; /* Authorization context */
NameContext sNC; /* Name context to resolve WHERE expression */
int iDb; /* Database number */
int rcauth; /* Value returned by authorization callback */
int iCur; /* Cursor number used by where.c */
Trigger *pTrigger; /* List of triggers, or NULL */
memset(&sContext, 0, sizeof(sContext));
memset(&sNC, 0, sizeof(sNC));
db = pParse->db;
if( pParse->nErr || db->mallocFailed ){
goto delete_from_cleanup;
}
assert( pTabList->nSrc==1 );
/* Locate the table to delete records from. If it is a view, make sure
** that the column names are initialized. */
pTab = sqlite4SrcListLookup(pParse, pTabList);
if( pTab==0 || sqlite4ViewGetColumnNames(pParse, pTab) ){
goto delete_from_cleanup;
}
iDb = sqlite4SchemaToIndex(db, pTab->pSchema);
zDb = db->aDb[iDb].zName;
/* Figure out if there are any triggers */
pTrigger = sqlite4TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
/* Check the table is not read-only. A table is read-only if it is one
** of the built-in system tables (e.g. sqlite_master, sqlite_stat) or
** if it is a view and there are no INSTEAD OF triggers to handle the
** delete. */
if( sqlite4IsReadOnly(pParse, pTab, pTrigger!=0) ) goto delete_from_cleanup;
assert( !IsView(pTab) || pTrigger );
assert( !IsView(pTab) || pTab->pIndex==0 );
/* Invoke the authorization callback */
rcauth = sqlite4AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb);
assert( rcauth==SQLITE_OK || rcauth==SQLITE_DENY || rcauth==SQLITE_IGNORE );
if( rcauth==SQLITE_DENY ){
goto delete_from_cleanup;
}
/* Assign a cursor number to the table or view this statement is
** deleting from. If pTab is actually a view, this will be used as the
** ephemeral table cursor.
**
** Or, if this is a real table, it is the number of a read-only cursor
** used by where.c to iterate through those records that match the WHERE
** clause supplied by the user. This is a separate cursor from the array
** of read-write cursors used to delete entries from each of the tables
** indexes. */
pTabList->a[0].iCursor = iCur = pParse->nTab++;
/* Begin generating code */
v = sqlite4GetVdbe(pParse);
if( v==0 ) goto delete_from_cleanup;
if( pParse->nested==0 ) sqlite4VdbeCountChanges(v);
sqlite4BeginWriteOperation(pParse, 1, iDb);
/* If we are trying to delete from a view, realize that view into
** a ephemeral table. */
if( IsView(pTab) ){
sqlite4AuthContextPush(pParse, &sContext, pTab->zName);
sqlite4MaterializeView(pParse, pTab, pWhere, iCur);
}
/* Resolve the column names in the WHERE clause. This has to come after
** the call to sqlite4MaterializeView() above. */
sNC.pParse = pParse;
sNC.pSrcList = pTabList;
if( sqlite4ResolveExprNames(&sNC, pWhere) ){
goto delete_from_cleanup;
}
#ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
/* 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 sqlite4_count_changes) to be set incorrectly. */
if( rcauth==SQLITE_OK && pWhere==0 && !pTrigger && !IsVirtual(pTab)
&& 0==sqlite4FkRequired(pParse, pTab, 0)
){
Index *pIdx; /* For looping over indices of the table */
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
assert( pIdx->pSchema==pTab->pSchema );
sqlite4VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb);
if( pIdx->eIndexType==SQLITE_INDEX_PRIMARYKEY ){
sqlite4VdbeChangeP5(v, OPFLAG_NCHANGE);
}
}
}else
#endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */
/* The usual case: There is a WHERE clause so we have to scan through
** the table and pick which records to delete.
*/
{
WhereInfo *pWInfo; /* Information about the WHERE clause */
int baseCur = 0;
int regSet = ++pParse->nMem; /* Register for rowset of rows to delete */
int regKey = ++pParse->nMem; /* Used for storing row keys */
int addrTop; /* Instruction (RowSetRead) at top of loop */
/* Query the table for all rows that match the WHERE clause. Store the
** PRIMARY KEY for each matching row in the RowSet object in register
** regSet. After the scan is complete, the VM will loop through the set
** of keys in the RowSet and delete each row. Rows must be deleted after
** the scan is complete because deleting an item can change the scan
** order. */
sqlite4VdbeAddOp2(v, OP_Null, 0, regSet);
VdbeComment((v, "initialize RowSet"));
pWInfo = sqlite4WhereBegin(
pParse, pTabList, pWhere, 0, 0, WHERE_DUPLICATES_OK
);
if( pWInfo==0 ) goto delete_from_cleanup;
sqlite4VdbeAddOp2(v, OP_RowKey, iCur, regKey);
sqlite4VdbeAddOp3(v, OP_RowSetAdd, regSet, 0, regKey);
sqlite4WhereEnd(pWInfo);
/* Unless this is a view, open cursors for all indexes on the table
** from which we are deleting. */
if( !IsView(pTab) ){
baseCur = pParse->nTab;
sqlite4OpenAllIndexes(pParse, pTab, baseCur, OP_OpenWrite);
}
addrTop = sqlite4VdbeAddOp3(v, OP_RowSetRead, regSet, 0, regKey);
/* Delete the row */
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( IsVirtual(pTab) ){
const char *pVTab = (const char *)sqlite4GetVTable(db, pTab);
sqlite4VtabMakeWritable(pParse, pTab);
sqlite4VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVTab, P4_VTAB);
sqlite4VdbeChangeP5(v, OE_Abort);
sqlite4MayAbort(pParse);
}else
#endif
{
sqlite4GenerateRowDelete(
pParse, pTab, baseCur, regKey, pParse->nested==0, pTrigger, OE_Default
);
}
/* End of the delete loop */
sqlite4VdbeAddOp2(v, OP_Goto, 0, addrTop);
sqlite4VdbeJumpHere(v, addrTop);
/* Close all open cursors */
sqlite4CloseAllIndexes(pParse, pTab, baseCur);
}
delete_from_cleanup:
sqlite4AuthContextPop(&sContext);
sqlite4SrcListDelete(db, pTabList);
sqlite4ExprDelete(db, pWhere);
return;
}
/*
** This routine generates VDBE code that causes a single row of a
** single table to be deleted.
**
** The VDBE must be in a particular state when this routine is called.
** These are the requirements:
**
** 1. A read/write cursor pointing to pTab, the table containing the row
** to be deleted, must be opened as cursor number $iCur.
**
** 2. Read/write cursors for all indices of pTab must be open as
** cursor number base+i for the i-th index.
**
** 3. The record number of the row to be deleted must be stored in
** memory cell iRowid.
**
** This routine generates code to remove both the table record and all
** index entries that point to that record.
*/
SQLITE_PRIVATE void sqlite4GenerateRowDelete(
Parse *pParse, /* Parsing context */
Table *pTab, /* Table containing the row to be deleted */
int baseCur, /* Base cursor number */
int regKey, /* Register containing PK of row to delete */
int bCount, /* True to increment the row change counter */
Trigger *pTrigger, /* List of triggers to (potentially) fire */
int onconf /* Default ON CONFLICT policy for triggers */
){
Vdbe *v = pParse->pVdbe; /* Vdbe */
int regOld = 0; /* First register in OLD.* array */
int iLabel; /* Label resolved to end of generated code */
int iPk; /* Offset of PK cursor in cursor array */
int iPkCsr; /* Primary key cursor number */
Index *pPk; /* Primary key index */
/* Vdbe is guaranteed to have been allocated by this stage. */
assert( v );
pPk = sqlite4FindPrimaryKey(pTab, &iPk);
iPkCsr = baseCur + iPk;
/* Seek the PK cursor to the row to delete. If this row no longer exists
** (this can happen if a trigger program has already deleted it), do
** not attempt to delete it or fire any DELETE triggers. */
iLabel = sqlite4VdbeMakeLabel(v);
sqlite4VdbeAddOp4Int(v, OP_NotFound, iPkCsr, iLabel, regKey, 0);
/* If there are any triggers to fire, allocate a range of registers to
** use for the old.* references in the triggers. */
if( sqlite4FkRequired(pParse, pTab, 0) || pTrigger ){
u32 mask; /* Mask of OLD.* columns in use */
int iCol; /* Iterator used while populating OLD.* */
/* Determine which table columns may be required by either foreign key
** logic or triggers. This block sets stack variable mask to a 32-bit mask
** where bit 0 corresponds to the left-most table column, bit 1 to the
** second left-most, and so on. If an OLD.* column may be required, then
** the corresponding bit is set.
**
** Or, if the table contains more than 32 columns and at least one of
** the columns following the 32nd is required, set mask to 0xffffffff. */
mask = sqlite4TriggerColmask(
pParse, pTrigger, 0, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onconf
);
mask |= sqlite4FkOldmask(pParse, pTab);
/* Allocate an array of (nCol+1) registers, where nCol is the number
** of columns in the table.
**
** If the table has an implicit PK, the first register in the array
** contains the rowid. Otherwise, its contents are undefined. The
** remaining registers contain the OLD.* column values, in order. */
regOld = pParse->nMem+1;
pParse->nMem += (pTab->nCol+1);
for(iCol=0; iCol<pTab->nCol; iCol++){
if( mask==0xffffffff || mask&(1<<iCol) ){
sqlite4ExprCodeGetColumnOfTable(v, pTab, iPkCsr, iCol, regOld+iCol+1);
}
}
assert( (pPk==0)==IsView(pTab) );
if( pPk && pPk->aiColumn[0]<0 ){
sqlite4VdbeAddOp2(v, OP_Rowid, iPkCsr, regOld);
}
/* Invoke BEFORE DELETE trigger programs. */
sqlite4CodeRowTrigger(pParse, pTrigger,
TK_DELETE, 0, TRIGGER_BEFORE, pTab, regOld, onconf, iLabel
);
/* Seek the cursor to the row to be deleted again. It may be that
** the BEFORE triggers coded above have already removed the row
** being deleted. Do not attempt to delete the row a second time, and
** do not fire AFTER triggers. */
sqlite4VdbeAddOp4Int(v, OP_NotFound, iPkCsr, iLabel, regKey, 0);
/* Do FK processing. This call checks that any FK constraints that
** refer to this table (i.e. constraints attached to other tables)
** are not violated by deleting this row. */
sqlite4FkCheck(pParse, pTab, regOld+1, 0);
}
/* 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( !IsView(pTab) ){
sqlite4GenerateRowIndexDelete(pParse, pTab, bCount, baseCur, 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
** to the row just deleted. This is a no-op if there are no configured
** foreign keys that use this table as a parent table. */
sqlite4FkActions(pParse, pTab, 0, regOld);
/* Invoke AFTER DELETE trigger programs. */
sqlite4CodeRowTrigger(pParse, pTrigger,
TK_DELETE, 0, TRIGGER_AFTER, pTab, regOld, onconf, iLabel
);
/* Jump here if the row had already been deleted before any BEFORE
** trigger programs were invoked. Or if a trigger program throws a
** RAISE(IGNORE) exception. */
sqlite4VdbeResolveLabel(v, iLabel);
}
/*
** Generate code that will assemble an index key and put it in register
** regOut. The key is for use with index pIdx.
*/
SQLITE_PRIVATE void sqlite4EncodeIndexKey(
Parse *pParse, /* Parse context */
Index *pPk, /* Primary key index (or NULL) */
int iPkCsr, /* Cursor open on primary key */
Index *pIdx, int iIdxCsr, /* Index and cursor to create a key for */
int bAddSeq, /* True to append a sequence number */
int regOut /* Output register */
){
Vdbe *v = pParse->pVdbe; /* VM to write code to */
int nTmpReg; /* Number of temp registers required */
int regTmp; /* First register in temp array */
int i; /* Iterator variable */
int nPkCol; /* Number of columns to copy from PK */
/* Allocate temp registers */
assert( pIdx!=pPk );
nPkCol = (pPk ? pPk->nColumn : 0);
nTmpReg = pIdx->nColumn + nPkCol;
regTmp = sqlite4GetTempRange(pParse, nTmpReg);
/* Assemble the values for the key in the array of temp registers */
for(i=0; i<pIdx->nColumn; i++){
int regVal = regTmp + i;
sqlite4VdbeAddOp3(v, OP_Column, iPkCsr, pIdx->aiColumn[i], regVal);
}
for(i=0; i<nPkCol; i++){
int iCol = pPk->aiColumn[i];
int regVal = pIdx->nColumn + regTmp + i;
if( iCol<0 ){
sqlite4VdbeAddOp2(v, OP_Rowid, iPkCsr, regVal);
}else{
sqlite4VdbeAddOp3(v, OP_Column, iPkCsr, pPk->aiColumn[i], regVal);
}
}
/* Build the index key. If bAddSeq is true, append a sequence number to
** the end of the key to ensure it is unique. */
sqlite4VdbeAddOp3(v, OP_MakeIdxKey, iIdxCsr, regTmp, regOut);
if( bAddSeq ) sqlite4VdbeChangeP5(v, 1);
/* Release temp registers */
sqlite4ReleaseTempRange(pParse, regTmp, nTmpReg);
}
/*
** This routine generates VDBE code that causes the deletion of all
** index entries associated with a single row of a single table.
**
** The VDBE must be in a particular state when this routine is called.
** These are the requirements:
**
** 1. A read/write cursor pointing to pTab, the table containing the row
** to be deleted, must be opened as cursor number "iCur".
**
** 2. Read/write cursors for all indices of pTab must be open as
** cursor number iCur+i for the i-th index.
**
** 3. The "iCur" cursor must be pointing to the row that is to be
** deleted.
*/
SQLITE_PRIVATE void sqlite4GenerateRowIndexDelete(
Parse *pParse, /* Parsing and code generating context */
Table *pTab, /* Table containing the row to be deleted */
int bCount, /* Non-zero to increment change counter */
int baseCur, /* Cursor number for the table */
int *aRegIdx /* Only delete if (aRegIdx && aRegIdx[i]>0) */
){
Vdbe *v = pParse->pVdbe;
Index *pPk;
int iPk;
int i;
int regKey;
Index *pIdx;
regKey = sqlite4GetTempReg(pParse);
pPk = sqlite4FindPrimaryKey(pTab, &iPk);
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
if( pIdx!=pPk && (aRegIdx==0 || aRegIdx[i]>0) ){
int addrNotFound;
sqlite4EncodeIndexKey(pParse, pPk, baseCur+iPk, pIdx, baseCur+i,0,regKey);
addrNotFound = sqlite4VdbeAddOp4(v,
OP_NotFound, baseCur+i, 0, regKey, 0, P4_INT32
);
sqlite4VdbeAddOp1(v, OP_Delete, baseCur+i);
sqlite4VdbeJumpHere(v, addrNotFound);
}
}
sqlite4VdbeAddOp2(v, OP_Delete, baseCur+iPk, (bCount ? OPFLAG_NCHANGE: 0));
sqlite4ReleaseTempReg(pParse, regKey);
}
/************** End of delete.c **********************************************/
/************** Begin file func.c ********************************************/
/*
** 2002 February 23
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the C functions that implement various SQL
** functions of SQLite.
**
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
*/
/* #include <stdlib.h> */
/* #include <assert.h> */
/*
** Return the collating function associated with a function.
*/
static CollSeq *sqlite4GetFuncCollSeq(sqlite4_context *context){
return context->pColl;
}
/*
** Implementation of the non-aggregate min() and max() functions
*/
static void minmaxFunc(
sqlite4_context *context,
int argc,
sqlite4_value **argv
){
int i;
int mask; /* 0 for min() or 0xffffffff for max() */
int iBest;
CollSeq *pColl;
assert( argc>1 );
mask = sqlite4_user_data(context)==0 ? 0 : -1;
pColl = sqlite4GetFuncCollSeq(context);
assert( pColl );
assert( mask==-1 || mask==0 );
iBest = 0;
if( sqlite4_value_type(argv[0])==SQLITE_NULL ) return;
for(i=1; i<argc; i++){
if( sqlite4_value_type(argv[i])==SQLITE_NULL ) return;
if( (sqlite4MemCompare(argv[iBest], argv[i], pColl)^mask)>=0 ){
testcase( mask==0 );
iBest = i;
}
}
sqlite4_result_value(context, argv[iBest]);
}
/*
** Return the type of the argument.
*/
static void typeofFunc(
sqlite4_context *context,
int NotUsed,
sqlite4_value **argv
){
const char *z = 0;
UNUSED_PARAMETER(NotUsed);
switch( sqlite4_value_type(argv[0]) ){
case SQLITE_INTEGER: z = "integer"; break;
case SQLITE_TEXT: z = "text"; break;
case SQLITE_FLOAT: z = "real"; break;
case SQLITE_BLOB: z = "blob"; break;
default: z = "null"; break;
}
sqlite4_result_text(context, z, -1, SQLITE_STATIC);
}
/*
** Implementation of the length() function
*/
static void lengthFunc(
sqlite4_context *context,
int argc,
sqlite4_value **argv
){
int len;
assert( argc==1 );
UNUSED_PARAMETER(argc);
switch( sqlite4_value_type(argv[0]) ){
case SQLITE_BLOB:
case SQLITE_INTEGER:
case SQLITE_FLOAT: {
sqlite4_result_int(context, sqlite4_value_bytes(argv[0]));
break;
}
case SQLITE_TEXT: {
const unsigned char *z = sqlite4_value_text(argv[0]);
if( z==0 ) return;
len = 0;
while( *z ){
len++;
SQLITE_SKIP_UTF8(z);
}
sqlite4_result_int(context, len);
break;
}
default: {
sqlite4_result_null(context);
break;
}
}
}
/*
** Implementation of the abs() function.
**
** IMP: R-23979-26855 The abs(X) function returns the absolute value of
** the numeric argument X.
*/
static void absFunc(sqlite4_context *context, int argc, sqlite4_value **argv){
assert( argc==1 );
UNUSED_PARAMETER(argc);
switch( sqlite4_value_type(argv[0]) ){
case SQLITE_INTEGER: {
i64 iVal = sqlite4_value_int64(argv[0]);
if( iVal<0 ){
if( (iVal<<1)==0 ){
/* IMP: R-35460-15084 If X is the integer -9223372036854775807 then
** abs(X) throws an integer overflow error since there is no
** equivalent positive 64-bit two complement value. */
sqlite4_result_error(context, "integer overflow", -1);
return;
}
iVal = -iVal;
}
sqlite4_result_int64(context, iVal);
break;
}
case SQLITE_NULL: {
/* IMP: R-37434-19929 Abs(X) returns NULL if X is NULL. */
sqlite4_result_null(context);
break;
}
default: {
/* Because sqlite4_value_double() returns 0.0 if the argument is not
** something that can be converted into a number, we have:
** IMP: R-57326-31541 Abs(X) return 0.0 if X is a string or blob that
** cannot be converted to a numeric value.
*/
double rVal = sqlite4_value_double(argv[0]);
if( rVal<0 ) rVal = -rVal;
sqlite4_result_double(context, rVal);
break;
}
}
}
/*
** Implementation of the substr() function.
**
** substr(x,p1,p2) returns p2 characters of x[] beginning with p1.
** p1 is 1-indexed. So substr(x,1,1) returns the first character
** of x. If x is text, then we actually count UTF-8 characters.
** If x is a blob, then we count bytes.
**
** If p1 is negative, then we begin abs(p1) from the end of x[].
**
** If p2 is negative, return the p2 characters preceeding p1.
*/
static void substrFunc(
sqlite4_context *context,
int argc,
sqlite4_value **argv
){
const unsigned char *z;
const unsigned char *z2;
int len;
int p0type;
i64 p1, p2;
int negP2 = 0;
assert( argc==3 || argc==2 );
if( sqlite4_value_type(argv[1])==SQLITE_NULL
|| (argc==3 && sqlite4_value_type(argv[2])==SQLITE_NULL)
){
return;
}
p0type = sqlite4_value_type(argv[0]);
p1 = sqlite4_value_int(argv[1]);
if( p0type==SQLITE_BLOB ){
len = sqlite4_value_bytes(argv[0]);
z = sqlite4_value_blob(argv[0]);
if( z==0 ) return;
assert( len==sqlite4_value_bytes(argv[0]) );
}else{
z = sqlite4_value_text(argv[0]);
if( z==0 ) return;
len = 0;
if( p1<0 ){
for(z2=z; *z2; len++){
SQLITE_SKIP_UTF8(z2);
}
}
}
if( argc==3 ){
p2 = sqlite4_value_int(argv[2]);
if( p2<0 ){
p2 = -p2;
negP2 = 1;
}
}else{
p2 = sqlite4_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH];
}
if( p1<0 ){
p1 += len;
if( p1<0 ){
p2 += p1;
if( p2<0 ) p2 = 0;
p1 = 0;
}
}else if( p1>0 ){
p1--;
}else if( p2>0 ){
p2--;
}
if( negP2 ){
p1 -= p2;
if( p1<0 ){
p2 += p1;
p1 = 0;
}
}
assert( p1>=0 && p2>=0 );
if( p0type!=SQLITE_BLOB ){
while( *z && p1 ){
SQLITE_SKIP_UTF8(z);
p1--;
}
for(z2=z; *z2 && p2; p2--){
SQLITE_SKIP_UTF8(z2);
}
sqlite4_result_text(context, (char*)z, (int)(z2-z), SQLITE_TRANSIENT);
}else{
if( p1+p2>len ){
p2 = len-p1;
if( p2<0 ) p2 = 0;
}
sqlite4_result_blob(context, (char*)&z[p1], (int)p2, SQLITE_TRANSIENT);
}
}
/*
** Implementation of the round() function
*/
#ifndef SQLITE_OMIT_FLOATING_POINT
static void roundFunc(sqlite4_context *context, int argc, sqlite4_value **argv){
int n = 0;
double r;
char *zBuf;
sqlite4_env *pEnv = sqlite4_context_env(context);
assert( argc==1 || argc==2 );
if( argc==2 ){
if( SQLITE_NULL==sqlite4_value_type(argv[1]) ) return;
n = sqlite4_value_int(argv[1]);
if( n>30 ) n = 30;
if( n<0 ) n = 0;
}
if( sqlite4_value_type(argv[0])==SQLITE_NULL ) return;
r = sqlite4_value_double(argv[0]);
/* If Y==0 and X will fit in a 64-bit int,
** handle the rounding directly,
** otherwise use printf.
*/
if( n==0 && r>=0 && r<LARGEST_INT64-1 ){
r = (double)((sqlite_int64)(r+0.5));
}else if( n==0 && r<0 && (-r)<LARGEST_INT64-1 ){
r = -(double)((sqlite_int64)((-r)+0.5));
}else{
zBuf = sqlite4_mprintf(pEnv,"%.*f",n,r);
if( zBuf==0 ){
sqlite4_result_error_nomem(context);
return;
}
sqlite4AtoF(zBuf, &r, sqlite4Strlen30(zBuf), SQLITE_UTF8);
sqlite4_free(pEnv, zBuf);
}
sqlite4_result_double(context, r);
}
#endif
/*
** Allocate nByte bytes of space using sqlite4_malloc(). If the
** allocation fails, call sqlite4_result_error_nomem() to notify
** the database handle that malloc() has failed and return NULL.
** If nByte is larger than the maximum string or blob length, then
** raise an SQLITE_TOOBIG exception and return NULL.
*/
static void *contextMalloc(sqlite4_context *context, i64 nByte){
char *z;
sqlite4 *db = sqlite4_context_db_handle(context);
assert( nByte>0 );
testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH] );
testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
sqlite4_result_error_toobig(context);
z = 0;
}else{
z = sqlite4Malloc(db->pEnv, (int)nByte);
if( !z ){
sqlite4_result_error_nomem(context);
}
}
return z;
}
/*
** Implementation of the upper() and lower() SQL functions.
*/
static void upperFunc(sqlite4_context *context, int argc, sqlite4_value **argv){
char *z1;
const char *z2;
int i, n;
UNUSED_PARAMETER(argc);
z2 = (char*)sqlite4_value_text(argv[0]);
n = sqlite4_value_bytes(argv[0]);
/* Verify that the call to _bytes() does not invalidate the _text() pointer */
assert( z2==(char*)sqlite4_value_text(argv[0]) );
if( z2 ){
z1 = contextMalloc(context, ((i64)n)+1);
if( z1 ){
for(i=0; i<n; i++){
z1[i] = (char)sqlite4Toupper(z2[i]);
}
sqlite4_result_text(context, z1, n, SQLITE_DYNAMIC);
}
}
}
static void lowerFunc(sqlite4_context *context, int argc, sqlite4_value **argv){
char *z1;
const char *z2;
int i, n;
UNUSED_PARAMETER(argc);
z2 = (char*)sqlite4_value_text(argv[0]);
n = sqlite4_value_bytes(argv[0]);
/* Verify that the call to _bytes() does not invalidate the _text() pointer */
assert( z2==(char*)sqlite4_value_text(argv[0]) );
if( z2 ){
z1 = contextMalloc(context, ((i64)n)+1);
if( z1 ){
for(i=0; i<n; i++){
z1[i] = sqlite4Tolower(z2[i]);
}
sqlite4_result_text(context, z1, n, SQLITE_DYNAMIC);
}
}
}
#if 0 /* This function is never used. */
/*
** The COALESCE() and IFNULL() functions used to be implemented as shown
** here. But now they are implemented as VDBE code so that unused arguments
** do not have to be computed. This legacy implementation is retained as
** comment.
*/
/*
** Implementation of the IFNULL(), NVL(), and COALESCE() functions.
** All three do the same thing. They return the first non-NULL
** argument.
*/
static void ifnullFunc(
sqlite4_context *context,
int argc,
sqlite4_value **argv
){
int i;
for(i=0; i<argc; i++){
if( SQLITE_NULL!=sqlite4_value_type(argv[i]) ){
sqlite4_result_value(context, argv[i]);
break;
}
}
}
#endif /* NOT USED */
#define ifnullFunc versionFunc /* Substitute function - never called */
/*
** Implementation of random(). Return a random integer.
*/
static void randomFunc(
sqlite4_context *context,
int NotUsed,
sqlite4_value **NotUsed2
){
sqlite_int64 r;
UNUSED_PARAMETER2(NotUsed, NotUsed2);
sqlite4_randomness(sqlite4_context_env(context), sizeof(r), &r);
if( r<0 ){
/* We need to prevent a random number of 0x8000000000000000
** (or -9223372036854775808) since when you do abs() of that
** number of you get the same value back again. To do this
** in a way that is testable, mask the sign bit off of negative
** values, resulting in a positive value. Then take the
** 2s complement of that positive value. The end result can
** therefore be no less than -9223372036854775807.
*/
r = -(r ^ (((sqlite4_int64)1)<<63));
}
sqlite4_result_int64(context, r);
}
/*
** Implementation of randomblob(N). Return a random blob
** that is N bytes long.
*/
static void randomBlob(
sqlite4_context *context,
int argc,
sqlite4_value **argv
){
int n;
unsigned char *p;
assert( argc==1 );
UNUSED_PARAMETER(argc);
n = sqlite4_value_int(argv[0]);
if( n<1 ){
n = 1;
}
p = contextMalloc(context, n);
if( p ){
sqlite4_randomness(sqlite4_context_env(context), n, p);
sqlite4_result_blob(context, (char*)p, n, SQLITE_DYNAMIC);
}
}
/*
** Implementation of the last_insert_rowid() SQL function. The return
** value is the same as the sqlite4_last_insert_rowid() API function.
*/
static void last_insert_rowid(
sqlite4_context *context,
int NotUsed,
sqlite4_value **NotUsed2
){
sqlite4 *db = sqlite4_context_db_handle(context);
UNUSED_PARAMETER2(NotUsed, NotUsed2);
/* IMP: R-51513-12026 The last_insert_rowid() SQL function is a
** wrapper around the sqlite4_last_insert_rowid() C/C++ interface
** function. */
sqlite4_result_int64(context, sqlite4_last_insert_rowid(db));
}
/*
** Implementation of the changes() SQL function.
**
** IMP: R-62073-11209 The changes() SQL function is a wrapper
** around the sqlite4_changes() C/C++ function and hence follows the same
** rules for counting changes.
*/
static void changes(
sqlite4_context *context,
int NotUsed,
sqlite4_value **NotUsed2
){
sqlite4 *db = sqlite4_context_db_handle(context);
UNUSED_PARAMETER2(NotUsed, NotUsed2);
sqlite4_result_int(context, sqlite4_changes(db));
}
/*
** Implementation of the total_changes() SQL function. The return value is
** the same as the sqlite4_total_changes() API function.
*/
static void total_changes(
sqlite4_context *context,
int NotUsed,
sqlite4_value **NotUsed2
){
sqlite4 *db = sqlite4_context_db_handle(context);
UNUSED_PARAMETER2(NotUsed, NotUsed2);
/* IMP: R-52756-41993 This function is a wrapper around the
** sqlite4_total_changes() C/C++ interface. */
sqlite4_result_int(context, sqlite4_total_changes(db));
}
/*
** A structure defining how to do GLOB-style comparisons.
*/
struct compareInfo {
u8 matchAll;
u8 matchOne;
u8 matchSet;
u8 noCase;
};
/*
** For LIKE and GLOB matching on EBCDIC machines, assume that every
** character is exactly one byte in size. Also, all characters are
** able to participate in upper-case-to-lower-case mappings in EBCDIC
** whereas only characters less than 0x80 do in ASCII.
*/
#if defined(SQLITE_EBCDIC)
# define sqlite4Utf8Read(A,C) (*(A++))
# define GlogUpperToLower(A) A = sqlite4UpperToLower[A]
#else
# define GlogUpperToLower(A) if( !((A)&~0x7f) ){ A = sqlite4UpperToLower[A]; }
#endif
static const struct compareInfo globInfo = { '*', '?', '[', 0 };
/* The correct SQL-92 behavior is for the LIKE operator to ignore
** case. Thus 'a' LIKE 'A' would be true. */
static const struct compareInfo likeInfoNorm = { '%', '_', 0, 1 };
/* If SQLITE_CASE_SENSITIVE_LIKE is defined, then the LIKE operator
** is case sensitive causing 'a' LIKE 'A' to be false */
static const struct compareInfo likeInfoAlt = { '%', '_', 0, 0 };
/*
** Compare two UTF-8 strings for equality where the first string can
** potentially be a "glob" expression. Return true (1) if they
** are the same and false (0) if they are different.
**
** Globbing rules:
**
** '*' Matches any sequence of zero or more characters.
**
** '?' Matches exactly one character.
**
** [...] Matches one character from the enclosed list of
** characters.
**
** [^...] Matches one character not in the enclosed list.
**
** With the [...] and [^...] matching, a ']' character can be included
** in the list by making it the first character after '[' or '^'. A
** range of characters can be specified using '-'. Example:
** "[a-z]" matches any single lower-case letter. To match a '-', make
** it the last character in the list.
**
** This routine is usually quick, but can be N**2 in the worst case.
**
** Hints: to match '*' or '?', put them in "[]". Like this:
**
** abc[*]xyz Matches "abc*xyz" only
*/
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 esc /* The escape character */
){
u32 c, c2;
int invert;
int seen;
u8 matchOne = pInfo->matchOne;
u8 matchAll = pInfo->matchAll;
u8 matchSet = pInfo->matchSet;
u8 noCase = pInfo->noCase;
int prevEscape = 0; /* True if the previous character was 'escape' */
while( (c = sqlite4Utf8Read(zPattern,&zPattern))!=0 ){
if( !prevEscape && c==matchAll ){
while( (c=sqlite4Utf8Read(zPattern,&zPattern)) == matchAll
|| c == matchOne ){
if( c==matchOne && sqlite4Utf8Read(zString, &zString)==0 ){
return 0;
}
}
if( c==0 ){
return 1;
}else if( c==esc ){
c = sqlite4Utf8Read(zPattern, &zPattern);
if( c==0 ){
return 0;
}
}else if( c==matchSet ){
assert( esc==0 ); /* This is GLOB, not LIKE */
assert( matchSet<0x80 ); /* '[' is a single-byte character */
while( *zString && patternCompare(&zPattern[-1],zString,pInfo,esc)==0 ){
SQLITE_SKIP_UTF8(zString);
}
return *zString!=0;
}
while( (c2 = sqlite4Utf8Read(zString,&zString))!=0 ){
if( noCase ){
GlogUpperToLower(c2);
GlogUpperToLower(c);
while( c2 != 0 && c2 != c ){
c2 = sqlite4Utf8Read(zString, &zString);
GlogUpperToLower(c2);
}
}else{
while( c2 != 0 && c2 != c ){
c2 = sqlite4Utf8Read(zString, &zString);
}
}
if( c2==0 ) return 0;
if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
}
return 0;
}else if( !prevEscape && c==matchOne ){
if( sqlite4Utf8Read(zString, &zString)==0 ){
return 0;
}
}else if( c==matchSet ){
u32 prior_c = 0;
assert( esc==0 ); /* This only occurs for GLOB, not LIKE */
seen = 0;
invert = 0;
c = sqlite4Utf8Read(zString, &zString);
if( c==0 ) return 0;
c2 = sqlite4Utf8Read(zPattern, &zPattern);
if( c2=='^' ){
invert = 1;
c2 = sqlite4Utf8Read(zPattern, &zPattern);
}
if( c2==']' ){
if( c==']' ) seen = 1;
c2 = sqlite4Utf8Read(zPattern, &zPattern);
}
while( c2 && c2!=']' ){
if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){
c2 = sqlite4Utf8Read(zPattern, &zPattern);
if( c>=prior_c && c<=c2 ) seen = 1;
prior_c = 0;
}else{
if( c==c2 ){
seen = 1;
}
prior_c = c2;
}
c2 = sqlite4Utf8Read(zPattern, &zPattern);
}
if( c2==0 || (seen ^ invert)==0 ){
return 0;
}
}else if( esc==c && !prevEscape ){
prevEscape = 1;
}else{
c2 = sqlite4Utf8Read(zString, &zString);
if( noCase ){
GlogUpperToLower(c);
GlogUpperToLower(c2);
}
if( c!=c2 ){
return 0;
}
prevEscape = 0;
}
}
return *zString==0;
}
/*
** 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.
*/
#ifdef SQLITE_TEST
SQLITE_API int sqlite4_like_count = 0;
#endif
/*
** Implementation of the like() SQL function. This function implements
** the build-in LIKE operator. The first argument to the function is the
** pattern and the second argument is the string. So, the SQL statements:
**
** A LIKE B
**
** is implemented as like(B,A).
**
** This same function (with a different compareInfo structure) computes
** the GLOB operator.
*/
static void likeFunc(
sqlite4_context *context,
int argc,
sqlite4_value **argv
){
const unsigned char *zA, *zB;
u32 escape = 0;
int nPat;
sqlite4 *db = sqlite4_context_db_handle(context);
zB = sqlite4_value_text(argv[0]);
zA = sqlite4_value_text(argv[1]);
/* Limit the length of the LIKE or GLOB pattern to avoid problems
** of deep recursion and N*N behavior in patternCompare().
*/
nPat = sqlite4_value_bytes(argv[0]);
testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] );
testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]+1 );
if( nPat > db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ){
sqlite4_result_error(context, "LIKE or GLOB pattern too complex", -1);
return;
}
assert( zB==sqlite4_value_text(argv[0]) ); /* Encoding did not change */
if( argc==3 ){
/* The escape character string must consist of a single UTF-8 character.
** Otherwise, return an error.
*/
const unsigned char *zEsc = sqlite4_value_text(argv[2]);
if( zEsc==0 ) return;
if( sqlite4Utf8CharLen((char*)zEsc, -1)!=1 ){
sqlite4_result_error(context,
"ESCAPE expression must be a single character", -1);
return;
}
escape = sqlite4Utf8Read(zEsc, &zEsc);
}
if( zA && zB ){
struct compareInfo *pInfo = sqlite4_user_data(context);
#ifdef SQLITE_TEST
sqlite4_like_count++;
#endif
sqlite4_result_int(context, patternCompare(zB, zA, pInfo, escape));
}
}
/*
** Implementation of the NULLIF(x,y) function. The result is the first
** argument if the arguments are different. The result is NULL if the
** arguments are equal to each other.
*/
static void nullifFunc(
sqlite4_context *context,
int NotUsed,
sqlite4_value **argv
){
CollSeq *pColl = sqlite4GetFuncCollSeq(context);
UNUSED_PARAMETER(NotUsed);
if( sqlite4MemCompare(argv[0], argv[1], pColl)!=0 ){
sqlite4_result_value(context, argv[0]);
}
}
/*
** Implementation of the sqlite_version() function. The result is the version
** of the SQLite library that is running.
*/
static void versionFunc(
sqlite4_context *context,
int NotUsed,
sqlite4_value **NotUsed2
){
UNUSED_PARAMETER2(NotUsed, NotUsed2);
/* IMP: R-48699-48617 This function is an SQL wrapper around the
** sqlite4_libversion() C-interface. */
sqlite4_result_text(context, sqlite4_libversion(), -1, SQLITE_STATIC);
}
/*
** Implementation of the sqlite_source_id() function. The result is a string
** that identifies the particular version of the source code used to build
** SQLite.
*/
static void sourceidFunc(
sqlite4_context *context,
int NotUsed,
sqlite4_value **NotUsed2
){
UNUSED_PARAMETER2(NotUsed, NotUsed2);
/* IMP: R-24470-31136 This function is an SQL wrapper around the
** sqlite4_sourceid() C interface. */
sqlite4_result_text(context, sqlite4_sourceid(), -1, SQLITE_STATIC);
}
/*
** Implementation of the sqlite_log() function. This is a wrapper around
** sqlite4_log(). The return value is NULL. The function exists purely for
** its side-effects.
*/
static void errlogFunc(
sqlite4_context *context,
int argc,
sqlite4_value **argv
){
UNUSED_PARAMETER(argc);
sqlite4_log(sqlite4_context_env(context),
sqlite4_value_int(argv[0]), "%s", sqlite4_value_text(argv[1]));
}
/*
** Implementation of the sqlite_compileoption_used() function.
** The result is an integer that identifies if the compiler option
** was used to build SQLite.
*/
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
static void compileoptionusedFunc(
sqlite4_context *context,
int argc,
sqlite4_value **argv
){
const char *zOptName;
assert( argc==1 );
UNUSED_PARAMETER(argc);
/* IMP: R-39564-36305 The sqlite_compileoption_used() SQL
** function is a wrapper around the sqlite4_compileoption_used() C/C++
** function.
*/
if( (zOptName = (const char*)sqlite4_value_text(argv[0]))!=0 ){
sqlite4_result_int(context, sqlite4_compileoption_used(zOptName));
}
}
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
/*
** Implementation of the sqlite_compileoption_get() function.
** The result is a string that identifies the compiler options
** used to build SQLite.
*/
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
static void compileoptiongetFunc(
sqlite4_context *context,
int argc,
sqlite4_value **argv
){
int n;
assert( argc==1 );
UNUSED_PARAMETER(argc);
/* IMP: R-04922-24076 The sqlite_compileoption_get() SQL function
** is a wrapper around the sqlite4_compileoption_get() C/C++ function.
*/
n = sqlite4_value_int(argv[0]);
sqlite4_result_text(context, sqlite4_compileoption_get(n), -1, SQLITE_STATIC);
}
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
/* Array for converting from half-bytes (nybbles) into ASCII hex
** digits. */
static const char hexdigits[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
/*
** EXPERIMENTAL - This is not an official function. The interface may
** change. This function may disappear. Do not write code that depends
** on this function.
**
** Implementation of the QUOTE() function. This function takes a single
** argument. If the argument is numeric, the return value is the same as
** the argument. If the argument is NULL, the return value is the string
** "NULL". Otherwise, the argument is enclosed in single quotes with
** single-quote escapes.
*/
static void quoteFunc(sqlite4_context *context, int argc, sqlite4_value **argv){
assert( argc==1 );
UNUSED_PARAMETER(argc);
switch( sqlite4_value_type(argv[0]) ){
case SQLITE_INTEGER:
case SQLITE_FLOAT: {
sqlite4_result_value(context, argv[0]);
break;
}
case SQLITE_BLOB: {
char *zText = 0;
char const *zBlob = sqlite4_value_blob(argv[0]);
int nBlob = sqlite4_value_bytes(argv[0]);
assert( zBlob==sqlite4_value_blob(argv[0]) ); /* No encoding change */
zText = (char *)contextMalloc(context, (2*(i64)nBlob)+4);
if( zText ){
int i;
for(i=0; i<nBlob; i++){
zText[(i*2)+2] = hexdigits[(zBlob[i]>>4)&0x0F];
zText[(i*2)+3] = hexdigits[(zBlob[i])&0x0F];
}
zText[(nBlob*2)+2] = '\'';
zText[(nBlob*2)+3] = '\0';
zText[0] = 'X';
zText[1] = '\'';
sqlite4_result_text(context, zText, -1, SQLITE_TRANSIENT);
sqlite4_free(sqlite4_context_env(context), zText);
}
break;
}
case SQLITE_TEXT: {
int i,j;
u64 n;
const unsigned char *zArg = sqlite4_value_text(argv[0]);
char *z;
if( zArg==0 ) return;
for(i=0, n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; }
z = contextMalloc(context, ((i64)i)+((i64)n)+3);
if( z ){
z[0] = '\'';
for(i=0, j=1; zArg[i]; i++){
z[j++] = zArg[i];
if( zArg[i]=='\'' ){
z[j++] = '\'';
}
}
z[j++] = '\'';
z[j] = 0;
sqlite4_result_text(context, z, j, SQLITE_DYNAMIC);
}
break;
}
default: {
assert( sqlite4_value_type(argv[0])==SQLITE_NULL );
sqlite4_result_text(context, "NULL", 4, SQLITE_STATIC);
break;
}
}
}
/*
** The hex() function. Interpret the argument as a blob. Return
** a hexadecimal rendering as text.
*/
static void hexFunc(
sqlite4_context *context,
int argc,
sqlite4_value **argv
){
int i, n;
const unsigned char *pBlob;
char *zHex, *z;
assert( argc==1 );
UNUSED_PARAMETER(argc);
pBlob = sqlite4_value_blob(argv[0]);
n = sqlite4_value_bytes(argv[0]);
assert( pBlob==sqlite4_value_blob(argv[0]) ); /* No encoding change */
z = zHex = contextMalloc(context, ((i64)n)*2 + 1);
if( zHex ){
for(i=0; i<n; i++, pBlob++){
unsigned char c = *pBlob;
*(z++) = hexdigits[(c>>4)&0xf];
*(z++) = hexdigits[c&0xf];
}
*z = 0;
sqlite4_result_text(context, zHex, n*2, SQLITE_DYNAMIC);
}
}
/*
** The zeroblob(N) function returns a zero-filled blob of size N bytes.
*/
static void zeroblobFunc(
sqlite4_context *context,
int argc,
sqlite4_value **argv
){
i64 n;
sqlite4 *db = sqlite4_context_db_handle(context);
assert( argc==1 );
UNUSED_PARAMETER(argc);
n = sqlite4_value_int64(argv[0]);
testcase( n==db->aLimit[SQLITE_LIMIT_LENGTH] );
testcase( n==db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
if( n>db->aLimit[SQLITE_LIMIT_LENGTH] ){
sqlite4_result_error_toobig(context);
}else{
sqlite4_result_zeroblob(context, (int)n); /* IMP: R-00293-64994 */
}
}
/*
** The replace() function. Three arguments are all strings: call
** them A, B, and C. The result is also a string which is derived
** from A by replacing every occurance of B with C. The match
** must be exact. Collating sequences are not used.
*/
static void replaceFunc(
sqlite4_context *context,
int argc,
sqlite4_value **argv
){
const unsigned char *zStr; /* The input string A */
const unsigned char *zPattern; /* The pattern string B */
const unsigned char *zRep; /* The replacement string C */
unsigned char *zOut; /* The output */
int nStr; /* Size of zStr */
int nPattern; /* Size of zPattern */
int nRep; /* Size of zRep */
i64 nOut; /* Maximum size of zOut */
int loopLimit; /* Last zStr[] that might match zPattern[] */
int i, j; /* Loop counters */
assert( argc==3 );
UNUSED_PARAMETER(argc);
zStr = sqlite4_value_text(argv[0]);
if( zStr==0 ) return;
nStr = sqlite4_value_bytes(argv[0]);
assert( zStr==sqlite4_value_text(argv[0]) ); /* No encoding change */
zPattern = sqlite4_value_text(argv[1]);
if( zPattern==0 ){
assert( sqlite4_value_type(argv[1])==SQLITE_NULL
|| sqlite4_context_db_handle(context)->mallocFailed );
return;
}
if( zPattern[0]==0 ){
assert( sqlite4_value_type(argv[1])!=SQLITE_NULL );
sqlite4_result_value(context, argv[0]);
return;
}
nPattern = sqlite4_value_bytes(argv[1]);
assert( zPattern==sqlite4_value_text(argv[1]) ); /* No encoding change */
zRep = sqlite4_value_text(argv[2]);
if( zRep==0 ) return;
nRep = sqlite4_value_bytes(argv[2]);
assert( zRep==sqlite4_value_text(argv[2]) );
nOut = nStr + 1;
assert( nOut<SQLITE_MAX_LENGTH );
zOut = contextMalloc(context, (i64)nOut);
if( zOut==0 ){
return;
}
loopLimit = nStr - nPattern;
for(i=j=0; i<=loopLimit; i++){
if( zStr[i]!=zPattern[0] || memcmp(&zStr[i], zPattern, nPattern) ){
zOut[j++] = zStr[i];
}else{
u8 *zOld;
sqlite4 *db = sqlite4_context_db_handle(context);
nOut += nRep - nPattern;
testcase( nOut-1==db->aLimit[SQLITE_LIMIT_LENGTH] );
testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] );
if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){
sqlite4_result_error_toobig(context);
sqlite4_free(db->pEnv, zOut);
return;
}
zOld = zOut;
zOut = sqlite4_realloc(db->pEnv, zOut, (int)nOut);
if( zOut==0 ){
sqlite4_result_error_nomem(context);
sqlite4_free(db->pEnv, zOld);
return;
}
memcpy(&zOut[j], zRep, nRep);
j += nRep;
i += nPattern-1;
}
}
assert( j+nStr-i+1==nOut );
memcpy(&zOut[j], &zStr[i], nStr-i);
j += nStr - i;
assert( j<=nOut );
zOut[j] = 0;
sqlite4_result_text(context, (char*)zOut, j, SQLITE_DYNAMIC);
}
/*
** Implementation of the TRIM(), LTRIM(), and RTRIM() functions.
** The userdata is 0x1 for left trim, 0x2 for right trim, 0x3 for both.
*/
static void trimFunc(
sqlite4_context *context,
int argc,
sqlite4_value **argv
){
const unsigned char *zIn; /* Input string */
const unsigned char *zCharSet; /* Set of characters to trim */
int nIn; /* Number of bytes in input */
int flags; /* 1: trimleft 2: trimright 3: trim */
int i; /* Loop counter */
unsigned char *aLen = 0; /* Length of each character in zCharSet */
unsigned char **azChar = 0; /* Individual characters in zCharSet */
int nChar; /* Number of characters in zCharSet */
if( sqlite4_value_type(argv[0])==SQLITE_NULL ){
return;
}
zIn = sqlite4_value_text(argv[0]);
if( zIn==0 ) return;
nIn = sqlite4_value_bytes(argv[0]);
assert( zIn==sqlite4_value_text(argv[0]) );
if( argc==1 ){
static const unsigned char lenOne[] = { 1 };
static unsigned char * const azOne[] = { (u8*)" " };
nChar = 1;
aLen = (u8*)lenOne;
azChar = (unsigned char **)azOne;
zCharSet = 0;
}else if( (zCharSet = sqlite4_value_text(argv[1]))==0 ){
return;
}else{
const unsigned char *z;
for(z=zCharSet, nChar=0; *z; nChar++){
SQLITE_SKIP_UTF8(z);
}
if( nChar>0 ){
azChar = contextMalloc(context, ((i64)nChar)*(sizeof(char*)+1));
if( azChar==0 ){
return;
}
aLen = (unsigned char*)&azChar[nChar];
for(z=zCharSet, nChar=0; *z; nChar++){
azChar[nChar] = (unsigned char *)z;
SQLITE_SKIP_UTF8(z);
aLen[nChar] = (u8)(z - azChar[nChar]);
}
}
}
if( nChar>0 ){
flags = SQLITE_PTR_TO_INT(sqlite4_user_data(context));
if( flags & 1 ){
while( nIn>0 ){
int len = 0;
for(i=0; i<nChar; i++){
len = aLen[i];
if( len<=nIn && memcmp(zIn, azChar[i], len)==0 ) break;
}
if( i>=nChar ) break;
zIn += len;
nIn -= len;
}
}
if( flags & 2 ){
while( nIn>0 ){
int len = 0;
for(i=0; i<nChar; i++){
len = aLen[i];
if( len<=nIn && memcmp(&zIn[nIn-len],azChar[i],len)==0 ) break;
}
if( i>=nChar ) break;
nIn -= len;
}
}
if( zCharSet ){
sqlite4_free(sqlite4_context_env(context), azChar);
}
}
sqlite4_result_text(context, (char*)zIn, nIn, SQLITE_TRANSIENT);
}
/* 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.
*/
#ifdef SQLITE_SOUNDEX
/*
** Compute the soundex encoding of a word.
**
** IMP: R-59782-00072 The soundex(X) function returns a string that is the
** soundex encoding of the string X.
*/
static void soundexFunc(
sqlite4_context *context,
int argc,
sqlite4_value **argv
){
char zResult[8];
const u8 *zIn;
int i, j;
static const unsigned char iCode[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,
1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,
1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
};
assert( argc==1 );
zIn = (u8*)sqlite4_value_text(argv[0]);
if( zIn==0 ) zIn = (u8*)"";
for(i=0; zIn[i] && !sqlite4Isalpha(zIn[i]); i++){}
if( zIn[i] ){
u8 prevcode = iCode[zIn[i]&0x7f];
zResult[0] = sqlite4Toupper(zIn[i]);
for(j=1; j<4 && zIn[i]; i++){
int code = iCode[zIn[i]&0x7f];
if( code>0 ){
if( code!=prevcode ){
prevcode = code;
zResult[j++] = code + '0';
}
}else{
prevcode = 0;
}
}
while( j<4 ){
zResult[j++] = '0';
}
zResult[j] = 0;
sqlite4_result_text(context, zResult, 4, SQLITE_TRANSIENT);
}else{
/* IMP: R-64894-50321 The string "?000" is returned if the argument
** is NULL or contains no ASCII alphabetic characters. */
sqlite4_result_text(context, "?000", 4, SQLITE_STATIC);
}
}
#endif /* SQLITE_SOUNDEX */
#if 0 /*ndef SQLITE_OMIT_LOAD_EXTENSION*/
/*
** A function that loads a shared-library extension then returns NULL.
*/
static void loadExt(sqlite4_context *context, int argc, sqlite4_value **argv){
const char *zFile = (const char *)sqlite4_value_text(argv[0]);
const char *zProc;
sqlite4 *db = sqlite4_context_db_handle(context);
char *zErrMsg = 0;
if( argc==2 ){
zProc = (const char *)sqlite4_value_text(argv[1]);
}else{
zProc = 0;
}
if( zFile && sqlite4_load_extension(db, zFile, zProc, &zErrMsg) ){
sqlite4_result_error(context, zErrMsg, -1);
sqlite4_free(zErrMsg);
}
}
#endif
/*
** An instance of the following structure holds the context of a
** sum() or avg() aggregate computation.
*/
typedef struct SumCtx SumCtx;
struct SumCtx {
double rSum; /* Floating point sum */
i64 iSum; /* Integer sum */
i64 cnt; /* Number of elements summed */
u8 overflow; /* True if integer overflow seen */
u8 approx; /* True if non-integer value was input to the sum */
};
/*
** Routines used to compute the sum, average, and total.
**
** The SUM() function follows the (broken) SQL standard which means
** that it returns NULL if it sums over no inputs. TOTAL returns
** 0.0 in that case. In addition, TOTAL always returns a float where
** SUM might return an integer if it never encounters a floating point
** value. TOTAL never fails, but SUM might through an exception if
** it overflows an integer.
*/
static void sumStep(sqlite4_context *context, int argc, sqlite4_value **argv){
SumCtx *p;
int type;
assert( argc==1 );
UNUSED_PARAMETER(argc);
p = sqlite4_aggregate_context(context, sizeof(*p));
type = sqlite4_value_numeric_type(argv[0]);
if( p && type!=SQLITE_NULL ){
p->cnt++;
if( type==SQLITE_INTEGER ){
i64 v = sqlite4_value_int64(argv[0]);
p->rSum += v;
if( (p->approx|p->overflow)==0 && sqlite4AddInt64(&p->iSum, v) ){
p->overflow = 1;
}
}else{
p->rSum += sqlite4_value_double(argv[0]);
p->approx = 1;
}
}
}
static void sumFinalize(sqlite4_context *context){
SumCtx *p;
p = sqlite4_aggregate_context(context, 0);
if( p && p->cnt>0 ){
if( p->overflow ){
sqlite4_result_error(context,"integer overflow",-1);
}else if( p->approx ){
sqlite4_result_double(context, p->rSum);
}else{
sqlite4_result_int64(context, p->iSum);
}
}
}
static void avgFinalize(sqlite4_context *context){
SumCtx *p;
p = sqlite4_aggregate_context(context, 0);
if( p && p->cnt>0 ){
sqlite4_result_double(context, p->rSum/(double)p->cnt);
}
}
static void totalFinalize(sqlite4_context *context){
SumCtx *p;
p = sqlite4_aggregate_context(context, 0);
/* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
sqlite4_result_double(context, p ? p->rSum : (double)0);
}
/*
** The following structure keeps track of state information for the
** count() aggregate function.
*/
typedef struct CountCtx CountCtx;
struct CountCtx {
i64 n;
};
/*
** Routines to implement the count() aggregate function.
*/
static void countStep(sqlite4_context *context, int argc, sqlite4_value **argv){
CountCtx *p;
p = sqlite4_aggregate_context(context, sizeof(*p));
if( (argc==0 || SQLITE_NULL!=sqlite4_value_type(argv[0])) && p ){
p->n++;
}
#ifndef SQLITE_OMIT_DEPRECATED
/* The sqlite4_aggregate_count() function is deprecated. But just to make
** sure it still operates correctly, verify that its count agrees with our
** internal count when using count(*) and when the total count can be
** expressed as a 32-bit integer. */
assert( argc==1 || p==0 || p->n>0x7fffffff
|| p->n==sqlite4_aggregate_count(context) );
#endif
}
static void countFinalize(sqlite4_context *context){
CountCtx *p;
p = sqlite4_aggregate_context(context, 0);
sqlite4_result_int64(context, p ? p->n : 0);
}
/*
** Routines to implement min() and max() aggregate functions.
*/
static void minmaxStep(
sqlite4_context *context,
int NotUsed,
sqlite4_value **argv
){
Mem *pArg = (Mem *)argv[0];
Mem *pBest;
UNUSED_PARAMETER(NotUsed);
if( sqlite4_value_type(argv[0])==SQLITE_NULL ) return;
pBest = (Mem *)sqlite4_aggregate_context(context, sizeof(*pBest));
if( !pBest ) return;
if( pBest->flags ){
int max;
int cmp;
CollSeq *pColl = sqlite4GetFuncCollSeq(context);
/* This step function is used for both the min() and max() aggregates,
** the only difference between the two being that the sense of the
** comparison is inverted. For the max() aggregate, the
** sqlite4_user_data() function returns (void *)-1. For min() it
** returns (void *)db, where db is the sqlite4* database pointer.
** Therefore the next statement sets variable 'max' to 1 for the max()
** aggregate, or 0 for min().
*/
max = sqlite4_user_data(context)!=0;
cmp = sqlite4MemCompare(pBest, pArg, pColl);
if( (max && cmp<0) || (!max && cmp>0) ){
sqlite4VdbeMemCopy(pBest, pArg);
}
}else{
sqlite4VdbeMemCopy(pBest, pArg);
}
}
static void minMaxFinalize(sqlite4_context *context){
sqlite4_value *pRes;
pRes = (sqlite4_value *)sqlite4_aggregate_context(context, 0);
if( pRes ){
if( ALWAYS(pRes->flags) ){
sqlite4_result_value(context, pRes);
}
sqlite4VdbeMemRelease(pRes);
}
}
/*
** group_concat(EXPR, ?SEPARATOR?)
*/
static void groupConcatStep(
sqlite4_context *context,
int argc,
sqlite4_value **argv
){
const char *zVal;
StrAccum *pAccum;
const char *zSep;
int nVal, nSep;
assert( argc==1 || argc==2 );
if( sqlite4_value_type(argv[0])==SQLITE_NULL ) return;
pAccum = (StrAccum*)sqlite4_aggregate_context(context, sizeof(*pAccum));
if( pAccum ){
sqlite4 *db = sqlite4_context_db_handle(context);
int firstTerm = pAccum->useMalloc==0;
pAccum->useMalloc = 2;
pAccum->pEnv = db->pEnv;
pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH];
if( !firstTerm ){
if( argc==2 ){
zSep = (char*)sqlite4_value_text(argv[1]);
nSep = sqlite4_value_bytes(argv[1]);
}else{
zSep = ",";
nSep = 1;
}
sqlite4StrAccumAppend(pAccum, zSep, nSep);
}
zVal = (char*)sqlite4_value_text(argv[0]);
nVal = sqlite4_value_bytes(argv[0]);
sqlite4StrAccumAppend(pAccum, zVal, nVal);
}
}
static void groupConcatFinalize(sqlite4_context *context){
StrAccum *pAccum;
pAccum = sqlite4_aggregate_context(context, 0);
if( pAccum ){
if( pAccum->tooBig ){
sqlite4_result_error_toobig(context);
}else if( pAccum->mallocFailed ){
sqlite4_result_error_nomem(context);
}else{
sqlite4_result_text(context, sqlite4StrAccumFinish(pAccum), -1,
SQLITE_DYNAMIC);
}
}
}
/*
** This routine does per-connection function registration. Most
** 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 sqlite4RegisterBuiltinFunctions(sqlite4 *db){
int rc = sqlite4_overload_function(db, "MATCH", 2);
assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
if( rc==SQLITE_NOMEM ){
db->mallocFailed = 1;
}
}
/*
** Set the LIKEOPT flag on the 2-argument function with the given name.
*/
static void setLikeOptFlag(sqlite4 *db, const char *zName, u8 flagVal){
FuncDef *pDef;
pDef = sqlite4FindFunction(db, zName, sqlite4Strlen30(zName),
2, SQLITE_UTF8, 0);
if( ALWAYS(pDef) ){
pDef->flags = flagVal;
}
}
/*
** Register the built-in LIKE and GLOB functions. The caseSensitive
** parameter determines whether or not the LIKE operator is case
** sensitive. GLOB is always case sensitive.
*/
SQLITE_PRIVATE void sqlite4RegisterLikeFunctions(sqlite4 *db, int caseSensitive){
struct compareInfo *pInfo;
if( caseSensitive ){
pInfo = (struct compareInfo*)&likeInfoAlt;
}else{
pInfo = (struct compareInfo*)&likeInfoNorm;
}
sqlite4CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0);
sqlite4CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0);
sqlite4CreateFunc(db, "glob", 2, SQLITE_UTF8,
(struct compareInfo*)&globInfo, likeFunc, 0, 0, 0);
setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
setLikeOptFlag(db, "like",
caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
}
/*
** 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
** return TRUE. If the function is not a LIKE-style function then
** return FALSE.
*/
SQLITE_PRIVATE int sqlite4IsLikeFunction(sqlite4 *db, Expr *pExpr, int *pIsNocase, char *aWc){
FuncDef *pDef;
if( pExpr->op!=TK_FUNCTION
|| !pExpr->x.pList
|| pExpr->x.pList->nExpr!=2
){
return 0;
}
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
pDef = sqlite4FindFunction(db, pExpr->u.zToken,
sqlite4Strlen30(pExpr->u.zToken),
2, SQLITE_UTF8, 0);
if( NEVER(pDef==0) || (pDef->flags & SQLITE_FUNC_LIKE)==0 ){
return 0;
}
/* The memcpy() statement assumes that the wildcard characters are
** the first three statements in the compareInfo structure. The
** asserts() that follow verify that assumption
*/
memcpy(aWc, pDef->pUserData, 3);
assert( (char*)&likeInfoAlt == (char*)&likeInfoAlt.matchAll );
assert( &((char*)&likeInfoAlt)[1] == (char*)&likeInfoAlt.matchOne );
assert( &((char*)&likeInfoAlt)[2] == (char*)&likeInfoAlt.matchSet );
*pIsNocase = (pDef->flags & SQLITE_FUNC_CASE)==0;
return 1;
}
/*
** Add all of the FuncDef structures in the aBuiltinFunc[] array above
** to the global function hash table. This occurs at start-time (as
** a consequence of calling sqlite4_initialize()).
**
** After this routine runs
*/
SQLITE_PRIVATE void sqlite4RegisterGlobalFunctions(sqlite4_env *pEnv){
/*
** The following array holds FuncDef structures for all of the functions
** defined in this file.
**
** The array cannot be constant since changes are made to the
** FuncDef.pNextName and FuncDef.pSameName elements at start-time.
*/
static FuncDef aBuiltinFunc[] = {
FUNCTION(ltrim, 1, 1, 0, trimFunc ),
FUNCTION(ltrim, 2, 1, 0, trimFunc ),
FUNCTION(rtrim, 1, 2, 0, trimFunc ),
FUNCTION(rtrim, 2, 2, 0, trimFunc ),
FUNCTION(trim, 1, 3, 0, trimFunc ),
FUNCTION(trim, 2, 3, 0, trimFunc ),
FUNCTION(min, -1, 0, 1, minmaxFunc ),
FUNCTION(min, 0, 0, 1, 0 ),
AGGREGATE(min, 1, 0, 1, minmaxStep, minMaxFinalize ),
FUNCTION(max, -1, 1, 1, minmaxFunc ),
FUNCTION(max, 0, 1, 1, 0 ),
AGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize ),
FUNCTION(typeof, 1, 0, 0, typeofFunc ),
FUNCTION(length, 1, 0, 0, lengthFunc ),
FUNCTION(substr, 2, 0, 0, substrFunc ),
FUNCTION(substr, 3, 0, 0, substrFunc ),
FUNCTION(abs, 1, 0, 0, absFunc ),
#ifndef SQLITE_OMIT_FLOATING_POINT
FUNCTION(round, 1, 0, 0, roundFunc ),
FUNCTION(round, 2, 0, 0, roundFunc ),
#endif
FUNCTION(upper, 1, 0, 0, upperFunc ),
FUNCTION(lower, 1, 0, 0, lowerFunc ),
FUNCTION(coalesce, 1, 0, 0, 0 ),
FUNCTION(coalesce, 0, 0, 0, 0 ),
/* FUNCTION(coalesce, -1, 0, 0, ifnullFunc ), */
{-1,SQLITE_UTF8,SQLITE_FUNC_COALESCE,0,0,ifnullFunc,0,0,"coalesce",0,0},
FUNCTION(hex, 1, 0, 0, hexFunc ),
/* FUNCTION(ifnull, 2, 0, 0, ifnullFunc ), */
{2,SQLITE_UTF8,SQLITE_FUNC_COALESCE,0,0,ifnullFunc,0,0,"ifnull",0,0},
FUNCTION(random, 0, 0, 0, randomFunc ),
FUNCTION(randomblob, 1, 0, 0, randomBlob ),
FUNCTION(nullif, 2, 0, 1, nullifFunc ),
FUNCTION(sqlite_version, 0, 0, 0, versionFunc ),
FUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ),
FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ),
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
FUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ),
FUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ),
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
FUNCTION(quote, 1, 0, 0, quoteFunc ),
FUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid),
FUNCTION(changes, 0, 0, 0, changes ),
FUNCTION(total_changes, 0, 0, 0, total_changes ),
FUNCTION(replace, 3, 0, 0, replaceFunc ),
FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ),
#ifdef SQLITE_SOUNDEX
FUNCTION(soundex, 1, 0, 0, soundexFunc ),
#endif
#if 0 /*ndef SQLITE_OMIT_LOAD_EXTENSION*/
FUNCTION(load_extension, 1, 0, 0, loadExt ),
FUNCTION(load_extension, 2, 0, 0, loadExt ),
#endif
AGGREGATE(sum, 1, 0, 0, sumStep, sumFinalize ),
AGGREGATE(total, 1, 0, 0, sumStep, totalFinalize ),
AGGREGATE(avg, 1, 0, 0, sumStep, avgFinalize ),
/* AGGREGATE(count, 0, 0, 0, countStep, countFinalize ), */
{0,SQLITE_UTF8,SQLITE_FUNC_COUNT,0,0,0,countStep,countFinalize,"count",0,0},
AGGREGATE(count, 1, 0, 0, countStep, countFinalize ),
AGGREGATE(group_concat, 1, 0, 0, groupConcatStep, groupConcatFinalize),
AGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize),
LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
#ifdef SQLITE_CASE_SENSITIVE_LIKE
LIKEFUNC(like, 2, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
LIKEFUNC(like, 3, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
#else
LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE),
LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE),
#endif
};
int i;
FuncDefTable *pFuncTab = &pEnv->aGlobalFuncs;
FuncDef *aFunc = (FuncDef*)aBuiltinFunc;
for(i=0; i<ArraySize(aBuiltinFunc); i++){
sqlite4FuncDefInsert(pFuncTab, &aFunc[i], 1);
}
sqlite4RegisterDateTimeFunctions(pEnv);
#ifndef SQLITE_OMIT_ALTERTABLE
sqlite4AlterFunctions(pEnv);
#endif
}
/************** End of func.c ************************************************/
/************** Begin file fkey.c ********************************************/
/*
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used by the compiler to add foreign key
** support to compiled SQL statements.
*/
#ifndef SQLITE_OMIT_FOREIGN_KEY
#ifndef SQLITE_OMIT_TRIGGER
/*
** Deferred and Immediate FKs
** --------------------------
**
** Foreign keys in SQLite come in two flavours: deferred and immediate.
** If an immediate foreign key constraint is violated, SQLITE_CONSTRAINT
** is returned and the current statement transaction rolled back. If a
** deferred foreign key constraint is violated, no action is taken
** immediately. However if the application attempts to commit the
** transaction before fixing the constraint violation, the attempt fails.
**
** Deferred constraints are implemented using a simple counter associated
** with the database handle. The counter is set to zero each time a
** database transaction is opened. Each time a statement is executed
** that causes a foreign key violation, the counter is incremented. Each
** time a statement is executed that removes an existing violation from
** the database, the counter is decremented. When the transaction is
** committed, the commit fails if the current value of the counter is
** greater than zero. This scheme has two big drawbacks:
**
** * When a commit fails due to a deferred foreign key constraint,
** there is no way to tell which foreign constraint is not satisfied,
** or which row it is not satisfied for.
**
** * If the database contains foreign key violations when the
** transaction is opened, this may cause the mechanism to malfunction.
**
** Despite these problems, this approach is adopted as it seems simpler
** than the alternatives.
**
** INSERT operations:
**
** I.1) For each FK for which the table is the child table, search
** the parent table for a match. If none is found increment the
** constraint counter.
**
** I.2) For each FK for which the table is the parent table,
** search the child table for rows that correspond to the new
** row in the parent table. Decrement the counter for each row
** found (as the constraint is now satisfied).
**
** DELETE operations:
**
** D.1) For each FK for which the table is the child table,
** search the parent table for a row that corresponds to the
** deleted row in the child table. If such a row is not found,
** decrement the counter.
**
** D.2) For each FK for which the table is the parent table, search
** the child table for rows that correspond to the deleted row
** in the parent table. For each found increment the counter.
**
** UPDATE operations:
**
** An UPDATE command requires that all 4 steps above are taken, but only
** for FK constraints for which the affected columns are actually
** modified (values must be compared at runtime).
**
** Note that I.1 and D.1 are very similar operations, as are I.2 and D.2.
** This simplifies the implementation a bit.
**
** For the purposes of immediate FK constraints, the OR REPLACE conflict
** resolution is considered to delete rows before the new row is inserted.
** If a delete caused by OR REPLACE violates an FK constraint, an exception
** is thrown, even if the FK constraint would be satisfied after the new
** row is inserted.
**
** Immediate constraints are usually handled similarly. The only difference
** is that the counter used is stored as part of each individual statement
** object (struct Vdbe). If, after the statement has run, its immediate
** constraint counter is greater than zero, it returns SQLITE_CONSTRAINT
** and the statement transaction is rolled back. An exception is an INSERT
** statement that inserts a single row only (no triggers). In this case,
** instead of using a counter, an exception is thrown immediately if the
** INSERT violates a foreign key constraint. This is necessary as such
** an INSERT does not open a statement transaction.
**
** TODO: How should dropping a table be handled? How should renaming a
** table be handled?
**
**
** Query API Notes
** ---------------
**
** Before coding an UPDATE or DELETE row operation, the code-generator
** for those two operations needs to know whether or not the operation
** requires any FK processing and, if so, which columns of the original
** row are required by the FK processing VDBE code (i.e. if FKs were
** implemented using triggers, which of the old.* columns would be
** accessed). No information is required by the code-generator before
** coding an INSERT operation. The functions used by the UPDATE/DELETE
** generation code to query for this information are:
**
** sqlite4FkRequired() - Test to see if FK processing is required.
** sqlite4FkOldmask() - Query for the set of required old.* columns.
**
**
** Externally accessible module functions
** --------------------------------------
**
** sqlite4FkCheck() - Check for foreign key violations.
** sqlite4FkActions() - Code triggers for ON UPDATE/ON DELETE actions.
** sqlite4FkDelete() - Delete an FKey structure.
*/
/*
** VDBE Calling Convention
** -----------------------
**
** Example:
**
** For the following INSERT statement:
**
** CREATE TABLE t1(a, b INTEGER PRIMARY KEY, c);
** INSERT INTO t1 VALUES(1, 2, 3.1);
**
** Register (x): 2 (type integer)
** Register (x+1): 1 (type integer)
** Register (x+2): NULL (type NULL)
** Register (x+3): 3.1 (type real)
*/
/*
** A foreign key constraint requires that the key columns in the parent
** table are collectively subject to a UNIQUE or PRIMARY KEY constraint.
** Given that pParent is the parent table for foreign key constraint pFKey,
** search the schema for a unique index on the parent key columns.
**
** If successful, zero is returned and *ppIdx is set to point to the
** unique index.
**
** If the parent key consists of a single column (the foreign key constraint
** is not a composite foreign key), output variable *paiCol is set to NULL.
** Otherwise, it is set to point to an allocated array of size N, where
** N is the number of columns in the parent key. The first element of the
** array is the index of the child table column that is mapped by the FK
** constraint to the parent table column stored in the left-most column
** of index *ppIdx. The second element of the array is the index of the
** child table column that corresponds to the second left-most column of
** *ppIdx, and so on.
**
** If the required index cannot be found, either because:
**
** 1) The named parent key columns do not exist, or
**
** 2) The named parent key columns do exist, but are not subject to a
** UNIQUE or PRIMARY KEY constraint, or
**
** 3) No parent key columns were provided explicitly as part of the
** foreign key definition, and the parent table does not have a
** PRIMARY KEY, or
**
** 4) No parent key columns were provided explicitly as part of the
** foreign key definition, and the PRIMARY KEY of the parent table
** consists of a a different number of columns to the child key in
** the child table.
**
** then non-zero is returned, and a "foreign key mismatch" error loaded
** into pParse. If an OOM error occurs, non-zero is returned and the
** pParse->db->mallocFailed flag is set.
*/
static int locateFkeyIndex(
Parse *pParse, /* Parse context to store any error in */
Table *pParent, /* Parent table of FK constraint pFKey */
FKey *pFKey, /* Foreign key to find index for */
Index **ppIdx, /* OUT: Unique index on parent table */
int **paiCol /* OUT: Map of index columns in pFKey */
){
Index *pIdx = 0; /* Value to return via *ppIdx */
int *aiCol = 0; /* Value to return via *paiCol */
int nCol = pFKey->nCol; /* Number of columns in parent key */
int bImplicit; /* True if no explicit parent columns */
/* The caller is responsible for zeroing output parameters. */
assert( ppIdx && *ppIdx==0 );
assert( !paiCol || *paiCol==0 );
assert( pParse );
bImplicit = (pFKey->aCol[0].zCol==0);
/* If this is a composite foreign key (more than one column), allocate
** space for the aiCol array (returned via output parameter *paiCol).
** Non-composite foreign keys do not require the aiCol array. */
if( paiCol && nCol>1 ){
assert( nCol>1 );
aiCol = (int *)sqlite4DbMallocRaw(pParse->db, nCol*sizeof(int));
if( !aiCol ) return 1;
*paiCol = aiCol;
}
for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){
if( pIdx->nColumn==nCol
&& pIdx->onError!=OE_None
&& pIdx->aiColumn[0]!=-1
){
/* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number
** of columns. If each indexed column corresponds to a foreign key
** column of pFKey, then this index is a winner. */
if( bImplicit ){
if( pIdx->eIndexType==SQLITE_INDEX_PRIMARYKEY ){
if( aiCol ){
int i;
for(i=0; i<nCol; i++) aiCol[i] = pFKey->aCol[i].iFrom;
}
break;
}
}else{
/* If this foreign key was declared to map to an explicit list of
** columns in table pParent. Check if this index matches those
** columns. Also, check that the index uses the default collation
** sequences for each column. */
int i, j;
for(i=0; i<nCol; i++){
int iCol = pIdx->aiColumn[i]; /* Index of column in parent tbl */
char *zDfltColl; /* Def. collation for column */
char *zIdxCol; /* Name of indexed column */
/* 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 = pParent->aCol[iCol].zColl;
if( !zDfltColl ){
zDfltColl = "BINARY";
}
if( sqlite4StrICmp(pIdx->azColl[i], zDfltColl) ) break;
zIdxCol = pParent->aCol[iCol].zName;
for(j=0; j<nCol; j++){
if( sqlite4StrICmp(pFKey->aCol[j].zCol, zIdxCol)==0 ){
if( aiCol ) aiCol[i] = pFKey->aCol[j].iFrom;
break;
}
}
if( j==nCol ) break;
}
if( i==nCol ) break; /* pIdx is usable */
}
}
}
if( !pIdx ){
if( !pParse->disableTriggers ){
sqlite4ErrorMsg(pParse, "foreign key mismatch");
}
sqlite4DbFree(pParse->db, aiCol);
return 1;
}
*ppIdx = pIdx;
return 0;
}
/*
** This function is called when a row is inserted into or deleted from the
** child table of foreign key constraint pFKey. If an SQL UPDATE is executed
** on the child table of pFKey, this function is invoked twice for each row
** affected - once to "delete" the old row, and then again to "insert" the
** new row.
**
** Each time it is called, this function generates VDBE code to locate the
** row in the parent table that corresponds to the row being inserted into
** or deleted from the child table. If the parent row can be found, no
** special action is taken. Otherwise, if the parent row can *not* be
** found in the parent table:
**
** Operation | FK type | Action taken
** --------------------------------------------------------------------------
** INSERT immediate Increment the "immediate constraint counter".
**
** DELETE immediate Decrement the "immediate constraint counter".
**
** INSERT deferred Increment the "deferred constraint counter".
**
** DELETE deferred Decrement the "deferred constraint counter".
**
** These operations are identified in the comment at the top of this file
** (fkey.c) as "I.1" and "D.1".
*/
static void fkLookupParent(
Parse *pParse, /* Parse context */
int iDb, /* Index of database housing pTab */
Table *pTab, /* Parent table of FK pFKey */
Index *pIdx, /* Unique index on parent key columns in pTab */
FKey *pFKey, /* Foreign key constraint */
int *aiCol, /* Map from parent key columns to child table columns */
int regContent, /* Address of array containing child table row */
int nIncr, /* Increment constraint counter by this */
int isIgnore /* If true, pretend pTab contains all NULL values */
){
int i; /* Iterator variable */
Vdbe *v = sqlite4GetVdbe(pParse); /* Vdbe to add code to */
int iCur = pParse->nTab - 1; /* Cursor number to use */
int iOk = sqlite4VdbeMakeLabel(v); /* jump here if parent key found */
assert( pIdx );
/* If nIncr is less than zero (this is a DELETE), then check at runtime if
** there are any outstanding constraints to resolve. If there are not,
** there is no need to check if deleting this row resolves any outstanding
** violations. */
if( nIncr<0 ){
sqlite4VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, iOk);
}
/* Check if any of the key columns in the child table row are NULL. If
** any are, then the constraint is considered satisfied. No need to
** search for a matching row in the parent table. */
for(i=0; i<pFKey->nCol; i++){
int iReg = aiCol[i] + regContent;
sqlite4VdbeAddOp2(v, OP_IsNull, iReg, iOk);
}
if( isIgnore==0 ){
int nCol = pFKey->nCol;
int regTemp = sqlite4GetTempRange(pParse, nCol);
int regRec = sqlite4GetTempReg(pParse);
sqlite4OpenIndex(pParse, iCur, iDb, pIdx, OP_OpenRead);
/* Assemble the child key values in a contiguous array of registers.
** Then apply the affinity transformation for the parent index. */
for(i=0; i<nCol; i++){
sqlite4VdbeAddOp2(v, OP_Copy, aiCol[i]+regContent, regTemp+i);
}
sqlite4VdbeAddOp2(v, OP_Affinity, regTemp, nCol);
sqlite4VdbeChangeP4(v, -1, sqlite4IndexAffinityStr(v, pIdx), P4_TRANSIENT);
/* If the parent table is the same as the child table, and we are about
** to increment the constraint-counter (i.e. this is an INSERT operation),
** then check if the row being inserted matches itself. If so, do not
** increment the constraint-counter.
**
** If any of the parent-key values are NULL, then the row cannot match
** itself. So set JUMPIFNULL to make sure we do the OP_Found if any
** of the parent-key values are NULL (at this point it is known that
** none of the child key values are). */
if( pTab==pFKey->pFrom && nIncr==1 ){
int iJump = sqlite4VdbeCurrentAddr(v) + nCol + 1;
for(i=0; i<nCol; i++){
int iChild = regTemp+i;
int iParent = pIdx->aiColumn[i]+regContent;
sqlite4VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent);
sqlite4VdbeChangeP5(v, SQLITE_JUMPIFNULL);
assert( iChild<=pParse->nMem && iParent<=pParse->nMem );
}
sqlite4VdbeAddOp2(v, OP_Goto, 0, iOk);
}
sqlite4VdbeAddOp4Int(v, OP_MakeIdxKey, iCur, regTemp, regRec, nCol);
sqlite4VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0);
#if 0
sqlite4VdbeAddOp3(v, OP_MakeRecord, regTemp, nCol, regRec);
sqlite4VdbeChangeP4(v, -1, sqlite4IndexAffinityStr(v,pIdx), P4_TRANSIENT);
sqlite4VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0);
#endif
sqlite4ReleaseTempReg(pParse, regRec);
sqlite4ReleaseTempRange(pParse, regTemp, nCol);
}
if( !pFKey->isDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){
/* Special case: If this is an INSERT statement that will insert exactly
** one row into the table, raise a constraint immediately instead of
** incrementing a counter. This is necessary as the VM code is being
** generated for will not open a statement transaction. */
assert( nIncr==1 );
sqlite4HaltConstraint(
pParse, OE_Abort, "foreign key constraint failed", P4_STATIC
);
}else{
if( nIncr>0 && pFKey->isDeferred==0 ){
sqlite4ParseToplevel(pParse)->mayAbort = 1;
}
sqlite4VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
}
sqlite4VdbeResolveLabel(v, iOk);
sqlite4VdbeAddOp1(v, OP_Close, iCur);
}
/*
** This function is called to generate code executed when a row is inserted
** into or deleted from the parent table of foreign key constraint pFKey.
** When generating code for an SQL UPDATE operation, this function may be
** called twice - once to "delete" the old row and once to "insert" the
** new row.
**
** The code generated by this function scans through the rows in the child
** table that correspond to the parent table row being deleted or inserted.
** For each child row found, one of the following actions is taken:
**
** Operation | FK type | Action taken
** --------------------------------------------------------------------------
** DELETE immediate Increment the "immediate constraint counter".
** Or, if the ON (UPDATE|DELETE) action is RESTRICT,
** throw a "foreign key constraint failed" exception.
**
** INSERT immediate Decrement the "immediate constraint counter".
**
** DELETE deferred Increment the "deferred constraint counter".
** Or, if the ON (UPDATE|DELETE) action is RESTRICT,
** throw a "foreign key constraint failed" exception.
**
** INSERT deferred Decrement the "deferred constraint counter".
**
** These operations are identified in the comment at the top of this file
** (fkey.c) as "I.2" and "D.2".
*/
static void fkScanChildren(
Parse *pParse, /* Parse context */
SrcList *pSrc, /* SrcList containing the table to scan */
Table *pTab,
Index *pIdx, /* Foreign key index */
FKey *pFKey, /* Foreign key relationship */
int *aiCol, /* Map from pIdx cols to child table cols */
int regData, /* Referenced table data starts here */
int nIncr /* Amount to increment deferred counter by */
){
sqlite4 *db = pParse->db; /* Database handle */
int i; /* Iterator variable */
Expr *pWhere = 0; /* WHERE clause to scan with */
NameContext sNameContext; /* Context used to resolve WHERE clause */
WhereInfo *pWInfo; /* Context used by sqlite4WhereXXX() */
int iFkIfZero = 0; /* Address of OP_FkIfZero */
Vdbe *v = sqlite4GetVdbe(pParse);
assert( pIdx && pIdx->pTable==pTab );
if( nIncr<0 ){
iFkIfZero = sqlite4VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, 0);
}
/* Create an Expr object representing an SQL expression like:
**
** <parent-key1> = <child-key1> AND <parent-key2> = <child-key2> ...
**
** The collation sequence used for the comparison should be that of
** the parent key columns. The affinity of the parent key column should
** be applied to each child key value before the comparison takes place.
*/
for(i=0; i<pFKey->nCol; i++){
Expr *pLeft; /* Value from parent table row */
Expr *pRight; /* Column ref to child table */
Expr *pEq; /* Expression (pLeft = pRight) */
int iCol; /* Index of column in child table */
const char *zCol; /* Name of column in child table */
pLeft = sqlite4Expr(db, TK_REGISTER, 0);
if( pLeft ){
/* Set the collation sequence and affinity of the LHS of each TK_EQ
** expression to the parent key column defaults. */
Column *pCol;
iCol = pIdx->aiColumn[i];
pCol = &pTab->aCol[iCol];
pLeft->iTable = regData+iCol;
pLeft->affinity = pCol->affinity;
pLeft->pColl = sqlite4LocateCollSeq(pParse, pCol->zColl);
}
iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
assert( iCol>=0 );
zCol = pFKey->pFrom->aCol[iCol].zName;
pRight = sqlite4Expr(db, TK_ID, zCol);
pEq = sqlite4PExpr(pParse, TK_EQ, pLeft, pRight, 0);
pWhere = sqlite4ExprAnd(db, pWhere, pEq);
}
/* If the child table is the same as the parent table, and this scan
** is taking place as part of a DELETE operation (operation D.2), omit the
** row being deleted from the scan by adding ($rowid != rowid) to the WHERE
** clause, where $rowid is the rowid of the row being deleted. */
if( pTab==pFKey->pFrom && nIncr>0 ){
Expr *pEq; /* Expression (pLeft = pRight) */
Expr *pLeft; /* Value from parent table row */
Expr *pRight; /* Column ref to child table */
pLeft = sqlite4Expr(db, TK_REGISTER, 0);
pRight = sqlite4Expr(db, TK_COLUMN, 0);
if( pLeft && pRight ){
pLeft->iTable = regData;
pLeft->affinity = SQLITE_AFF_INTEGER;
pRight->iTable = pSrc->a[0].iCursor;
pRight->iColumn = -1;
}
pEq = sqlite4PExpr(pParse, TK_NE, pLeft, pRight, 0);
pWhere = sqlite4ExprAnd(db, pWhere, pEq);
}
/* Resolve the references in the WHERE clause. */
memset(&sNameContext, 0, sizeof(NameContext));
sNameContext.pSrcList = pSrc;
sNameContext.pParse = pParse;
sqlite4ResolveExprNames(&sNameContext, pWhere);
/* Create VDBE to loop through the entries in pSrc that match the WHERE
** clause. For each row found, increment the relevant constraint counter
** by nIncr. */
pWInfo = sqlite4WhereBegin(pParse, pSrc, pWhere, 0, 0, 0);
if( nIncr>0 && pFKey->isDeferred==0 ){
sqlite4ParseToplevel(pParse)->mayAbort = 1;
}
sqlite4VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
if( pWInfo ){
sqlite4WhereEnd(pWInfo);
}
/* Clean up the WHERE clause constructed above. */
sqlite4ExprDelete(db, pWhere);
if( iFkIfZero ){
sqlite4VdbeJumpHere(v, iFkIfZero);
}
}
/*
** This function returns a pointer to the head of a linked list of FK
** constraints for which table pTab is the parent table. For example,
** given the following schema:
**
** CREATE TABLE t1(a PRIMARY KEY);
** CREATE TABLE t2(b REFERENCES t1(a);
**
** Calling this function with table "t1" as an argument returns a pointer
** to the FKey structure representing the foreign key constraint on table
** "t2". Calling this function with "t2" as the argument would return a
** NULL pointer (as there are no FK constraints for which t2 is the parent
** table).
*/
SQLITE_PRIVATE FKey *sqlite4FkReferences(Table *pTab){
int nName = sqlite4Strlen30(pTab->zName);
return (FKey *)sqlite4HashFind(&pTab->pSchema->fkeyHash, pTab->zName, nName);
}
/*
** The second argument is a Trigger structure allocated by the
** fkActionTrigger() routine. This function deletes the Trigger structure
** and all of its sub-components.
**
** The Trigger structure or any of its sub-components may be allocated from
** the lookaside buffer belonging to database handle dbMem.
*/
static void fkTriggerDelete(sqlite4 *dbMem, Trigger *p){
if( p ){
TriggerStep *pStep = p->step_list;
sqlite4ExprDelete(dbMem, pStep->pWhere);
sqlite4ExprListDelete(dbMem, pStep->pExprList);
sqlite4SelectDelete(dbMem, pStep->pSelect);
sqlite4ExprDelete(dbMem, p->pWhen);
sqlite4DbFree(dbMem, p);
}
}
/*
** This function is called to generate code that runs when table pTab is
** being dropped from the database. The SrcList passed as the second argument
** to this function contains a single entry guaranteed to resolve to
** table pTab.
**
** Normally, no code is required. However, if either
**
** (a) The table is the parent table of a FK constraint, or
** (b) The table is the child table of a deferred FK constraint and it is
** determined at runtime that there are outstanding deferred FK
** constraint violations in the database,
**
** then the equivalent of "DELETE FROM <tbl>" is executed before dropping
** the table from the database. Triggers are disabled while running this
** DELETE, but foreign key actions are not.
*/
SQLITE_PRIVATE void sqlite4FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){
sqlite4 *db = pParse->db;
if( (db->flags&SQLITE_ForeignKeys) && !IsVirtual(pTab) && !pTab->pSelect ){
int iSkip = 0;
Vdbe *v = sqlite4GetVdbe(pParse);
assert( v ); /* VDBE has already been allocated */
if( sqlite4FkReferences(pTab)==0 ){
/* Search for a deferred foreign key constraint for which this table
** is the child table. If one cannot be found, return without
** generating any VDBE code. If one can be found, then jump over
** the entire DELETE if there are no outstanding deferred constraints
** when this statement is run. */
FKey *p;
for(p=pTab->pFKey; p; p=p->pNextFrom){
if( p->isDeferred ) break;
}
if( !p ) return;
iSkip = sqlite4VdbeMakeLabel(v);
sqlite4VdbeAddOp2(v, OP_FkIfZero, 1, iSkip);
}
pParse->disableTriggers = 1;
sqlite4DeleteFrom(pParse, sqlite4SrcListDup(db, pName, 0), 0);
pParse->disableTriggers = 0;
/* If the DELETE has generated immediate foreign key constraint
** violations, halt the VDBE and return an error at this point, before
** any modifications to the schema are made. This is because statement
** transactions are not able to rollback schema changes. */
sqlite4VdbeAddOp2(v, OP_FkIfZero, 0, sqlite4VdbeCurrentAddr(v)+2);
sqlite4HaltConstraint(
pParse, OE_Abort, "foreign key constraint failed", P4_STATIC
);
if( iSkip ){
sqlite4VdbeResolveLabel(v, iSkip);
}
}
}
/*
** This function is called when inserting, deleting or updating a row of
** table pTab to generate VDBE code to perform foreign key constraint
** processing for the operation.
**
** For a DELETE operation, parameter regOld is passed the index of the
** first register in an array of (pTab->nCol+1) registers containing the
** rowid of the row being deleted, followed by each of the column values
** of the row being deleted, from left to right. Parameter regNew is passed
** zero in this case.
**
** For an INSERT operation, regOld is passed zero and regNew is passed the
** first register of an array of (pTab->nCol+1) registers containing the new
** row data.
**
** For an UPDATE operation, this function is called twice. Once before
** the original record is deleted from the table using the calling convention
** described for DELETE. Then again after the original record is deleted
** but before the new record is inserted using the INSERT convention.
*/
SQLITE_PRIVATE void sqlite4FkCheck(
Parse *pParse, /* Parse context */
Table *pTab, /* Row is being deleted from this table */
int regOld, /* Previous row data is stored here */
int regNew /* New row data is stored here */
){
sqlite4 *db = pParse->db; /* Database handle */
FKey *pFKey; /* Used to iterate through FKs */
int iDb; /* Index of database containing pTab */
const char *zDb; /* Name of database containing pTab */
int isIgnoreErrors = pParse->disableTriggers;
/* Exactly one of regOld and regNew should be non-zero. */
assert( (regOld==0)!=(regNew==0) );
/* If foreign-keys are disabled, this function is a no-op. */
if( (db->flags&SQLITE_ForeignKeys)==0 ) return;
iDb = sqlite4SchemaToIndex(db, pTab->pSchema);
zDb = db->aDb[iDb].zName;
/* Loop through all the foreign key constraints for which pTab is the
** child table (the table that the foreign key definition is part of). */
for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){
Table *pTo; /* Parent table of foreign key pFKey */
Index *pIdx = 0; /* Index on key columns in pTo */
int *aiFree = 0;
int *aiCol;
int iCol;
int i;
int isIgnore = 0;
/* Find the parent table of this foreign key. Also find a unique index
** on the parent key columns in the parent table. If either of these
** schema items cannot be located, set an error in pParse and return
** early. */
if( pParse->disableTriggers ){
pTo = sqlite4FindTable(db, pFKey->zTo, zDb);
}else{
pTo = sqlite4LocateTable(pParse, 0, pFKey->zTo, zDb);
}
if( !pTo || locateFkeyIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){
assert( isIgnoreErrors==0 || (regOld!=0 && regNew==0) );
if( !isIgnoreErrors || db->mallocFailed ) return;
if( pTo==0 ){
/* If isIgnoreErrors is true, then a table is being dropped. In this
** case SQLite runs a "DELETE FROM xxx" on the table being dropped
** before actually dropping it in order to check FK constraints.
** If the parent table of an FK constraint on the current table is
** missing, behave as if it is empty. i.e. decrement the relevant
** FK counter for each row of the current table with non-NULL keys.
*/
Vdbe *v = sqlite4GetVdbe(pParse);
int iJump = sqlite4VdbeCurrentAddr(v) + pFKey->nCol + 1;
for(i=0; i<pFKey->nCol; i++){
int iReg = pFKey->aCol[i].iFrom + regOld;
sqlite4VdbeAddOp2(v, OP_IsNull, iReg, iJump);
}
sqlite4VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, -1);
}
continue;
}
assert( pFKey->nCol==1 || (aiFree && pIdx) );
if( aiFree ){
aiCol = aiFree;
}else{
iCol = pFKey->aCol[0].iFrom;
aiCol = &iCol;
}
#ifndef SQLITE_OMIT_AUTHORIZATION
for(i=0; i<pFKey->nCol; i++){
/* Request permission to read the parent key columns. If the
** authorization callback returns SQLITE_IGNORE, behave as if any
** values read from the parent table are NULL. */
if( db->xAuth ){
int rcauth;
char *zCol = pTo->aCol[pIdx->aiColumn[i]].zName;
rcauth = sqlite4AuthReadCol(pParse, pTo->zName, zCol, iDb);
isIgnore = (rcauth==SQLITE_IGNORE);
}
}
#endif
pParse->nTab++;
if( regOld!=0 ){
/* A row is being removed from the child table. Search for the parent.
** If the parent does not exist, removing the child row resolves an
** outstanding foreign key constraint violation. */
fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regOld, -1,isIgnore);
}
if( regNew!=0 ){
/* A row is being added to the child table. If a parent row cannot
** be found, adding the child row has violated the FK constraint. */
fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1,isIgnore);
}
sqlite4DbFree(db, aiFree);
}
/* Loop through all the foreign key constraints that refer to this table */
for(pFKey = sqlite4FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){
Index *pIdx = 0; /* Foreign key index for pFKey */
SrcList *pSrc;
int *aiCol = 0;
if( !pFKey->isDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){
assert( regOld==0 && regNew!=0 );
/* Inserting a single row into a parent table cannot cause an immediate
** foreign key violation. So do nothing in this case. */
continue;
}
if( locateFkeyIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){
if( !isIgnoreErrors || db->mallocFailed ) return;
continue;
}
assert( aiCol || pFKey->nCol==1 );
/* Create a SrcList structure containing a single table (the table
** the foreign key that refers to this table is attached to). This
** is required for the sqlite4WhereXXX() interface. */
pSrc = sqlite4SrcListAppend(db, 0, 0, 0);
if( pSrc ){
struct SrcList_item *pItem = pSrc->a;
pItem->pTab = pFKey->pFrom;
pItem->zName = pFKey->pFrom->zName;
pItem->pTab->nRef++;
pItem->iCursor = pParse->nTab++;
if( regNew!=0 ){
fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1);
}
if( regOld!=0 ){
/* If there is a RESTRICT action configured for the current operation
** on the parent table of this FK, then throw an exception
** immediately if the FK constraint is violated, even if this is a
** deferred trigger. That's what RESTRICT means. To defer checking
** the constraint, the FK should specify NO ACTION (represented
** using OE_None). NO ACTION is the default. */
fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regOld, 1);
}
pItem->zName = 0;
sqlite4SrcListDelete(db, pSrc);
}
sqlite4DbFree(db, aiCol);
}
}
#define COLUMN_MASK(x) (((x)>31) ? 0xffffffff : ((u32)1<<(x)))
/*
** This function is called before generating code to update or delete a
** row contained in table pTab.
*/
SQLITE_PRIVATE u32 sqlite4FkOldmask(
Parse *pParse, /* Parse context */
Table *pTab /* Table being modified */
){
u32 mask = 0;
if( pParse->db->flags&SQLITE_ForeignKeys ){
FKey *p;
int i;
for(p=pTab->pFKey; p; p=p->pNextFrom){
for(i=0; i<p->nCol; i++) mask |= COLUMN_MASK(p->aCol[i].iFrom);
}
for(p=sqlite4FkReferences(pTab); p; p=p->pNextTo){
Index *pIdx = 0;
locateFkeyIndex(pParse, pTab, p, &pIdx, 0);
if( pIdx ){
for(i=0; i<pIdx->nColumn; i++) mask |= COLUMN_MASK(pIdx->aiColumn[i]);
}
}
}
return mask;
}
/*
** This function is called before generating code to update or delete a
** row contained in table pTab. If the operation is a DELETE, then
** parameter aChange is passed a NULL value. For an UPDATE, aChange points
** to an array of size N, where N is the number of columns in table pTab.
** If the i'th column is not modified by the UPDATE, then the corresponding
** entry in the aChange[] array is set to -1. If the column is modified,
** the value is 0 or greater. Parameter chngRowid is set to true if the
** UPDATE statement modifies the rowid fields of the table.
**
** If any foreign key processing will be required, this function returns
** true. If there is no foreign key related processing, this function
** returns false.
*/
SQLITE_PRIVATE int sqlite4FkRequired(
Parse *pParse, /* Parse context */
Table *pTab, /* Table being modified */
int *aChange /* Non-NULL for UPDATE operations */
){
if( pParse->db->flags&SQLITE_ForeignKeys ){
if( !aChange ){
/* A DELETE operation. Foreign key processing is required if the
** table in question is either the child or parent table for any
** foreign key constraint. */
return (sqlite4FkReferences(pTab) || pTab->pFKey);
}else{
/* This is an UPDATE. Foreign key processing is only required if the
** operation modifies one or more child or parent key columns. */
int i;
FKey *p;
/* Check if any child key columns are being modified. */
for(p=pTab->pFKey; p; p=p->pNextFrom){
for(i=0; i<p->nCol; i++){
int iChildKey = p->aCol[i].iFrom;
if( aChange[iChildKey]>=0 ) return 1;
}
}
/* Check if any parent key columns are being modified. */
for(p=sqlite4FkReferences(pTab); p; p=p->pNextTo){
for(i=0; i<p->nCol; i++){
char *zKey = p->aCol[i].zCol;
int iKey;
for(iKey=0; iKey<pTab->nCol; iKey++){
Column *pCol = &pTab->aCol[iKey];
if( (zKey ? !sqlite4StrICmp(pCol->zName, zKey) : pCol->isPrimKey) ){
if( aChange[iKey]>=0 ) return 1;
}
}
}
}
}
}
return 0;
}
/*
** This function is called when an UPDATE or DELETE operation is being
** compiled on table pTab, which is the parent table of foreign-key pFKey.
** If the current operation is an UPDATE, then the pChanges parameter is
** passed a pointer to the list of columns being modified. If it is a
** DELETE, pChanges is passed a NULL pointer.
**
** It returns a pointer to a Trigger structure containing a trigger
** equivalent to the ON UPDATE or ON DELETE action specified by pFKey.
** If the action is "NO ACTION" or "RESTRICT", then a NULL pointer is
** returned (these actions require no special handling by the triggers
** sub-system, code for them is created by fkScanChildren()).
**
** For example, if pFKey is the foreign key and pTab is table "p" in
** the following schema:
**
** CREATE TABLE p(pk PRIMARY KEY);
** CREATE TABLE c(ck REFERENCES p ON DELETE CASCADE);
**
** then the returned trigger structure is equivalent to:
**
** CREATE TRIGGER ... DELETE ON p BEGIN
** DELETE FROM c WHERE ck = old.pk;
** END;
**
** The returned pointer is cached as part of the foreign key object. It
** is eventually freed along with the rest of the foreign key object by
** sqlite4FkDelete().
*/
static Trigger *fkActionTrigger(
Parse *pParse, /* Parse context */
Table *pTab, /* Table being updated or deleted from */
FKey *pFKey, /* Foreign key to get action for */
ExprList *pChanges /* Change-list for UPDATE, NULL for DELETE */
){
sqlite4 *db = pParse->db; /* Database handle */
int action; /* One of OE_None, OE_Cascade etc. */
Trigger *pTrigger; /* Trigger definition to return */
int iAction = (pChanges!=0); /* 1 for UPDATE, 0 for DELETE */
action = pFKey->aAction[iAction];
pTrigger = pFKey->apTrigger[iAction];
if( action!=OE_None && !pTrigger ){
u8 enableLookaside; /* Copy of db->lookaside.bEnabled */
char const *zFrom; /* Name of child table */
int nFrom; /* Length in bytes of zFrom */
Index *pIdx = 0; /* Parent key index for this FK */
int *aiCol = 0; /* child table cols -> parent key cols */
TriggerStep *pStep = 0; /* First (only) step of trigger program */
Expr *pWhere = 0; /* WHERE clause of trigger step */
ExprList *pList = 0; /* Changes list if ON UPDATE CASCADE */
Select *pSelect = 0; /* If RESTRICT, "SELECT RAISE(...)" */
int i; /* Iterator variable */
Expr *pWhen = 0; /* WHEN clause for the trigger */
if( locateFkeyIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ) return 0;
assert( aiCol || pFKey->nCol==1 );
for(i=0; i<pFKey->nCol; i++){
Token tOld = { "old", 3 }; /* Literal "old" token */
Token tNew = { "new", 3 }; /* Literal "new" token */
Token tFromCol; /* Name of column in child table */
Token tToCol; /* Name of column in parent table */
int iFromCol; /* Idx of column in child table */
Expr *pEq; /* tFromCol = OLD.tToCol */
iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
assert( iFromCol>=0 );
tToCol.z = pIdx ? pTab->aCol[pIdx->aiColumn[i]].zName : "oid";
tFromCol.z = pFKey->pFrom->aCol[iFromCol].zName;
tToCol.n = sqlite4Strlen30(tToCol.z);
tFromCol.n = sqlite4Strlen30(tFromCol.z);
/* Create the expression "OLD.zToCol = zFromCol". It is important
** that the "OLD.zToCol" term is on the LHS of the = operator, so
** that the affinity and collation sequence associated with the
** parent table are used for the comparison. */
pEq = sqlite4PExpr(pParse, TK_EQ,
sqlite4PExpr(pParse, TK_DOT,
sqlite4PExpr(pParse, TK_ID, 0, 0, &tOld),
sqlite4PExpr(pParse, TK_ID, 0, 0, &tToCol)
, 0),
sqlite4PExpr(pParse, TK_ID, 0, 0, &tFromCol)
, 0);
pWhere = sqlite4ExprAnd(db, pWhere, pEq);
/* For ON UPDATE, construct the next term of the WHEN clause.
** The final WHEN clause will be like this:
**
** WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN)
*/
if( pChanges ){
pEq = sqlite4PExpr(pParse, TK_IS,
sqlite4PExpr(pParse, TK_DOT,
sqlite4PExpr(pParse, TK_ID, 0, 0, &tOld),
sqlite4PExpr(pParse, TK_ID, 0, 0, &tToCol),
0),
sqlite4PExpr(pParse, TK_DOT,
sqlite4PExpr(pParse, TK_ID, 0, 0, &tNew),
sqlite4PExpr(pParse, TK_ID, 0, 0, &tToCol),
0),
0);
pWhen = sqlite4ExprAnd(db, pWhen, pEq);
}
if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){
Expr *pNew;
if( action==OE_Cascade ){
pNew = sqlite4PExpr(pParse, TK_DOT,
sqlite4PExpr(pParse, TK_ID, 0, 0, &tNew),
sqlite4PExpr(pParse, TK_ID, 0, 0, &tToCol)
, 0);
}else if( action==OE_SetDflt ){
Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt;
if( pDflt ){
pNew = sqlite4ExprDup(db, pDflt, 0);
}else{
pNew = sqlite4PExpr(pParse, TK_NULL, 0, 0, 0);
}
}else{
pNew = sqlite4PExpr(pParse, TK_NULL, 0, 0, 0);
}
pList = sqlite4ExprListAppend(pParse, pList, pNew);
sqlite4ExprListSetName(pParse, pList, &tFromCol, 0);
}
}
sqlite4DbFree(db, aiCol);
zFrom = pFKey->pFrom->zName;
nFrom = sqlite4Strlen30(zFrom);
if( action==OE_Restrict ){
Token tFrom;
Expr *pRaise;
tFrom.z = zFrom;
tFrom.n = nFrom;
pRaise = sqlite4Expr(db, TK_RAISE, "foreign key constraint failed");
if( pRaise ){
pRaise->affinity = OE_Abort;
}
pSelect = sqlite4SelectNew(pParse,
sqlite4ExprListAppend(pParse, 0, pRaise),
sqlite4SrcListAppend(db, 0, &tFrom, 0),
pWhere,
0, 0, 0, 0, 0, 0
);
pWhere = 0;
}
/* Disable lookaside memory allocation */
enableLookaside = db->lookaside.bEnabled;
db->lookaside.bEnabled = 0;
pTrigger = (Trigger *)sqlite4DbMallocZero(db,
sizeof(Trigger) + /* struct Trigger */
sizeof(TriggerStep) + /* Single step in trigger program */
nFrom + 1 /* Space for pStep->target.z */
);
if( pTrigger ){
pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1];
pStep->target.z = (char *)&pStep[1];
pStep->target.n = nFrom;
memcpy((char *)pStep->target.z, zFrom, nFrom);
pStep->pWhere = sqlite4ExprDup(db, pWhere, EXPRDUP_REDUCE);
pStep->pExprList = sqlite4ExprListDup(db, pList, EXPRDUP_REDUCE);
pStep->pSelect = sqlite4SelectDup(db, pSelect, EXPRDUP_REDUCE);
if( pWhen ){
pWhen = sqlite4PExpr(pParse, TK_NOT, pWhen, 0, 0);
pTrigger->pWhen = sqlite4ExprDup(db, pWhen, EXPRDUP_REDUCE);
}
}
/* Re-enable the lookaside buffer, if it was disabled earlier. */
db->lookaside.bEnabled = enableLookaside;
sqlite4ExprDelete(db, pWhere);
sqlite4ExprDelete(db, pWhen);
sqlite4ExprListDelete(db, pList);
sqlite4SelectDelete(db, pSelect);
if( db->mallocFailed==1 ){
fkTriggerDelete(db, pTrigger);
return 0;
}
assert( pStep!=0 );
switch( action ){
case OE_Restrict:
pStep->op = TK_SELECT;
break;
case OE_Cascade:
if( !pChanges ){
pStep->op = TK_DELETE;
break;
}
default:
pStep->op = TK_UPDATE;
}
pStep->pTrig = pTrigger;
pTrigger->pSchema = pTab->pSchema;
pTrigger->pTabSchema = pTab->pSchema;
pFKey->apTrigger[iAction] = pTrigger;
pTrigger->op = (pChanges ? TK_UPDATE : TK_DELETE);
}
return pTrigger;
}
/*
** This function is called when deleting or updating a row to implement
** any required CASCADE, SET NULL or SET DEFAULT actions.
*/
SQLITE_PRIVATE void sqlite4FkActions(
Parse *pParse, /* Parse context */
Table *pTab, /* Table being updated or deleted from */
ExprList *pChanges, /* Change-list for UPDATE, NULL for DELETE */
int regOld /* Address of array containing old row */
){
/* If foreign-key support is enabled, iterate through all FKs that
** refer to table pTab. If there is an action associated with the FK
** for this operation (either update or delete), invoke the associated
** trigger sub-program. */
if( pParse->db->flags&SQLITE_ForeignKeys ){
FKey *pFKey; /* Iterator variable */
for(pFKey = sqlite4FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){
Trigger *pAction = fkActionTrigger(pParse, pTab, pFKey, pChanges);
if( pAction ){
sqlite4CodeRowTriggerDirect(pParse, pAction, pTab, regOld, OE_Abort, 0);
}
}
}
}
#endif /* ifndef SQLITE_OMIT_TRIGGER */
/*
** Free all memory associated with foreign key definitions attached to
** table pTab. Remove the deleted foreign keys from the Schema.fkeyHash
** hash table.
*/
SQLITE_PRIVATE void sqlite4FkDelete(sqlite4 *db, Table *pTab){
FKey *pFKey; /* Iterator variable */
FKey *pNext; /* Copy of pFKey->pNextFrom */
for(pFKey=pTab->pFKey; pFKey; pFKey=pNext){
/* Remove the FK from the fkeyHash hash table. */
if( !db || db->pnBytesFreed==0 ){
if( pFKey->pPrevTo ){
pFKey->pPrevTo->pNextTo = pFKey->pNextTo;
}else{
void *p = (void *)pFKey->pNextTo;
const char *z = (p ? pFKey->pNextTo->zTo : pFKey->zTo);
sqlite4HashInsert(&pTab->pSchema->fkeyHash, z, sqlite4Strlen30(z), p);
}
if( pFKey->pNextTo ){
pFKey->pNextTo->pPrevTo = pFKey->pPrevTo;
}
}
/* EV: R-30323-21917 Each foreign key constraint in SQLite is
** classified as either immediate or deferred.
*/
assert( pFKey->isDeferred==0 || pFKey->isDeferred==1 );
/* Delete any triggers created to implement actions for this FK. */
#ifndef SQLITE_OMIT_TRIGGER
fkTriggerDelete(db, pFKey->apTrigger[0]);
fkTriggerDelete(db, pFKey->apTrigger[1]);
#endif
pNext = pFKey->pNextFrom;
sqlite4DbFree(db, pFKey);
}
}
#endif /* ifndef SQLITE_OMIT_FOREIGN_KEY */
/************** End of fkey.c ************************************************/
/************** Begin file insert.c ******************************************/
/*
** 2001 September 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.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
*/
/*
** Generate code that will open a table for reading.
*/
SQLITE_PRIVATE void sqlite4OpenTable(
Parse *p, /* Generate code into this VDBE */
int iCur, /* The cursor number of the table */
int iDb, /* The database index in sqlite4.aDb[] */
Table *pTab, /* The table to be opened */
int opcode /* OP_OpenRead or OP_OpenWrite */
){
assert( 0 );
}
/*
** Open VDBE cursor iCur to access index pIdx. pIdx is guaranteed to be
** a part of database iDb.
*/
SQLITE_PRIVATE void sqlite4OpenIndex(
Parse *p, /* Current parser context */
int iCur, /* The cursor number of the cursor to open */
int iDb, /* The database index in sqlite4.aDb[] */
Index *pIdx, /* The index to be opened */
int opcode /* OP_OpenRead or OP_OpenWrite */
){
KeyInfo *pKey; /* KeyInfo structure describing PK index */
Vdbe *v; /* VM to write code into */
assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
assert( pIdx->tnum>0 );
v = sqlite4GetVdbe(p);
pKey = sqlite4IndexKeyinfo(p, pIdx);
testcase( pKey==0 );
sqlite4VdbeAddOp3(v, opcode, iCur, pIdx->tnum, iDb);
sqlite4VdbeChangeP4(v, -1, (const char *)pKey, P4_KEYINFO_HANDOFF);
VdbeComment((v, "%s", pIdx->zName));
}
/*
** Generate code that will open the primary key of a table for either
** reading (if opcode==OP_OpenRead) or writing (if opcode==OP_OpenWrite).
*/
SQLITE_PRIVATE void sqlite4OpenPrimaryKey(
Parse *p, /* Current parser context */
int iCur, /* The cursor number of the cursor to open */
int iDb, /* The database index in sqlite4.aDb[] */
Table *pTab, /* The table to be opened */
int opcode /* OP_OpenRead or OP_OpenWrite */
){
assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
if( IsVirtual(pTab)==0 ){
Index *pIdx; /* PRIMARY KEY index for table pTab */
pIdx = sqlite4FindPrimaryKey(pTab, 0);
sqlite4OpenIndex(p, iCur, iDb, pIdx, opcode);
assert( pIdx->eIndexType==SQLITE_INDEX_PRIMARYKEY );
}
}
/*
** Return a pointer to the column affinity string associated with index
** pIdx. A column affinity string has one character for each column in
** the index key. If the index is the PRIMARY KEY of its table, the key
** consists of the index columns only. Otherwise, it consists of the
** indexed columns, followed by the columns that make up the tables PRIMARY
** KEY. For each column in the index key, the corresponding character of
** the affinity string is set according to the column affinity, as follows:
**
** Character Column affinity
** ------------------------------
** 'a' TEXT
** 'b' NONE
** 'c' NUMERIC
** 'd' INTEGER
** 'e' REAL
**
** Memory for the buffer containing the column index affinity string
** is managed along with the rest of the Index structure. It will be
** released when sqlite4DeleteIndex() is called.
*/
SQLITE_PRIVATE const char *sqlite4IndexAffinityStr(Vdbe *v, Index *pIdx){
/* The first time a column affinity string for a particular index is
** required, it is allocated and populated here. It is then stored as
** a member of the Index structure for subsequent use. The column
** affinity string will eventually be deleted by sqliteDeleteIndex()
** when the Index structure itself is cleaned up. */
if( !pIdx->zColAff ){
sqlite4 *db = sqlite4VdbeDb(v);
Table *pTab = pIdx->pTable; /* Table pIdx is attached to */
int n; /* Iterator variable for zAff */
Index *pPk; /* Primary key on same table as pIdx */
Index *p; /* Iterator variable */
char *zAff; /* Affinity string to populate and return */
int nAff; /* Characters in zAff */
/* Determine how many characters are in the affinity string. There is
** one character for each indexed column, and, if the index is not itself
** the primary key, one character for each column in the primary key
** of the table pIdx indexes. */
nAff = pIdx->nColumn;
pPk = sqlite4FindPrimaryKey(pTab, 0);
if( pPk && pIdx!=pPk ){
nAff += pPk->nColumn;
}
/* Allocate space for the affinity string */
zAff = pIdx->zColAff = (char *)sqlite4DbMallocRaw(0, nAff+1);
if( !zAff ){
db->mallocFailed = 1;
return 0;
}
/* Populate the affinity string. This loop runs either once or twice.
** The first iteration populates zAff with affinities according to the
** columns indexed by pIdx. If pIdx is not itself the table's primary
** key, then the second iteration of the loop adds the primary key
** columns to zAff. */
for(n=0, p=pIdx; p; p=(p==pPk ? 0 : pPk)){
int i;
for(i=0; i<p->nColumn; i++){
int iCol = p->aiColumn[i];
zAff[n++] = (iCol<0) ? SQLITE_AFF_INTEGER : pTab->aCol[iCol].affinity;
}
}
zAff[n] = 0;
}
return pIdx->zColAff;
}
/*
** Set P4 of the most recently inserted opcode to a column affinity
** string for table pTab. A column affinity string has one character
** for each column indexed by the index, according to the affinity of the
** column:
**
** Character Column affinity
** ------------------------------
** 'a' TEXT
** 'b' NONE
** 'c' NUMERIC
** 'd' INTEGER
** 'e' REAL
*/
SQLITE_PRIVATE void sqlite4TableAffinityStr(Vdbe *v, Table *pTab){
/* The first time a column affinity string for a particular table
** is required, it is allocated and populated here. It is then
** stored as a member of the Table structure for subsequent use.
**
** The column affinity string will eventually be deleted by
** sqlite4DeleteTable() when the Table structure itself is cleaned up.
*/
if( !pTab->zColAff ){
char *zColAff;
int i;
sqlite4 *db = sqlite4VdbeDb(v);
zColAff = (char *)sqlite4DbMallocRaw(0, pTab->nCol+1);
if( !zColAff ){
db->mallocFailed = 1;
return;
}
for(i=0; i<pTab->nCol; i++){
zColAff[i] = pTab->aCol[i].affinity;
}
zColAff[pTab->nCol] = '\0';
pTab->zColAff = zColAff;
}
sqlite4VdbeChangeP4(v, -1, pTab->zColAff, P4_TRANSIENT);
}
/*
** Return non-zero if the table pTab in database iDb or any of its indices
** have been opened at any point in the VDBE program beginning at location
** iStartAddr throught the end of the program. This is used to see if
** a statement of the form "INSERT INTO <iDb, pTab> SELECT ..." can
** run without using temporary table for the results of the SELECT.
*/
static int readsTable(Parse *p, int iStartAddr, int iDb, Table *pTab){
Vdbe *v = sqlite4GetVdbe(p);
int i;
int iEnd = sqlite4VdbeCurrentAddr(v);
#ifndef SQLITE_OMIT_VIRTUALTABLE
VTable *pVTab = IsVirtual(pTab) ? sqlite4GetVTable(p->db, pTab) : 0;
#endif
for(i=iStartAddr; i<iEnd; i++){
VdbeOp *pOp = sqlite4VdbeGetOp(v, i);
assert( pOp!=0 );
if( pOp->opcode==OP_OpenRead && pOp->p3==iDb ){
Index *pIndex;
int tnum = pOp->p2;
for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){
if( tnum==pIndex->tnum ){
return 1;
}
}
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( pOp->opcode==OP_VOpen && pOp->p4.pVtab==pVTab ){
assert( pOp->p4.pVtab!=0 );
assert( pOp->p4type==P4_VTAB );
return 1;
}
#endif
}
return 0;
}
#ifndef SQLITE_OMIT_AUTOINCREMENT
/*
** 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.
**
** There is at most one AutoincInfo structure per table even if the
** same table is autoincremented multiple times due to inserts within
** triggers. A new AutoincInfo structure is created if this is the
** first use of table pTab. On 2nd and subsequent uses, the original
** AutoincInfo structure is used.
**
** Three memory locations are allocated:
**
** (1) Register to hold the name of the pTab table.
** (2) Register to hold the maximum ROWID of pTab.
** (3) Register to hold the rowid in sqlite_sequence of pTab
**
** The 2nd register is the one that is returned. That is all the
** insert routine needs to know about.
*/
static int autoIncBegin(
Parse *pParse, /* Parsing context */
int iDb, /* Index of the database holding pTab */
Table *pTab /* The table we are writing to */
){
int memId = 0; /* Register holding maximum rowid */
if( pTab->tabFlags & TF_Autoincrement ){
Parse *pToplevel = sqlite4ParseToplevel(pParse);
AutoincInfo *pInfo;
pInfo = pToplevel->pAinc;
while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; }
if( pInfo==0 ){
pInfo = sqlite4DbMallocRaw(pParse->db, sizeof(*pInfo));
if( pInfo==0 ) return 0;
pInfo->pNext = pToplevel->pAinc;
pToplevel->pAinc = pInfo;
pInfo->pTab = pTab;
pInfo->iDb = iDb;
pToplevel->nMem++; /* Register to hold name of table */
pInfo->regCtr = ++pToplevel->nMem; /* Max rowid register */
pToplevel->nMem++; /* Rowid in sqlite_sequence */
}
memId = pInfo->regCtr;
}
return memId;
}
/*
** This routine generates code that will initialize all of the
** register used by the autoincrement tracker.
*/
SQLITE_PRIVATE void sqlite4AutoincrementBegin(Parse *pParse){
AutoincInfo *p; /* Information about an AUTOINCREMENT */
sqlite4 *db = pParse->db; /* The database connection */
Db *pDb; /* Database only autoinc table */
int memId; /* Register holding max rowid */
int addr; /* A VDBE address */
Vdbe *v = pParse->pVdbe; /* VDBE under construction */
/* This routine is never called during trigger-generation. It is
** only called from the top-level */
assert( pParse->pTriggerTab==0 );
assert( pParse==sqlite4ParseToplevel(pParse) );
assert( v ); /* We failed long ago if this is not so */
for(p = pParse->pAinc; p; p = p->pNext){
pDb = &db->aDb[p->iDb];
memId = p->regCtr;
sqlite4OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead);
sqlite4VdbeAddOp3(v, OP_Null, 0, memId, memId+1);
addr = sqlite4VdbeCurrentAddr(v);
sqlite4VdbeAddOp4(v, OP_String8, 0, memId-1, 0, p->pTab->zName, 0);
sqlite4VdbeAddOp2(v, OP_Rewind, 0, addr+9);
sqlite4VdbeAddOp3(v, OP_Column, 0, 0, memId);
sqlite4VdbeAddOp3(v, OP_Ne, memId-1, addr+7, memId);
sqlite4VdbeChangeP5(v, SQLITE_JUMPIFNULL);
sqlite4VdbeAddOp2(v, OP_Rowid, 0, memId+1);
sqlite4VdbeAddOp3(v, OP_Column, 0, 1, memId);
sqlite4VdbeAddOp2(v, OP_Goto, 0, addr+9);
sqlite4VdbeAddOp2(v, OP_Next, 0, addr+2);
sqlite4VdbeAddOp2(v, OP_Integer, 0, memId);
sqlite4VdbeAddOp0(v, OP_Close);
}
}
/*
** Update the maximum rowid for an autoincrement calculation.
**
** This routine should be called when the top of the stack 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. The stack is unchanged.
*/
static void autoIncStep(Parse *pParse, int memId, int regRowid){
if( memId>0 ){
sqlite4VdbeAddOp2(pParse->pVdbe, OP_MemMax, memId, regRowid);
}
}
/*
** This routine generates the code needed to write autoincrement
** maximum rowid values back into the sqlite_sequence register.
** Every statement that might do an INSERT into an autoincrement
** table (either directly or through triggers) needs to call this
** routine just before the "exit" code.
*/
SQLITE_PRIVATE void sqlite4AutoincrementEnd(Parse *pParse){
AutoincInfo *p;
Vdbe *v = pParse->pVdbe;
sqlite4 *db = pParse->db;
assert( v );
for(p = pParse->pAinc; p; p = p->pNext){
Db *pDb = &db->aDb[p->iDb];
int j1, j2, j3, j4, j5;
int iRec;
int memId = p->regCtr;
iRec = sqlite4GetTempReg(pParse);
sqlite4OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
j1 = sqlite4VdbeAddOp1(v, OP_NotNull, memId+1);
j2 = sqlite4VdbeAddOp0(v, OP_Rewind);
j3 = sqlite4VdbeAddOp3(v, OP_Column, 0, 0, iRec);
j4 = sqlite4VdbeAddOp3(v, OP_Eq, memId-1, 0, iRec);
sqlite4VdbeAddOp2(v, OP_Next, 0, j3);
sqlite4VdbeJumpHere(v, j2);
sqlite4VdbeAddOp2(v, OP_NewRowid, 0, memId+1);
j5 = sqlite4VdbeAddOp0(v, OP_Goto);
sqlite4VdbeJumpHere(v, j4);
sqlite4VdbeAddOp2(v, OP_Rowid, 0, memId+1);
sqlite4VdbeJumpHere(v, j1);
sqlite4VdbeJumpHere(v, j5);
sqlite4VdbeAddOp3(v, OP_MakeRecord, memId-1, 2, iRec);
sqlite4VdbeAddOp3(v, OP_Insert, 0, iRec, memId+1);
sqlite4VdbeChangeP5(v, OPFLAG_APPEND);
sqlite4VdbeAddOp0(v, OP_Close);
sqlite4ReleaseTempReg(pParse, iRec);
}
}
#else
/*
** If SQLITE_OMIT_AUTOINCREMENT is defined, then the three routines
** above are all no-ops
*/
# define autoIncBegin(A,B,C) (0)
# define autoIncStep(A,B,C)
#endif /* SQLITE_OMIT_AUTOINCREMENT */
/* Forward declaration */
static int xferOptimization(
Parse *pParse, /* Parser context */
Table *pDest, /* The table we are inserting into */
Select *pSelect, /* A SELECT statement to use as the data source */
int onError, /* How to handle constraint errors */
int iDbDest /* The database of pDest */
);
/*
** This routine is call to handle SQL of the following forms:
**
** insert into TABLE (IDLIST) values(EXPRLIST)
** insert into TABLE (IDLIST) select
**
** The IDLIST following the table name is always optional. If omitted,
** then a list of all columns for the table is substituted. The IDLIST
** appears in the pColumn parameter. pColumn is NULL if IDLIST is omitted.
**
** The pList parameter holds EXPRLIST in the first form of the INSERT
** statement above, and pSelect is NULL. For the second form, pList is
** NULL and pSelect is a pointer to the select statement used to generate
** data for the insert.
**
** The code generated follows one of four templates. For a simple
** select with data coming from a VALUES clause, the code executes
** once straight down through. Pseudo-code follows (we call this
** the "1st template"):
**
** open write cursor to <table> and its indices
** puts VALUES clause expressions onto the stack
** write the resulting record into <table>
** cleanup
**
** The three remaining templates assume the statement is of the form
**
** INSERT INTO <table> SELECT ...
**
** If the SELECT clause is of the restricted form "SELECT * FROM <table2>" -
** in other words if the SELECT pulls all columns from a single table
** and there is no WHERE or LIMIT or GROUP BY or ORDER BY clauses, and
** if <table2> and <table1> are distinct tables but have identical
** schemas, including all the same indices, then a special optimization
** is invoked that copies raw records from <table2> over to <table1>.
** See the xferOptimization() function for the implementation of this
** template. This is the 2nd template.
**
** open a write cursor to <table>
** open read cursor on <table2>
** transfer all records in <table2> over to <table>
** close cursors
** foreach index on <table>
** open a write cursor on the <table> index
** open a read cursor on the corresponding <table2> index
** transfer all records from the read to the write cursors
** close cursors
** end foreach
**
** The 3rd template is for when the second template does not apply
** and the SELECT clause does not read from <table> at any time.
** The generated code follows this template:
**
** EOF <- 0
** X <- A
** goto B
** A: setup for the SELECT
** loop over the rows in the SELECT
** load values into registers R..R+n
** yield X
** end loop
** cleanup after the SELECT
** EOF <- 1
** yield X
** goto A
** B: open write cursor to <table> and its indices
** C: yield X
** if EOF goto D
** insert the select result into <table> from R..R+n
** goto C
** D: cleanup
**
** The 4th template is used if the insert statement takes its
** values from a SELECT but the data is being inserted into a table
** that is also read as part of the SELECT. In the third form,
** we have to use a intermediate table to store the results of
** the select. The template is like this:
**
** EOF <- 0
** X <- A
** goto B
** A: setup for the SELECT
** loop over the tables in the SELECT
** load value into register R..R+n
** yield X
** end loop
** cleanup after the SELECT
** EOF <- 1
** yield X
** halt-error
** B: open temp table
** L: yield X
** if EOF goto M
** insert row from R..R+n into temp table
** goto L
** M: open write cursor to <table> and its indices
** rewind temp table
** C: loop over rows of intermediate table
** transfer values form intermediate table into <table>
** end loop
** D: cleanup
*/
SQLITE_PRIVATE void sqlite4Insert(
Parse *pParse, /* Parser context */
SrcList *pTabList, /* Name of table into which we are inserting */
ExprList *pList, /* List of values to be inserted */
Select *pSelect, /* A SELECT statement to use as the data source */
IdList *pColumn, /* Column names corresponding to IDLIST. */
int onError /* How to handle constraint errors */
){
sqlite4 *db; /* The main database structure */
Table *pTab; /* The table to insert into. aka TABLE */
char *zTab; /* Name of the table into which we are inserting */
const char *zDb; /* Name of the database holding this table */
int i, j, idx; /* 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 */
int nHidden = 0; /* Number of hidden columns if TABLE is virtual */
int baseCur = 0; /* VDBE Cursor number for pTab */
int endOfLoop; /* Label for the end of the insertion loop */
int useTempTable = 0; /* Store SELECT results in intermediate table */
int srcTab = 0; /* Data comes from this temporary cursor if >=0 */
int addrInsTop = 0; /* Jump to label "D" */
int addrCont = 0; /* Top of insert loop. Label "C" in templates 3 and 4 */
int addrSelect = 0; /* Address of coroutine that implements the SELECT */
SelectDest dest; /* Destination for SELECT on rhs of INSERT */
int iDb; /* Index of database holding TABLE */
Db *pDb; /* The database containing table being inserted into */
int appendFlag = 0; /* True if the insert is likely to be an append */
/* Register allocations */
int regFromSelect = 0;/* Base register for data coming from SELECT */
int regEof = 0; /* Register recording end of SELECT data */
int *aRegIdx = 0; /* One register allocated to each index */
int iPk; /* Cursor offset of PK index cursor */
Index *pPk; /* Primary key for table pTab */
int bImplicitPK; /* True if table pTab has an implicit PK */
int regContent; /* First register in column value array */
int regRowid; /* If bImplicitPK, register holding IPK */
#ifndef SQLITE_OMIT_TRIGGER
int isView; /* True if attempting to insert into a view */
Trigger *pTrigger; /* List of triggers on pTab, if required */
int tmask; /* Mask of trigger times */
#endif
db = pParse->db;
memset(&dest, 0, sizeof(dest));
if( pParse->nErr || db->mallocFailed ){
goto insert_cleanup;
}
/* Locate the table into which we will be inserting new information. */
assert( pTabList->nSrc==1 );
zTab = pTabList->a[0].zName;
if( NEVER(zTab==0) ) goto insert_cleanup;
pTab = sqlite4SrcListLookup(pParse, pTabList);
if( pTab==0 ){
goto insert_cleanup;
}
iDb = sqlite4SchemaToIndex(db, pTab->pSchema);
assert( iDb<db->nDb );
pDb = &db->aDb[iDb];
zDb = pDb->zName;
if( sqlite4AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){
goto insert_cleanup;
}
/* Set bImplicitPK to true for an implicit PRIMARY KEY, or false otherwise.
** Also set pPk to point to the primary key, and iPk to the cursor offset
** of the primary key cursor (i.e. so that the cursor opened on the primary
** key index is VDBE cursor (baseCur+iPk). */
pPk = sqlite4FindPrimaryKey(pTab, &iPk);
assert( (pPk==0)==IsView(pTab) );
bImplicitPK = (pPk && pPk->aiColumn[0]==-1);
/* Figure out if we have any triggers and if the table being
** inserted into is a view. */
#ifndef SQLITE_OMIT_TRIGGER
pTrigger = sqlite4TriggersExist(pParse, pTab, TK_INSERT, 0, &tmask);
isView = pTab->pSelect!=0;
#else
# define pTrigger 0
# define tmask 0
# define isView 0
#endif
#ifdef SQLITE_OMIT_VIEW
# undef isView
# define isView 0
#endif
assert( (pTrigger && tmask) || (pTrigger==0 && tmask==0) );
/* If pTab is really a view, make sure it has been initialized.
** ViewGetColumnNames() is a no-op if pTab is not a view (or virtual
** module table). */
if( sqlite4ViewGetColumnNames(pParse, pTab) ){
goto insert_cleanup;
}
/* Ensure that:
** (a) the table is not read-only (e.g. sqlite_master, sqlite_stat), and
** (b) that if it is a view then ON INSERT triggers exist
*/
if( sqlite4IsReadOnly(pParse, pTab, tmask) ){
goto insert_cleanup;
}
/* Allocate a VDBE and begin a write transaction */
v = sqlite4GetVdbe(pParse);
if( v==0 ) goto insert_cleanup;
if( pParse->nested==0 ) sqlite4VdbeCountChanges(v);
sqlite4BeginWriteOperation(pParse, pSelect || pTrigger, iDb);
#ifndef SQLITE_OMIT_XFER_OPT
/* If the statement is of the form
**
** INSERT INTO <table1> SELECT * FROM <table2>;
**
** Then special optimizations can be applied that make the transfer
** very fast and which reduce fragmentation of indices.
**
** This is the 2nd template.
*/
if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){
assert( !pTrigger );
assert( pList==0 );
goto insert_end;
}
#endif /* SQLITE_OMIT_XFER_OPT */
/* Figure out how many columns of data are supplied. If the data
** is coming from a SELECT statement, then generate a co-routine that
** produces a single row of the SELECT on each invocation. The
** co-routine is the common header to the 3rd and 4th templates.
*/
if( pSelect ){
/* Data is coming from a SELECT. Generate code to implement that SELECT
** as a co-routine. The code is common to both the 3rd and 4th
** templates:
**
** EOF <- 0
** X <- A
** goto B
** A: setup for the SELECT
** loop over the tables in the SELECT
** load value into register R..R+n
** yield X
** end loop
** cleanup after the SELECT
** EOF <- 1
** yield X
** halt-error
**
** On each invocation of the co-routine, it puts a single row of the
** SELECT result into registers dest.iMem...dest.iMem+dest.nMem-1.
** (These output registers are allocated by sqlite4Select().) When
** the SELECT completes, it sets the EOF flag stored in regEof.
*/
int rc, j1;
regEof = ++pParse->nMem;
sqlite4VdbeAddOp2(v, OP_Integer, 0, regEof); /* EOF <- 0 */
VdbeComment((v, "SELECT eof flag"));
sqlite4SelectDestInit(&dest, SRT_Coroutine, ++pParse->nMem);
addrSelect = sqlite4VdbeCurrentAddr(v)+2;
sqlite4VdbeAddOp2(v, OP_Integer, addrSelect-1, dest.iParm);
j1 = sqlite4VdbeAddOp2(v, OP_Goto, 0, 0);
VdbeComment((v, "Jump over SELECT coroutine"));
/* Resolve the expressions in the SELECT statement and execute it. */
rc = sqlite4Select(pParse, pSelect, &dest);
assert( pParse->nErr==0 || rc );
if( rc || NEVER(pParse->nErr) || db->mallocFailed ){
goto insert_cleanup;
}
sqlite4VdbeAddOp2(v, OP_Integer, 1, regEof); /* EOF <- 1 */
sqlite4VdbeAddOp1(v, OP_Yield, dest.iParm); /* yield X */
sqlite4VdbeAddOp2(v, OP_Halt, SQLITE_INTERNAL, OE_Abort);
VdbeComment((v, "End of SELECT coroutine"));
sqlite4VdbeJumpHere(v, j1); /* label B: */
regFromSelect = dest.iMem;
assert( pSelect->pEList );
nColumn = pSelect->pEList->nExpr;
assert( dest.nMem==nColumn );
/* Set useTempTable to TRUE if the result of the SELECT statement
** should be written into a temporary table (template 4). Set to
** FALSE if each* row of the SELECT can be written directly into
** the destination table (template 3).
**
** A temp table must be used if the table being updated is also one
** of the tables being read by the SELECT statement. Also use a
** temp table in the case of row triggers.
*/
if( pTrigger || readsTable(pParse, addrSelect, iDb, pTab) ){
useTempTable = 1;
}
if( useTempTable ){
/* Invoke the coroutine to extract information from the SELECT
** and add it to a transient table srcTab. The code generated
** here is from the 4th template:
**
** B: open temp table
** L: yield X
** if EOF goto M
** insert row from R..R+n into temp table
** goto L
** M: ...
*/
int regRec; /* Register to hold packed record */
int regTempRowid; /* Register to hold temp table ROWID */
int addrTop; /* Label "L" */
int addrIf; /* Address of jump to M */
srcTab = pParse->nTab++;
regRec = sqlite4GetTempReg(pParse);
regTempRowid = sqlite4GetTempReg(pParse);
sqlite4VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn);
addrTop = sqlite4VdbeAddOp1(v, OP_Yield, dest.iParm);
addrIf = sqlite4VdbeAddOp1(v, OP_If, regEof);
sqlite4VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec);
sqlite4VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid);
sqlite4VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid);
sqlite4VdbeAddOp2(v, OP_Goto, 0, addrTop);
sqlite4VdbeJumpHere(v, addrIf);
sqlite4ReleaseTempReg(pParse, regRec);
sqlite4ReleaseTempReg(pParse, regTempRowid);
}
}else{
/* This is the case if the data for the INSERT is coming from a VALUES
** (or DEFAULT VALUES) clause. Resolve all references in the VALUES(...)
** expressions. */
NameContext sNC;
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = pParse;
srcTab = -1;
assert( useTempTable==0 );
nColumn = pList ? pList->nExpr : 0;
for(i=0; i<nColumn; i++){
if( sqlite4ResolveExprNames(&sNC, pList->a[i].pExpr) ){
goto insert_cleanup;
}
}
}
/* Make sure the number of columns in the source data matches the number
** of columns to be inserted into the table.
*/
if( IsVirtual(pTab) ){
for(i=0; i<pTab->nCol; i++){
nHidden += (IsHiddenColumn(&pTab->aCol[i]) ? 1 : 0);
}
}
if( pColumn==0 && nColumn && nColumn!=(pTab->nCol-nHidden) ){
sqlite4ErrorMsg(pParse,
"table %S has %d columns but %d values were supplied",
pTabList, 0, pTab->nCol-nHidden, nColumn);
goto insert_cleanup;
}
if( pColumn!=0 && nColumn!=pColumn->nId ){
sqlite4ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId);
goto insert_cleanup;
}
/* If the INSERT statement included an IDLIST term, then make sure
** all elements of the IDLIST really are columns of the table. Set
** the pColumn->a[iCol].idx variables to indicate which column of the
** table each IDLIST element corresponds to.
*/
if( pColumn ){
for(i=0; i<pColumn->nId; i++){
pColumn->a[i].idx = -1;
}
for(i=0; i<pColumn->nId; i++){
char *zTest = pColumn->a[i].zName;
for(j=0; j<pTab->nCol; j++){
if( sqlite4StrICmp(zTest, pTab->aCol[j].zName)==0 ){
pColumn->a[i].idx = j;
break;
}
}
if( j==pTab->nCol ){
sqlite4ErrorMsg(pParse, "table %S has no column named %s",
pTabList, 0, pColumn->a[i].zName);
pParse->checkSchema = 1;
goto insert_cleanup;
}
}
}
/* If this is not a view, open a write cursor on each index. Allocate
** a contiguous array of (nIdx+1) registers, where nIdx is the total
** number of indexes (including the PRIMARY KEY index).
**
** Register aRegIdx[0]: The PRIMARY KEY index key
** Register aRegIdx[1..nIdx-1]: Keys for other table indexes
** Register aRegIdx[nIdx]: Data record for table row.
*/
if( !isView ){
int nIdx;
baseCur = pParse->nTab;
nIdx = sqlite4OpenAllIndexes(pParse, pTab, baseCur, OP_OpenWrite);
aRegIdx = sqlite4DbMallocRaw(db, sizeof(int)*(nIdx+1));
if( aRegIdx==0 ){
goto insert_cleanup;
}
for(i=0; i<nIdx; i++){
aRegIdx[i] = ++pParse->nMem; /* Register in which to store key */
pParse->nMem++; /* Extra register for data */
}
}
/* This is the top of the main insertion loop */
if( useTempTable ){
/* This block codes the top of loop only. The complete loop is the
** following pseudocode (template 4):
**
** rewind temp table
** C: loop over rows of intermediate table
** transfer values form intermediate table into <table>
** end loop
** D: ...
*/
addrInsTop = sqlite4VdbeAddOp1(v, OP_Rewind, srcTab);
addrCont = sqlite4VdbeCurrentAddr(v);
}else if( pSelect ){
/* This block codes the top of loop only. The complete loop is the
** following pseudocode (template 3):
**
** C: yield X
** if EOF goto D
** insert the select result into <table> from R..R+n
** goto C
** D: ...
*/
addrCont = sqlite4VdbeAddOp1(v, OP_Yield, dest.iParm);
addrInsTop = sqlite4VdbeAddOp1(v, OP_If, regEof);
}
/* Allocate an array of registers in which to assemble the values for the
** new row. If the table has an explicit primary key, we need one register
** for each table column. If the table uses an implicit primary key, the
** nCol+1 registers are required. */
regRowid = ++pParse->nMem;
regContent = pParse->nMem+1;
pParse->nMem += pTab->nCol;
if( IsVirtual(pTab) ){
/* TODO: Fix this */
regContent++;
regRowid++;
pParse->nMem++;
}
endOfLoop = sqlite4VdbeMakeLabel(v);
for(i=0; i<pTab->nCol; i++){
j = i;
if( pColumn ){
for(j=0; j<pColumn->nId; j++){
if( pColumn->a[j].idx==i ) break;
}
}
if( nColumn==0 || (pColumn && j>=pColumn->nId) ){
sqlite4ExprCode(pParse, pTab->aCol[i].pDflt, regContent+i);
}else if( useTempTable ){
sqlite4VdbeAddOp3(v, OP_Column, srcTab, j, regContent+i);
}else if( pSelect ){
sqlite4VdbeAddOp2(v, OP_SCopy, regFromSelect+j, regContent+i);
}else{
assert( pSelect==0 ); /* Otherwise useTempTable is true */
sqlite4ExprCodeAndCache(pParse, pList->a[j].pExpr, regContent+i);
}
}
if( !isView ){
sqlite4VdbeAddOp2(v, OP_Affinity, regContent, pTab->nCol);
sqlite4TableAffinityStr(v, pTab);
}
/* Fire BEFORE or INSTEAD OF triggers */
if( pTrigger ){
sqlite4VdbeAddOp2(v, OP_Integer, -1, regRowid);
VdbeComment((v, "new.rowid value for BEFORE triggers"));
sqlite4CodeRowTrigger(
pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE,
pTab, (regRowid - pTab->nCol - 1), onError, endOfLoop
);
}
if( bImplicitPK ){
assert( !isView );
sqlite4VdbeAddOp2(v, OP_NewRowid, baseCur+iPk, regRowid);
}
if( !isView ){
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( IsVirtual(pTab) ){
const char *pVTab = (const char *)sqlite4GetVTable(db, pTab);
sqlite4VtabMakeWritable(pParse, pTab);
sqlite4VdbeAddOp4(v, OP_VUpdate, 1, pTab->nCol+2, regIns, pVTab, P4_VTAB);
sqlite4VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError);
sqlite4MayAbort(pParse);
}else
#endif
{
/* Generate code to check constraints and generate index keys and
** do the insertion. */
int isReplace; /* Set to true if constraints may cause a replace */
sqlite4GenerateConstraintChecks(pParse, pTab, baseCur,
regContent, aRegIdx, 0, 0, onError, endOfLoop, &isReplace
);
sqlite4FkCheck(pParse, pTab, 0, regContent);
sqlite4CompleteInsertion(pParse, pTab, baseCur,
regContent, aRegIdx, 0, appendFlag, isReplace==0
);
}
}
/* Code AFTER triggers */
sqlite4CodeRowTrigger(
pParse, pTrigger, TK_INSERT, 0, TRIGGER_AFTER,
pTab, regRowid - pTab->nCol - 1, onError, endOfLoop
);
/* The bottom of the main insertion loop, if the data source
** is a SELECT statement.
*/
sqlite4VdbeResolveLabel(v, endOfLoop);
if( useTempTable ){
sqlite4VdbeAddOp2(v, OP_Next, srcTab, addrCont);
sqlite4VdbeJumpHere(v, addrInsTop);
sqlite4VdbeAddOp1(v, OP_Close, srcTab);
}else if( pSelect ){
sqlite4VdbeAddOp2(v, OP_Goto, 0, addrCont);
sqlite4VdbeJumpHere(v, addrInsTop);
}
if( !IsVirtual(pTab) && !isView ){
/* Close all tables opened */
for(idx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
sqlite4VdbeAddOp1(v, OP_Close, idx+baseCur);
}
}
insert_end:
/* Update the sqlite_sequence table by storing the content of the
** maximum rowid counter values recorded while inserting into
** autoincrement tables.
*/
if( pParse->nested==0 && pParse->pTriggerTab==0 ){
sqlite4AutoincrementEnd(pParse);
}
insert_cleanup:
sqlite4SrcListDelete(db, pTabList);
sqlite4ExprListDelete(db, pList);
sqlite4SelectDelete(db, pSelect);
sqlite4IdListDelete(db, pColumn);
sqlite4DbFree(db, aRegIdx);
}
/* Make sure "isView" and other macros defined above are undefined. Otherwise
** thely may interfere with compilation of other functions in this file
** (or in another file, if this file becomes part of the amalgamation). */
#ifdef isView
#undef isView
#endif
#ifdef pTrigger
#undef pTrigger
#endif
#ifdef tmask
#undef tmask
#endif
/*
** Return the name of the iCol'th column in index pIdx.
*/
const char *indexColumnName(Index *pIdx, int iCol){
int iTbl = pIdx->aiColumn[iCol];
assert( iTbl>=-1 && iTbl<pIdx->pTable->nCol );
if( iTbl<0 ){
assert( pIdx->eIndexType==SQLITE_INDEX_PRIMARYKEY && pIdx->nColumn==1 );
return "rowid";
}
return pIdx->pTable->aCol[iTbl].zName;
}
static void generateNotNullChecks(
Parse *pParse, /* Parse context */
Table *pTab, /* Table to generate checks for */
int regContent, /* Index of the range of input registers */
int overrideError, /* Override default OE_* with this */
int ignoreDest /* Jump to this lable if OE_Ignore */
){
Vdbe *v = pParse->pVdbe;
int i;
for(i=0; i<pTab->nCol; i++){
int onError = pTab->aCol[i].notNull;
if( onError ){
if( overrideError!=OE_Default ){
onError = overrideError;
}else if( onError==OE_Default ){
onError = OE_Abort;
}
if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){
onError = OE_Abort;
}
switch( onError ){
case OE_Abort:
sqlite4MayAbort(pParse);
case OE_Rollback:
case OE_Fail: {
char *zMsg = sqlite4MPrintf(pParse->db, "%s.%s may not be NULL",
pTab->zName, pTab->aCol[i].zName
);
sqlite4VdbeAddOp4(v, OP_HaltIfNull,
SQLITE_CONSTRAINT, onError, regContent+i, zMsg, P4_DYNAMIC
);
break;
}
case OE_Ignore:
sqlite4VdbeAddOp2(v, OP_IsNull, regContent+i, ignoreDest);
break;
default: {
int j1 = sqlite4VdbeAddOp1(v, OP_NotNull, regContent+i);
sqlite4ExprCode(pParse, pTab->aCol[i].pDflt, regContent+i);
sqlite4VdbeJumpHere(v, j1);
assert( onError==OE_Replace );
break;
}
}
}
}
}
#ifndef SQLITE_OMIT_CHECK
static void generateCheckChecks(
Parse *pParse, /* Parse context */
Table *pTab, /* Table to generate checks for */
int regContent, /* Index of the range of input registers */
int overrideError, /* Override default OE_* with this */
int ignoreDest /* Jump to this lable if OE_Ignore */
){
Vdbe *v = pParse->pVdbe;
if( pTab->pCheck && (pParse->db->flags & SQLITE_IgnoreChecks)==0 ){
int onError;
int allOk = sqlite4VdbeMakeLabel(v);
pParse->ckBase = regContent;
sqlite4ExprIfTrue(pParse, pTab->pCheck, allOk, SQLITE_JUMPIFNULL);
onError = overrideError!=OE_Default ? overrideError : OE_Abort;
if( onError==OE_Ignore ){
sqlite4VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
}else{
if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
sqlite4HaltConstraint(pParse, onError, 0, 0);
}
sqlite4VdbeResolveLabel(v, allOk);
}
}
#else /* !defined(SQLITE_OMIT_CHECK) */
# define generateCheckChecks(a,b,c,d,e)
#endif
SQLITE_PRIVATE Index *sqlite4FindPrimaryKey(
Table *pTab, /* Table to locate primary key for */
int *piPk /* OUT: Index of PRIMARY KEY */
){
Index *p;
int iPk = 0;
for(p=pTab->pIndex; p && p->eIndexType!=SQLITE_INDEX_PRIMARYKEY; p=p->pNext){
iPk++;
}
if( piPk ) *piPk = iPk;
return p;
}
/*
** Index pIdx is a UNIQUE index. This function returns a pointer to a buffer
** containing an error message to tell the user that the UNIQUE constraint
** has failed.
**
** The returned buffer should be freed by the caller using sqlite4DbFree().
*/
static char *notUniqueMessage(
Parse *pParse, /* Parse context */
Index *pIdx /* Index to generate error message for */
){
const int nCol = pIdx->nColumn; /* Number of columns indexed by pIdx */
StrAccum errMsg; /* Buffer to build error message within */
int iCol; /* Used to iterate through indexed columns */
sqlite4StrAccumInit(&errMsg, 0, 0, 200);
errMsg.db = pParse->db;
errMsg.pEnv = errMsg.db->pEnv;
if( pIdx->eIndexType==SQLITE_INDEX_PRIMARYKEY ){
sqlite4StrAccumAppend(&errMsg, "PRIMARY KEY must be unique", -1);
}else{
sqlite4StrAccumAppend(&errMsg, (nCol>1 ? "columns " : "column "), -1);
for(iCol=0; iCol<pIdx->nColumn; iCol++){
const char *zCol = indexColumnName(pIdx, iCol);
sqlite4StrAccumAppend(&errMsg, (iCol==0 ? "" : ", "), -1);
sqlite4StrAccumAppend(&errMsg, zCol, -1);
}
sqlite4StrAccumAppend(&errMsg, (nCol>1 ? " are" : " is"), -1);
sqlite4StrAccumAppend(&errMsg, " not unique", -1);
}
return sqlite4StrAccumFinish(&errMsg);
}
/*
** This function generates code used as part of both INSERT and UPDATE
** statements. The generated code performs two tasks:
**
** 1. Checks all NOT NULL, CHECK and UNIQUE database constraints,
** including the implicit NOT NULL and UNIQUE constraints imposed
** by the PRIMARY KEY definition.
**
** 2. Generates serialized index keys (using OP_MakeKey) for the caller
** to store in database indexes. This function does not encode the
** actual data record, just the index keys.
**
** Both INSERT and UPDATE use this function in concert with the
** sqlite4CompleteInsertion(). This function does as described above, and
** then CompleteInsertion() generates code to serialize the data record
** and do the actual inserts into the database.
**
** regContent:
** The first in an array of registers that contain the column values
** for the new row. Register regContent contains the value for the
** left-most table column, (regContent+1) contains the value for the next
** column, and so on. All entries in this array have had any required
** affinity transformations applied already. All zero-blobs have been
** expanded.
**
** If the table has an implicit primary key and aRegIdx[0] is not 0 (see
** below), register (regContent-1) is also valid. It contains the new
** implicit integer PRIMARY KEY value.
**
** aRegIdx:
** Array sized so that there is one entry for each index (including the
** PK index) attached to the database table. Entries are in the same order
** as the linked list of Index structures attached to the table.
**
** If an array entry is non-zero, it contains the register that the
** corresponding index key should be written to. If an entry is zero, then
** the corresponding index key is not required by the caller. In this case
** any UNIQUE constraint enforced by the index does not need to be checked.
**
**
**
** Generate code to do constraint checks prior to an INSERT or an UPDATE.
**
** The input is a range of consecutive registers as follows:
**
** 1. The rowid of the row after the update.
**
** 2. The data in the first column of the entry after the update.
**
** i. Data from middle columns...
**
** N. The data in the last column of the entry after the update.
**
** The regRowid parameter is the index of the register containing (1).
**
** If isUpdate is true and rowidChng is non-zero, then rowidChng contains
** the address of a register containing the rowid before the update takes
** place. isUpdate is true for UPDATEs and false for INSERTs. If isUpdate
** is false, indicating an INSERT statement, then a non-zero rowidChng
** indicates that the rowid was explicitly specified as part of the
** INSERT statement. If rowidChng is false, it means that the rowid is
** computed automatically in an insert or that the rowid value is not
** modified by an update.
**
** The code generated by this routine store new index entries into
** registers identified by aRegIdx[]. No index entry is created for
** indices where aRegIdx[i]==0. The order of indices in aRegIdx[] is
** the same as the order of indices on the linked list of indices
** attached to the table.
**
** This routine also generates code to check constraints. NOT NULL,
** CHECK, and UNIQUE constraints are all checked. If a constraint fails,
** then the appropriate action is performed. There are five possible
** actions: ROLLBACK, ABORT, FAIL, REPLACE, and IGNORE.
**
** Constraint type Action What Happens
** --------------- ---------- ----------------------------------------
** any ROLLBACK The current transaction is rolled back and
** sqlite4_exec() returns immediately with a
** return code of SQLITE_CONSTRAINT.
**
** any ABORT Back out changes from the current command
** only (do not do a complete rollback) then
** cause sqlite4_exec() to return immediately
** with SQLITE_CONSTRAINT.
**
** any FAIL Sqlite3_exec() returns immediately with a
** return code of SQLITE_CONSTRAINT. The
** transaction is not rolled back and any
** prior changes are retained.
**
** any IGNORE The record number and data is popped from
** the stack and there is an immediate jump
** to label ignoreDest.
**
** NOT NULL REPLACE The NULL value is replace by the default
** value for that column. If the default value
** is NULL, the action is the same as ABORT.
**
** UNIQUE REPLACE The other row that conflicts with the row
** being inserted is removed.
**
** CHECK REPLACE Illegal. The results in an exception.
**
** Which action to take is determined by the overrideError parameter.
** Or if overrideError==OE_Default, then the pParse->onError parameter
** is used. Or if pParse->onError==OE_Default then the onError value
** for the constraint is used.
**
** The calling routine must open a read/write cursor for pTab with
** cursor number "baseCur". All indices of pTab must also have open
** read/write cursors with cursor number baseCur+i for the i-th cursor.
** Except, if there is no possibility of a REPLACE action then
** cursors do not need to be open for indices where aRegIdx[i]==0.
*/
SQLITE_PRIVATE void sqlite4GenerateConstraintChecks(
Parse *pParse, /* The parser context */
Table *pTab, /* the table into which we are inserting */
int baseCur, /* First in array of cursors for pTab indexes */
int regContent, /* Index of the range of input registers */
int *aRegIdx, /* Register used by each index. 0 for unused indices */
int regOldKey, /* For an update, the original encoded PK */
int isUpdate, /* True for UPDATE, False for INSERT */
int 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 */
){
u8 aPkRoot[10]; /* Root page number for pPk as a varint */
int nPkRoot; /* Size of aPkRoot in bytes */
Index *pPk; /* Primary key index for table pTab */
int i; /* loop counter */
Vdbe *v; /* VDBE under constrution */
int nCol; /* Number of columns */
int onError; /* Conflict resolution strategy */
int iCur; /* Table cursor number */
Index *pIdx; /* Pointer to one of the indices */
int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */
v = sqlite4GetVdbe(pParse);
assert( v!=0 );
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
nCol = pTab->nCol;
pPk = sqlite4FindPrimaryKey(pTab, 0);
nPkRoot = sqlite4PutVarint64(aPkRoot, pPk->tnum);
assert( pPk->eIndexType==SQLITE_INDEX_PRIMARYKEY );
/* Test all NOT NULL constraints. */
generateNotNullChecks(pParse, pTab, regContent, overrideError, ignoreDest);
/* Test all CHECK constraints */
generateCheckChecks(pParse, pTab, regContent, overrideError, ignoreDest);
/* Test all UNIQUE constraints by creating entries for each UNIQUE
** index and making sure that duplicate entries do not already exist.
** Add the new records to the indices as we go.
*/
for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
int nTmpReg; /* Number of temp registers required */
int regTmp; /* First temp register allocated */
int regPk; /* PK of conflicting row (for REPLACE) */
int regKey = aRegIdx[iCur]; /* Write encoded index key for pIdx here */
int iIdx = baseCur+iCur; /* Cursor for index pIdx */
/* If regKey is 0, pIdx will not be updated. */
if( regKey==0 ) continue;
/* Create an index key. Primary key indexes consists of just the primary
** key values. Other indexes consists of the indexed columns followed by
** the primary key values. */
nTmpReg = 1 + pIdx->nColumn + (pIdx==pPk ? 0 : pPk->nColumn);
regTmp = sqlite4GetTempRange(pParse, nTmpReg);
regPk = regTmp + nTmpReg - 1;
for(i=0; i<pIdx->nColumn; i++){
int idx = pIdx->aiColumn[i];
sqlite4VdbeAddOp2(v, OP_SCopy, regContent+idx, regTmp+i);
}
if( pIdx!=pPk ){
for(i=0; i<pPk->nColumn; i++){
int idx = pPk->aiColumn[i];
sqlite4VdbeAddOp2(v, OP_SCopy, regContent+idx, regTmp+i+pIdx->nColumn);
}
}
sqlite4VdbeAddOp3(v, OP_MakeIdxKey, iIdx, regTmp, regKey);
VdbeComment((v, "key for %s", pIdx->zName));
/* If Index.onError==OE_None, then pIdx is not a UNIQUE or PRIMARY KEY
** index. In this case there is no need to test the index for uniqueness
** - all that is required is to populate the regKey register. Jump
** to the next iteration of the loop if this is the case. */
onError = pIdx->onError;
if( onError!=OE_None ){
int iLabel;
/* Figure out what to do if a UNIQUE constraint is encountered.
**
** TODO: If a previous constraint is a REPLACE, why change IGNORE to
** REPLACE and FAIL to ABORT here? */
if( overrideError!=OE_Default ){
onError = overrideError;
}else if( onError==OE_Default ){
onError = OE_Abort;
}
if( seenReplace ){
if( onError==OE_Ignore ) onError = OE_Replace;
else if( onError==OE_Fail ) onError = OE_Abort;
}
iLabel = sqlite4VdbeMakeLabel(v);
if( pIdx!=pPk ){
sqlite4VdbeAddOp3(v, OP_IsNull, regTmp, iLabel, pIdx->nColumn);
}
if( regOldKey && pIdx==pPk ){
sqlite4VdbeAddOp3(v, OP_Eq, regOldKey, iLabel, regKey);
}
sqlite4VdbeAddOp4(v, OP_Blob, nPkRoot, regPk, 0, (char*)aPkRoot, nPkRoot);
sqlite4VdbeAddOp4Int(v, OP_IsUnique, iIdx, iLabel, regKey, regPk);
if( regOldKey && pIdx!=pPk ){
sqlite4VdbeAddOp3(v, OP_Eq, regOldKey, iLabel, regPk);
}
switch( onError ){
case OE_Rollback:
case OE_Abort:
case OE_Fail: {
char *zErr = notUniqueMessage(pParse, pIdx);
sqlite4HaltConstraint(pParse, onError, zErr, 0);
sqlite4DbFree(pParse->db, zErr);
break;
}
case OE_Ignore: {
assert( seenReplace==0 );
sqlite4VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
break;
}
default: {
Trigger *pTrigger;
assert( onError==OE_Replace );
sqlite4MultiWrite(pParse);
pTrigger = sqlite4TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
sqlite4GenerateRowDelete(
pParse, pTab, baseCur, regPk, 0, pTrigger, OE_Replace
);
seenReplace = 1;
break;
}
}
sqlite4VdbeResolveLabel(v, iLabel);
}
sqlite4ReleaseTempRange(pParse, regTmp, nTmpReg);
}
if( pbMayReplace ){
*pbMayReplace = seenReplace;
}
}
/*
** This routine generates code to finish the INSERT or UPDATE operation
** that was started by a prior call to sqlite4GenerateConstraintChecks.
** The arguments to this routine should be the same as the first six
** arguments to sqlite4GenerateConstraintChecks.
**
** Argument regContent points to the first in a contiguous array of
** registers that contain the row content. This function uses OP_MakeRecord
** to encode them into a record before inserting them into the database.
**
** The array aRegIdx[] contains one entry for each index attached to
** the table, in the same order as the Table.pIndex linked list. If an
** aRegIdx[] entry is 0, this indicates that the entry in the corresponding
** index does not need to be modified. Otherwise, it is the number of
** a register containing the serialized key to insert into the index.
** aRegIdx[0] (the PRIMARY KEY index key) is never 0.
*/
SQLITE_PRIVATE void sqlite4CompleteInsertion(
Parse *pParse, /* The parser context */
Table *pTab, /* the table into which we are inserting */
int baseCur, /* Index of a read/write cursor pointing at pTab */
int regContent, /* First register of content */
int *aRegIdx, /* Register used by each index. 0 for unused indices */
int isUpdate, /* 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 */
){
int i;
Vdbe *v;
Index *pIdx;
u8 pik_flags;
int regRec;
v = sqlite4GetVdbe(pParse);
assert( v!=0 );
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
if( pParse->nested ){
pik_flags = 0;
}else{
pik_flags = OPFLAG_NCHANGE | (isUpdate?OPFLAG_ISUPDATE:0);
}
/* Generate code to serialize array of registers into a database record. */
regRec = sqlite4GetTempReg(pParse);
sqlite4VdbeAddOp3(v, OP_MakeRecord, regContent, pTab->nCol, regRec);
sqlite4TableAffinityStr(v, pTab);
sqlite4ExprCacheAffinityChange(pParse, regContent, pTab->nCol);
/* Write the entry to each index. */
for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
assert( pIdx->eIndexType!=SQLITE_INDEX_PRIMARYKEY || aRegIdx[i] );
if( aRegIdx[i] ){
int regData = 0;
int flags = 0;
if( pIdx->eIndexType==SQLITE_INDEX_PRIMARYKEY ){
regData = regRec;
flags = pik_flags;
}
sqlite4VdbeAddOp3(v, OP_IdxInsert, baseCur+i, regData, aRegIdx[i]);
sqlite4VdbeChangeP5(v, flags);
}
}
}
/*
** Generate code that will open cursors for a table and for all
** indices of that table. The "baseCur" parameter is the cursor number used
** for the table. Indices are opened on subsequent cursors.
**
** Return the number of indices on the table.
*/
SQLITE_PRIVATE int sqlite4OpenAllIndexes(
Parse *pParse, /* Parsing context */
Table *pTab, /* Table to be opened */
int baseCur, /* Cursor number assigned to the table */
int op /* OP_OpenRead or OP_OpenWrite */
){
int i = 0;
if( IsVirtual(pTab)==0 ){
int iDb;
Index *pIdx;
iDb = sqlite4SchemaToIndex(pParse->db, pTab->pSchema);
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
sqlite4OpenIndex(pParse, baseCur+i, iDb, pIdx, op);
i++;
}
if( pParse->nTab<baseCur+i ){
pParse->nTab = baseCur+i;
}
}
return i;
}
SQLITE_PRIVATE void sqlite4CloseAllIndexes(
Parse *pParse,
Table *pTab,
int baseCur
){
int i;
Index *pIdx;
Vdbe *v;
assert( pTab->pIndex==0 || IsVirtual(pTab)==0 );
assert( pTab->pIndex==0 || IsView(pTab)==0 );
v = sqlite4GetVdbe(pParse);
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
sqlite4VdbeAddOp1(v, OP_Close, baseCur+i);
}
}
#ifdef SQLITE_TEST
/*
** The following global variable is incremented whenever the
** transfer optimization is used. This is used for testing
** purposes only - to make sure the transfer optimization really
** is happening when it is suppose to.
*/
SQLITE_API int sqlite4_xferopt_count;
#endif /* SQLITE_TEST */
#ifndef SQLITE_OMIT_XFER_OPT
/*
** Check to collation names to see if they are compatible.
*/
static int xferCompatibleCollation(const char *z1, const char *z2){
if( z1==0 ){
return z2==0;
}
if( z2==0 ){
return 0;
}
return sqlite4StrICmp(z1, z2)==0;
}
/*
** Check to see if index pSrc is compatible as a source of data
** for index pDest in an insert transfer optimization. The rules
** for a compatible index:
**
** * The index is over the same set of columns
** * The same DESC and ASC markings occurs on all columns
** * The same onError processing (OE_Abort, OE_Ignore, etc)
** * The same collating sequence on each column
*/
static int xferCompatibleIndex(Index *pDest, Index *pSrc){
int i;
assert( pDest && pSrc );
assert( pDest->pTable!=pSrc->pTable );
if( pDest->nColumn!=pSrc->nColumn ){
return 0; /* Different number of columns */
}
if( pDest->onError!=pSrc->onError ){
return 0; /* Different conflict resolution strategies */
}
for(i=0; i<pSrc->nColumn; i++){
if( pSrc->aiColumn[i]!=pDest->aiColumn[i] ){
return 0; /* Different columns indexed */
}
if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){
return 0; /* Different sort orders */
}
if( !xferCompatibleCollation(pSrc->azColl[i],pDest->azColl[i]) ){
return 0; /* Different collating sequences */
}
}
/* If no test above fails then the indices must be compatible */
return 1;
}
/*
** Attempt the transfer optimization on INSERTs of the form
**
** INSERT INTO tab1 SELECT * FROM tab2;
**
** The xfer optimization transfers raw records from tab2 over to tab1.
** Columns are not decoded and reassemblied, which greatly improves
** performance. Raw index records are transferred in the same way.
**
** The xfer optimization is only attempted if tab1 and tab2 are compatible.
** There are lots of rules for determining compatibility - see comments
** embedded in the code for details.
**
** This routine returns TRUE if the optimization is guaranteed to be used.
** Sometimes the xfer optimization will only work if the destination table
** is empty - a factor that can only be determined at run-time. In that
** case, this routine generates code for the xfer optimization but also
** does a test to see if the destination table is empty and jumps over the
** xfer optimization code if the test fails. In that case, this routine
** returns FALSE so that the caller will know to go ahead and generate
** an unoptimized transfer. This routine also returns FALSE if there
** is no chance that the xfer optimization can be applied.
**
** This optimization is particularly useful at making VACUUM run faster.
*/
static int xferOptimization(
Parse *pParse, /* Parser context */
Table *pDest, /* The table we are inserting into */
Select *pSelect, /* A SELECT statement to use as the data source */
int onError, /* How to handle constraint errors */
int iDbDest /* The database of pDest */
){
ExprList *pEList; /* The result set of the SELECT */
Table *pSrc; /* The table in the FROM clause of SELECT */
Index *pSrcIdx, *pDestIdx; /* Source and destination indices */
struct SrcList_item *pItem; /* An element of pSelect->pSrc */
int i; /* Loop counter */
int iDbSrc; /* The database of pSrc */
int iSrc, iDest; /* Cursors from source and destination */
int addr1, addr2; /* Loop addresses */
int emptyDestTest; /* Address of test for empty pDest */
int emptySrcTest; /* Address of test for empty pSrc */
Vdbe *v; /* The VDBE we are building */
KeyInfo *pKey; /* Key information for an index */
int regAutoinc; /* Memory register used by AUTOINC */
int destHasUniqueIdx = 0; /* True if pDest has a UNIQUE index */
int regData, regRowid, regKey; /* Registers holding data and rowid */
if( pSelect==0 ){
return 0; /* Must be of the form INSERT INTO ... SELECT ... */
}
if( sqlite4TriggerList(pParse, pDest) ){
return 0; /* tab1 must not have triggers */
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( pDest->tabFlags & TF_Virtual ){
return 0; /* tab1 must not be a virtual table */
}
#endif
if( onError==OE_Default ){
if( pDest->iPKey>=0 ) onError = pDest->keyConf;
if( onError==OE_Default ) onError = OE_Abort;
}
assert(pSelect->pSrc); /* allocated even if there is no FROM clause */
if( pSelect->pSrc->nSrc!=1 ){
return 0; /* FROM clause must have exactly one term */
}
if( pSelect->pSrc->a[0].pSelect ){
return 0; /* FROM clause cannot contain a subquery */
}
if( pSelect->pWhere ){
return 0; /* SELECT may not have a WHERE clause */
}
if( pSelect->pOrderBy ){
return 0; /* SELECT may not have an ORDER BY clause */
}
/* Do not need to test for a HAVING clause. If HAVING is present but
** there is no ORDER BY, we will get an error. */
if( pSelect->pGroupBy ){
return 0; /* SELECT may not have a GROUP BY clause */
}
if( pSelect->pLimit ){
return 0; /* SELECT may not have a LIMIT clause */
}
assert( pSelect->pOffset==0 ); /* Must be so if pLimit==0 */
if( pSelect->pPrior ){
return 0; /* SELECT may not be a compound query */
}
if( pSelect->selFlags & SF_Distinct ){
return 0; /* SELECT may not be DISTINCT */
}
pEList = pSelect->pEList;
assert( pEList!=0 );
if( pEList->nExpr!=1 ){
return 0; /* The result set must have exactly one column */
}
assert( pEList->a[0].pExpr );
if( pEList->a[0].pExpr->op!=TK_ALL ){
return 0; /* The result set must be the special operator "*" */
}
/* At this point we have established that the statement is of the
** correct syntactic form to participate in this optimization. Now
** we have to check the semantics.
*/
pItem = pSelect->pSrc->a;
pSrc = sqlite4LocateTable(pParse, 0, pItem->zName, pItem->zDatabase);
if( pSrc==0 ){
return 0; /* FROM clause does not contain a real table */
}
if( pSrc==pDest ){
return 0; /* tab1 and tab2 may not be the same table */
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( pSrc->tabFlags & TF_Virtual ){
return 0; /* tab2 must not be a virtual table */
}
#endif
if( pSrc->pSelect ){
return 0; /* tab2 may not be a view */
}
if( pDest->nCol!=pSrc->nCol ){
return 0; /* Number of columns must be the same in tab1 and tab2 */
}
if( pDest->iPKey!=pSrc->iPKey ){
return 0; /* Both tables must have the same INTEGER PRIMARY KEY */
}
for(i=0; i<pDest->nCol; i++){
if( pDest->aCol[i].affinity!=pSrc->aCol[i].affinity ){
return 0; /* Affinity must be the same on all columns */
}
if( !xferCompatibleCollation(pDest->aCol[i].zColl, pSrc->aCol[i].zColl) ){
return 0; /* Collating sequence must be the same on all columns */
}
if( pDest->aCol[i].notNull && !pSrc->aCol[i].notNull ){
return 0; /* tab2 must be NOT NULL if tab1 is */
}
}
for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
if( pDestIdx->onError!=OE_None ){
destHasUniqueIdx = 1;
}
for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){
if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
}
if( pSrcIdx==0 ){
return 0; /* pDestIdx has no corresponding index in pSrc */
}
}
#ifndef SQLITE_OMIT_CHECK
if( pDest->pCheck && sqlite4ExprCompare(pSrc->pCheck, pDest->pCheck) ){
return 0; /* Tables have different CHECK constraints. Ticket #2252 */
}
#endif
#ifndef SQLITE_OMIT_FOREIGN_KEY
/* Disallow the transfer optimization if the destination table constains
** any foreign key constraints. This is more restrictive than necessary.
** But the main beneficiary of the transfer optimization is the VACUUM
** command, and the VACUUM command disables foreign key constraints. So
** the extra complication to make this rule less restrictive is probably
** not worth the effort. Ticket [6284df89debdfa61db8073e062908af0c9b6118e]
*/
if( (pParse->db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){
return 0;
}
#endif
/* If we get this far, it means that the xfer optimization is at
** least a possibility, though it might only work if the destination
** table (tab1) is initially empty.
*/
#ifdef SQLITE_TEST
sqlite4_xferopt_count++;
#endif
iDbSrc = sqlite4SchemaToIndex(pParse->db, pSrc->pSchema);
v = sqlite4GetVdbe(pParse);
sqlite4CodeVerifySchema(pParse, iDbSrc);
iSrc = pParse->nTab++;
iDest = pParse->nTab++;
regAutoinc = autoIncBegin(pParse, iDbDest, pDest);
sqlite4OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite);
if( (pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */
|| destHasUniqueIdx /* (2) */
|| (onError!=OE_Abort && onError!=OE_Rollback) /* (3) */
){
/* In some circumstances, we are able to run the xfer optimization
** only if the destination table is initially empty. This code makes
** that determination. Conditions under which the destination must
** be empty:
**
** (1) There is no INTEGER PRIMARY KEY but there are indices.
** (If the destination is not initially empty, the rowid fields
** of index entries might need to change.)
**
** (2) The destination has a unique index. (The xfer optimization
** is unable to test uniqueness.)
**
** (3) onError is something other than OE_Abort and OE_Rollback.
*/
addr1 = sqlite4VdbeAddOp2(v, OP_Rewind, iDest, 0);
emptyDestTest = sqlite4VdbeAddOp2(v, OP_Goto, 0, 0);
sqlite4VdbeJumpHere(v, addr1);
}else{
emptyDestTest = 0;
}
sqlite4OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead);
emptySrcTest = sqlite4VdbeAddOp2(v, OP_Rewind, iSrc, 0);
regKey = sqlite4GetTempReg(pParse);
regData = sqlite4GetTempReg(pParse);
regRowid = sqlite4GetTempReg(pParse);
if( pDest->iPKey>=0 ){
addr1 = sqlite4VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
addr2 = sqlite4VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid);
sqlite4HaltConstraint(
pParse, onError, "PRIMARY KEY must be unique", P4_STATIC);
sqlite4VdbeJumpHere(v, addr2);
autoIncStep(pParse, regAutoinc, regRowid);
}else if( pDest->pIndex==0 ){
addr1 = sqlite4VdbeAddOp2(v, OP_NewRowid, iDest, regRowid);
}else{
addr1 = sqlite4VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
assert( (pDest->tabFlags & TF_Autoincrement)==0 );
}
sqlite4VdbeAddOp2(v, OP_RowData, iSrc, regData);
sqlite4VdbeAddOp3(v, OP_Insert, iDest, regData, regRowid);
sqlite4VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND);
sqlite4VdbeChangeP4(v, -1, pDest->zName, 0);
sqlite4VdbeAddOp2(v, OP_Next, iSrc, addr1);
for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){
if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
}
assert( pSrcIdx );
sqlite4VdbeAddOp2(v, OP_Close, iSrc, 0);
sqlite4VdbeAddOp2(v, OP_Close, iDest, 0);
pKey = sqlite4IndexKeyinfo(pParse, pSrcIdx);
sqlite4VdbeAddOp4(v, OP_OpenRead, iSrc, pSrcIdx->tnum, iDbSrc,
(char*)pKey, P4_KEYINFO_HANDOFF);
VdbeComment((v, "%s", pSrcIdx->zName));
pKey = sqlite4IndexKeyinfo(pParse, pDestIdx);
sqlite4VdbeAddOp4(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest,
(char*)pKey, P4_KEYINFO_HANDOFF);
VdbeComment((v, "%s", pDestIdx->zName));
addr1 = sqlite4VdbeAddOp2(v, OP_Rewind, iSrc, 0);
sqlite4VdbeAddOp2(v, OP_RowKey, iSrc, regKey);
sqlite4VdbeAddOp2(v, OP_RowData, iSrc, regData);
sqlite4VdbeAddOp3(v, OP_IdxInsert, iDest, regKey, regData);
sqlite4VdbeChangeP5(v, OPFLAG_APPENDBIAS);
sqlite4VdbeAddOp2(v, OP_Next, iSrc, addr1+1);
sqlite4VdbeJumpHere(v, addr1);
}
sqlite4VdbeJumpHere(v, emptySrcTest);
sqlite4ReleaseTempReg(pParse, regRowid);
sqlite4ReleaseTempReg(pParse, regData);
sqlite4ReleaseTempReg(pParse, regKey);
sqlite4VdbeAddOp2(v, OP_Close, iSrc, 0);
sqlite4VdbeAddOp2(v, OP_Close, iDest, 0);
if( emptyDestTest ){
sqlite4VdbeAddOp2(v, OP_Halt, SQLITE_OK, 0);
sqlite4VdbeJumpHere(v, emptyDestTest);
sqlite4VdbeAddOp2(v, OP_Close, iDest, 0);
return 0;
}else{
return 1;
}
}
#endif /* SQLITE_OMIT_XFER_OPT */
/************** End of insert.c **********************************************/
/************** Begin file legacy.c ******************************************/
/*
** 2001 September 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.
**
*************************************************************************
** Main file for the SQLite library. The routines in this file
** implement the programmer interface to the library. Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
*/
/*
** Execute SQL code. Return one of the SQLITE_ success/failure
** codes. Also write an error message into memory obtained from
** malloc() and make *pzErrMsg point to that message.
**
** If the SQL is a query, then for each row in the query result
** the xCallback() function is called. pArg becomes the first
** argument to xCallback(). If xCallback=NULL then no callback
** is invoked, even for queries.
*/
SQLITE_API int sqlite4_exec(
sqlite4 *db, /* The database on which the SQL executes */
const char *zSql, /* The SQL to be executed */
sqlite4_callback xCallback, /* Invoke this callback routine */
void *pArg, /* First argument to xCallback() */
char **pzErrMsg /* Write error messages here */
){
int rc = SQLITE_OK; /* Return code */
const char *zLeftover; /* Tail of unprocessed SQL */
sqlite4_stmt *pStmt = 0; /* The current SQL statement */
char **azCols = 0; /* Names of result columns */
int nRetry = 0; /* Number of retry attempts */
int callbackIsInit; /* True if callback data is initialized */
if( !sqlite4SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
if( zSql==0 ) zSql = "";
sqlite4_mutex_enter(db->mutex);
sqlite4Error(db, SQLITE_OK, 0);
while( (rc==SQLITE_OK || (rc==SQLITE_SCHEMA && (++nRetry)<2)) && zSql[0] ){
int nCol;
char **azVals = 0;
pStmt = 0;
rc = sqlite4_prepare(db, zSql, -1, &pStmt, &zLeftover);
assert( rc==SQLITE_OK || pStmt==0 );
if( rc!=SQLITE_OK ){
continue;
}
if( !pStmt ){
/* this happens for a comment or white-space */
zSql = zLeftover;
continue;
}
callbackIsInit = 0;
nCol = sqlite4_column_count(pStmt);
while( 1 ){
int i;
rc = sqlite4_step(pStmt);
/* Invoke the callback function if required */
if( xCallback && SQLITE_ROW==rc ){
if( !callbackIsInit ){
azCols = sqlite4DbMallocZero(db, 2*nCol*sizeof(const char*) + 1);
if( azCols==0 ){
goto exec_out;
}
for(i=0; i<nCol; i++){
azCols[i] = (char *)sqlite4_column_name(pStmt, i);
/* sqlite4VdbeSetColName() installs column names as UTF8
** strings so there is no way for sqlite4_column_name() to fail. */
assert( azCols[i]!=0 );
}
callbackIsInit = 1;
}
if( rc==SQLITE_ROW ){
azVals = &azCols[nCol];
for(i=0; i<nCol; i++){
azVals[i] = (char *)sqlite4_column_text(pStmt, i);
if( !azVals[i] && sqlite4_column_type(pStmt, i)!=SQLITE_NULL ){
db->mallocFailed = 1;
goto exec_out;
}
}
}
if( xCallback(pArg, nCol, azVals, azCols) ){
rc = SQLITE_ABORT;
sqlite4VdbeFinalize((Vdbe *)pStmt);
pStmt = 0;
sqlite4Error(db, SQLITE_ABORT, 0);
goto exec_out;
}
}
if( rc!=SQLITE_ROW ){
rc = sqlite4VdbeFinalize((Vdbe *)pStmt);
pStmt = 0;
if( rc!=SQLITE_SCHEMA ){
nRetry = 0;
zSql = zLeftover;
while( sqlite4Isspace(zSql[0]) ) zSql++;
}
break;
}
}
sqlite4DbFree(db, azCols);
azCols = 0;
}
exec_out:
if( pStmt ) sqlite4VdbeFinalize((Vdbe *)pStmt);
sqlite4DbFree(db, azCols);
rc = sqlite4ApiExit(db, rc);
if( rc!=SQLITE_OK && ALWAYS(rc==sqlite4_errcode(db)) && pzErrMsg ){
int nErrMsg = 1 + sqlite4Strlen30(sqlite4_errmsg(db));
*pzErrMsg = sqlite4Malloc(0, nErrMsg);
if( *pzErrMsg ){
memcpy(*pzErrMsg, sqlite4_errmsg(db), nErrMsg);
}else{
rc = SQLITE_NOMEM;
sqlite4Error(db, SQLITE_NOMEM, 0);
}
}else if( pzErrMsg ){
*pzErrMsg = 0;
}
sqlite4_mutex_leave(db->mutex);
return rc;
}
/************** End of legacy.c **********************************************/
/************** Begin file pragma.c ******************************************/
/*
** 2003 April 6
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the PRAGMA command.
*/
/*
** Interpret the given string as a boolean value.
*/
SQLITE_PRIVATE u8 sqlite4GetBoolean(const char *z){
/* 123456789 12345 */
static const char zText[] = "onoffalseyestrue";
static const u8 iOffset[] = {0, 1, 2, 4, 9, 12};
static const u8 iLength[] = {2, 2, 3, 5, 3, 4};
static const u8 iValue[] = {1, 0, 0, 0, 1, 1};
int i, n;
if( sqlite4Isdigit(*z) ){
return (u8)sqlite4Atoi(z);
}
n = sqlite4Strlen30(z);
for(i=0; i<ArraySize(iLength); i++){
if( iLength[i]==n && sqlite4StrNICmp(&zText[iOffset[i]],z,n)==0 ){
return iValue[i];
}
}
return 1;
}
/* The sqlite4GetBoolean() function is used by other modules but the
** remainder of this file is specific to PRAGMA processing. So omit
** the rest of the file if PRAGMAs are omitted from the build.
*/
#if !defined(SQLITE_OMIT_PRAGMA)
/*
** Generate code to return a single integer value.
*/
static void returnSingleInt(Parse *pParse, const char *zLabel, i64 value){
Vdbe *v = sqlite4GetVdbe(pParse);
int mem = ++pParse->nMem;
i64 *pI64 = sqlite4DbMallocRaw(pParse->db, sizeof(value));
if( pI64 ){
memcpy(pI64, &value, sizeof(value));
}
sqlite4VdbeAddOp4(v, OP_Int64, 0, mem, 0, (char*)pI64, P4_INT64);
sqlite4VdbeSetNumCols(v, 1);
sqlite4VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC);
sqlite4VdbeAddOp2(v, OP_ResultRow, mem, 1);
}
#ifndef SQLITE_OMIT_FLAG_PRAGMAS
/*
** Check to see if zRight and zLeft refer to a pragma that queries
** or changes one of the flags in db->flags. Return 1 if so and 0 if not.
** Also, implement the pragma.
*/
static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
static const struct sPragmaType {
const char *zName; /* Name of the pragma */
int mask; /* Mask for the db->flags value */
} aPragma[] = {
{ "reverse_unordered_selects", SQLITE_ReverseOrder },
{ "automatic_index", SQLITE_AutoIndex },
#ifdef SQLITE_DEBUG
{ "sql_trace", SQLITE_SqlTrace },
{ "vdbe_listing", SQLITE_VdbeListing },
{ "vdbe_trace", SQLITE_VdbeTrace },
{ "kv_trace", SQLITE_KvTrace },
{ "trace", SQLITE_SqlTrace | SQLITE_VdbeListing |
SQLITE_VdbeTrace | SQLITE_KvTrace },
#endif
#ifndef SQLITE_OMIT_CHECK
{ "ignore_check_constraints", SQLITE_IgnoreChecks },
#endif
/* The following is VERY experimental */
{ "writable_schema", SQLITE_WriteSchema|SQLITE_RecoveryMode },
/* This flag may only be set if both foreign-key and trigger support
** are present in the build. */
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
{ "foreign_keys", SQLITE_ForeignKeys },
#endif
};
int i, j;
const struct sPragmaType *p;
for(i=0, p=aPragma; i<ArraySize(aPragma); i++, p++){
if( sqlite4StrICmp(zLeft, p->zName)==0 ){
sqlite4 *db = pParse->db;
Vdbe *v;
v = sqlite4GetVdbe(pParse);
assert( v!=0 ); /* Already allocated by sqlite4Pragma() */
if( ALWAYS(v) ){
if( zRight==0 ){
returnSingleInt(pParse, p->zName, (db->flags & p->mask)!=0 );
}else{
int mask = p->mask; /* Mask of bits to set or clear. */
if( db->pSavepoint ){
/* Foreign key support may not be enabled or disabled while not
** in auto-commit mode. */
mask &= ~(SQLITE_ForeignKeys);
}
if( sqlite4GetBoolean(zRight) ){
db->flags |= mask;
}else{
db->flags &= ~mask;
}
/* Many of the flag-pragmas modify the code generated by the SQL
** compiler (eg. count_changes). So add an opcode to expire all
** compiled SQL statements after modifying a pragma value.
*/
sqlite4VdbeAddOp2(v, OP_Expire, 0, 0);
}
for(j=0; j<db->nDb; j++){
if( db->aDb[j].pKV ){
db->aDb[j].pKV->fTrace = (db->flags & SQLITE_KvTrace)!=0;
}
}
}
return 1;
}
}
return 0;
}
#endif /* SQLITE_OMIT_FLAG_PRAGMAS */
/*
** Return a human-readable name for a constraint resolution action.
*/
#ifndef SQLITE_OMIT_FOREIGN_KEY
static const char *actionName(u8 action){
const char *zName;
switch( action ){
case OE_SetNull: zName = "SET NULL"; break;
case OE_SetDflt: zName = "SET DEFAULT"; break;
case OE_Cascade: zName = "CASCADE"; break;
case OE_Restrict: zName = "RESTRICT"; break;
default: zName = "NO ACTION";
assert( action==OE_None ); break;
}
return zName;
}
#endif
/*
** Process a pragma statement.
**
** Pragmas are of this form:
**
** PRAGMA [database.]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
** a number that was preceded by a minus sign.
**
** If the left side is "database.id" then pId1 is the database name
** and pId2 is the id. If the left side is just "id" then pId1 is the
** id and pId2 is any empty string.
*/
SQLITE_PRIVATE void sqlite4Pragma(
Parse *pParse,
Token *pId1, /* First part of [database.]id field */
Token *pId2, /* Second part of [database.]id field, or NULL */
Token *pValue, /* Token for <value>, or NULL */
int minusFlag /* True if a '-' sign preceded <value> */
){
char *zLeft = 0; /* Nul-terminated UTF-8 string <id> */
char *zRight = 0; /* Nul-terminated UTF-8 string <value>, or NULL */
const char *zDb = 0; /* The database name */
Token *pId; /* Pointer to <id> token */
int iDb; /* Database index for <database> */
sqlite4 *db = pParse->db;
Db *pDb;
Vdbe *v = pParse->pVdbe = sqlite4VdbeCreate(db);
if( v==0 ) return;
sqlite4VdbeRunOnlyOnce(v);
pParse->nMem = 2;
/* Interpret the [database.] part of the pragma statement. iDb is the
** index of the database this pragma is being applied to in db.aDb[]. */
iDb = sqlite4TwoPartName(pParse, pId1, pId2, &pId);
if( iDb<0 ) return;
pDb = &db->aDb[iDb];
/* If the temp database has been explicitly named as part of the
** pragma, make sure it is open.
*/
if( iDb==1 && sqlite4OpenTempDatabase(pParse) ){
return;
}
zLeft = sqlite4NameFromToken(db, pId);
if( !zLeft ) return;
if( minusFlag ){
zRight = sqlite4MPrintf(db, "-%T", pValue);
}else{
zRight = sqlite4NameFromToken(db, pValue);
}
assert( pId2 );
zDb = pId2->n>0 ? pDb->zName : 0;
if( sqlite4AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){
goto pragma_out;
}
#ifndef SQLITE_OMIT_FLAG_PRAGMAS
if( flagPragma(pParse, zLeft, zRight) ){
/* The flagPragma() subroutine also generates any necessary code
** there is nothing more to do here */
}else
#endif /* SQLITE_OMIT_FLAG_PRAGMAS */
#ifndef SQLITE_OMIT_SCHEMA_PRAGMAS
/*
** PRAGMA table_info(<table>)
**
** Return a single row for each column of the named table. The columns of
** the returned data set are:
**
** cid: Column id (numbered from left to right, starting at 0)
** name: Column name
** type: Column declaration type.
** notnull: True if 'NOT NULL' is part of column declaration
** dflt_value: The default value for the column, if any.
*/
if( sqlite4StrICmp(zLeft, "table_info")==0 && zRight ){
Table *pTab;
if( sqlite4ReadSchema(pParse) ) goto pragma_out;
pTab = sqlite4FindTable(db, zRight, zDb);
if( pTab ){
int i;
int nHidden = 0;
Column *pCol;
sqlite4VdbeSetNumCols(v, 6);
pParse->nMem = 6;
sqlite4VdbeSetColName(v, 0, COLNAME_NAME, "cid", SQLITE_STATIC);
sqlite4VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
sqlite4VdbeSetColName(v, 2, COLNAME_NAME, "type", SQLITE_STATIC);
sqlite4VdbeSetColName(v, 3, COLNAME_NAME, "notnull", SQLITE_STATIC);
sqlite4VdbeSetColName(v, 4, COLNAME_NAME, "dflt_value", SQLITE_STATIC);
sqlite4VdbeSetColName(v, 5, COLNAME_NAME, "pk", SQLITE_STATIC);
sqlite4ViewGetColumnNames(pParse, pTab);
for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
if( IsHiddenColumn(pCol) ){
nHidden++;
continue;
}
sqlite4VdbeAddOp2(v, OP_Integer, i-nHidden, 1);
sqlite4VdbeAddOp4(v, OP_String8, 0, 2, 0, pCol->zName, 0);
sqlite4VdbeAddOp4(v, OP_String8, 0, 3, 0,
pCol->zType ? pCol->zType : "", 0);
sqlite4VdbeAddOp2(v, OP_Integer, (pCol->notNull ? 1 : 0), 4);
if( pCol->zDflt ){
sqlite4VdbeAddOp4(v, OP_String8, 0, 5, 0, (char*)pCol->zDflt, 0);
}else{
sqlite4VdbeAddOp2(v, OP_Null, 0, 5);
}
sqlite4VdbeAddOp2(v, OP_Integer, pCol->isPrimKey, 6);
sqlite4VdbeAddOp2(v, OP_ResultRow, 1, 6);
}
}
}else
if( sqlite4StrICmp(zLeft, "index_info")==0 && zRight ){
Index *pIdx;
Table *pTab;
if( sqlite4ReadSchema(pParse) ) goto pragma_out;
pIdx = sqlite4FindIndex(db, zRight, zDb);
if( pIdx ){
int i;
pTab = pIdx->pTable;
sqlite4VdbeSetNumCols(v, 3);
pParse->nMem = 3;
sqlite4VdbeSetColName(v, 0, COLNAME_NAME, "seqno", SQLITE_STATIC);
sqlite4VdbeSetColName(v, 1, COLNAME_NAME, "cid", SQLITE_STATIC);
sqlite4VdbeSetColName(v, 2, COLNAME_NAME, "name", SQLITE_STATIC);
for(i=0; i<pIdx->nColumn; i++){
int cnum = pIdx->aiColumn[i];
sqlite4VdbeAddOp2(v, OP_Integer, i, 1);
sqlite4VdbeAddOp2(v, OP_Integer, cnum, 2);
assert( pTab->nCol>cnum );
sqlite4VdbeAddOp4(v, OP_String8, 0, 3, 0, pTab->aCol[cnum].zName, 0);
sqlite4VdbeAddOp2(v, OP_ResultRow, 1, 3);
}
}
}else
if( sqlite4StrICmp(zLeft, "index_list")==0 && zRight ){
Index *pIdx;
Table *pTab;
if( sqlite4ReadSchema(pParse) ) goto pragma_out;
pTab = sqlite4FindTable(db, zRight, zDb);
if( pTab ){
v = sqlite4GetVdbe(pParse);
pIdx = pTab->pIndex;
if( pIdx ){
int i = 0;
sqlite4VdbeSetNumCols(v, 3);
pParse->nMem = 3;
sqlite4VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
sqlite4VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
sqlite4VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC);
while(pIdx){
sqlite4VdbeAddOp2(v, OP_Integer, i, 1);
sqlite4VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0);
sqlite4VdbeAddOp2(v, OP_Integer, pIdx->onError!=OE_None, 3);
sqlite4VdbeAddOp2(v, OP_ResultRow, 1, 3);
++i;
pIdx = pIdx->pNext;
}
}
}
}else
if( sqlite4StrICmp(zLeft, "database_list")==0 ){
int i;
if( sqlite4ReadSchema(pParse) ) goto pragma_out;
sqlite4VdbeSetNumCols(v, 3);
pParse->nMem = 3;
sqlite4VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
sqlite4VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
sqlite4VdbeSetColName(v, 2, COLNAME_NAME, "file", SQLITE_STATIC);
for(i=0; i<db->nDb; i++){
if( db->aDb[i].pKV==0 ) continue;
assert( db->aDb[i].zName!=0 );
sqlite4VdbeAddOp2(v, OP_Integer, i, 1);
sqlite4VdbeAddOp4(v, OP_String8, 0, 2, 0, db->aDb[i].zName, 0);
sqlite4VdbeAddOp4(v, OP_String8, 0, 3, 0,
"filename", 0);
sqlite4VdbeAddOp2(v, OP_ResultRow, 1, 3);
}
}else
if( sqlite4StrICmp(zLeft, "collation_list")==0 ){
int i = 0;
HashElem *p;
sqlite4VdbeSetNumCols(v, 2);
pParse->nMem = 2;
sqlite4VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
sqlite4VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){
CollSeq *pColl = (CollSeq *)sqliteHashData(p);
sqlite4VdbeAddOp2(v, OP_Integer, i++, 1);
sqlite4VdbeAddOp4(v, OP_String8, 0, 2, 0, pColl->zName, 0);
sqlite4VdbeAddOp2(v, OP_ResultRow, 1, 2);
}
}else
#endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */
#ifndef SQLITE_OMIT_FOREIGN_KEY
if( sqlite4StrICmp(zLeft, "foreign_key_list")==0 && zRight ){
FKey *pFK;
Table *pTab;
if( sqlite4ReadSchema(pParse) ) goto pragma_out;
pTab = sqlite4FindTable(db, zRight, zDb);
if( pTab ){
v = sqlite4GetVdbe(pParse);
pFK = pTab->pFKey;
if( pFK ){
int i = 0;
sqlite4VdbeSetNumCols(v, 8);
pParse->nMem = 8;
sqlite4VdbeSetColName(v, 0, COLNAME_NAME, "id", SQLITE_STATIC);
sqlite4VdbeSetColName(v, 1, COLNAME_NAME, "seq", SQLITE_STATIC);
sqlite4VdbeSetColName(v, 2, COLNAME_NAME, "table", SQLITE_STATIC);
sqlite4VdbeSetColName(v, 3, COLNAME_NAME, "from", SQLITE_STATIC);
sqlite4VdbeSetColName(v, 4, COLNAME_NAME, "to", SQLITE_STATIC);
sqlite4VdbeSetColName(v, 5, COLNAME_NAME, "on_update", SQLITE_STATIC);
sqlite4VdbeSetColName(v, 6, COLNAME_NAME, "on_delete", SQLITE_STATIC);
sqlite4VdbeSetColName(v, 7, COLNAME_NAME, "match", SQLITE_STATIC);
while(pFK){
int j;
for(j=0; j<pFK->nCol; j++){
char *zCol = pFK->aCol[j].zCol;
char *zOnDelete = (char *)actionName(pFK->aAction[0]);
char *zOnUpdate = (char *)actionName(pFK->aAction[1]);
sqlite4VdbeAddOp2(v, OP_Integer, i, 1);
sqlite4VdbeAddOp2(v, OP_Integer, j, 2);
sqlite4VdbeAddOp4(v, OP_String8, 0, 3, 0, pFK->zTo, 0);
sqlite4VdbeAddOp4(v, OP_String8, 0, 4, 0,
pTab->aCol[pFK->aCol[j].iFrom].zName, 0);
sqlite4VdbeAddOp4(v, zCol ? OP_String8 : OP_Null, 0, 5, 0, zCol, 0);
sqlite4VdbeAddOp4(v, OP_String8, 0, 6, 0, zOnUpdate, 0);
sqlite4VdbeAddOp4(v, OP_String8, 0, 7, 0, zOnDelete, 0);
sqlite4VdbeAddOp4(v, OP_String8, 0, 8, 0, "NONE", 0);
sqlite4VdbeAddOp2(v, OP_ResultRow, 1, 8);
}
++i;
pFK = pFK->pNextFrom;
}
}
}
}else
#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
#ifndef NDEBUG
if( sqlite4StrICmp(zLeft, "parser_trace")==0 ){
if( zRight ){
if( sqlite4GetBoolean(zRight) ){
sqlite4ParserTrace(stderr, "parser: ");
}else{
sqlite4ParserTrace(0, 0);
}
}
}else
#endif
/* Reinstall the LIKE and GLOB functions. The variant of LIKE
** used will be case sensitive or not depending on the RHS.
*/
if( sqlite4StrICmp(zLeft, "case_sensitive_like")==0 ){
if( zRight ){
sqlite4RegisterLikeFunctions(db, sqlite4GetBoolean(zRight));
}
}else
#ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX
# define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100
#endif
#ifndef SQLITE_OMIT_UTF16
/*
** PRAGMA encoding
** PRAGMA encoding = "utf-8"|"utf-16"|"utf-16le"|"utf-16be"
**
** In its first form, this pragma returns the encoding of the main
** database. If the database is not initialized, it is initialized now.
**
** The second form of this pragma is a no-op if the main database file
** has not already been initialized. In this case it sets the default
** encoding that will be used for the main database file if a new file
** is created. If an existing main database file is opened, then the
** default text encoding for the existing database is used.
**
** In all cases new databases created using the ATTACH command are
** created to use the same default text encoding as the main database. If
** the main database has not been initialized and/or created when ATTACH
** is executed, this is done before the ATTACH operation.
**
** In the second form this pragma sets the text encoding to be used in
** new database files created using this database handle. It is only
** useful if invoked immediately after the main database i
*/
if( sqlite4StrICmp(zLeft, "encoding")==0 ){
static const struct EncName {
char *zName;
u8 enc;
} encnames[] = {
{ "UTF8", SQLITE_UTF8 },
{ "UTF-8", SQLITE_UTF8 }, /* Must be element [1] */
{ "UTF-16le", SQLITE_UTF16LE }, /* Must be element [2] */
{ "UTF-16be", SQLITE_UTF16BE }, /* Must be element [3] */
{ "UTF16le", SQLITE_UTF16LE },
{ "UTF16be", SQLITE_UTF16BE },
{ "UTF-16", 0 }, /* SQLITE_UTF16NATIVE */
{ "UTF16", 0 }, /* SQLITE_UTF16NATIVE */
{ 0, 0 }
};
const struct EncName *pEnc;
if( !zRight ){ /* "PRAGMA encoding" */
if( sqlite4ReadSchema(pParse) ) goto pragma_out;
sqlite4VdbeSetNumCols(v, 1);
sqlite4VdbeSetColName(v, 0, COLNAME_NAME, "encoding", SQLITE_STATIC);
sqlite4VdbeAddOp2(v, OP_String8, 0, 1);
assert( encnames[SQLITE_UTF8].enc==SQLITE_UTF8 );
assert( encnames[SQLITE_UTF16LE].enc==SQLITE_UTF16LE );
assert( encnames[SQLITE_UTF16BE].enc==SQLITE_UTF16BE );
sqlite4VdbeChangeP4(v, -1, encnames[ENC(pParse->db)].zName, P4_STATIC);
sqlite4VdbeAddOp2(v, OP_ResultRow, 1, 1);
}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
** will be overwritten when the schema is next loaded. If it does not
** already exists, it will be created to use the new encoding value.
*/
if(
!(DbHasProperty(db, 0, DB_SchemaLoaded)) ||
DbHasProperty(db, 0, DB_Empty)
){
for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
if( 0==sqlite4StrICmp(zRight, pEnc->zName) ){
ENC(pParse->db) = pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE;
break;
}
}
if( !pEnc->zName ){
sqlite4ErrorMsg(pParse, "unsupported encoding: %s", zRight);
}
}
}
}else
#endif /* SQLITE_OMIT_UTF16 */
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
/*
** PRAGMA compile_options
**
** Return the names of all compile-time options used in this build,
** one option per row.
*/
if( sqlite4StrICmp(zLeft, "compile_options")==0 ){
int i = 0;
const char *zOpt;
sqlite4VdbeSetNumCols(v, 1);
pParse->nMem = 1;
sqlite4VdbeSetColName(v, 0, COLNAME_NAME, "compile_option", SQLITE_STATIC);
while( (zOpt = sqlite4_compileoption_get(i++))!=0 ){
sqlite4VdbeAddOp4(v, OP_String8, 0, 1, 0, zOpt, 0);
sqlite4VdbeAddOp2(v, OP_ResultRow, 1, 1);
}
}else
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
#ifdef SQLITE_DEBUG
/*
** PRAGMA kvdump
**
** Print an ascii rendering of the complete content of the database file.
*/
if( sqlite4StrICmp(zLeft, "kvdump")==0 ){
sqlite4KVStoreDump(db->aDb[0].pKV);
}else
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
/*
** PRAGMA integrity_check
**
** Check that for each table, the content of any auxilliary indexes are
** consistent with the primary key index.
*/
if( sqlite4StrICmp(zLeft, "integrity_check")==0 ){
const int baseCsr = 1; /* Base cursor for OpenAllIndexes() call */
const int regErrcnt = 1; /* Register containing error count */
const int regErrstr = 2; /* Register containing error string */
const int regTmp = 3; /* Register for tmp use */
const int regRowcnt1 = 4; /* Register containing row count (from PK) */
const int regRowcnt2 = 5; /* Register containing error count */
const int regResult = 6; /* Register containing result string */
const int regKey = 7; /* Register containing encoded key */
const int regArray = 8; /* First in array of registers */
int i;
int nMaxArray = 1;
int addrNot = 0;
Vdbe *v;
if( sqlite4ReadSchema(pParse) ) goto pragma_out;
for(i=0; i<db->nDb; i++){
if( OMIT_TEMPDB && i==1 ) continue;
sqlite4CodeVerifySchema(pParse, i);
}
v = sqlite4GetVdbe(pParse);
sqlite4VdbeAddOp2(v, OP_Integer, 0, regErrcnt);
sqlite4VdbeAddOp4(v, OP_String8, 0, regErrstr, 0, "", 0);
for(i=0; i<db->nDb; i++){
Hash *pTbls;
HashElem *x;
if( OMIT_TEMPDB && i==1 ) continue;
pTbls = &db->aDb[i].pSchema->tblHash;
for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
Index *pIdx;
Table *pTab = (Table *)sqliteHashData(x);
int addrRewind;
int nIdx = 0;
int iPkCsr;
Index *pPk;
int iCsr;
/* Do nothing for views */
if( IsView(pTab) ) continue;
/* Open all indexes for table pTab. */
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( pIdx->eIndexType==SQLITE_INDEX_PRIMARYKEY ){
pPk = pIdx;
iPkCsr = nIdx+baseCsr;
}
nIdx++;
}
sqlite4OpenAllIndexes(pParse, pTab, baseCsr, OP_OpenRead);
sqlite4VdbeAddOp2(v, OP_Integer, 0, regRowcnt1);
addrRewind = sqlite4VdbeAddOp1(v, OP_Rewind, iPkCsr);
/* Increment the row-count register */
sqlite4VdbeAddOp2(v, OP_AddImm, regRowcnt1, 1);
for(iCsr=baseCsr, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCsr++){
assert( (pIdx->eIndexType==SQLITE_INDEX_PRIMARYKEY)==(iCsr==iPkCsr) );
if( iCsr!=iPkCsr ){
char *zErr;
int iCol;
int jmp;
for(iCol=0; iCol<pIdx->nColumn; iCol++){
int r = regArray + iCol;
sqlite4VdbeAddOp3(v, OP_Column, iPkCsr, pIdx->aiColumn[iCol], r);
assert( pIdx->aiColumn[iCol]>=0 );
}
for(iCol=0; iCol<pPk->nColumn; iCol++){
int reg = regArray + pIdx->nColumn + iCol;
int iTblCol = pPk->aiColumn[iCol];
if( iTblCol<0 ){
sqlite4VdbeAddOp2(v, OP_Rowid, iPkCsr, reg);
}else{
sqlite4VdbeAddOp3(v, OP_Column, iPkCsr, iTblCol, reg);
}
}
if( (pPk->nColumn+pIdx->nColumn)>nMaxArray ){
nMaxArray = pPk->nColumn + pIdx->nColumn;
}
sqlite4VdbeAddOp3(v, OP_MakeIdxKey, iCsr, regArray, regKey);
jmp = sqlite4VdbeAddOp4(v, OP_Found, iCsr, 0, regKey, 0, P4_INT32);
sqlite4VdbeAddOp2(v, OP_AddImm, regErrcnt, 1);
zErr = sqlite4MPrintf(
db, "entry missing from index %s: ", pIdx->zName
);
sqlite4VdbeAddOp4(v, OP_String8, 0, regTmp, 0, zErr, 0);
sqlite4VdbeAddOp3(v, OP_Concat, regTmp, regErrstr, regErrstr);
sqlite4VdbeAddOp3(v, OP_Function, 0, regKey, regTmp);
sqlite4VdbeChangeP4(v, -1,
(char *)sqlite4FindFunction(db, "hex", 3, 1, SQLITE_UTF8, 0),
P4_FUNCDEF
);
sqlite4VdbeChangeP5(v, 1);
sqlite4VdbeAddOp3(v, OP_Concat, regTmp, regErrstr, regErrstr);
sqlite4VdbeAddOp4(v, OP_String8, 0, regTmp, 0, "\n", 0);
sqlite4VdbeAddOp3(v, OP_Concat, regTmp, regErrstr, regErrstr);
sqlite4VdbeJumpHere(v, jmp);
sqlite4DbFree(db, zErr);
}
}
sqlite4VdbeAddOp2(v, OP_Next, iPkCsr, addrRewind+1);
sqlite4VdbeJumpHere(v, addrRewind);
for(iCsr=baseCsr, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCsr++){
if( iCsr!=iPkCsr ){
char *zErr;
int addrEq;
int addrRewind2;
sqlite4VdbeAddOp2(v, OP_Integer, 0, regRowcnt2);
addrRewind2 = sqlite4VdbeAddOp1(v, OP_Rewind, iCsr);
sqlite4VdbeAddOp2(v, OP_AddImm, regRowcnt2, 1);
sqlite4VdbeAddOp2(v, OP_Next, iCsr, addrRewind2+1);
sqlite4VdbeJumpHere(v, addrRewind2);
zErr = sqlite4MPrintf(
db, "wrong # number of entries in index %s\n", pIdx->zName
);
addrEq = sqlite4VdbeAddOp3(v, OP_Eq, regRowcnt1, 0, regRowcnt2);
sqlite4VdbeAddOp2(v, OP_AddImm, regErrcnt, 1);
sqlite4VdbeAddOp4(v, OP_String8, 0, regTmp, 0, zErr, 0);
sqlite4VdbeAddOp3(v, OP_Concat, regTmp, regErrstr, regErrstr);
sqlite4VdbeJumpHere(v, addrEq);
sqlite4DbFree(db, zErr);
}
}
for(iCsr=baseCsr; iCsr<(baseCsr+nIdx); iCsr++){
sqlite4VdbeAddOp1(v, OP_Close, iCsr);
}
}
}
sqlite4VdbeAddOp4(v, OP_String8, 0, regResult, 0, "ok", 0);
addrNot = sqlite4VdbeAddOp1(v, OP_IfNot, regErrcnt);
sqlite4VdbeAddOp4(v, OP_String8, 0, regArray, 0, " errors:\n", 0);
sqlite4VdbeAddOp3(v, OP_Concat, regArray, regErrcnt, regResult);
sqlite4VdbeAddOp3(v, OP_Concat, regErrstr, regResult, regResult);
sqlite4VdbeJumpHere(v, addrNot);
pParse->nMem = (regArray + nMaxArray);
sqlite4VdbeSetNumCols(v, 1);
sqlite4VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", SQLITE_STATIC);
sqlite4VdbeAddOp2(v, OP_ResultRow, regResult, 1);
}else
/*
** PRAGMA shrink_memory
**
** This pragma attempts to free as much memory as possible from the
** current database connection.
*/
if( sqlite4StrICmp(zLeft, "shrink_memory")==0 ){
sqlite4_db_release_memory(db);
}else
{/* Empty ELSE clause */}
pragma_out:
sqlite4DbFree(db, zLeft);
sqlite4DbFree(db, zRight);
}
#endif /* SQLITE_OMIT_PRAGMA */
/************** End of pragma.c **********************************************/
/************** Begin file prepare.c *****************************************/
/*
** 2005 May 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.
**
*************************************************************************
** This file contains the implementation of the sqlite4_prepare()
** interface, and routines that contribute to loading the database schema
** from disk.
*/
/*
** Fill the InitData structure with an error message that indicates
** that the database is corrupt.
*/
static void corruptSchema(
InitData *pData, /* Initialization context */
const char *zObj, /* Object being parsed at the point of error */
const char *zExtra /* Error information */
){
sqlite4 *db = pData->db;
if( !db->mallocFailed && (db->flags & SQLITE_RecoveryMode)==0 ){
if( zObj==0 ) zObj = "?";
sqlite4SetString(pData->pzErrMsg, db,
"malformed database schema (%s)", zObj);
if( zExtra ){
*pData->pzErrMsg = sqlite4MAppendf(db, *pData->pzErrMsg,
"%s - %s", *pData->pzErrMsg, zExtra);
}
}
pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT_BKPT;
}
/*
** This is the callback routine for the code that initializes the
** database. See sqlite4Init() below for additional information.
** This routine is also called from the OP_ParseSchema opcode of the VDBE.
**
** Each callback contains the following information:
**
** argv[0] = name of thing being created
** argv[1] = root page number for table or index. 0 for trigger or view.
** argv[2] = SQL text for the CREATE statement.
**
*/
SQLITE_PRIVATE int sqlite4InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
InitData *pData = (InitData*)pInit;
sqlite4 *db = pData->db;
int iDb = pData->iDb;
assert( argc==3 );
UNUSED_PARAMETER2(NotUsed, argc);
assert( sqlite4_mutex_held(db->mutex) );
DbClearProperty(db, iDb, DB_Empty);
if( db->mallocFailed ){
corruptSchema(pData, argv[0], 0);
return 1;
}
assert( iDb>=0 && iDb<db->nDb );
if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */
if( argv[1]==0 ){
corruptSchema(pData, argv[0], 0);
}else if( argv[2] && argv[2][0] ){
/* Call the parser to process a CREATE TABLE, INDEX or VIEW.
** But because db->init.busy is set to 1, no VDBE code is generated
** or executed. All the parser does is build the internal data
** structures that describe the table, index, or view.
*/
int rc;
sqlite4_stmt *pStmt;
TESTONLY(int rcp); /* Return code from sqlite4_prepare() */
assert( db->init.busy );
db->init.iDb = iDb;
db->init.newTnum = sqlite4Atoi(argv[1]);
db->init.orphanTrigger = 0;
TESTONLY(rcp = ) sqlite4_prepare(db, argv[2], -1, &pStmt, 0);
rc = db->errCode;
assert( (rc&0xFF)==(rcp&0xFF) );
db->init.iDb = 0;
if( SQLITE_OK!=rc ){
if( db->init.orphanTrigger ){
assert( iDb==1 );
}else{
pData->rc = rc;
if( rc==SQLITE_NOMEM ){
db->mallocFailed = 1;
}else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){
corruptSchema(pData, argv[0], sqlite4_errmsg(db));
}
}
}
sqlite4_finalize(pStmt);
}else if( argv[0]==0 ){
corruptSchema(pData, 0, 0);
}else{
/* If the SQL column is blank it means this is an index that
** was created to be the PRIMARY KEY or to fulfill a UNIQUE
** constraint for a CREATE TABLE. The index should have already
** been created when we processed the CREATE TABLE. All we have
** to do here is record the root page number for that index.
*/
Index *pIndex;
pIndex = sqlite4FindIndex(db, argv[0], db->aDb[iDb].zName);
if( pIndex==0 ){
/* This can occur if there exists an index on a TEMP table which
** has the same name as another index on a permanent index. Since
** the permanent table is hidden by the TEMP table, we can also
** safely ignore the index on the permanent table.
*/
/* Do Nothing */;
}else if( sqlite4GetInt32(argv[1], &pIndex->tnum)==0 ){
corruptSchema(pData, argv[0], "invalid rootpage");
}
}
return 0;
}
/*
** Attempt to read the database schema and initialize internal
** data structures for a single database file. The index of the
** database file is given by iDb. iDb==0 is used for the main
** database. iDb==1 should never be used. iDb>=2 is used for
** auxiliary databases. Return one of the SQLITE_ error codes to
** indicate success or failure.
*/
static int sqlite4InitOne(sqlite4 *db, int iDb, char **pzErrMsg){
int rc;
Table *pTab;
Db *pDb;
char const *azArg[4];
unsigned int meta[5];
InitData initData;
char const *zMasterSchema;
char const *zMasterName;
int openedTransaction = 0;
/*
** The master database table has a structure like this
*/
static const char master_schema[] =
"CREATE TABLE sqlite_master(\n"
" type text,\n"
" name text,\n"
" tbl_name text,\n"
" rootpage integer,\n"
" sql text\n"
")"
;
#ifndef SQLITE_OMIT_TEMPDB
static const char temp_master_schema[] =
"CREATE TEMP TABLE sqlite_temp_master(\n"
" type text,\n"
" name text,\n"
" tbl_name text,\n"
" rootpage integer,\n"
" sql text\n"
")"
;
#else
#define temp_master_schema 0
#endif
assert( iDb>=0 && iDb<db->nDb );
assert( db->aDb[iDb].pSchema );
assert( sqlite4_mutex_held(db->mutex) );
/* zMasterSchema and zInitScript are set to point at the master schema
** and initialisation script appropriate for the database being
** initialised. zMasterName is the name of the master table.
*/
if( !OMIT_TEMPDB && iDb==1 ){
zMasterSchema = temp_master_schema;
}else{
zMasterSchema = master_schema;
}
zMasterName = SCHEMA_TABLE(iDb);
/* Construct the schema tables. */
azArg[0] = zMasterName;
azArg[1] = "1";
azArg[2] = zMasterSchema;
azArg[3] = 0;
initData.db = db;
initData.iDb = iDb;
initData.rc = SQLITE_OK;
initData.pzErrMsg = pzErrMsg;
sqlite4InitCallback(&initData, 3, (char **)azArg, 0);
if( initData.rc ){
rc = initData.rc;
goto error_out;
}
pTab = sqlite4FindTable(db, zMasterName, db->aDb[iDb].zName);
if( ALWAYS(pTab) ){
pTab->tabFlags |= TF_Readonly;
}
/* Create a cursor to hold the database open
*/
pDb = &db->aDb[iDb];
if( pDb->pKV==0 ){
if( !OMIT_TEMPDB && ALWAYS(iDb==1) ){
DbSetProperty(db, 1, DB_SchemaLoaded);
}
return SQLITE_OK;
}
/* If there is not already a read-only (or read-write) transaction opened
** on the database, open one now. If a transaction is opened, it
** will be closed before this function returns. */
if( pDb->pKV->iTransLevel==0 ){
rc = sqlite4KVStoreBegin(pDb->pKV, 1);
if( rc!=SQLITE_OK ){
sqlite4SetString(pzErrMsg, db, "%s", sqlite4ErrStr(rc));
goto initone_error_out;
}
openedTransaction = 1;
}
/* Get the database meta information.
**
** Meta values are as follows:
** meta[0] Schema cookie. Changes with each schema change.
** meta[1] unused
** meta[2] unused
** meta[3] unused
** meta[4] unused
** meta[5] unused
** meta[6] unused
** meta[7] unused
** meta[8] unused
** meta[9] unused
**
** Note: The #defined SQLITE_UTF* symbols in sqliteInt.h correspond to
** the possible values of meta[4].
*/
sqlite4KVStoreGetMeta(pDb->pKV, 0, ArraySize(meta), meta);
pDb->pSchema->schema_cookie = meta[0];
/* Read the schema information out of the schema tables
*/
assert( db->init.busy );
{
char *zSql;
zSql = sqlite4MPrintf(db,
"SELECT name, rootpage, sql FROM '%q'.%s ORDER BY rowid",
db->aDb[iDb].zName, zMasterName);
#ifndef SQLITE_OMIT_AUTHORIZATION
{
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
xAuth = db->xAuth;
db->xAuth = 0;
#endif
rc = sqlite4_exec(db, zSql, sqlite4InitCallback, &initData, 0);
#ifndef SQLITE_OMIT_AUTHORIZATION
db->xAuth = xAuth;
}
#endif
if( rc==SQLITE_OK ) rc = initData.rc;
sqlite4DbFree(db, zSql);
#ifndef SQLITE_OMIT_ANALYZE
if( rc==SQLITE_OK ){
sqlite4AnalysisLoad(db, iDb);
}
#endif
}
if( db->mallocFailed ){
rc = SQLITE_NOMEM;
sqlite4ResetInternalSchema(db, -1);
}
if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){
/* Black magic: If the SQLITE_RecoveryMode flag is set, then consider
** the schema loaded, even if errors occurred. In this situation the
** current sqlite4_prepare() operation will fail, but the following one
** will attempt to compile the supplied statement against whatever subset
** of the schema was loaded before the error occurred. The primary
** purpose of this is to allow access to the sqlite_master table
** even when its contents have been corrupted.
*/
DbSetProperty(db, iDb, DB_SchemaLoaded);
rc = SQLITE_OK;
}
/* Jump here for an error that occurs after successfully allocating
** curMain. For an error that occurs before that point, jump to error_out.
*/
initone_error_out:
if( openedTransaction ){
sqlite4KVStoreCommit(pDb->pKV, 0);
}
error_out:
if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
db->mallocFailed = 1;
}
return rc;
}
/*
** Initialize all database files - the main database file, the file
** used to store temporary tables, and any additional database files
** created using ATTACH statements. Return a success code. If an
** error occurs, write an error message into *pzErrMsg.
**
** After a database is initialized, the DB_SchemaLoaded bit is set
** bit is set in the flags field of the Db structure. If the database
** file was of zero-length, then the DB_Empty flag is also set.
*/
SQLITE_PRIVATE int sqlite4Init(sqlite4 *db, char **pzErrMsg){
int i, rc;
int commit_internal = !(db->flags&SQLITE_InternChanges);
assert( sqlite4_mutex_held(db->mutex) );
rc = SQLITE_OK;
db->init.busy = 1;
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
rc = sqlite4InitOne(db, i, pzErrMsg);
if( rc ){
sqlite4ResetInternalSchema(db, i);
}
}
/* Once all the other databases have been initialised, load the schema
** for the TEMP database. This is loaded last, as the TEMP database
** schema may contain references to objects in other databases.
*/
#ifndef SQLITE_OMIT_TEMPDB
if( rc==SQLITE_OK && ALWAYS(db->nDb>1)
&& !DbHasProperty(db, 1, DB_SchemaLoaded) ){
rc = sqlite4InitOne(db, 1, pzErrMsg);
if( rc ){
sqlite4ResetInternalSchema(db, 1);
}
}
#endif
db->init.busy = 0;
if( rc==SQLITE_OK && commit_internal ){
sqlite4CommitInternalChanges(db);
}
return rc;
}
/*
** This routine is a no-op if the database schema is already initialised.
** Otherwise, the schema is loaded. An error code is returned.
*/
SQLITE_PRIVATE int sqlite4ReadSchema(Parse *pParse){
int rc = SQLITE_OK;
sqlite4 *db = pParse->db;
assert( sqlite4_mutex_held(db->mutex) );
if( !db->init.busy ){
rc = sqlite4Init(db, &pParse->zErrMsg);
}
if( rc!=SQLITE_OK ){
pParse->rc = rc;
pParse->nErr++;
}
return rc;
}
/*
** Check schema cookies in all databases. If any cookie is out
** of date set pParse->rc to SQLITE_SCHEMA. If all schema cookies
** make no changes to pParse->rc.
*/
static void schemaIsValid(Parse *pParse){
sqlite4 *db = pParse->db;
int iDb;
int rc;
int cookie;
assert( pParse->checkSchema );
assert( sqlite4_mutex_held(db->mutex) );
for(iDb=0; iDb<db->nDb; iDb++){
int openedTransaction = 0; /* True if a transaction is opened */
KVStore *pKV = db->aDb[iDb].pKV; /* Database to read cookie from */
if( pKV==0 ) continue;
/* If there is not already a read-only (or read-write) transaction opened
** on the b-tree database, open one now. If a transaction is opened, it
** will be closed immediately after reading the meta-value. */
if( pKV->iTransLevel==0 ){
rc = sqlite4KVStoreBegin(pKV, 1);
if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
db->mallocFailed = 1;
}
if( rc!=SQLITE_OK ) return;
openedTransaction = 1;
}
/* Read the schema cookie from the database. If it does not match the
** value stored as part of the in-memory schema representation,
** set Parse.rc to SQLITE_SCHEMA. */
sqlite4KVStoreGetMeta(pKV, 0, 1, (u32 *)&cookie);
if( cookie!=db->aDb[iDb].pSchema->schema_cookie ){
sqlite4ResetInternalSchema(db, iDb);
pParse->rc = SQLITE_SCHEMA;
}
/* Close the transaction, if one was opened. */
if( openedTransaction ){
sqlite4KVStoreCommit(pKV, 0);
}
}
}
/*
** Convert a schema pointer into the iDb index that indicates
** which database file in db->aDb[] the schema refers to.
**
** If the same database is attached more than once, the first
** attached database is returned.
*/
SQLITE_PRIVATE int sqlite4SchemaToIndex(sqlite4 *db, Schema *pSchema){
int i = -1000000;
/* If pSchema is NULL, then return -1000000. This happens when code in
** expr.c is trying to resolve a reference to a transient table (i.e. one
** created by a sub-select). In this case the return value of this
** function should never be used.
**
** We return -1000000 instead of the more usual -1 simply because using
** -1000000 as the incorrect index into db->aDb[] is much
** more likely to cause a segfault than -1 (of course there are assert()
** statements too, but it never hurts to play the odds).
*/
assert( sqlite4_mutex_held(db->mutex) );
if( pSchema ){
for(i=0; ALWAYS(i<db->nDb); i++){
if( db->aDb[i].pSchema==pSchema ){
break;
}
}
assert( i>=0 && i<db->nDb );
}
return i;
}
/*
** Compile the UTF-8 encoded SQL statement zSql into a statement handle.
*/
static int sqlite4Prepare(
sqlite4 *db, /* Database handle. */
const char *zSql, /* UTF-8 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
Vdbe *pReprepare, /* VM being reprepared */
sqlite4_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
const char **pzTail /* OUT: End of parsed string */
){
Parse *pParse; /* Parsing context */
char *zErrMsg = 0; /* Error message */
int rc = SQLITE_OK; /* Result code */
int i; /* Loop counter */
/* Allocate the parsing context */
pParse = sqlite4StackAllocZero(db, sizeof(*pParse));
if( pParse==0 ){
rc = SQLITE_NOMEM;
goto end_prepare;
}
pParse->pReprepare = pReprepare;
assert( ppStmt && *ppStmt==0 );
assert( !db->mallocFailed );
assert( sqlite4_mutex_held(db->mutex) );
sqlite4VtabUnlockList(db);
pParse->db = db;
pParse->nQueryLoop = (double)1;
if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
char *zSqlCopy;
int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
testcase( nBytes==mxLen );
testcase( nBytes==mxLen+1 );
if( nBytes>mxLen ){
sqlite4Error(db, SQLITE_TOOBIG, "statement too long");
rc = sqlite4ApiExit(db, SQLITE_TOOBIG);
goto end_prepare;
}
zSqlCopy = sqlite4DbStrNDup(db, zSql, nBytes);
if( zSqlCopy ){
sqlite4RunParser(pParse, zSqlCopy, &zErrMsg);
sqlite4DbFree(db, zSqlCopy);
pParse->zTail = &zSql[pParse->zTail-zSqlCopy];
}else{
pParse->zTail = &zSql[nBytes];
}
}else{
sqlite4RunParser(pParse, zSql, &zErrMsg);
}
assert( 1==(int)pParse->nQueryLoop );
if( db->mallocFailed ){
pParse->rc = SQLITE_NOMEM;
}
if( pParse->rc==SQLITE_DONE ) pParse->rc = SQLITE_OK;
if( pParse->checkSchema ){
schemaIsValid(pParse);
}
if( db->mallocFailed ){
pParse->rc = SQLITE_NOMEM;
}
if( pzTail ){
*pzTail = pParse->zTail;
}
rc = pParse->rc;
#ifndef SQLITE_OMIT_EXPLAIN
if( rc==SQLITE_OK && pParse->pVdbe && pParse->explain ){
static const char * const azColName[] = {
"addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
"selectid", "order", "from", "detail"
};
int iFirst, mx;
if( pParse->explain==2 ){
sqlite4VdbeSetNumCols(pParse->pVdbe, 4);
iFirst = 8;
mx = 12;
}else{
sqlite4VdbeSetNumCols(pParse->pVdbe, 8);
iFirst = 0;
mx = 8;
}
for(i=iFirst; i<mx; i++){
sqlite4VdbeSetColName(pParse->pVdbe, i-iFirst, COLNAME_NAME,
azColName[i], SQLITE_STATIC);
}
}
#endif
if( db->init.busy==0 ){
Vdbe *pVdbe = pParse->pVdbe;
sqlite4VdbeSetSql(pVdbe, zSql, (int)(pParse->zTail-zSql));
}
if( pParse->pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){
sqlite4VdbeFinalize(pParse->pVdbe);
assert(!(*ppStmt));
}else{
*ppStmt = (sqlite4_stmt*)pParse->pVdbe;
}
if( zErrMsg ){
sqlite4Error(db, rc, "%s", zErrMsg);
sqlite4DbFree(db, zErrMsg);
}else{
sqlite4Error(db, rc, 0);
}
/* Delete any TriggerPrg structures allocated while parsing this statement. */
while( pParse->pTriggerPrg ){
TriggerPrg *pT = pParse->pTriggerPrg;
pParse->pTriggerPrg = pT->pNext;
sqlite4DbFree(db, pT);
}
end_prepare:
sqlite4StackFree(db, pParse);
rc = sqlite4ApiExit(db, rc);
return rc;
}
static int sqlite4LockAndPrepare(
sqlite4 *db, /* Database handle. */
const char *zSql, /* UTF-8 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
Vdbe *pOld, /* VM being reprepared */
sqlite4_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
const char **pzTail /* OUT: End of parsed string */
){
int rc;
assert( ppStmt!=0 );
*ppStmt = 0;
if( !sqlite4SafetyCheckOk(db) ){
return SQLITE_MISUSE_BKPT;
}
sqlite4_mutex_enter(db->mutex);
rc = sqlite4Prepare(db, zSql, nBytes, pOld, ppStmt, pzTail);
if( rc==SQLITE_SCHEMA ){
sqlite4_finalize(*ppStmt);
rc = sqlite4Prepare(db, zSql, nBytes, pOld, ppStmt, pzTail);
}
sqlite4_mutex_leave(db->mutex);
return rc;
}
/*
** Rerun the compilation of a statement after a schema change.
**
** If the statement is successfully recompiled, return SQLITE_OK. Otherwise,
** if the statement cannot be recompiled because another connection has
** locked the sqlite4_master table, return SQLITE_LOCKED. If any other error
** occurs, return SQLITE_SCHEMA.
*/
SQLITE_PRIVATE int sqlite4Reprepare(Vdbe *p){
int rc;
sqlite4_stmt *pNew;
const char *zSql;
sqlite4 *db;
assert( sqlite4_mutex_held(sqlite4VdbeDb(p)->mutex) );
zSql = sqlite4_sql((sqlite4_stmt *)p);
db = sqlite4VdbeDb(p);
assert( sqlite4_mutex_held(db->mutex) );
rc = sqlite4LockAndPrepare(db, zSql, -1, p, &pNew, 0);
if( rc ){
if( rc==SQLITE_NOMEM ){
db->mallocFailed = 1;
}
assert( pNew==0 );
return rc;
}else{
assert( pNew!=0 );
}
sqlite4VdbeSwap((Vdbe*)pNew, p);
sqlite4TransferBindings(pNew, (sqlite4_stmt*)p);
sqlite4VdbeResetStepResult((Vdbe*)pNew);
sqlite4VdbeFinalize((Vdbe*)pNew);
return SQLITE_OK;
}
/*
** Two versions of the official API. Legacy and new use. In the legacy
** version, the original SQL text is not saved in the prepared statement
** and so if a schema change occurs, SQLITE_SCHEMA is returned by
** sqlite4_step(). In the new version, the original SQL text is retained
** and the statement is automatically recompiled if an schema change
** occurs.
*/
SQLITE_API int sqlite4_prepare(
sqlite4 *db, /* Database handle. */
const char *zSql, /* UTF-8 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
sqlite4_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
const char **pzTail /* OUT: End of parsed string */
){
int rc;
rc = sqlite4LockAndPrepare(db,zSql,nBytes,0,ppStmt,pzTail);
assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
return rc;
}
/************** End of prepare.c *********************************************/
/************** Begin file select.c ******************************************/
/*
** 2001 September 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.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
*/
/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
*/
static void clearSelect(sqlite4 *db, Select *p){
sqlite4ExprListDelete(db, p->pEList);
sqlite4SrcListDelete(db, p->pSrc);
sqlite4ExprDelete(db, p->pWhere);
sqlite4ExprListDelete(db, p->pGroupBy);
sqlite4ExprDelete(db, p->pHaving);
sqlite4ExprListDelete(db, p->pOrderBy);
sqlite4SelectDelete(db, p->pPrior);
sqlite4ExprDelete(db, p->pLimit);
sqlite4ExprDelete(db, p->pOffset);
}
/*
** Initialize a SelectDest structure.
*/
SQLITE_PRIVATE void sqlite4SelectDestInit(SelectDest *pDest, int eDest, int iParm){
pDest->eDest = (u8)eDest;
pDest->iParm = iParm;
pDest->affinity = 0;
pDest->iMem = 0;
pDest->nMem = 0;
}
/*
** Allocate a new Select structure and return a pointer to that
** structure.
*/
SQLITE_PRIVATE Select *sqlite4SelectNew(
Parse *pParse, /* Parsing context */
ExprList *pEList, /* which columns to include in the result */
SrcList *pSrc, /* the FROM clause -- which tables to scan */
Expr *pWhere, /* the WHERE clause */
ExprList *pGroupBy, /* the GROUP BY clause */
Expr *pHaving, /* the HAVING clause */
ExprList *pOrderBy, /* the ORDER BY clause */
int isDistinct, /* true if the DISTINCT keyword is present */
Expr *pLimit, /* LIMIT value. NULL means not used */
Expr *pOffset /* OFFSET value. NULL means no offset */
){
Select *pNew;
Select standin;
sqlite4 *db = pParse->db;
pNew = sqlite4DbMallocZero(db, sizeof(*pNew) );
assert( db->mallocFailed || !pOffset || pLimit ); /* OFFSET implies LIMIT */
if( pNew==0 ){
assert( db->mallocFailed );
pNew = &standin;
memset(pNew, 0, sizeof(*pNew));
}
if( pEList==0 ){
pEList = sqlite4ExprListAppend(pParse, 0, sqlite4Expr(db,TK_ALL,0));
}
pNew->pEList = pEList;
pNew->pSrc = pSrc;
pNew->pWhere = pWhere;
pNew->pGroupBy = pGroupBy;
pNew->pHaving = pHaving;
pNew->pOrderBy = pOrderBy;
pNew->selFlags = isDistinct ? SF_Distinct : 0;
pNew->op = TK_SELECT;
pNew->pLimit = pLimit;
pNew->pOffset = pOffset;
assert( pOffset==0 || pLimit!=0 );
pNew->addrOpenEphm[0] = -1;
pNew->addrOpenEphm[1] = -1;
pNew->addrOpenEphm[2] = -1;
if( db->mallocFailed ) {
clearSelect(db, pNew);
if( pNew!=&standin ) sqlite4DbFree(db, pNew);
pNew = 0;
}else{
assert( pNew->pSrc!=0 || pParse->nErr>0 );
}
assert( pNew!=&standin );
return pNew;
}
/*
** Delete the given Select structure and all of its substructures.
*/
SQLITE_PRIVATE void sqlite4SelectDelete(sqlite4 *db, Select *p){
if( p ){
clearSelect(db, p);
sqlite4DbFree(db, p);
}
}
/*
** Given 1 to 3 identifiers preceeding the JOIN keyword, determine the
** type of join. Return an integer constant that expresses that type
** in terms of the following bit values:
**
** JT_INNER
** JT_CROSS
** JT_OUTER
** JT_NATURAL
** JT_LEFT
** JT_RIGHT
**
** A full outer join is the combination of JT_LEFT and JT_RIGHT.
**
** If an illegal or unsupported join type is seen, then still return
** a join type, but put an error in the pParse structure.
*/
SQLITE_PRIVATE int sqlite4JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){
int jointype = 0;
Token *apAll[3];
Token *p;
/* 0123456789 123456789 123456789 123 */
static const char zKeyText[] = "naturaleftouterightfullinnercross";
static const struct {
u8 i; /* Beginning of keyword text in zKeyText[] */
u8 nChar; /* Length of the keyword in characters */
u8 code; /* Join type mask */
} aKeyword[] = {
/* natural */ { 0, 7, JT_NATURAL },
/* left */ { 6, 4, JT_LEFT|JT_OUTER },
/* outer */ { 10, 5, JT_OUTER },
/* right */ { 14, 5, JT_RIGHT|JT_OUTER },
/* full */ { 19, 4, JT_LEFT|JT_RIGHT|JT_OUTER },
/* inner */ { 23, 5, JT_INNER },
/* cross */ { 28, 5, JT_INNER|JT_CROSS },
};
int i, j;
apAll[0] = pA;
apAll[1] = pB;
apAll[2] = pC;
for(i=0; i<3 && apAll[i]; i++){
p = apAll[i];
for(j=0; j<ArraySize(aKeyword); j++){
if( p->n==aKeyword[j].nChar
&& sqlite4StrNICmp((char*)p->z, &zKeyText[aKeyword[j].i], p->n)==0 ){
jointype |= aKeyword[j].code;
break;
}
}
testcase( j==0 || j==1 || j==2 || j==3 || j==4 || j==5 || j==6 );
if( j>=ArraySize(aKeyword) ){
jointype |= JT_ERROR;
break;
}
}
if(
(jointype & (JT_INNER|JT_OUTER))==(JT_INNER|JT_OUTER) ||
(jointype & JT_ERROR)!=0
){
const char *zSp = " ";
assert( pB!=0 );
if( pC==0 ){ zSp++; }
sqlite4ErrorMsg(pParse, "unknown or unsupported join type: "
"%T %T%s%T", pA, pB, zSp, pC);
jointype = JT_INNER;
}else if( (jointype & JT_OUTER)!=0
&& (jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ){
sqlite4ErrorMsg(pParse,
"RIGHT and FULL OUTER JOINs are not currently supported");
jointype = JT_INNER;
}
return jointype;
}
/*
** Return the index of a column in a table. Return -1 if the column
** is not contained in the table.
*/
static int columnIndex(Table *pTab, const char *zCol){
int i;
for(i=0; i<pTab->nCol; i++){
if( sqlite4StrICmp(pTab->aCol[i].zName, zCol)==0 ) return i;
}
return -1;
}
/*
** Search the first N tables in pSrc, from left to right, looking for a
** table that has a column named zCol.
**
** When found, set *piTab and *piCol to the table index and column index
** of the matching column and return TRUE.
**
** If not found, return FALSE.
*/
static int tableAndColumnIndex(
SrcList *pSrc, /* Array of tables to search */
int N, /* Number of tables in pSrc->a[] to search */
const char *zCol, /* Name of the column we are looking for */
int *piTab, /* Write index of pSrc->a[] here */
int *piCol /* Write index of pSrc->a[*piTab].pTab->aCol[] here */
){
int i; /* For looping over tables in pSrc */
int iCol; /* Index of column matching zCol */
assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */
for(i=0; i<N; i++){
iCol = columnIndex(pSrc->a[i].pTab, zCol);
if( iCol>=0 ){
if( piTab ){
*piTab = i;
*piCol = iCol;
}
return 1;
}
}
return 0;
}
/*
** This function is used to add terms implied by JOIN syntax to the
** WHERE clause expression of a SELECT statement. The new term, which
** is ANDed with the existing WHERE clause, is of the form:
**
** (tab1.col1 = tab2.col2)
**
** where tab1 is the iSrc'th table in SrcList pSrc and tab2 is the
** (iSrc+1)'th. Column col1 is column iColLeft of tab1, and col2 is
** column iColRight of tab2.
*/
static void addWhereTerm(
Parse *pParse, /* Parsing context */
SrcList *pSrc, /* List of tables in FROM clause */
int iLeft, /* Index of first table to join in pSrc */
int iColLeft, /* Index of column in first table */
int iRight, /* Index of second table in pSrc */
int iColRight, /* Index of column in second table */
int isOuterJoin, /* True if this is an OUTER join */
Expr **ppWhere /* IN/OUT: The WHERE clause to add to */
){
sqlite4 *db = pParse->db;
Expr *pE1;
Expr *pE2;
Expr *pEq;
assert( iLeft<iRight );
assert( pSrc->nSrc>iRight );
assert( pSrc->a[iLeft].pTab );
assert( pSrc->a[iRight].pTab );
pE1 = sqlite4CreateColumnExpr(db, pSrc, iLeft, iColLeft);
pE2 = sqlite4CreateColumnExpr(db, pSrc, iRight, iColRight);
pEq = sqlite4PExpr(pParse, TK_EQ, pE1, pE2, 0);
if( pEq && isOuterJoin ){
ExprSetProperty(pEq, EP_FromJoin);
assert( !ExprHasAnyProperty(pEq, EP_TokenOnly|EP_Reduced) );
ExprSetIrreducible(pEq);
pEq->iRightJoinTable = (i16)pE2->iTable;
}
*ppWhere = sqlite4ExprAnd(db, *ppWhere, pEq);
}
/*
** Set the EP_FromJoin property on all terms of the given expression.
** And set the Expr.iRightJoinTable to iTable for every term in the
** expression.
**
** The EP_FromJoin property is used on terms of an expression to tell
** the LEFT OUTER JOIN processing logic that this term is part of the
** join restriction specified in the ON or USING clause and not a part
** of the more general WHERE clause. These terms are moved over to the
** WHERE clause during join processing but we need to remember that they
** originated in the ON or USING clause.
**
** The Expr.iRightJoinTable tells the WHERE clause processing that the
** expression depends on table iRightJoinTable even if that table is not
** explicitly mentioned in the expression. That information is needed
** for cases like this:
**
** SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.b AND t1.x=5
**
** The where clause needs to defer the handling of the t1.x=5
** term until after the t2 loop of the join. In that way, a
** NULL t2 row will be inserted whenever t1.x!=5. If we do not
** defer the handling of t1.x=5, it will be processed immediately
** after the t1 loop and rows with t1.x!=5 will never appear in
** the output, which is incorrect.
*/
static void setJoinExpr(Expr *p, int iTable){
while( p ){
ExprSetProperty(p, EP_FromJoin);
assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) );
ExprSetIrreducible(p);
p->iRightJoinTable = (i16)iTable;
setJoinExpr(p->pLeft, iTable);
p = p->pRight;
}
}
/*
** This routine processes the join information for a SELECT statement.
** ON and USING clauses are converted into extra terms of the WHERE clause.
** NATURAL joins also create extra WHERE clause terms.
**
** The terms of a FROM clause are contained in the Select.pSrc structure.
** The left most table is the first entry in Select.pSrc. The right-most
** table is the last entry. The join operator is held in the entry to
** the left. Thus entry 0 contains the join operator for the join between
** entries 0 and 1. Any ON or USING clauses associated with the join are
** also attached to the left entry.
**
** This routine returns the number of errors encountered.
*/
static int sqliteProcessJoin(Parse *pParse, Select *p){
SrcList *pSrc; /* All tables in the FROM clause */
int i, j; /* Loop counters */
struct SrcList_item *pLeft; /* Left table being joined */
struct SrcList_item *pRight; /* Right table being joined */
pSrc = p->pSrc;
pLeft = &pSrc->a[0];
pRight = &pLeft[1];
for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){
Table *pLeftTab = pLeft->pTab;
Table *pRightTab = pRight->pTab;
int isOuter;
if( NEVER(pLeftTab==0 || pRightTab==0) ) continue;
isOuter = (pRight->jointype & JT_OUTER)!=0;
/* When the NATURAL keyword is present, add WHERE clause terms for
** every column that the two tables have in common.
*/
if( pRight->jointype & JT_NATURAL ){
if( pRight->pOn || pRight->pUsing ){
sqlite4ErrorMsg(pParse, "a NATURAL join may not have "
"an ON or USING clause", 0);
return 1;
}
for(j=0; j<pRightTab->nCol; j++){
char *zName; /* Name of column in the right table */
int iLeft; /* Matching left table */
int iLeftCol; /* Matching column in the left table */
zName = pRightTab->aCol[j].zName;
if( tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol) ){
addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, j,
isOuter, &p->pWhere);
}
}
}
/* Disallow both ON and USING clauses in the same join
*/
if( pRight->pOn && pRight->pUsing ){
sqlite4ErrorMsg(pParse, "cannot have both ON and USING "
"clauses in the same join");
return 1;
}
/* Add the ON clause to the end of the WHERE clause, connected by
** an AND operator.
*/
if( pRight->pOn ){
if( isOuter ) setJoinExpr(pRight->pOn, pRight->iCursor);
p->pWhere = sqlite4ExprAnd(pParse->db, p->pWhere, pRight->pOn);
pRight->pOn = 0;
}
/* Create extra terms on the WHERE clause for each column named
** in the USING clause. Example: If the two tables to be joined are
** A and B and the USING clause names X, Y, and Z, then add this
** to the WHERE clause: A.X=B.X AND A.Y=B.Y AND A.Z=B.Z
** Report an error if any column mentioned in the USING clause is
** not contained in both tables to be joined.
*/
if( pRight->pUsing ){
IdList *pList = pRight->pUsing;
for(j=0; j<pList->nId; j++){
char *zName; /* Name of the term in the USING clause */
int iLeft; /* Table on the left with matching column name */
int iLeftCol; /* Column number of matching column on the left */
int iRightCol; /* Column number of matching column on the right */
zName = pList->a[j].zName;
iRightCol = columnIndex(pRightTab, zName);
if( iRightCol<0
|| !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol)
){
sqlite4ErrorMsg(pParse, "cannot join using column %s - column "
"not present in both tables", zName);
return 1;
}
addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, iRightCol,
isOuter, &p->pWhere);
}
}
}
return 0;
}
/*
** Insert code into "v" that will push the record on the top of the
** stack into the sorter.
*/
static void pushOntoSorter(
Parse *pParse, /* Parser context */
ExprList *pOrderBy, /* The ORDER BY clause */
Select *pSelect, /* The whole SELECT statement */
int regData /* Register holding data to be sorted */
){
Vdbe *v = pParse->pVdbe;
int nExpr = pOrderBy->nExpr;
int regBase = sqlite4GetTempRange(pParse, nExpr+1);
int regKey = sqlite4GetTempReg(pParse);
int op;
/* Assemble the sort-key values in a contiguous array of registers
** starting at regBase. The sort-key consists of the result of each
** expression in the ORDER BY clause followed by a unique sequence
** number. The sequence number allows more than one row with the same
** sort-key. */
sqlite4ExprCacheClear(pParse);
sqlite4ExprCodeExprList(pParse, pOrderBy, regBase, 0);
sqlite4VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr);
/* Encode the sort-key. */
sqlite4VdbeAddOp3(v, OP_MakeIdxKey, pOrderBy->iECursor, regBase, regKey);
/* Insert an entry into the sorter. The key inserted is the encoded key
** created by the OP_MakeIdxKey coded above. The value is the record
** currently stored in register regData. */
if( pSelect->selFlags & SF_UseSorter ){
op = OP_SorterInsert;
}else{
op = OP_IdxInsert;
}
sqlite4VdbeAddOp3(v, op, pOrderBy->iECursor, regData, regKey);
/* Release the temporary registers */
sqlite4ReleaseTempReg(pParse, regKey);
sqlite4ReleaseTempRange(pParse, regBase, nExpr+1);
if( pSelect->iLimit ){
int addr1, addr2;
int iLimit;
if( pSelect->iOffset ){
iLimit = pSelect->iOffset+1;
}else{
iLimit = pSelect->iLimit;
}
addr1 = sqlite4VdbeAddOp1(v, OP_IfZero, iLimit);
sqlite4VdbeAddOp2(v, OP_AddImm, iLimit, -1);
addr2 = sqlite4VdbeAddOp0(v, OP_Goto);
sqlite4VdbeJumpHere(v, addr1);
sqlite4VdbeAddOp1(v, OP_Last, pOrderBy->iECursor);
sqlite4VdbeAddOp1(v, OP_Delete, pOrderBy->iECursor);
sqlite4VdbeJumpHere(v, addr2);
}
}
/*
** Add code to implement the OFFSET
*/
static void codeOffset(
Vdbe *v, /* Generate code into this VM */
Select *p, /* The SELECT statement being coded */
int iContinue /* Jump here to skip the current record */
){
if( p->iOffset && iContinue!=0 ){
int addr;
sqlite4VdbeAddOp2(v, OP_AddImm, p->iOffset, -1);
addr = sqlite4VdbeAddOp1(v, OP_IfNeg, p->iOffset);
sqlite4VdbeAddOp2(v, OP_Goto, 0, iContinue);
VdbeComment((v, "skip OFFSET records"));
sqlite4VdbeJumpHere(v, addr);
}
}
/*
** Add code that will check to make sure the N registers starting at iMem
** form a distinct entry. iTab is a sorting index that holds previously
** seen combinations of the N values. A new entry is made in iTab
** if the current N values are new.
**
** A jump to addrRepeat is made and the N+1 values are popped from the
** stack if the top N elements are not distinct.
*/
static void codeDistinct(
Parse *pParse, /* Parsing and code generating context */
int iTab, /* A sorting index used to test for distinctness */
int addrRepeat, /* Jump to here if not distinct */
int N, /* Number of elements */
int iMem /* First element */
){
Vdbe *v;
int r1, r2;
v = pParse->pVdbe;
r1 = sqlite4GetTempReg(pParse);
r2 = sqlite4GetTempReg(pParse);
sqlite4VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N);
sqlite4VdbeAddOp2(v, OP_MakeKey, iTab, r2);
sqlite4VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1);
sqlite4VdbeAddOp3(v, OP_IdxInsert, iTab, r1, r2);
sqlite4ReleaseTempReg(pParse, r1);
sqlite4ReleaseTempReg(pParse, r2);
}
#ifndef SQLITE_OMIT_SUBQUERY
/*
** Generate an error message when a SELECT is used within a subexpression
** (example: "a IN (SELECT * FROM table)") but it has more than 1 result
** column. We do this in a subroutine because the error used to occur
** in multiple places. (The error only occurs in one place now, but we
** retain the subroutine to minimize code disruption.)
*/
static int checkForMultiColumnSelectError(
Parse *pParse, /* Parse context. */
SelectDest *pDest, /* Destination of SELECT results */
int nExpr /* Number of result columns returned by SELECT */
){
int eDest = pDest->eDest;
if( nExpr>1 && (eDest==SRT_Mem || eDest==SRT_Set) ){
sqlite4ErrorMsg(pParse, "only a single result allowed for "
"a SELECT that is part of an expression");
return 1;
}else{
return 0;
}
}
#endif
/*
** This routine generates the code for the inside of the inner loop
** of a SELECT.
**
** If srcTab and nColumn are both zero, then the pEList expressions
** are evaluated in order to get the data for this row. If nColumn>0
** then data is pulled from srcTab and pEList is used only to get the
** datatypes for each column.
*/
static void selectInnerLoop(
Parse *pParse, /* The parser context */
Select *p, /* The complete select statement being coded */
ExprList *pEList, /* List of values being extracted */
int srcTab, /* Pull data from this table */
int nColumn, /* Number of columns in the source table */
ExprList *pOrderBy, /* If not NULL, sort results using this key */
int distinct, /* If >=0, make sure results are distinct */
SelectDest *pDest, /* How to dispose of the results */
int iContinue, /* Jump here to continue with next row */
int iBreak /* Jump here to break out of the inner loop */
){
Vdbe *v = pParse->pVdbe;
int i;
int hasDistinct; /* True if the DISTINCT keyword is present */
int regResult; /* Start of memory holding result set */
int eDest = pDest->eDest; /* How to dispose of results */
int iParm = pDest->iParm; /* First argument to disposal method */
int nResultCol; /* Number of result columns */
assert( v );
if( NEVER(v==0) ) return;
assert( pEList!=0 );
hasDistinct = distinct>=0;
if( pOrderBy==0 && !hasDistinct ){
codeOffset(v, p, iContinue);
}
/* Pull the requested columns.
*/
if( nColumn>0 ){
nResultCol = nColumn;
}else{
nResultCol = pEList->nExpr;
}
if( pDest->iMem==0 ){
pDest->iMem = pParse->nMem+1;
pDest->nMem = nResultCol;
pParse->nMem += nResultCol;
}else{
assert( pDest->nMem==nResultCol );
}
regResult = pDest->iMem;
if( nColumn>0 ){
for(i=0; i<nColumn; i++){
sqlite4VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i);
}
}else if( eDest!=SRT_Exists ){
/* If the destination is an EXISTS(...) expression, the actual
** values returned by the SELECT are not required.
*/
sqlite4ExprCacheClear(pParse);
sqlite4ExprCodeExprList(pParse, pEList, regResult, eDest==SRT_Output);
}
nColumn = nResultCol;
/* If the DISTINCT keyword was present on the SELECT statement
** and this row has been seen before, then do not make this row
** part of the result.
*/
if( hasDistinct ){
assert( pEList!=0 );
assert( pEList->nExpr==nColumn );
codeDistinct(pParse, distinct, iContinue, nColumn, regResult);
if( pOrderBy==0 ){
codeOffset(v, p, iContinue);
}
}
switch( eDest ){
/* In this mode, write each query result to the key of the temporary
** table iParm.
*/
#ifndef SQLITE_OMIT_COMPOUND_SELECT
case SRT_Union: {
int r1, r2;
r1 = sqlite4GetTempReg(pParse);
r2 = sqlite4GetTempReg(pParse);
sqlite4VdbeAddOp2(v, OP_MakeKey, iParm, r2);
sqlite4VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
sqlite4VdbeAddOp3(v, OP_IdxInsert, iParm, r1, r2);
sqlite4ReleaseTempReg(pParse, r1);
sqlite4ReleaseTempReg(pParse, r2);
break;
}
/* This is used for processing queries of the form:
**
** <select-1> EXCEPT <select-2>
**
** Temporary index iParm contains the results of <select-1>. This
** code is processing the results of <select-2>. For each row of
** <select-2>, remove any identical row from iParm. */
case SRT_Except: {
int regKey = sqlite4GetTempReg(pParse);
sqlite4VdbeAddOp4Int(v, OP_MakeIdxKey, iParm, regResult, regKey, 0);
sqlite4VdbeAddOp3(v, OP_IdxDelete, iParm, 0, regKey);
sqlite4ReleaseTempReg(pParse, regKey);
break;
}
#endif
/* Store the result as data using a unique key.
*/
case SRT_Table:
case SRT_EphemTab: {
int r1 = sqlite4GetTempReg(pParse);
testcase( eDest==SRT_Table );
testcase( eDest==SRT_EphemTab );
sqlite4VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
if( pOrderBy ){
pushOntoSorter(pParse, pOrderBy, p, r1);
}else{
int r2 = sqlite4GetTempReg(pParse);
sqlite4VdbeAddOp2(v, OP_NewRowid, iParm, r2);
sqlite4VdbeAddOp3(v, OP_Insert, iParm, r1, r2);
sqlite4VdbeChangeP5(v, OPFLAG_APPEND);
sqlite4ReleaseTempReg(pParse, r2);
}
sqlite4ReleaseTempReg(pParse, r1);
break;
}
#ifndef SQLITE_OMIT_SUBQUERY
/* If we are creating a set for an "expr IN (SELECT ...)" construct,
** then there should be a single item on the stack. Write this
** item into the set table with bogus data.
*/
case SRT_Set: {
int r1 = sqlite4GetTempReg(pParse);
assert( nColumn==1 );
p->affinity = sqlite4CompareAffinity(pEList->a[0].pExpr, pDest->affinity);
if( pOrderBy ){
/* At first glance you would think we could optimize out the
** 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 */
sqlite4VdbeAddOp4(v, OP_MakeRecord, regResult, 1, r1, &p->affinity, 1);
pushOntoSorter(pParse, pOrderBy, p, r1);
}else{
int r2 = sqlite4GetTempReg(pParse);
sqlite4VdbeAddOp2(v, OP_MakeKey, iParm, r2);
sqlite4VdbeAddOp4(v, OP_MakeRecord, regResult, 1, r1, &p->affinity, 1);
sqlite4ExprCacheAffinityChange(pParse, regResult, 1);
sqlite4VdbeAddOp3(v, OP_IdxInsert, iParm, r1, r2);
sqlite4ReleaseTempReg(pParse, r2);
}
sqlite4ReleaseTempReg(pParse, r1);
break;
}
/* If any row exist in the result set, record that fact and abort.
*/
case SRT_Exists: {
sqlite4VdbeAddOp2(v, OP_Integer, 1, iParm);
/* The LIMIT clause will terminate the loop for us */
break;
}
/* If this is a scalar select that is part of an expression, then
** store the results in the appropriate memory cell and break out
** of the scan loop.
*/
case SRT_Mem: {
assert( nColumn==1 );
if( pOrderBy ){
int regRecord = sqlite4GetTempReg(pParse);
sqlite4VdbeAddOp3(v, OP_MakeRecord, regResult, 1, regRecord);
pushOntoSorter(pParse, pOrderBy, p, regRecord);
sqlite4ReleaseTempReg(pParse, regRecord);
}else{
sqlite4ExprCodeMove(pParse, regResult, iParm, 1);
/* The LIMIT clause will jump out of the loop for us */
}
break;
}
#endif /* #ifndef SQLITE_OMIT_SUBQUERY */
/* Send the data to the callback function or to a subroutine. In the
** case of a subroutine, the subroutine itself is responsible for
** popping the data from the stack.
*/
case SRT_Coroutine:
case SRT_Output: {
testcase( eDest==SRT_Coroutine );
testcase( eDest==SRT_Output );
if( pOrderBy ){
int r1 = sqlite4GetTempReg(pParse);
sqlite4VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
pushOntoSorter(pParse, pOrderBy, p, r1);
sqlite4ReleaseTempReg(pParse, r1);
}else if( eDest==SRT_Coroutine ){
sqlite4VdbeAddOp1(v, OP_Yield, pDest->iParm);
}else{
sqlite4VdbeAddOp2(v, OP_ResultRow, regResult, nColumn);
sqlite4ExprCacheAffinityChange(pParse, regResult, nColumn);
}
break;
}
#if !defined(SQLITE_OMIT_TRIGGER)
/* Discard the results. This is used for SELECT statements inside
** the body of a TRIGGER. The purpose of such selects is to call
** user-defined functions that have side effects. We do not care
** about the actual results of the select.
*/
default: {
assert( eDest==SRT_Discard );
break;
}
#endif
}
/* Jump to the end of the loop if the LIMIT is reached. Except, if
** there is a sorter, in which case the sorter has already limited
** the output for us.
*/
if( pOrderBy==0 && p->iLimit ){
sqlite4VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1);
}
}
/*
** Given an expression list, generate a KeyInfo structure that can be
** used to encode the results of the expressions into an index key.
**
** If the ExprList is an ORDER BY or GROUP BY clause then the resulting
** KeyInfo structure is appropriate for initializing a virtual index to
** implement that clause. If the ExprList is the result set of a SELECT
** then the KeyInfo structure is appropriate for initializing a virtual
** index to implement a DISTINCT test.
**
** Space to hold the KeyInfo structure is obtain from malloc. The calling
** function is responsible for seeing that this structure is eventually
** freed. Add the KeyInfo structure to the P4 field of an opcode using
** P4_KEYINFO_HANDOFF is the usual way of dealing with this.
*/
static KeyInfo *keyInfoFromExprList(
Parse *pParse,
ExprList *pList,
int bOrderBy /* True for ORDER BY */
){
sqlite4 *db = pParse->db; /* Database handle */
int nField; /* Number of fields in keys */
KeyInfo *pInfo; /* Object to return */
int nByte; /* Bytes of space to allocate */
assert( bOrderBy==0 || bOrderBy==1 );
nField = pList->nExpr + bOrderBy;
nByte = sizeof(KeyInfo) + nField * sizeof(CollSeq *) + nField;
pInfo = (KeyInfo *)sqlite4DbMallocZero(db, nByte);
if( pInfo ){
int i; /* Used to iterate through pList */
pInfo->aSortOrder = (u8*)&pInfo->aColl[nField];
pInfo->nField = (u16)nField;
pInfo->enc = ENC(db);
pInfo->db = db;
for(i=0; i<pList->nExpr; i++){
CollSeq *pColl;
pColl = sqlite4ExprCollSeq(pParse, pList->a[i].pExpr);
if( !pColl ) pColl = db->pDfltColl;
pInfo->aColl[i] = pColl;
pInfo->aSortOrder[i] = pList->a[i].sortOrder;
}
}
return pInfo;
}
#ifndef SQLITE_OMIT_COMPOUND_SELECT
/*
** Name of the connection operator, used for error messages.
*/
static const char *selectOpName(int id){
char *z;
switch( id ){
case TK_ALL: z = "UNION ALL"; break;
case TK_INTERSECT: z = "INTERSECT"; break;
case TK_EXCEPT: z = "EXCEPT"; break;
default: z = "UNION"; break;
}
return z;
}
#endif /* SQLITE_OMIT_COMPOUND_SELECT */
#ifndef SQLITE_OMIT_EXPLAIN
/*
** Unless an "EXPLAIN QUERY PLAN" command is being processed, this function
** is a no-op. Otherwise, it adds a single row of output to the EQP result,
** where the caption is of the form:
**
** "USE TEMP B-TREE FOR xxx"
**
** where xxx is one of "DISTINCT", "ORDER BY" or "GROUP BY". Exactly which
** is determined by the zUsage argument.
*/
static void explainTempTable(Parse *pParse, const char *zUsage){
if( pParse->explain==2 ){
Vdbe *v = pParse->pVdbe;
char *zMsg = sqlite4MPrintf(pParse->db, "USE TEMP B-TREE FOR %s", zUsage);
sqlite4VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
}
}
/*
** Assign expression b to lvalue a. A second, no-op, version of this macro
** is provided when SQLITE_OMIT_EXPLAIN is defined. This allows the code
** in sqlite4Select() to assign values to structure member variables that
** only exist if SQLITE_OMIT_EXPLAIN is not defined without polluting the
** code with #ifndef directives.
*/
# define explainSetInteger(a, b) a = b
#else
/* No-op versions of the explainXXX() functions and macros. */
# define explainTempTable(y,z)
# define explainSetInteger(y,z)
#endif
#if !defined(SQLITE_OMIT_EXPLAIN) && !defined(SQLITE_OMIT_COMPOUND_SELECT)
/*
** Unless an "EXPLAIN QUERY PLAN" command is being processed, this function
** is a no-op. Otherwise, it adds a single row of output to the EQP result,
** where the caption is of one of the two forms:
**
** "COMPOSITE SUBQUERIES iSub1 and iSub2 (op)"
** "COMPOSITE SUBQUERIES iSub1 and iSub2 USING TEMP B-TREE (op)"
**
** where iSub1 and iSub2 are the integers passed as the corresponding
** function parameters, and op is the text representation of the parameter
** of the same name. The parameter "op" must be one of TK_UNION, TK_EXCEPT,
** TK_INTERSECT or TK_ALL. The first form is used if argument bUseTmp is
** false, or the second form if it is true.
*/
static void explainComposite(
Parse *pParse, /* Parse context */
int op, /* One of TK_UNION, TK_EXCEPT etc. */
int iSub1, /* Subquery id 1 */
int iSub2, /* Subquery id 2 */
int bUseTmp /* True if a temp table was used */
){
assert( op==TK_UNION || op==TK_EXCEPT || op==TK_INTERSECT || op==TK_ALL );
if( pParse->explain==2 ){
Vdbe *v = pParse->pVdbe;
char *zMsg = sqlite4MPrintf(
pParse->db, "COMPOUND SUBQUERIES %d AND %d %s(%s)", iSub1, iSub2,
bUseTmp?"USING TEMP B-TREE ":"", selectOpName(op)
);
sqlite4VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
}
}
#else
/* No-op versions of the explainXXX() functions and macros. */
# define explainComposite(v,w,x,y,z)
#endif
/*
** If the inner loop was generated using a non-null pOrderBy argument,
** then the results were placed in a sorter. After the loop is terminated
** we need to loop through the contents of the sorter and output the
** results. The following routine generates the code needed to do that.
*/
static void generateSortTail(
Parse *pParse, /* Parsing context */
Select *p, /* The SELECT statement */
Vdbe *v, /* Generate code into this VDBE */
int nColumn, /* Number of columns of data */
SelectDest *pDest /* Write the sorted results here */
){
int addrBreak = sqlite4VdbeMakeLabel(v); /* Jump here to exit loop */
int addrContinue = sqlite4VdbeMakeLabel(v); /* Jump here for next cycle */
int addr;
int iTab; /* Sorter object cursor */
ExprList *pOrderBy = p->pOrderBy;
int eDest = pDest->eDest;
int iParm = pDest->iParm;
int regRow;
int regRowid = 0;
iTab = pOrderBy->iECursor;
regRow = sqlite4GetTempReg(pParse);
if( eDest!=SRT_Output && eDest!=SRT_Coroutine ){
regRowid = sqlite4GetTempReg(pParse);
}
if( p->selFlags & SF_UseSorter ){
int regSortOut = ++pParse->nMem;
int ptab2 = pParse->nTab++;
sqlite4VdbeAddOp3(v, OP_OpenPseudo, ptab2, regSortOut, pOrderBy->nExpr+2);
addr = 1 + sqlite4VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
codeOffset(v, p, addrContinue);
sqlite4VdbeAddOp2(v, OP_SorterData, iTab, regSortOut);
sqlite4VdbeAddOp3(v, OP_Column, ptab2, pOrderBy->nExpr+1, regRow);
sqlite4VdbeChangeP5(v, OPFLAG_CLEARCACHE);
}else{
addr = 1 + sqlite4VdbeAddOp2(v, OP_Sort, iTab, addrBreak);
codeOffset(v, p, addrContinue);
/* sqlite4VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr+1, regRow); */
}
switch( eDest ){
case SRT_Table:
case SRT_EphemTab: {
testcase( eDest==SRT_Table );
testcase( eDest==SRT_EphemTab );
sqlite4VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
sqlite4VdbeAddOp2(v, OP_RowData, iTab, regRow);
sqlite4VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid);
sqlite4VdbeChangeP5(v, OPFLAG_APPEND);
break;
}
#ifndef SQLITE_OMIT_SUBQUERY
case SRT_Set: {
assert( nColumn==1 );
int regKey = sqlite4GetTempReg(pParse);
sqlite4VdbeAddOp2(v, OP_MakeKey, iParm, regKey);
sqlite4VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid, &p->affinity, 1);
sqlite4ExprCacheAffinityChange(pParse, regRow, 1);
sqlite4VdbeAddOp3(v, OP_IdxInsert, iParm, regRowid, regKey);
sqlite4ReleaseTempReg(pParse, regKey);
break;
}
case SRT_Mem: {
assert( nColumn==1 );
sqlite4VdbeAddOp3(v, OP_Column, iTab, 0, iParm);
/* The LIMIT clause will terminate the loop for us */
break;
}
#endif
default: {
int i;
assert( eDest==SRT_Output || eDest==SRT_Coroutine );
testcase( eDest==SRT_Output );
testcase( eDest==SRT_Coroutine );
/* Read the data out of the sorter and into the array of nColumn
** contiguous registers starting at pDest->iMem. */
for(i=0; i<nColumn; i++){
sqlite4VdbeAddOp3(v, OP_Column, iTab, i, pDest->iMem+i);
}
if( eDest==SRT_Output ){
sqlite4VdbeAddOp2(v, OP_ResultRow, pDest->iMem, nColumn);
sqlite4ExprCacheAffinityChange(pParse, pDest->iMem, nColumn);
}else{
sqlite4VdbeAddOp1(v, OP_Yield, pDest->iParm);
}
break;
}
}
sqlite4ReleaseTempReg(pParse, regRow);
sqlite4ReleaseTempReg(pParse, regRowid);
/* The bottom of the loop
*/
sqlite4VdbeResolveLabel(v, addrContinue);
if( p->selFlags & SF_UseSorter ){
sqlite4VdbeAddOp2(v, OP_SorterNext, iTab, addr);
}else{
sqlite4VdbeAddOp2(v, OP_Next, iTab, addr);
}
sqlite4VdbeResolveLabel(v, addrBreak);
}
/*
** Return a pointer to a string containing the 'declaration type' of the
** expression pExpr. The string may be treated as static by the caller.
**
** The declaration type is the exact datatype definition extracted from the
** original CREATE TABLE statement if the expression is a column. The
** declaration type for a ROWID field is INTEGER. Exactly when an expression
** is considered a column can be complex in the presence of subqueries. The
** result-set expression in all of the following SELECT statements is
** considered a column by this function.
**
** SELECT col FROM tbl;
** SELECT (SELECT col FROM tbl;
** SELECT (SELECT col FROM tbl);
** SELECT abc FROM (SELECT col AS abc FROM tbl);
**
** The declaration type for any expression other than a column is NULL.
*/
static const char *columnType(
NameContext *pNC,
Expr *pExpr,
const char **pzOriginDb,
const char **pzOriginTab,
const char **pzOriginCol
){
char const *zType = 0;
char const *zOriginDb = 0;
char const *zOriginTab = 0;
char const *zOriginCol = 0;
int j;
if( NEVER(pExpr==0) || pNC->pSrcList==0 ) return 0;
switch( pExpr->op ){
case TK_AGG_COLUMN:
case TK_COLUMN: {
/* The expression is a column. Locate the table the column is being
** extracted from in NameContext.pSrcList. This table may be real
** database table or a subquery.
*/
Table *pTab = 0; /* Table structure column is extracted from */
Select *pS = 0; /* Select the column is extracted from */
int iCol = pExpr->iColumn; /* Index of column in pTab */
testcase( pExpr->op==TK_AGG_COLUMN );
testcase( pExpr->op==TK_COLUMN );
while( pNC && !pTab ){
SrcList *pTabList = pNC->pSrcList;
for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++);
if( j<pTabList->nSrc ){
pTab = pTabList->a[j].pTab;
pS = pTabList->a[j].pSelect;
}else{
pNC = pNC->pNext;
}
}
if( pTab==0 ){
/* At one time, code such as "SELECT new.x" within a trigger would
** cause this condition to run. Since then, we have restructured how
** trigger code is generated and so this condition is no longer
** possible. However, it can still be true for statements like
** the following:
**
** CREATE TABLE t1(col INTEGER);
** SELECT (SELECT t1.col) FROM FROM t1;
**
** when columnType() is called on the expression "t1.col" in the
** sub-select. In this case, set the column type to NULL, even
** though it should really be "INTEGER".
**
** This is not a problem, as the column type of "t1.col" is never
** used. When columnType() is called on the expression
** "(SELECT t1.col)", the correct type is returned (see the TK_SELECT
** branch below. */
break;
}
assert( pTab && pExpr->pTab==pTab );
if( pS ){
/* The "table" is actually a sub-select or a view in the FROM clause
** of the SELECT statement. Return the declaration type and origin
** data for the result-set column of the sub-select.
*/
if( iCol>=0 && ALWAYS(iCol<pS->pEList->nExpr) ){
/* If iCol is less than zero, then the expression requests the
** rowid of the sub-select or view. This expression is legal (see
** test case misc2.2.2) - it always evaluates to NULL.
*/
NameContext sNC;
Expr *p = pS->pEList->a[iCol].pExpr;
sNC.pSrcList = pS->pSrc;
sNC.pNext = pNC;
sNC.pParse = pNC->pParse;
zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol);
}
}else if( ALWAYS(pTab->pSchema) ){
/* A real table */
assert( !pS );
assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
if( iCol<0 ){
zType = "INTEGER";
zOriginCol = "rowid";
}else{
zType = pTab->aCol[iCol].zType;
zOriginCol = pTab->aCol[iCol].zName;
}
zOriginTab = pTab->zName;
if( pNC->pParse ){
int iDb = sqlite4SchemaToIndex(pNC->pParse->db, pTab->pSchema);
zOriginDb = pNC->pParse->db->aDb[iDb].zName;
}
}
break;
}
#ifndef SQLITE_OMIT_SUBQUERY
case TK_SELECT: {
/* The expression is a sub-select. Return the declaration type and
** origin info for the single column in the result set of the SELECT
** statement.
*/
NameContext sNC;
Select *pS = pExpr->x.pSelect;
Expr *p = pS->pEList->a[0].pExpr;
assert( ExprHasProperty(pExpr, EP_xIsSelect) );
sNC.pSrcList = pS->pSrc;
sNC.pNext = pNC;
sNC.pParse = pNC->pParse;
zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol);
break;
}
#endif
}
if( pzOriginDb ){
assert( pzOriginTab && pzOriginCol );
*pzOriginDb = zOriginDb;
*pzOriginTab = zOriginTab;
*pzOriginCol = zOriginCol;
}
return zType;
}
/*
** Generate code that will tell the VDBE the declaration types of columns
** in the result set.
*/
static void generateColumnTypes(
Parse *pParse, /* Parser context */
SrcList *pTabList, /* List of tables */
ExprList *pEList /* Expressions defining the result set */
){
#ifndef SQLITE_OMIT_DECLTYPE
Vdbe *v = pParse->pVdbe;
int i;
NameContext sNC;
sNC.pSrcList = pTabList;
sNC.pParse = pParse;
for(i=0; i<pEList->nExpr; i++){
Expr *p = pEList->a[i].pExpr;
const char *zType;
#ifdef SQLITE_ENABLE_COLUMN_METADATA
const char *zOrigDb = 0;
const char *zOrigTab = 0;
const char *zOrigCol = 0;
zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol);
/* The vdbe must make its own copy of the column-type and other
** column specific strings, in case the schema is reset before this
** virtual machine is deleted.
*/
sqlite4VdbeSetColName(v, i, COLNAME_DATABASE, zOrigDb, SQLITE_TRANSIENT);
sqlite4VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, SQLITE_TRANSIENT);
sqlite4VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, SQLITE_TRANSIENT);
#else
zType = columnType(&sNC, p, 0, 0, 0);
#endif
sqlite4VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT);
}
#endif /* SQLITE_OMIT_DECLTYPE */
}
/*
** Generate code that will tell the VDBE the names of columns
** in the result set. This information is used to provide the
** azCol[] values in the callback.
*/
static void generateColumnNames(
Parse *pParse, /* Parser context */
SrcList *pTabList, /* List of tables */
ExprList *pEList /* Expressions defining the result set */
){
Vdbe *v = pParse->pVdbe;
int i, j;
sqlite4 *db = pParse->db;
#ifndef SQLITE_OMIT_EXPLAIN
/* If this is an EXPLAIN, skip this step */
if( pParse->explain ){
return;
}
#endif
if( pParse->colNamesSet || NEVER(v==0) || db->mallocFailed ) return;
pParse->colNamesSet = 1;
sqlite4VdbeSetNumCols(v, pEList->nExpr);
for(i=0; i<pEList->nExpr; i++){
Expr *p;
p = pEList->a[i].pExpr;
if( NEVER(p==0) ) continue;
if( pEList->a[i].zName ){
char *zName = pEList->a[i].zName;
sqlite4VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT);
}else if( (p->op==TK_COLUMN || p->op==TK_AGG_COLUMN) && pTabList ){
Table *pTab;
char *zCol;
int iCol = p->iColumn;
for(j=0; ALWAYS(j<pTabList->nSrc); j++){
if( pTabList->a[j].iCursor==p->iTable ) break;
}
assert( j<pTabList->nSrc );
pTab = pTabList->a[j].pTab;
assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
if( iCol<0 ){
zCol = "rowid";
}else{
zCol = pTab->aCol[iCol].zName;
}
sqlite4VdbeSetColName(v, i, COLNAME_NAME, zCol, SQLITE_TRANSIENT);
}else{
sqlite4VdbeSetColName(v, i, COLNAME_NAME,
sqlite4DbStrDup(db, pEList->a[i].zSpan), SQLITE_DYNAMIC);
}
}
generateColumnTypes(pParse, pTabList, pEList);
}
/*
** Given a an expression list (which is really the list of expressions
** that form the result set of a SELECT statement) compute appropriate
** column names for a table that would hold the expression list.
**
** All column names will be unique.
**
** Only the column names are computed. Column.zType, Column.zColl,
** and other fields of Column are zeroed.
**
** Return SQLITE_OK on success. If a memory allocation error occurs,
** store NULL in *paCol and 0 in *pnCol and return SQLITE_NOMEM.
*/
static int selectColumnsFromExprList(
Parse *pParse, /* Parsing context */
ExprList *pEList, /* Expr list from which to derive column names */
int *pnCol, /* Write the number of columns here */
Column **paCol /* Write the new column list here */
){
sqlite4 *db = pParse->db; /* Database connection */
int i, j; /* Loop counters */
int 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 */
Expr *p; /* Expression for a single result column */
char *zName; /* Column name */
int nName; /* Size of name in zName[] */
*pnCol = nCol = pEList->nExpr;
aCol = *paCol = sqlite4DbMallocZero(db, sizeof(aCol[0])*nCol);
if( aCol==0 ) return SQLITE_NOMEM;
for(i=0, pCol=aCol; i<nCol; i++, pCol++){
/* Get an appropriate name for the column
*/
p = pEList->a[i].pExpr;
assert( p->pRight==0 || ExprHasProperty(p->pRight, EP_IntValue)
|| p->pRight->u.zToken==0 || p->pRight->u.zToken[0]!=0 );
if( (zName = pEList->a[i].zName)!=0 ){
/* If the column contains an "AS <name>" phrase, use <name> as the name */
zName = sqlite4DbStrDup(db, zName);
}else{
Expr *pColExpr = p; /* The expression that is the result column name */
Table *pTab; /* Table associated with this expression */
while( pColExpr->op==TK_DOT ){
pColExpr = pColExpr->pRight;
assert( pColExpr!=0 );
}
if( pColExpr->op==TK_COLUMN && ALWAYS(pColExpr->pTab!=0) ){
/* For columns use the column name name */
int iCol = pColExpr->iColumn;
pTab = pColExpr->pTab;
zName = sqlite4MPrintf(db, "%s",
iCol>=0 ? pTab->aCol[iCol].zName : "rowid");
}else if( pColExpr->op==TK_ID ){
assert( !ExprHasProperty(pColExpr, EP_IntValue) );
zName = sqlite4MPrintf(db, "%s", pColExpr->u.zToken);
}else{
/* Use the original text of the column expression as its name */
zName = sqlite4MPrintf(db, "%s", pEList->a[i].zSpan);
}
}
if( db->mallocFailed ){
sqlite4DbFree(db, zName);
break;
}
/* Make sure the column name is unique. If the name is not unique,
** append a integer to the name so that it becomes unique.
*/
nName = sqlite4Strlen30(zName);
for(j=cnt=0; j<i; j++){
if( sqlite4StrICmp(aCol[j].zName, zName)==0 ){
char *zNewName;
zName[nName] = 0;
zNewName = sqlite4MPrintf(db, "%s:%d", zName, ++cnt);
sqlite4DbFree(db, zName);
zName = zNewName;
j = -1;
if( zName==0 ) break;
}
}
pCol->zName = zName;
}
if( db->mallocFailed ){
for(j=0; j<i; j++){
sqlite4DbFree(db, aCol[j].zName);
}
sqlite4DbFree(db, aCol);
*paCol = 0;
*pnCol = 0;
return SQLITE_NOMEM;
}
return SQLITE_OK;
}
/*
** Add type and collation information to a column list based on
** a SELECT statement.
**
** The column list presumably came from selectColumnNamesFromExprList().
** The column list has only names, not types or collations. This
** routine goes through and adds the types and collations.
**
** This routine requires that all identifiers in the SELECT
** statement be resolved.
*/
static void selectAddColumnTypeAndCollation(
Parse *pParse, /* Parsing contexts */
int nCol, /* Number of columns */
Column *aCol, /* List of columns */
Select *pSelect /* SELECT used to determine types and collations */
){
sqlite4 *db = pParse->db;
NameContext sNC;
Column *pCol;
CollSeq *pColl;
int i;
Expr *p;
struct ExprList_item *a;
assert( pSelect!=0 );
assert( (pSelect->selFlags & SF_Resolved)!=0 );
assert( nCol==pSelect->pEList->nExpr || db->mallocFailed );
if( db->mallocFailed ) return;
memset(&sNC, 0, sizeof(sNC));
sNC.pSrcList = pSelect->pSrc;
a = pSelect->pEList->a;
for(i=0, pCol=aCol; i<nCol; i++, pCol++){
p = a[i].pExpr;
pCol->zType = sqlite4DbStrDup(db, columnType(&sNC, p, 0, 0, 0));
pCol->affinity = sqlite4ExprAffinity(p);
if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_NONE;
pColl = sqlite4ExprCollSeq(pParse, p);
if( pColl ){
pCol->zColl = sqlite4DbStrDup(db, pColl->zName);
}
}
}
/*
** Given a SELECT statement, generate a Table structure that describes
** the result set of that SELECT.
*/
SQLITE_PRIVATE Table *sqlite4ResultSetOfSelect(Parse *pParse, Select *pSelect){
Table *pTab;
sqlite4 *db = pParse->db;
sqlite4SelectPrep(pParse, pSelect, 0);
if( pParse->nErr ) return 0;
while( pSelect->pPrior ) pSelect = pSelect->pPrior;
pTab = sqlite4DbMallocZero(db, sizeof(Table) );
if( pTab==0 ){
return 0;
}
/* The sqlite4ResultSetOfSelect() is only used n contexts where lookaside
** is disabled */
assert( db->lookaside.bEnabled==0 );
pTab->nRef = 1;
pTab->zName = 0;
pTab->nRowEst = 1000000;
selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSelect);
if( db->mallocFailed ){
sqlite4DeleteTable(db, pTab);
return 0;
}
return pTab;
}
/*
** Get a VDBE for the given parser context. Create a new one if necessary.
** If an error occurs, return NULL and leave a message in pParse.
*/
SQLITE_PRIVATE Vdbe *sqlite4GetVdbe(Parse *pParse){
Vdbe *v = pParse->pVdbe;
if( v==0 ){
v = pParse->pVdbe = sqlite4VdbeCreate(pParse->db);
#ifndef SQLITE_OMIT_TRACE
if( v ){
sqlite4VdbeAddOp0(v, OP_Trace);
}
#endif
}
return v;
}
/*
** Compute the iLimit and iOffset fields of the SELECT based on the
** pLimit and pOffset expressions. pLimit and pOffset 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
** the limit and offset. If there is no limit and/or offset, then
** iLimit and iOffset are negative.
**
** This routine changes the values of iLimit and iOffset only if
** a limit or offset is defined by pLimit and pOffset. iLimit and
** iOffset should have been preset to appropriate default values
** (usually but not always -1) prior to calling this routine.
** Only if pLimit!=0 or pOffset!=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.
*/
static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
Vdbe *v = 0;
int iLimit = 0;
int iOffset;
int addr1, n;
if( p->iLimit ) return;
/*
** "LIMIT -1" always shows all rows. There is some
** contraversy about what the correct behavior should be.
** The current implementation interprets "LIMIT 0" to mean
** no rows.
*/
sqlite4ExprCacheClear(pParse);
assert( p->pOffset==0 || p->pLimit!=0 );
if( p->pLimit ){
p->iLimit = iLimit = ++pParse->nMem;
v = sqlite4GetVdbe(pParse);
if( NEVER(v==0) ) return; /* VDBE should have already been allocated */
if( sqlite4ExprIsInteger(p->pLimit, &n) ){
sqlite4VdbeAddOp2(v, OP_Integer, n, iLimit);
VdbeComment((v, "LIMIT counter"));
if( n==0 ){
sqlite4VdbeAddOp2(v, OP_Goto, 0, iBreak);
}else{
if( p->nSelectRow > (double)n ) p->nSelectRow = (double)n;
}
}else{
sqlite4ExprCode(pParse, p->pLimit, iLimit);
sqlite4VdbeAddOp1(v, OP_MustBeInt, iLimit);
VdbeComment((v, "LIMIT counter"));
sqlite4VdbeAddOp2(v, OP_IfZero, iLimit, iBreak);
}
if( p->pOffset ){
p->iOffset = iOffset = ++pParse->nMem;
pParse->nMem++; /* Allocate an extra register for limit+offset */
sqlite4ExprCode(pParse, p->pOffset, iOffset);
sqlite4VdbeAddOp1(v, OP_MustBeInt, iOffset);
VdbeComment((v, "OFFSET counter"));
addr1 = sqlite4VdbeAddOp1(v, OP_IfPos, iOffset);
sqlite4VdbeAddOp2(v, OP_Integer, 0, iOffset);
sqlite4VdbeJumpHere(v, addr1);
sqlite4VdbeAddOp3(v, OP_Add, iLimit, iOffset, iOffset+1);
VdbeComment((v, "LIMIT+OFFSET"));
addr1 = sqlite4VdbeAddOp1(v, OP_IfPos, iLimit);
sqlite4VdbeAddOp2(v, OP_Integer, -1, iOffset+1);
sqlite4VdbeJumpHere(v, addr1);
}
}
}
#ifndef SQLITE_OMIT_COMPOUND_SELECT
/*
** Return the appropriate collating sequence for the iCol-th column of
** the result set for the compound-select statement "p". Return NULL if
** the column has no default collating sequence.
**
** The collating sequence for the compound select is taken from the
** left-most term of the select that has a collating sequence.
*/
static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){
CollSeq *pRet;
if( p->pPrior ){
pRet = multiSelectCollSeq(pParse, p->pPrior, iCol);
}else{
pRet = 0;
}
assert( iCol>=0 );
if( pRet==0 && iCol<p->pEList->nExpr ){
pRet = sqlite4ExprCollSeq(pParse, p->pEList->a[iCol].pExpr);
}
return pRet;
}
#endif /* SQLITE_OMIT_COMPOUND_SELECT */
/* Forward reference */
static int multiSelectOrderBy(
Parse *pParse, /* Parsing context */
Select *p, /* The right-most of SELECTs to be coded */
SelectDest *pDest /* What to do with query results */
);
#ifndef SQLITE_OMIT_COMPOUND_SELECT
/*
** This routine is called to process a compound query form from
** two or more separate queries using UNION, UNION ALL, EXCEPT, or
** INTERSECT
**
** "p" points to the right-most of the two queries. the query on the
** left is p->pPrior. The left query could also be a compound query
** in which case this routine will be called recursively.
**
** The results of the total query are to be written into a destination
** of type eDest with parameter iParm.
**
** Example 1: Consider a three-way compound SQL statement.
**
** SELECT a FROM t1 UNION SELECT b FROM t2 UNION SELECT c FROM t3
**
** This statement is parsed up as follows:
**
** SELECT c FROM t3
** |
** `-----> SELECT b FROM t2
** |
** `------> SELECT a FROM t1
**
** The arrows in the diagram above represent the Select.pPrior pointer.
** So if this routine is called with p equal to the t3 query, then
** pPrior will be the t2 query. p->op will be TK_UNION in this case.
**
** Notice that because of the way SQLite parses compound SELECTs, the
** individual selects always group from left to right.
*/
static int multiSelect(
Parse *pParse, /* Parsing context */
Select *p, /* The right-most of SELECTs to be coded */
SelectDest *pDest /* What to do with query results */
){
int rc = SQLITE_OK; /* Success code from a subroutine */
Select *pPrior; /* Another SELECT immediately to our left */
Vdbe *v; /* Generate code to this VDBE */
SelectDest dest; /* Alternative data destination */
Select *pDelete = 0; /* Chain of simple selects to delete */
sqlite4 *db; /* Database connection */
#ifndef SQLITE_OMIT_EXPLAIN
int iSub1; /* EQP id of left-hand query */
int iSub2; /* EQP id of right-hand query */
#endif
/* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only
** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT.
*/
assert( p && p->pPrior ); /* Calling function guarantees this much */
db = pParse->db;
pPrior = p->pPrior;
assert( pPrior->pRightmost!=pPrior );
assert( pPrior->pRightmost==p->pRightmost );
dest = *pDest;
if( pPrior->pOrderBy ){
sqlite4ErrorMsg(pParse,"ORDER BY clause should come after %s not before",
selectOpName(p->op));
rc = 1;
goto multi_select_end;
}
if( pPrior->pLimit ){
sqlite4ErrorMsg(pParse,"LIMIT clause should come after %s not before",
selectOpName(p->op));
rc = 1;
goto multi_select_end;
}
v = sqlite4GetVdbe(pParse);
assert( v!=0 ); /* The VDBE already created by calling function */
/* Create the destination temporary table if necessary
*/
if( dest.eDest==SRT_EphemTab ){
assert( p->pEList );
sqlite4VdbeAddOp2(v, OP_OpenEphemeral, dest.iParm, p->pEList->nExpr);
dest.eDest = SRT_Table;
}
/* Make sure all SELECTs in the statement have the same number of elements
** in their result sets.
*/
assert( p->pEList && pPrior->pEList );
if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
sqlite4ErrorMsg(pParse, "SELECTs to the left and right of %s"
" do not have the same number of result columns", selectOpName(p->op));
rc = 1;
goto multi_select_end;
}
/* Compound SELECTs that have an ORDER BY clause are handled separately.
*/
if( p->pOrderBy ){
return multiSelectOrderBy(pParse, p, pDest);
}
/* Generate code for the left and right SELECT statements.
*/
switch( p->op ){
case TK_ALL: {
int addr = 0;
int nLimit;
assert( !pPrior->pLimit );
pPrior->pLimit = p->pLimit;
pPrior->pOffset = p->pOffset;
explainSetInteger(iSub1, pParse->iNextSelectId);
rc = sqlite4Select(pParse, pPrior, &dest);
p->pLimit = 0;
p->pOffset = 0;
if( rc ){
goto multi_select_end;
}
p->pPrior = 0;
p->iLimit = pPrior->iLimit;
p->iOffset = pPrior->iOffset;
if( p->iLimit ){
addr = sqlite4VdbeAddOp1(v, OP_IfZero, p->iLimit);
VdbeComment((v, "Jump ahead if LIMIT reached"));
}
explainSetInteger(iSub2, pParse->iNextSelectId);
rc = sqlite4Select(pParse, p, &dest);
testcase( rc!=SQLITE_OK );
pDelete = p->pPrior;
p->pPrior = pPrior;
p->nSelectRow += pPrior->nSelectRow;
if( pPrior->pLimit
&& sqlite4ExprIsInteger(pPrior->pLimit, &nLimit)
&& p->nSelectRow > (double)nLimit
){
p->nSelectRow = (double)nLimit;
}
if( addr ){
sqlite4VdbeJumpHere(v, addr);
}
break;
}
case TK_EXCEPT:
case TK_UNION: {
int unionTab; /* Cursor number of the temporary table holding result */
u8 op = 0; /* One of the SRT_ operations to apply to self */
int priorOp; /* The SRT_ operation to apply to prior selects */
Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */
int addr;
SelectDest uniondest;
testcase( p->op==TK_EXCEPT );
testcase( p->op==TK_UNION );
priorOp = SRT_Union;
if( dest.eDest==priorOp && ALWAYS(!p->pLimit &&!p->pOffset) ){
/* We can reuse a temporary table generated by a SELECT to our
** right.
*/
assert( p->pRightmost!=p ); /* Can only happen for leftward elements
** of a 3-way or more compound */
assert( p->pLimit==0 ); /* Not allowed on leftward elements */
assert( p->pOffset==0 ); /* Not allowed on leftward elements */
unionTab = dest.iParm;
}else{
/* We will need to create our own temporary table to hold the
** intermediate results.
*/
unionTab = pParse->nTab++;
assert( p->pOrderBy==0 );
addr = sqlite4VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0);
assert( p->addrOpenEphm[0] == -1 );
p->addrOpenEphm[0] = addr;
p->pRightmost->selFlags |= SF_UsesEphemeral;
assert( p->pEList );
}
/* Code the SELECT statements to our left
*/
assert( !pPrior->pOrderBy );
sqlite4SelectDestInit(&uniondest, priorOp, unionTab);
explainSetInteger(iSub1, pParse->iNextSelectId);
rc = sqlite4Select(pParse, pPrior, &uniondest);
if( rc ){
goto multi_select_end;
}
/* Code the current SELECT statement
*/
if( p->op==TK_EXCEPT ){
op = SRT_Except;
}else{
assert( p->op==TK_UNION );
op = SRT_Union;
}
p->pPrior = 0;
pLimit = p->pLimit;
p->pLimit = 0;
pOffset = p->pOffset;
p->pOffset = 0;
uniondest.eDest = op;
explainSetInteger(iSub2, pParse->iNextSelectId);
rc = sqlite4Select(pParse, p, &uniondest);
testcase( rc!=SQLITE_OK );
/* Query flattening in sqlite4Select() might refill p->pOrderBy.
** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
sqlite4ExprListDelete(db, p->pOrderBy);
pDelete = p->pPrior;
p->pPrior = pPrior;
p->pOrderBy = 0;
if( p->op==TK_UNION ) p->nSelectRow += pPrior->nSelectRow;
sqlite4ExprDelete(db, p->pLimit);
p->pLimit = pLimit;
p->pOffset = pOffset;
p->iLimit = 0;
p->iOffset = 0;
/* Convert the data in the temporary table into whatever form
** it is that we currently need.
*/
assert( unionTab==dest.iParm || dest.eDest!=priorOp );
if( dest.eDest!=priorOp ){
int iCont, iBreak, iStart;
assert( p->pEList );
if( dest.eDest==SRT_Output ){
Select *pFirst = p;
while( pFirst->pPrior ) pFirst = pFirst->pPrior;
generateColumnNames(pParse, 0, pFirst->pEList);
}
iBreak = sqlite4VdbeMakeLabel(v);
iCont = sqlite4VdbeMakeLabel(v);
computeLimitRegisters(pParse, p, iBreak);
sqlite4VdbeAddOp2(v, OP_Rewind, unionTab, iBreak);
iStart = sqlite4VdbeCurrentAddr(v);
selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
0, -1, &dest, iCont, iBreak);
sqlite4VdbeResolveLabel(v, iCont);
sqlite4VdbeAddOp2(v, OP_Next, unionTab, iStart);
sqlite4VdbeResolveLabel(v, iBreak);
sqlite4VdbeAddOp2(v, OP_Close, unionTab, 0);
}
break;
}
default: assert( p->op==TK_INTERSECT ); {
int tab1, tab2;
int iCont, iBreak, iStart;
Expr *pLimit, *pOffset;
int addr;
SelectDest intersectdest;
int r1;
/* INTERSECT is different from the others since it requires
** two temporary tables. Hence it has its own case. Begin
** by allocating the tables we will need.
*/
tab1 = pParse->nTab++;
tab2 = pParse->nTab++;
assert( p->pOrderBy==0 );
addr = sqlite4VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0);
assert( p->addrOpenEphm[0] == -1 );
p->addrOpenEphm[0] = addr;
p->pRightmost->selFlags |= SF_UsesEphemeral;
assert( p->pEList );
/* Code the SELECTs to our left into temporary table "tab1".
*/
sqlite4SelectDestInit(&intersectdest, SRT_Union, tab1);
explainSetInteger(iSub1, pParse->iNextSelectId);
rc = sqlite4Select(pParse, pPrior, &intersectdest);
if( rc ){
goto multi_select_end;
}
/* Code the current SELECT into temporary table "tab2"
*/
addr = sqlite4VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0);
assert( p->addrOpenEphm[1] == -1 );
p->addrOpenEphm[1] = addr;
p->pPrior = 0;
pLimit = p->pLimit;
p->pLimit = 0;
pOffset = p->pOffset;
p->pOffset = 0;
intersectdest.iParm = tab2;
explainSetInteger(iSub2, pParse->iNextSelectId);
rc = sqlite4Select(pParse, p, &intersectdest);
testcase( rc!=SQLITE_OK );
pDelete = p->pPrior;
p->pPrior = pPrior;
if( p->nSelectRow>pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow;
sqlite4ExprDelete(db, p->pLimit);
p->pLimit = pLimit;
p->pOffset = pOffset;
/* Generate code to take the intersection of the two temporary
** tables.
*/
assert( p->pEList );
if( dest.eDest==SRT_Output ){
Select *pFirst = p;
while( pFirst->pPrior ) pFirst = pFirst->pPrior;
generateColumnNames(pParse, 0, pFirst->pEList);
}
iBreak = sqlite4VdbeMakeLabel(v);
iCont = sqlite4VdbeMakeLabel(v);
computeLimitRegisters(pParse, p, iBreak);
sqlite4VdbeAddOp2(v, OP_Rewind, tab1, iBreak);
r1 = sqlite4GetTempReg(pParse);
iStart = sqlite4VdbeAddOp2(v, OP_RowKey, tab1, r1);
sqlite4VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0);
sqlite4ReleaseTempReg(pParse, r1);
selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
0, -1, &dest, iCont, iBreak);
sqlite4VdbeResolveLabel(v, iCont);
sqlite4VdbeAddOp2(v, OP_Next, tab1, iStart);
sqlite4VdbeResolveLabel(v, iBreak);
sqlite4VdbeAddOp2(v, OP_Close, tab2, 0);
sqlite4VdbeAddOp2(v, OP_Close, tab1, 0);
break;
}
}
explainComposite(pParse, p->op, iSub1, iSub2, p->op!=TK_ALL);
/* Compute collating sequences used by
** temporary tables needed to implement the compound select.
** Attach the KeyInfo structure to all temporary tables.
**
** This section is run by the right-most SELECT statement only.
** SELECT statements to the left always skip this part. The right-most
** SELECT might also skip this part if it has no ORDER BY clause and
** no temp tables are required.
*/
if( p->selFlags & SF_UsesEphemeral ){
int i; /* Loop counter */
KeyInfo *pKeyInfo; /* Collating sequence for the result set */
Select *pLoop; /* For looping through SELECT statements */
CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */
int nCol; /* Number of columns in result set */
assert( p->pRightmost==p );
nCol = p->pEList->nExpr;
pKeyInfo = sqlite4DbMallocZero(db,
sizeof(*pKeyInfo)+nCol*(sizeof(CollSeq*) + 1));
if( !pKeyInfo ){
rc = SQLITE_NOMEM;
goto multi_select_end;
}
pKeyInfo->enc = ENC(db);
pKeyInfo->nField = (u16)nCol;
for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
*apColl = multiSelectCollSeq(pParse, p, i);
if( 0==*apColl ){
*apColl = db->pDfltColl;
}
}
for(pLoop=p; pLoop; pLoop=pLoop->pPrior){
for(i=0; i<2; i++){
int addr = pLoop->addrOpenEphm[i];
if( addr<0 ){
/* If [0] is unused then [1] is also unused. So we can
** always safely abort as soon as the first unused slot is found */
assert( pLoop->addrOpenEphm[1]<0 );
break;
}
sqlite4VdbeChangeP2(v, addr, nCol);
sqlite4VdbeChangeP4(v, addr, (char*)pKeyInfo, P4_KEYINFO);
pLoop->addrOpenEphm[i] = -1;
}
}
sqlite4DbFree(db, pKeyInfo);
}
multi_select_end:
pDest->iMem = dest.iMem;
pDest->nMem = dest.nMem;
sqlite4SelectDelete(db, pDelete);
return rc;
}
#endif /* SQLITE_OMIT_COMPOUND_SELECT */
/*
** Code an output subroutine for a coroutine implementation of a
** SELECT statment.
**
** The data to be output is contained in pIn->iMem. There are
** pIn->nMem columns to be output. pDest is where the output should
** be sent.
**
** regReturn is the number of the register holding the subroutine
** return address.
**
** If regPrev>0 then it is the first register in a vector that
** records the previous output. mem[regPrev] is a flag that is false
** if there has been no previous output. If regPrev>0 then code is
** generated to suppress duplicates. pKeyInfo is used for comparing
** keys.
**
** If the LIMIT found in p->iLimit is reached, jump immediately to
** iBreak.
*/
static int generateOutputSubroutine(
Parse *pParse, /* Parsing context */
Select *p, /* The SELECT statement */
SelectDest *pIn, /* Coroutine supplying data */
SelectDest *pDest, /* Where to send the data */
int regReturn, /* The return address register */
int regPrev, /* Previous result register. No uniqueness if 0 */
KeyInfo *pKeyInfo, /* For comparing with previous entry */
int p4type, /* The p4 type for pKeyInfo */
int iBreak /* Jump here if we hit the LIMIT */
){
Vdbe *v = pParse->pVdbe;
int iContinue;
int addr;
addr = sqlite4VdbeCurrentAddr(v);
iContinue = sqlite4VdbeMakeLabel(v);
/* Suppress duplicates for UNION, EXCEPT, and INTERSECT
*/
if( regPrev ){
int j1, j2;
j1 = sqlite4VdbeAddOp1(v, OP_IfNot, regPrev);
j2 = sqlite4VdbeAddOp4(v, OP_Compare, pIn->iMem, regPrev+1, pIn->nMem,
(char*)pKeyInfo, p4type);
sqlite4VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2);
sqlite4VdbeJumpHere(v, j1);
sqlite4ExprCodeCopy(pParse, pIn->iMem, regPrev+1, pIn->nMem);
sqlite4VdbeAddOp2(v, OP_Integer, 1, regPrev);
}
if( pParse->db->mallocFailed ) return 0;
/* Suppress the the first OFFSET entries if there is an OFFSET clause
*/
codeOffset(v, p, iContinue);
switch( pDest->eDest ){
/* Store the result as data using a unique key.
*/
case SRT_Table:
case SRT_EphemTab: {
int r1 = sqlite4GetTempReg(pParse);
int r2 = sqlite4GetTempReg(pParse);
testcase( pDest->eDest==SRT_Table );
testcase( pDest->eDest==SRT_EphemTab );
sqlite4VdbeAddOp3(v, OP_MakeRecord, pIn->iMem, pIn->nMem, r1);
sqlite4VdbeAddOp2(v, OP_NewRowid, pDest->iParm, r2);
sqlite4VdbeAddOp3(v, OP_Insert, pDest->iParm, r1, r2);
sqlite4VdbeChangeP5(v, OPFLAG_APPEND);
sqlite4ReleaseTempReg(pParse, r2);
sqlite4ReleaseTempReg(pParse, r1);
break;
}
#ifndef SQLITE_OMIT_SUBQUERY
/* If we are creating a set for an "expr IN (SELECT ...)" construct,
** then there should be a single item on the stack. Write this
** item into the set table with bogus data.
*/
case SRT_Set: {
int r1, r2;
assert( pIn->nMem==1 );
p->affinity =
sqlite4CompareAffinity(p->pEList->a[0].pExpr, pDest->affinity);
r1 = sqlite4GetTempReg(pParse);
r2 = sqlite4GetTempReg(pParse);
sqlite4VdbeAddOp2(v, OP_MakeKey, pDest->iParm, r2);
sqlite4VdbeAddOp4(v, OP_MakeRecord, pIn->iMem, 1, r1, &p->affinity, 1);
sqlite4ExprCacheAffinityChange(pParse, pIn->iMem, 1);
sqlite4VdbeAddOp3(v, OP_IdxInsert, pDest->iParm, r1, r2);
sqlite4ReleaseTempReg(pParse, r1);
sqlite4ReleaseTempReg(pParse, r2);
break;
}
#if 0 /* Never occurs on an ORDER BY query */
/* If any row exist in the result set, record that fact and abort.
*/
case SRT_Exists: {
sqlite4VdbeAddOp2(v, OP_Integer, 1, pDest->iParm);
/* The LIMIT clause will terminate the loop for us */
break;
}
#endif
/* If this is a scalar select that is part of an expression, then
** store the results in the appropriate memory cell and break out
** of the scan loop.
*/
case SRT_Mem: {
assert( pIn->nMem==1 );
sqlite4ExprCodeMove(pParse, pIn->iMem, pDest->iParm, 1);
/* The LIMIT clause will jump out of the loop for us */
break;
}
#endif /* #ifndef SQLITE_OMIT_SUBQUERY */
/* The results are stored in a sequence of registers
** starting at pDest->iMem. Then the co-routine yields.
*/
case SRT_Coroutine: {
if( pDest->iMem==0 ){
pDest->iMem = sqlite4GetTempRange(pParse, pIn->nMem);
pDest->nMem = pIn->nMem;
}
sqlite4ExprCodeMove(pParse, pIn->iMem, pDest->iMem, pDest->nMem);
sqlite4VdbeAddOp1(v, OP_Yield, pDest->iParm);
break;
}
/* If none of the above, then the result destination must be
** SRT_Output. This routine is never called with any other
** destination other than the ones handled above or SRT_Output.
**
** For SRT_Output, results are stored in a sequence of registers.
** Then the OP_ResultRow opcode is used to cause sqlite4_step() to
** return the next row of result.
*/
default: {
assert( pDest->eDest==SRT_Output );
sqlite4VdbeAddOp2(v, OP_ResultRow, pIn->iMem, pIn->nMem);
sqlite4ExprCacheAffinityChange(pParse, pIn->iMem, pIn->nMem);
break;
}
}
/* Jump to the end of the loop if the LIMIT is reached.
*/
if( p->iLimit ){
sqlite4VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1);
}
/* Generate the subroutine return
*/
sqlite4VdbeResolveLabel(v, iContinue);
sqlite4VdbeAddOp1(v, OP_Return, regReturn);
return addr;
}
/*
** Alternative compound select code generator for cases when there
** is an ORDER BY clause.
**
** We assume a query of the following form:
**
** <selectA> <operator> <selectB> ORDER BY <orderbylist>
**
** <operator> is one of UNION ALL, UNION, EXCEPT, or INTERSECT. The idea
** is to code both <selectA> and <selectB> with the ORDER BY clause as
** co-routines. Then run the co-routines in parallel and merge the results
** into the output. In addition to the two coroutines (called selectA and
** selectB) there are 7 subroutines:
**
** outA: Move the output of the selectA coroutine into the output
** of the compound query.
**
** outB: Move the output of the selectB coroutine into the output
** of the compound query. (Only generated for UNION and
** UNION ALL. EXCEPT and INSERTSECT never output a row that
** appears only in B.)
**
** AltB: Called when there is data from both coroutines and A<B.
**
** AeqB: Called when there is data from both coroutines and A==B.
**
** AgtB: Called when there is data from both coroutines and A>B.
**
** EofA: Called when data is exhausted from selectA.
**
** EofB: Called when data is exhausted from selectB.
**
** The implementation of the latter five subroutines depend on which
** <operator> is used:
**
**
** UNION ALL UNION EXCEPT INTERSECT
** ------------- ----------------- -------------- -----------------
** AltB: outA, nextA outA, nextA outA, nextA nextA
**
** AeqB: outA, nextA nextA nextA outA, nextA
**
** AgtB: outB, nextB outB, nextB nextB nextB
**
** EofA: outB, nextB outB, nextB halt halt
**
** EofB: outA, nextA outA, nextA outA, nextA halt
**
** In the AltB, AeqB, and AgtB subroutines, an EOF on A following nextA
** causes an immediate jump to EofA and an EOF on B following nextB causes
** an immediate jump to EofB. Within EofA and EofB, and EOF on entry or
** following nextX causes a jump to the end of the select processing.
**
** Duplicate removal in the UNION, EXCEPT, and INTERSECT cases is handled
** within the output subroutine. The regPrev register set holds the previously
** output value. A comparison is made against this value and the output
** is skipped if the next results would be the same as the previous.
**
** The implementation plan is to implement the two coroutines and seven
** subroutines first, then put the control logic at the bottom. Like this:
**
** goto Init
** coA: coroutine for left query (A)
** coB: coroutine for right query (B)
** outA: output one row of A
** outB: output one row of B (UNION and UNION ALL only)
** EofA: ...
** EofB: ...
** AltB: ...
** AeqB: ...
** AgtB: ...
** Init: initialize coroutine registers
** yield coA
** if eof(A) goto EofA
** yield coB
** if eof(B) goto EofB
** Cmpr: Compare A, B
** Jump AltB, AeqB, AgtB
** End: ...
**
** We call AltB, AeqB, AgtB, EofA, and EofB "subroutines" but they are not
** actually called using Gosub and they do not Return. EofA and EofB loop
** until all data is exhausted then jump to the "end" labe. AltB, AeqB,
** and AgtB jump to either L2 or to one of EofA or EofB.
*/
#ifndef SQLITE_OMIT_COMPOUND_SELECT
static int multiSelectOrderBy(
Parse *pParse, /* Parsing context */
Select *p, /* The right-most of SELECTs to be coded */
SelectDest *pDest /* What to do with query results */
){
int i, j; /* Loop counters */
Select *pPrior; /* Another SELECT immediately to our left */
Vdbe *v; /* Generate code to this VDBE */
SelectDest destA; /* Destination for coroutine A */
SelectDest destB; /* Destination for coroutine B */
int regAddrA; /* Address register for select-A coroutine */
int regEofA; /* Flag to indicate when select-A is complete */
int regAddrB; /* Address register for select-B coroutine */
int regEofB; /* Flag to indicate when select-B is complete */
int addrSelectA; /* Address of the select-A coroutine */
int addrSelectB; /* Address of the select-B coroutine */
int regOutA; /* Address register for the output-A subroutine */
int regOutB; /* Address register for the output-B subroutine */
int addrOutA; /* Address of the output-A subroutine */
int addrOutB = 0; /* Address of the output-B subroutine */
int addrEofA; /* Address of the select-A-exhausted subroutine */
int addrEofB; /* Address of the select-B-exhausted subroutine */
int addrAltB; /* Address of the A<B subroutine */
int addrAeqB; /* Address of the A==B subroutine */
int addrAgtB; /* Address of the A>B subroutine */
int regLimitA; /* Limit register for select-A */
int regLimitB; /* Limit register for select-A */
int regPrev; /* A range of registers to hold previous output */
int savedLimit; /* Saved value of p->iLimit */
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 j1; /* 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 */
sqlite4 *db; /* Database connection */
ExprList *pOrderBy; /* The ORDER BY clause */
int nOrderBy; /* Number of terms in the ORDER BY clause */
int *aPermute; /* Mapping from ORDER BY terms to result set columns */
#ifndef SQLITE_OMIT_EXPLAIN
int iSub1; /* EQP id of left-hand query */
int iSub2; /* EQP id of right-hand query */
#endif
assert( p->pOrderBy!=0 );
assert( pKeyDup==0 ); /* "Managed" code needs this. Ticket #3382. */
db = pParse->db;
v = pParse->pVdbe;
assert( v!=0 ); /* Already thrown the error if VDBE alloc failed */
labelEnd = sqlite4VdbeMakeLabel(v);
labelCmpr = sqlite4VdbeMakeLabel(v);
/* Patch up the ORDER BY clause
*/
op = p->op;
pPrior = p->pPrior;
assert( pPrior->pOrderBy==0 );
pOrderBy = p->pOrderBy;
assert( pOrderBy );
nOrderBy = pOrderBy->nExpr;
/* For operators other than UNION ALL we have to make sure that
** the ORDER BY clause covers every term of the result set. Add
** terms to the ORDER BY clause as necessary.
*/
if( op!=TK_ALL ){
for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){
struct ExprList_item *pItem;
for(j=0, pItem=pOrderBy->a; j<nOrderBy; j++, pItem++){
assert( pItem->iOrderByCol>0 );
if( pItem->iOrderByCol==i ) break;
}
if( j==nOrderBy ){
Expr *pNew = sqlite4Expr(db, TK_INTEGER, 0);
if( pNew==0 ) return SQLITE_NOMEM;
pNew->flags |= EP_IntValue;
pNew->u.iValue = i;
pOrderBy = sqlite4ExprListAppend(pParse, pOrderBy, pNew);
pOrderBy->a[nOrderBy++].iOrderByCol = (u16)i;
}
}
}
/* Compute the comparison permutation and keyinfo that is used with
** the permutation used to determine if the next
** row of results comes from selectA or selectB. Also add explicit
** collations to the ORDER BY clause terms so that when the subqueries
** to the right and the left are evaluated, they use the correct
** collation.
*/
aPermute = sqlite4DbMallocRaw(db, sizeof(int)*nOrderBy);
if( aPermute ){
struct ExprList_item *pItem;
for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){
assert( pItem->iOrderByCol>0 && pItem->iOrderByCol<=p->pEList->nExpr );
aPermute[i] = pItem->iOrderByCol - 1;
}
pKeyMerge =
sqlite4DbMallocRaw(db, sizeof(*pKeyMerge)+nOrderBy*(sizeof(CollSeq*)+1));
if( pKeyMerge ){
pKeyMerge->aSortOrder = (u8*)&pKeyMerge->aColl[nOrderBy];
pKeyMerge->nField = (u16)nOrderBy;
pKeyMerge->enc = ENC(db);
for(i=0; i<nOrderBy; i++){
CollSeq *pColl;
Expr *pTerm = pOrderBy->a[i].pExpr;
if( pTerm->flags & EP_ExpCollate ){
pColl = pTerm->pColl;
}else{
pColl = multiSelectCollSeq(pParse, p, aPermute[i]);
pTerm->flags |= EP_ExpCollate;
pTerm->pColl = pColl;
}
pKeyMerge->aColl[i] = pColl;
pKeyMerge->aSortOrder[i] = pOrderBy->a[i].sortOrder;
}
}
}else{
pKeyMerge = 0;
}
/* Reattach the ORDER BY clause to the query.
*/
p->pOrderBy = pOrderBy;
pPrior->pOrderBy = sqlite4ExprListDup(pParse->db, pOrderBy, 0);
/* Allocate a range of temporary registers and the KeyInfo needed
** for the logic that removes duplicate result rows when the
** operator is UNION, EXCEPT, or INTERSECT (but not UNION ALL).
*/
if( op==TK_ALL ){
regPrev = 0;
}else{
int nExpr = p->pEList->nExpr;
assert( nOrderBy>=nExpr || db->mallocFailed );
regPrev = sqlite4GetTempRange(pParse, nExpr+1);
sqlite4VdbeAddOp2(v, OP_Integer, 0, regPrev);
pKeyDup = sqlite4DbMallocZero(db,
sizeof(*pKeyDup) + nExpr*(sizeof(CollSeq*)+1) );
if( pKeyDup ){
pKeyDup->aSortOrder = (u8*)&pKeyDup->aColl[nExpr];
pKeyDup->nField = (u16)nExpr;
pKeyDup->enc = ENC(db);
for(i=0; i<nExpr; i++){
pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i);
pKeyDup->aSortOrder[i] = 0;
}
}
}
/* Separate the left and the right query from one another
*/
p->pPrior = 0;
sqlite4ResolveOrderGroupBy(pParse, p, p->pOrderBy, "ORDER");
if( pPrior->pPrior==0 ){
sqlite4ResolveOrderGroupBy(pParse, pPrior, pPrior->pOrderBy, "ORDER");
}
/* Compute the limit registers */
computeLimitRegisters(pParse, p, labelEnd);
if( p->iLimit && op==TK_ALL ){
regLimitA = ++pParse->nMem;
regLimitB = ++pParse->nMem;
sqlite4VdbeAddOp2(v, OP_Copy, p->iOffset ? p->iOffset+1 : p->iLimit,
regLimitA);
sqlite4VdbeAddOp2(v, OP_Copy, regLimitA, regLimitB);
}else{
regLimitA = regLimitB = 0;
}
sqlite4ExprDelete(db, p->pLimit);
p->pLimit = 0;
sqlite4ExprDelete(db, p->pOffset);
p->pOffset = 0;
regAddrA = ++pParse->nMem;
regEofA = ++pParse->nMem;
regAddrB = ++pParse->nMem;
regEofB = ++pParse->nMem;
regOutA = ++pParse->nMem;
regOutB = ++pParse->nMem;
sqlite4SelectDestInit(&destA, SRT_Coroutine, regAddrA);
sqlite4SelectDestInit(&destB, SRT_Coroutine, regAddrB);
/* Jump past the various subroutines and coroutines to the main
** merge loop
*/
j1 = sqlite4VdbeAddOp0(v, OP_Goto);
addrSelectA = sqlite4VdbeCurrentAddr(v);
/* Generate a coroutine to evaluate the SELECT statement to the
** left of the compound operator - the "A" select.
*/
VdbeNoopComment((v, "Begin coroutine for left SELECT"));
pPrior->iLimit = regLimitA;
explainSetInteger(iSub1, pParse->iNextSelectId);
sqlite4Select(pParse, pPrior, &destA);
sqlite4VdbeAddOp2(v, OP_Integer, 1, regEofA);
sqlite4VdbeAddOp1(v, OP_Yield, regAddrA);
VdbeNoopComment((v, "End coroutine for left SELECT"));
/* Generate a coroutine to evaluate the SELECT statement on
** the right - the "B" select
*/
addrSelectB = sqlite4VdbeCurrentAddr(v);
VdbeNoopComment((v, "Begin coroutine for right SELECT"));
savedLimit = p->iLimit;
savedOffset = p->iOffset;
p->iLimit = regLimitB;
p->iOffset = 0;
explainSetInteger(iSub2, pParse->iNextSelectId);
sqlite4Select(pParse, p, &destB);
p->iLimit = savedLimit;
p->iOffset = savedOffset;
sqlite4VdbeAddOp2(v, OP_Integer, 1, regEofB);
sqlite4VdbeAddOp1(v, OP_Yield, regAddrB);
VdbeNoopComment((v, "End coroutine for right SELECT"));
/* Generate a subroutine that outputs the current row of the A
** select as the next output row of the compound select.
*/
VdbeNoopComment((v, "Output routine for A"));
addrOutA = generateOutputSubroutine(pParse,
p, &destA, pDest, regOutA,
regPrev, pKeyDup, P4_KEYINFO_HANDOFF, labelEnd);
/* Generate a subroutine that outputs the current row of the B
** select as the next output row of the compound select.
*/
if( op==TK_ALL || op==TK_UNION ){
VdbeNoopComment((v, "Output routine for B"));
addrOutB = generateOutputSubroutine(pParse,
p, &destB, pDest, regOutB,
regPrev, pKeyDup, P4_KEYINFO_STATIC, labelEnd);
}
/* Generate a subroutine to run when the results from select A
** are exhausted and only data in select B remains.
*/
VdbeNoopComment((v, "eof-A subroutine"));
if( op==TK_EXCEPT || op==TK_INTERSECT ){
addrEofA = sqlite4VdbeAddOp2(v, OP_Goto, 0, labelEnd);
}else{
addrEofA = sqlite4VdbeAddOp2(v, OP_If, regEofB, labelEnd);
sqlite4VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
sqlite4VdbeAddOp1(v, OP_Yield, regAddrB);
sqlite4VdbeAddOp2(v, OP_Goto, 0, addrEofA);
p->nSelectRow += pPrior->nSelectRow;
}
/* Generate a subroutine to run when the results from select B
** are exhausted and only data in select A remains.
*/
if( op==TK_INTERSECT ){
addrEofB = addrEofA;
if( p->nSelectRow > pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow;
}else{
VdbeNoopComment((v, "eof-B subroutine"));
addrEofB = sqlite4VdbeAddOp2(v, OP_If, regEofA, labelEnd);
sqlite4VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
sqlite4VdbeAddOp1(v, OP_Yield, regAddrA);
sqlite4VdbeAddOp2(v, OP_Goto, 0, addrEofB);
}
/* Generate code to handle the case of A<B
*/
VdbeNoopComment((v, "A-lt-B subroutine"));
addrAltB = sqlite4VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
sqlite4VdbeAddOp1(v, OP_Yield, regAddrA);
sqlite4VdbeAddOp2(v, OP_If, regEofA, addrEofA);
sqlite4VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
/* Generate code to handle the case of A==B
*/
if( op==TK_ALL ){
addrAeqB = addrAltB;
}else if( op==TK_INTERSECT ){
addrAeqB = addrAltB;
addrAltB++;
}else{
VdbeNoopComment((v, "A-eq-B subroutine"));
addrAeqB =
sqlite4VdbeAddOp1(v, OP_Yield, regAddrA);
sqlite4VdbeAddOp2(v, OP_If, regEofA, addrEofA);
sqlite4VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
}
/* Generate code to handle the case of A>B
*/
VdbeNoopComment((v, "A-gt-B subroutine"));
addrAgtB = sqlite4VdbeCurrentAddr(v);
if( op==TK_ALL || op==TK_UNION ){
sqlite4VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
}
sqlite4VdbeAddOp1(v, OP_Yield, regAddrB);
sqlite4VdbeAddOp2(v, OP_If, regEofB, addrEofB);
sqlite4VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
/* This code runs once to initialize everything.
*/
sqlite4VdbeJumpHere(v, j1);
sqlite4VdbeAddOp2(v, OP_Integer, 0, regEofA);
sqlite4VdbeAddOp2(v, OP_Integer, 0, regEofB);
sqlite4VdbeAddOp2(v, OP_Gosub, regAddrA, addrSelectA);
sqlite4VdbeAddOp2(v, OP_Gosub, regAddrB, addrSelectB);
sqlite4VdbeAddOp2(v, OP_If, regEofA, addrEofA);
sqlite4VdbeAddOp2(v, OP_If, regEofB, addrEofB);
/* Implement the main merge loop
*/
sqlite4VdbeResolveLabel(v, labelCmpr);
sqlite4VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY);
sqlite4VdbeAddOp4(v, OP_Compare, destA.iMem, destB.iMem, nOrderBy,
(char*)pKeyMerge, P4_KEYINFO_HANDOFF);
sqlite4VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
/* Release temporary registers
*/
if( regPrev ){
sqlite4ReleaseTempRange(pParse, regPrev, nOrderBy+1);
}
/* Jump to the this point in order to terminate the query.
*/
sqlite4VdbeResolveLabel(v, labelEnd);
/* Set the number of output columns
*/
if( pDest->eDest==SRT_Output ){
Select *pFirst = pPrior;
while( pFirst->pPrior ) pFirst = pFirst->pPrior;
generateColumnNames(pParse, 0, pFirst->pEList);
}
/* Reassembly the compound query so that it will be freed correctly
** by the calling function */
if( p->pPrior ){
sqlite4SelectDelete(db, p->pPrior);
}
p->pPrior = pPrior;
/*** TBD: Insert subroutine calls to close cursors on incomplete
**** subqueries ****/
explainComposite(pParse, p->op, iSub1, iSub2, 0);
return SQLITE_OK;
}
#endif
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
/* Forward Declarations */
static void substExprList(sqlite4*, ExprList*, int, ExprList*);
static void substSelect(sqlite4*, Select *, int, ExprList *);
/*
** Scan through the expression pExpr. Replace every reference to
** a column in table number iTable with a copy of the iColumn-th
** entry in pEList. (But leave references to the ROWID column
** unchanged.)
**
** This routine is part of the flattening procedure. A subquery
** whose result set is defined by pEList appears as entry in the
** FROM clause of a SELECT such that the VDBE cursor assigned to that
** FORM clause entry is iTable. This routine make the necessary
** changes to pExpr so that it refers directly to the source table
** of the subquery rather the result set of the subquery.
*/
static Expr *substExpr(
sqlite4 *db, /* Report malloc errors to this connection */
Expr *pExpr, /* Expr in which substitution occurs */
int iTable, /* Table to be substituted */
ExprList *pEList /* Substitute expressions */
){
if( pExpr==0 ) return 0;
if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){
if( pExpr->iColumn<0 ){
pExpr->op = TK_NULL;
}else{
Expr *pNew;
assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
assert( pExpr->pLeft==0 && pExpr->pRight==0 );
pNew = sqlite4ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0);
if( pNew && pExpr->pColl ){
pNew->pColl = pExpr->pColl;
}
sqlite4ExprDelete(db, pExpr);
pExpr = pNew;
}
}else{
pExpr->pLeft = substExpr(db, pExpr->pLeft, iTable, pEList);
pExpr->pRight = substExpr(db, pExpr->pRight, iTable, pEList);
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
substSelect(db, pExpr->x.pSelect, iTable, pEList);
}else{
substExprList(db, pExpr->x.pList, iTable, pEList);
}
}
return pExpr;
}
static void substExprList(
sqlite4 *db, /* Report malloc errors here */
ExprList *pList, /* List to scan and in which to make substitutes */
int iTable, /* Table to be substituted */
ExprList *pEList /* Substitute values */
){
int i;
if( pList==0 ) return;
for(i=0; i<pList->nExpr; i++){
pList->a[i].pExpr = substExpr(db, pList->a[i].pExpr, iTable, pEList);
}
}
static void substSelect(
sqlite4 *db, /* Report malloc errors here */
Select *p, /* SELECT statement in which to make substitutions */
int iTable, /* Table to be replaced */
ExprList *pEList /* Substitute values */
){
SrcList *pSrc;
struct SrcList_item *pItem;
int i;
if( !p ) return;
substExprList(db, p->pEList, iTable, pEList);
substExprList(db, p->pGroupBy, iTable, pEList);
substExprList(db, p->pOrderBy, iTable, pEList);
p->pHaving = substExpr(db, p->pHaving, iTable, pEList);
p->pWhere = substExpr(db, p->pWhere, iTable, pEList);
substSelect(db, p->pPrior, iTable, pEList);
pSrc = p->pSrc;
assert( pSrc ); /* Even for (SELECT 1) we have: pSrc!=0 but pSrc->nSrc==0 */
if( ALWAYS(pSrc) ){
for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
substSelect(db, pItem->pSelect, iTable, pEList);
}
}
}
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
/*
** This routine attempts to flatten subqueries as a performance optimization.
** This routine returns 1 if it makes changes and 0 if no flattening occurs.
**
** To understand the concept of flattening, consider the following
** query:
**
** SELECT a FROM (SELECT x+y AS a FROM t1 WHERE z<100) WHERE a>5
**
** The default way of implementing this query is to execute the
** subquery first and store the results in a temporary table, then
** run the outer query on that temporary table. This requires two
** passes over the data. Furthermore, because the temporary table
** has no indices, the WHERE clause on the outer query cannot be
** optimized.
**
** This routine attempts to rewrite queries such as the above into
** a single flat select, like this:
**
** SELECT x+y AS a FROM t1 WHERE z<100 AND a>5
**
** The code generated for this simpification gives the same result
** but only has to scan the data once. And because indices might
** exist on the table t1, a complete scan of the data might be
** avoided.
**
** Flattening is only attempted if all of the following are true:
**
** (1) The subquery and the outer query do not both use aggregates.
**
** (2) The subquery is not an aggregate or the outer query is not a join.
**
** (3) The subquery is not the right operand of a left outer join
** (Originally ticket #306. Strengthened by ticket #3300)
**
** (4) The subquery is not 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.
**
** (6) The subquery does not use aggregates or the outer query is not
** DISTINCT.
**
** (7) The subquery has a FROM clause. TODO: For subqueries without
** A FROM clause, consider adding a FROM close with the special
** table sqlite_once that consists of a single row containing a
** single NULL.
**
** (8) The subquery does not use LIMIT or the outer query is not a join.
**
** (9) The subquery does not use LIMIT or the outer query does not use
** aggregates.
**
** (10) The subquery does not use aggregates or the outer query does not
** use LIMIT.
**
** (11) The subquery and the outer query do 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 do not both use LIMIT.
**
** (14) The subquery does not use OFFSET.
**
** (15) The outer query is not part of a compound select or the
** subquery does not have a LIMIT clause.
** (See ticket #2339 and ticket [02a8e81d44]).
**
** (16) The outer query is not an aggregate or the subquery does
** not contain ORDER BY. (Ticket #2942) This used to not matter
** until we introduced the group_concat() function.
**
** (17) The sub-query is not a compound select, or it is a UNION ALL
** compound clause made up entirely of non-aggregate queries, and
** the parent query:
**
** * is not itself part of a compound select,
** * is not an aggregate or DISTINCT query, and
** * is not a join
**
** The parent and sub-query may contain WHERE clauses. Subject to
** rules (11), (13) and (14), they may also contain ORDER BY,
** LIMIT and OFFSET clauses. The subquery cannot use any compound
** operator other than UNION ALL because all the other compound
** operators have an implied DISTINCT which is disallowed by
** restriction (4).
**
** (18) If the sub-query is a compound select, then all terms of the
** ORDER by clause of the parent must be simple references to
** columns of the sub-query.
**
** (19) The subquery does not use LIMIT or the outer query does not
** have a WHERE clause.
**
** (20) If the sub-query is a compound select, then it must not use
** an ORDER BY clause. Ticket #3773. We could relax this constraint
** somewhat by saying that the terms of the ORDER BY clause must
** appear as unmodified result columns in the outer query. But we
** have other optimizations in mind to deal with that case.
**
** (21) The subquery does not use LIMIT or the outer query is not
** DISTINCT. (See ticket [752e1646fc]).
**
** In this routine, the "p" parameter is a pointer to the outer query.
** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query
** uses aggregates and subqueryIsAgg is true if the subquery uses aggregates.
**
** If flattening is not attempted, this routine is a no-op and returns 0.
** If flattening is attempted this routine returns 1.
**
** All of the expression analysis must occur on both the outer query and
** the subquery before this routine runs.
*/
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 subqueryIsAgg /* True if the subquery uses aggregate functions */
){
const char *zSavedAuthContext = pParse->zAuthContext;
Select *pParent;
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 */
ExprList *pList; /* The result set of the outer query */
int iParent; /* VDBE cursor number of the pSub result set temp table */
int i; /* Loop counter */
Expr *pWhere; /* The WHERE clause */
struct SrcList_item *pSubitem; /* The subquery */
sqlite4 *db = pParse->db;
/* Check to see if flattening is permitted. Return 0 if not.
*/
assert( p!=0 );
assert( p->pPrior==0 ); /* Unable to flatten compound queries */
if( db->flags & SQLITE_QueryFlattener ) return 0;
pSrc = p->pSrc;
assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
pSubitem = &pSrc->a[iFrom];
iParent = pSubitem->iCursor;
pSub = pSubitem->pSelect;
assert( pSub!=0 );
if( isAgg && subqueryIsAgg ) return 0; /* Restriction (1) */
if( subqueryIsAgg && pSrc->nSrc>1 ) return 0; /* Restriction (2) */
pSubSrc = pSub->pSrc;
assert( pSubSrc );
/* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
** not arbitrary expresssions, we allowed some combining of LIMIT and OFFSET
** because they could be computed at compile-time. But when LIMIT and OFFSET
** became arbitrary expressions, we were forced to add restrictions (13)
** and (14). */
if( pSub->pLimit && p->pLimit ) return 0; /* Restriction (13) */
if( pSub->pOffset ) return 0; /* Restriction (14) */
if( p->pRightmost && pSub->pLimit ){
return 0; /* Restriction (15) */
}
if( pSubSrc->nSrc==0 ) return 0; /* Restriction (7) */
if( pSub->selFlags & SF_Distinct ) return 0; /* Restriction (5) */
if( pSub->pLimit && (pSrc->nSrc>1 || isAgg) ){
return 0; /* Restrictions (8)(9) */
}
if( (p->selFlags & SF_Distinct)!=0 && subqueryIsAgg ){
return 0; /* Restriction (6) */
}
if( p->pOrderBy && pSub->pOrderBy ){
return 0; /* Restriction (11) */
}
if( isAgg && pSub->pOrderBy ) return 0; /* Restriction (16) */
if( pSub->pLimit && p->pWhere ) return 0; /* Restriction (19) */
if( pSub->pLimit && (p->selFlags & SF_Distinct)!=0 ){
return 0; /* Restriction (21) */
}
/* OBSOLETE COMMENT 1:
** Restriction 3: If the subquery is a join, make sure the subquery is
** not used as the right operand of an outer join. Examples of why this
** is not allowed:
**
** t1 LEFT OUTER JOIN (t2 JOIN t3)
**
** If we flatten the above, we would get
**
** (t1 LEFT OUTER JOIN t2) JOIN t3
**
** which is not at all the same thing.
**
** OBSOLETE COMMENT 2:
** Restriction 12: If the subquery is the right operand of a left outer
** join, make sure the subquery has no WHERE clause.
** An examples of why this is not allowed:
**
** t1 LEFT OUTER JOIN (SELECT * FROM t2 WHERE t2.x>0)
**
** If we flatten the above, we would get
**
** (t1 LEFT OUTER JOIN t2) WHERE t2.x>0
**
** But the t2.x>0 test will always fail on a NULL row of t2, which
** effectively converts the OUTER JOIN into an INNER JOIN.
**
** THIS OVERRIDES OBSOLETE COMMENTS 1 AND 2 ABOVE:
** Ticket #3300 shows that flattening the right term of a LEFT JOIN
** is fraught with danger. Best to avoid the whole thing. If the
** subquery is the right term of a LEFT JOIN, then do not flatten.
*/
if( (pSubitem->jointype & JT_OUTER)!=0 ){
return 0;
}
/* 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 */
}
if( isAgg || (p->selFlags & SF_Distinct)!=0 || pSrc->nSrc!=1 ){
return 0;
}
for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){
testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
assert( pSub->pSrc!=0 );
if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0
|| (pSub1->pPrior && pSub1->op!=TK_ALL)
|| pSub1->pSrc->nSrc<1
){
return 0;
}
testcase( pSub1->pSrc->nSrc>1 );
}
/* Restriction 18. */
if( p->pOrderBy ){
int ii;
for(ii=0; ii<p->pOrderBy->nExpr; ii++){
if( p->pOrderBy->a[ii].iOrderByCol==0 ) return 0;
}
}
}
/***** If we reach this point, flattening is permitted. *****/
/* Authorize the subquery */
pParse->zAuthContext = pSubitem->zName;
sqlite4AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0);
pParse->zAuthContext = zSavedAuthContext;
/* If the sub-query is a compound SELECT statement, then (by restrictions
** 17 and 18 above) it must be a UNION ALL and the parent query must
** be of the form:
**
** SELECT <expr-list> FROM (<sub-query>) <where-clause>
**
** followed by any ORDER BY, LIMIT and/or OFFSET clauses. This block
** creates N-1 copies of the parent query without any ORDER BY, LIMIT or
** OFFSET clauses and joins them to the left-hand-side of the original
** using UNION ALL operators. In this case N is the number of simple
** select statements in the compound sub-query.
**
** Example:
**
** SELECT a+1 FROM (
** SELECT x FROM tab
** UNION ALL
** SELECT y FROM tab
** UNION ALL
** SELECT abs(z*2) FROM tab2
** ) WHERE a!=5 ORDER BY 1
**
** Transformed into:
**
** SELECT x+1 FROM tab WHERE x+1!=5
** UNION ALL
** SELECT y+1 FROM tab WHERE y+1!=5
** UNION ALL
** SELECT abs(z*2)+1 FROM tab2 WHERE abs(z*2)+1!=5
** ORDER BY 1
**
** We call this the "compound-subquery flattening".
*/
for(pSub=pSub->pPrior; pSub; pSub=pSub->pPrior){
Select *pNew;
ExprList *pOrderBy = p->pOrderBy;
Expr *pLimit = p->pLimit;
Select *pPrior = p->pPrior;
p->pOrderBy = 0;
p->pSrc = 0;
p->pPrior = 0;
p->pLimit = 0;
pNew = sqlite4SelectDup(db, p, 0);
p->pLimit = pLimit;
p->pOrderBy = pOrderBy;
p->pSrc = pSrc;
p->op = TK_ALL;
p->pRightmost = 0;
if( pNew==0 ){
pNew = pPrior;
}else{
pNew->pPrior = pPrior;
pNew->pRightmost = 0;
}
p->pPrior = pNew;
if( db->mallocFailed ) return 1;
}
/* Begin flattening the iFrom-th entry of the FROM clause
** in the outer query.
*/
pSub = pSub1 = pSubitem->pSelect;
/* Delete the transient table structure associated with the
** subquery
*/
sqlite4DbFree(db, pSubitem->zDatabase);
sqlite4DbFree(db, pSubitem->zName);
sqlite4DbFree(db, pSubitem->zAlias);
pSubitem->zDatabase = 0;
pSubitem->zName = 0;
pSubitem->zAlias = 0;
pSubitem->pSelect = 0;
/* Defer deleting the Table object associated with the
** subquery until code generation is
** complete, since there may still exist Expr.pTab entries that
** refer to the subquery even after flattening. Ticket #3346.
**
** pSubitem->pTab is always non-NULL by test restrictions and tests above.
*/
if( ALWAYS(pSubitem->pTab!=0) ){
Table *pTabToDel = pSubitem->pTab;
if( pTabToDel->nRef==1 ){
Parse *pToplevel = sqlite4ParseToplevel(pParse);
pTabToDel->pNextZombie = pToplevel->pZombieTab;
pToplevel->pZombieTab = pTabToDel;
}else{
pTabToDel->nRef--;
}
pSubitem->pTab = 0;
}
/* The following loop runs once for each term in a compound-subquery
** flattening (as described above). If we are doing a different kind
** of flattening - a flattening other than a compound-subquery flattening -
** then this loop only runs once.
**
** This loop moves all of the FROM elements of the subquery into the
** the FROM clause of the outer query. Before doing this, remember
** the cursor number for the original outer query FROM element in
** iParent. The iParent cursor will never be used. Subsequent code
** will scan expressions looking for iParent references and replace
** those references with expressions that resolve to the subquery FROM
** elements we are now copying in.
*/
for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){
int nSubSrc;
u8 jointype = 0;
pSubSrc = pSub->pSrc; /* FROM clause of subquery */
nSubSrc = pSubSrc->nSrc; /* Number of terms in subquery FROM clause */
pSrc = pParent->pSrc; /* FROM clause of the outer query */
if( pSrc ){
assert( pParent==p ); /* First time through the loop */
jointype = pSubitem->jointype;
}else{
assert( pParent!=p ); /* 2nd and subsequent times through the loop */
pSrc = pParent->pSrc = sqlite4SrcListAppend(db, 0, 0, 0);
if( pSrc==0 ){
assert( db->mallocFailed );
break;
}
}
/* The subquery uses a single slot of the FROM clause of the outer
** query. If the subquery has more than one element in its FROM clause,
** then expand the outer query to make space for it to hold all elements
** of the subquery.
**
** Example:
**
** SELECT * FROM tabA, (SELECT * FROM sub1, sub2), tabB;
**
** 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 out query 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 ){
pParent->pSrc = pSrc = sqlite4SrcListEnlarge(db, pSrc, nSubSrc-1,iFrom+1);
if( db->mallocFailed ){
break;
}
}
/* Transfer the FROM clause terms from the subquery into the
** outer query.
*/
for(i=0; i<nSubSrc; i++){
sqlite4IdListDelete(db, pSrc->a[i+iFrom].pUsing);
pSrc->a[i+iFrom] = pSubSrc->a[i];
memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
}
pSrc->a[iFrom].jointype = jointype;
/* Now begin substituting subquery result set expressions for
** references to the iParent in the outer query.
**
** Example:
**
** SELECT a+5, b*10 FROM (SELECT x*3 AS a, y+10 AS b FROM t1) WHERE a>b;
** \ \_____________ subquery __________/ /
** \_____________________ outer query ______________________________/
**
** We look at every expression in the outer query and every place we see
** "a" we substitute "x*3" and every place we see "b" we substitute "y+10".
*/
pList = pParent->pEList;
for(i=0; i<pList->nExpr; i++){
if( pList->a[i].zName==0 ){
const char *zSpan = pList->a[i].zSpan;
if( ALWAYS(zSpan) ){
pList->a[i].zName = sqlite4DbStrDup(db, zSpan);
}
}
}
substExprList(db, pParent->pEList, iParent, pSub->pEList);
if( isAgg ){
substExprList(db, pParent->pGroupBy, iParent, pSub->pEList);
pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
}
if( pSub->pOrderBy ){
assert( pParent->pOrderBy==0 );
pParent->pOrderBy = pSub->pOrderBy;
pSub->pOrderBy = 0;
}else if( pParent->pOrderBy ){
substExprList(db, pParent->pOrderBy, iParent, pSub->pEList);
}
if( pSub->pWhere ){
pWhere = sqlite4ExprDup(db, pSub->pWhere, 0);
}else{
pWhere = 0;
}
if( subqueryIsAgg ){
assert( pParent->pHaving==0 );
pParent->pHaving = pParent->pWhere;
pParent->pWhere = pWhere;
pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
pParent->pHaving = sqlite4ExprAnd(db, pParent->pHaving,
sqlite4ExprDup(db, pSub->pHaving, 0));
assert( pParent->pGroupBy==0 );
pParent->pGroupBy = sqlite4ExprListDup(db, pSub->pGroupBy, 0);
}else{
pParent->pWhere = substExpr(db, pParent->pWhere, iParent, pSub->pEList);
pParent->pWhere = sqlite4ExprAnd(db, pParent->pWhere, pWhere);
}
/* The flattened query is distinct if either the inner or the
** outer query is distinct.
*/
pParent->selFlags |= pSub->selFlags & SF_Distinct;
/*
** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y;
**
** One is tempted to try to add a and b to combine the limits. But this
** does not work if either limit is negative.
*/
if( pSub->pLimit ){
pParent->pLimit = pSub->pLimit;
pSub->pLimit = 0;
}
}
/* Finially, delete what is left of the subquery and return
** success.
*/
sqlite4SelectDelete(db, pSub1);
return 1;
}
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
/*
** Analyze the SELECT statement passed as an argument to see if it
** is a min() or max() query. Return WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX if
** it is, or 0 otherwise. At present, a query is considered to be
** a min()/max() query if:
**
** 1. There is a single object in the FROM clause.
**
** 2. There is a single expression in the result set, and it is
** either min(x) or max(x), where x is a column reference.
*/
static u8 minMaxQuery(Select *p){
Expr *pExpr;
ExprList *pEList = p->pEList;
if( pEList->nExpr!=1 ) return WHERE_ORDERBY_NORMAL;
pExpr = pEList->a[0].pExpr;
if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
if( NEVER(ExprHasProperty(pExpr, EP_xIsSelect)) ) return 0;
pEList = pExpr->x.pList;
if( pEList==0 || pEList->nExpr!=1 ) return 0;
if( pEList->a[0].pExpr->op!=TK_AGG_COLUMN ) return WHERE_ORDERBY_NORMAL;
assert( !ExprHasProperty(pExpr, EP_IntValue) );
if( sqlite4StrICmp(pExpr->u.zToken,"min")==0 ){
return WHERE_ORDERBY_MIN;
}else if( sqlite4StrICmp(pExpr->u.zToken,"max")==0 ){
return WHERE_ORDERBY_MAX;
}
return WHERE_ORDERBY_NORMAL;
}
/*
** If the source-list item passed as an argument was augmented with an
** INDEXED BY clause, then try to locate the specified index. If there
** was such a clause and the named index cannot be found, return
** SQLITE_ERROR and leave an error in pParse. Otherwise, populate
** pFrom->pIndex and return SQLITE_OK.
*/
SQLITE_PRIVATE int sqlite4IndexedByLookup(Parse *pParse, struct SrcList_item *pFrom){
if( pFrom->pTab && pFrom->zIndex ){
Table *pTab = pFrom->pTab;
char *zIndex = pFrom->zIndex;
Index *pIdx;
for(pIdx=pTab->pIndex;
pIdx && sqlite4StrICmp(pIdx->zName, zIndex);
pIdx=pIdx->pNext
);
if( !pIdx ){
sqlite4ErrorMsg(pParse, "no such index: %s", zIndex, 0);
pParse->checkSchema = 1;
return SQLITE_ERROR;
}
pFrom->pIndex = pIdx;
}
return SQLITE_OK;
}
/*
** This routine is a Walker callback for "expanding" a SELECT statement.
** "Expanding" means to do the following:
**
** (1) Make sure VDBE cursor numbers have been assigned to every
** element of the FROM clause.
**
** (2) Fill in the pTabList->a[].pTab fields in the SrcList that
** defines FROM clause. When views appear in the FROM clause,
** fill pTabList->a[].pSelect with a copy of the SELECT statement
** that implements the view. A copy is made of the view's SELECT
** statement so that we can freely modify or delete that statement
** without worrying about messing up the presistent representation
** of the view.
**
** (3) Add terms to the WHERE clause to accomodate the NATURAL keyword
** on joins and the ON and USING clause of joins.
**
** (4) Scan the list of columns in the result set (pEList) looking
** for instances of the "*" operator or the TABLE.* operator.
** If found, expand each "*" to be every column in every table
** and TABLE.* to be every column in TABLE.
**
*/
static int selectExpander(Walker *pWalker, Select *p){
Parse *pParse = pWalker->pParse;
int i, j, k;
SrcList *pTabList;
ExprList *pEList;
struct SrcList_item *pFrom;
sqlite4 *db = pParse->db;
if( db->mallocFailed ){
return WRC_Abort;
}
if( NEVER(p->pSrc==0) || (p->selFlags & SF_Expanded)!=0 ){
return WRC_Prune;
}
p->selFlags |= SF_Expanded;
pTabList = p->pSrc;
pEList = p->pEList;
/* Make sure cursor numbers have been assigned to all entries in
** the FROM clause of the SELECT statement.
*/
sqlite4SrcListAssignCursors(pParse, pTabList);
/* Look up every table named in the FROM clause of the select. If
** an entry of the FROM clause is a subquery instead of a table or view,
** then create a transient table structure to describe the subquery.
*/
for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
Table *pTab;
if( pFrom->pTab!=0 ){
/* This statement has already been prepared. There is no need
** to go further. */
assert( i==0 );
return WRC_Prune;
}
if( pFrom->zName==0 ){
#ifndef SQLITE_OMIT_SUBQUERY
Select *pSel = pFrom->pSelect;
/* A sub-query in the FROM clause of a SELECT */
assert( pSel!=0 );
assert( pFrom->pTab==0 );
sqlite4WalkSelect(pWalker, pSel);
pFrom->pTab = pTab = sqlite4DbMallocZero(db, sizeof(Table));
if( pTab==0 ) return WRC_Abort;
pTab->nRef = 1;
pTab->zName = sqlite4MPrintf(db, "sqlite_subquery_%p_", (void*)pTab);
while( pSel->pPrior ){ pSel = pSel->pPrior; }
selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol);
pTab->nRowEst = 1000000;
pTab->tabFlags |= TF_Ephemeral;
#endif
}else{
/* An ordinary table or view name in the FROM clause */
assert( pFrom->pTab==0 );
pFrom->pTab = pTab =
sqlite4LocateTable(pParse,0,pFrom->zName,pFrom->zDatabase);
if( pTab==0 ) return WRC_Abort;
pTab->nRef++;
#if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
if( pTab->pSelect || IsVirtual(pTab) ){
/* We reach here if the named table is a really a view */
if( sqlite4ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
assert( pFrom->pSelect==0 );
pFrom->pSelect = sqlite4SelectDup(db, pTab->pSelect, 0);
sqlite4WalkSelect(pWalker, pFrom->pSelect);
}
#endif
}
/* Locate the index named by the INDEXED BY clause, if any. */
if( sqlite4IndexedByLookup(pParse, pFrom) ){
return WRC_Abort;
}
}
/* Process NATURAL keywords, and ON and USING clauses of joins.
*/
if( db->mallocFailed || sqliteProcessJoin(pParse, p) ){
return WRC_Abort;
}
/* 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_ALL operator for each "*" that it found in the column list.
** The following code just has to locate the TK_ALL 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++){
Expr *pE = pEList->a[k].pExpr;
if( pE->op==TK_ALL ) 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_ALL ) break;
}
if( k<pEList->nExpr ){
/*
** If we get here it means the result set contains one or more "*"
** operators that need to be expanded. Loop through each expression
** in the result set and expand them one by one.
*/
struct ExprList_item *a = pEList->a;
ExprList *pNew = 0;
for(k=0; k<pEList->nExpr; k++){
Expr *pE = a[k].pExpr;
assert( pE->op!=TK_DOT || pE->pRight!=0 );
if( pE->op!=TK_ALL && (pE->op!=TK_DOT || pE->pRight->op!=TK_ALL) ){
/* This particular expression does not need to be expanded.
*/
pNew = sqlite4ExprListAppend(pParse, pNew, a[k].pExpr);
if( pNew ){
pNew->a[pNew->nExpr-1].zName = a[k].zName;
pNew->a[pNew->nExpr-1].zSpan = a[k].zSpan;
a[k].zName = 0;
a[k].zSpan = 0;
}
a[k].pExpr = 0;
}else{
/* This expression is a "*" or a "TABLE.*" and needs to be
** expanded. */
int tableSeen = 0; /* Set to 1 when TABLE matches */
char *zTName; /* text of name of TABLE */
if( pE->op==TK_DOT ){
assert( pE->pLeft!=0 );
assert( !ExprHasProperty(pE->pLeft, EP_IntValue) );
zTName = pE->pLeft->u.zToken;
}else{
zTName = 0;
}
for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
Table *pTab = pFrom->pTab;
char *zTabName = pFrom->zAlias;
if( zTabName==0 ){
zTabName = pTab->zName;
}
if( db->mallocFailed ) break;
if( zTName && sqlite4StrICmp(zTName, zTabName)!=0 ){
continue;
}
tableSeen = 1;
for(j=0; j<pTab->nCol; j++){
Expr *pExpr, *pRight;
char *zName = pTab->aCol[j].zName;
char *zColname; /* The computed column name */
char *zToFree; /* Malloced string that needs to be freed */
Token sColname; /* Computed column name as a token */
/* If a column is marked as 'hidden' (currently only possible
** for virtual tables), do not include it in the expanded
** result-set list.
*/
if( IsHiddenColumn(&pTab->aCol[j]) ){
assert(IsVirtual(pTab));
continue;
}
if( i>0 && zTName==0 ){
if( (pFrom->jointype & JT_NATURAL)!=0
&& tableAndColumnIndex(pTabList, i, zName, 0, 0)
){
/* In a NATURAL join, omit the join columns from the
** table to the right of the join */
continue;
}
if( sqlite4IdListIndex(pFrom->pUsing, zName)>=0 ){
/* In a join with a USING clause, omit columns in the
** using clause from the table on the right. */
continue;
}
}
pRight = sqlite4Expr(db, TK_ID, zName);
zColname = zName;
zToFree = 0;
if( pTabList->nSrc>1 ){
Expr *pLeft;
pLeft = sqlite4Expr(db, TK_ID, zTabName);
pExpr = sqlite4PExpr(pParse, TK_DOT, pLeft, pRight, 0);
}else{
pExpr = pRight;
}
pNew = sqlite4ExprListAppend(pParse, pNew, pExpr);
sColname.z = zColname;
sColname.n = sqlite4Strlen30(zColname);
sqlite4ExprListSetName(pParse, pNew, &sColname, 0);
sqlite4DbFree(db, zToFree);
}
}
if( !tableSeen ){
if( zTName ){
sqlite4ErrorMsg(pParse, "no such table: %s", zTName);
}else{
sqlite4ErrorMsg(pParse, "no tables specified");
}
}
}
}
sqlite4ExprListDelete(db, pEList);
p->pEList = pNew;
}
#if SQLITE_MAX_COLUMN
if( p->pEList && p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
sqlite4ErrorMsg(pParse, "too many columns in result set");
}
#endif
return WRC_Continue;
}
/*
** No-op routine for the parse-tree walker.
**
** When this routine is the Walker.xExprCallback then expression trees
** are walked without any actions being taken at each node. Presumably,
** when this routine is used for Walker.xExprCallback then
** Walker.xSelectCallback is set to do something useful for every
** subquery in the parser tree.
*/
static int exprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
UNUSED_PARAMETER2(NotUsed, NotUsed2);
return WRC_Continue;
}
/*
** 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.
**
** Expanding a SELECT statement is the first step in processing a
** SELECT statement. The SELECT statement must be expanded before
** name resolution is performed.
**
** If anything goes wrong, an error message is written into pParse.
** The calling function can detect the problem by looking at pParse->nErr
** and/or pParse->db->mallocFailed.
*/
static void sqlite4SelectExpand(Parse *pParse, Select *pSelect){
Walker w;
w.xSelectCallback = selectExpander;
w.xExprCallback = exprWalkNoop;
w.pParse = pParse;
sqlite4WalkSelect(&w, pSelect);
}
#ifndef SQLITE_OMIT_SUBQUERY
/*
** This is a Walker.xSelectCallback callback for the sqlite4SelectTypeInfo()
** interface.
**
** For each FROM-clause subquery, add Column.zType and Column.zColl
** information to the Table structure that represents the result set
** of that subquery.
**
** The Table structure that represents the result set was constructed
** by selectExpander() but the type and collation information was omitted
** at that point because identifiers had not yet been resolved. This
** routine is called after identifier resolution.
*/
static int selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
Parse *pParse;
int i;
SrcList *pTabList;
struct SrcList_item *pFrom;
assert( p->selFlags & SF_Resolved );
if( (p->selFlags & SF_HasTypeInfo)==0 ){
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;
if( ALWAYS(pTab!=0) && (pTab->tabFlags & TF_Ephemeral)!=0 ){
/* A sub-query in the FROM clause of a SELECT */
Select *pSel = pFrom->pSelect;
assert( pSel );
while( pSel->pPrior ) pSel = pSel->pPrior;
selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSel);
}
}
}
return WRC_Continue;
}
#endif
/*
** This routine adds datatype and collating sequence information to
** the Table structures of all FROM-clause subqueries in a
** SELECT statement.
**
** Use this routine after name resolution.
*/
static void sqlite4SelectAddTypeInfo(Parse *pParse, Select *pSelect){
#ifndef SQLITE_OMIT_SUBQUERY
Walker w;
w.xSelectCallback = selectAddSubqueryTypeInfo;
w.xExprCallback = exprWalkNoop;
w.pParse = pParse;
sqlite4WalkSelect(&w, pSelect);
#endif
}
/*
** This routine sets of a SELECT statement for processing. The
** following is accomplished:
**
** * VDBE Cursor numbers are assigned to all FROM-clause terms.
** * Ephemeral Table objects are created for all FROM-clause subqueries.
** * ON and USING clauses are shifted into WHERE statements
** * Wildcards "*" and "TABLE.*" in result sets are expanded.
** * Identifiers in expression are matched to tables.
**
** This routine acts recursively on all subqueries within the SELECT.
*/
SQLITE_PRIVATE void sqlite4SelectPrep(
Parse *pParse, /* The parser context */
Select *p, /* The SELECT statement being coded. */
NameContext *pOuterNC /* Name context for container */
){
sqlite4 *db;
if( NEVER(p==0) ) return;
db = pParse->db;
if( p->selFlags & SF_HasTypeInfo ) return;
sqlite4SelectExpand(pParse, p);
if( pParse->nErr || db->mallocFailed ) return;
sqlite4ResolveSelectNames(pParse, p, pOuterNC);
if( pParse->nErr || db->mallocFailed ) return;
sqlite4SelectAddTypeInfo(pParse, p);
}
/*
** Reset the aggregate accumulator.
**
** The aggregate accumulator is a set of memory cells that hold
** intermediate results while calculating an aggregate. This
** routine simply stores NULLs in all of those memory cells.
*/
static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
Vdbe *v = pParse->pVdbe;
int i;
struct AggInfo_func *pFunc;
if( pAggInfo->nFunc+pAggInfo->nColumn==0 ){
return;
}
for(i=0; i<pAggInfo->nColumn; i++){
sqlite4VdbeAddOp2(v, OP_Null, 0, pAggInfo->aCol[i].iMem);
}
for(pFunc=pAggInfo->aFunc, i=0; i<pAggInfo->nFunc; i++, pFunc++){
sqlite4VdbeAddOp2(v, OP_Null, 0, pFunc->iMem);
if( pFunc->iDistinct>=0 ){
Expr *pE = pFunc->pExpr;
assert( !ExprHasProperty(pE, EP_xIsSelect) );
if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){
sqlite4ErrorMsg(pParse, "DISTINCT aggregates must have exactly one "
"argument");
pFunc->iDistinct = -1;
}else{
KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList, 0);
sqlite4VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0,
(char*)pKeyInfo, P4_KEYINFO_HANDOFF);
}
}
}
}
/*
** Invoke the OP_AggFinalize opcode for every aggregate function
** in the AggInfo structure.
*/
static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){
Vdbe *v = pParse->pVdbe;
int i;
struct AggInfo_func *pF;
for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
ExprList *pList = pF->pExpr->x.pList;
assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) );
sqlite4VdbeAddOp4(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0, 0,
(void*)pF->pFunc, P4_FUNCDEF);
}
}
/*
** Update the accumulator memory cells for an aggregate based on
** the current cursor position.
*/
static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
Vdbe *v = pParse->pVdbe;
int i;
struct AggInfo_func *pF;
struct AggInfo_col *pC;
pAggInfo->directMode = 1;
sqlite4ExprCacheClear(pParse);
for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
int nArg;
int addrNext = 0;
int regAgg;
ExprList *pList = pF->pExpr->x.pList;
assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) );
if( pList ){
nArg = pList->nExpr;
regAgg = sqlite4GetTempRange(pParse, nArg);
sqlite4ExprCodeExprList(pParse, pList, regAgg, 1);
}else{
nArg = 0;
regAgg = 0;
}
if( pF->iDistinct>=0 ){
addrNext = sqlite4VdbeMakeLabel(v);
assert( nArg==1 );
codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg);
}
if( pF->pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
CollSeq *pColl = 0;
struct ExprList_item *pItem;
int j;
assert( pList!=0 ); /* pList!=0 if pF->pFunc has NEEDCOLL */
for(j=0, pItem=pList->a; !pColl && j<nArg; j++, pItem++){
pColl = sqlite4ExprCollSeq(pParse, pItem->pExpr);
}
if( !pColl ){
pColl = pParse->db->pDfltColl;
}
sqlite4VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
}
sqlite4VdbeAddOp4(v, OP_AggStep, 0, regAgg, pF->iMem,
(void*)pF->pFunc, P4_FUNCDEF);
sqlite4VdbeChangeP5(v, (u8)nArg);
sqlite4ExprCacheAffinityChange(pParse, regAgg, nArg);
sqlite4ReleaseTempRange(pParse, regAgg, nArg);
if( addrNext ){
sqlite4VdbeResolveLabel(v, addrNext);
sqlite4ExprCacheClear(pParse);
}
}
/* Before populating the accumulator registers, clear the column cache.
** Otherwise, if any of the required column values are already present
** in registers, sqlite4ExprCode() may use OP_SCopy to copy the value
** to pC->iMem. But by the time the value is used, the original register
** may have been used, invalidating the underlying buffer holding the
** text or blob value. See ticket [883034dcb5].
**
** Another solution would be to change the OP_SCopy used to copy cached
** values to an OP_Copy.
*/
sqlite4ExprCacheClear(pParse);
for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
sqlite4ExprCode(pParse, pC->pExpr, pC->iMem);
}
pAggInfo->directMode = 0;
sqlite4ExprCacheClear(pParse);
}
/*
** Generate code for the SELECT statement given in the p argument.
**
** The results are distributed in various ways depending on the
** contents of the SelectDest structure pointed to by argument pDest
** as follows:
**
** pDest->eDest Result
** ------------ -------------------------------------------
** SRT_Output Generate a row of output (using the OP_ResultRow
** opcode) for each row in the result set.
**
** SRT_Mem Only valid if the result is a single column.
** Store the first column of the first result row
** in register pDest->iParm then abandon the rest
** 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->iParm.
** Apply the affinity pDest->affinity before storing
** results. Used to implement "IN (SELECT ...)".
**
** SRT_Union Store results as a key in a temporary table pDest->iParm.
**
** SRT_Except Remove results from the temporary table pDest->iParm.
**
** SRT_Table Store results in temporary table pDest->iParm.
** This is like SRT_EphemTab except that the table
** is assumed to already be open.
**
** SRT_EphemTab Create an temporary table pDest->iParm and store
** the result there. The cursor is left open after
** returning. This is like SRT_Table except that
** this destination uses OP_OpenEphemeral to create
** the table first.
**
** SRT_Coroutine Generate a co-routine that returns a new row of
** results each time it is invoked. The entry point
** of the co-routine is stored in register pDest->iParm.
**
** SRT_Exists Store a 1 in memory cell pDest->iParm if the result
** set is not empty.
**
** SRT_Discard Throw the results away. This is used by SELECT
** statements within triggers whose only purpose is
** the side-effects of functions.
**
** This routine returns the number of errors. If any errors are
** encountered, then an appropriate error message is left in
** pParse->zErrMsg.
**
** This routine does NOT free the Select structure passed in. The
** calling function needs to do that.
*/
SQLITE_PRIVATE int sqlite4Select(
Parse *pParse, /* The parser context */
Select *p, /* The SELECT statement being coded. */
SelectDest *pDest /* What to do with the query results */
){
int i, j; /* Loop counters */
WhereInfo *pWInfo; /* Return from sqlite4WhereBegin() */
Vdbe *v; /* The virtual machine under construction */
int isAgg; /* True for select lists like "count(*)" */
ExprList *pEList; /* List of columns to extract. */
SrcList *pTabList; /* List of tables to select from */
Expr *pWhere; /* The WHERE clause. May be NULL */
ExprList *pOrderBy; /* The ORDER BY clause. May be NULL */
ExprList *pGroupBy; /* The GROUP BY clause. May be NULL */
Expr *pHaving; /* The HAVING clause. May be NULL */
int isDistinct; /* True if the DISTINCT keyword is present */
int distinct; /* Table to use for the distinct set */
int rc = 1; /* Value to return from this function */
int addrSortIndex; /* Address of an OP_OpenEphemeral instruction */
int addrDistinctIndex; /* Address of an OP_OpenEphemeral instruction */
AggInfo sAggInfo; /* Information used by aggregate queries */
int iEnd; /* Address of the end of the query */
sqlite4 *db; /* The database connection */
#ifndef SQLITE_OMIT_EXPLAIN
int iRestoreSelectId = pParse->iSelectId;
pParse->iSelectId = pParse->iNextSelectId++;
#endif
memset(&sAggInfo, 0, sizeof(sAggInfo));
db = pParse->db;
if( p==0 || db->mallocFailed || pParse->nErr ){
return 1;
}
if( sqlite4AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
if( IgnorableOrderby(pDest) ){
assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union ||
pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard);
/* If ORDER BY makes no difference in the output then neither does
** DISTINCT so it can be removed too. */
sqlite4ExprListDelete(db, p->pOrderBy);
p->pOrderBy = 0;
p->selFlags &= ~SF_Distinct;
}
sqlite4SelectPrep(pParse, p, 0);
pOrderBy = p->pOrderBy;
pTabList = p->pSrc;
pEList = p->pEList;
if( pParse->nErr || db->mallocFailed ){
goto select_end;
}
isAgg = (p->selFlags & SF_Aggregate)!=0;
assert( pEList!=0 );
/* Begin generating code.
*/
v = sqlite4GetVdbe(pParse);
if( v==0 ) goto select_end;
/* If writing to memory or generating a set
** only a single column may be output.
*/
#ifndef SQLITE_OMIT_SUBQUERY
if( checkForMultiColumnSelectError(pParse, pDest, pEList->nExpr) ){
goto select_end;
}
#endif
/* Generate code for all sub-queries in the FROM clause
*/
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
for(i=0; !p->pPrior && i<pTabList->nSrc; i++){
struct SrcList_item *pItem = &pTabList->a[i];
SelectDest dest;
Select *pSub = pItem->pSelect;
int isAggSub;
if( pSub==0 ) continue;
if( pItem->addrFillSub ){
sqlite4VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
continue;
}
/* Increment Parse.nHeight by the height of the largest expression
** tree refered to by this, the parent select. The child select
** may contain expression trees of at most
** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit
** more conservative than necessary, but much easier than enforcing
** an exact limit.
*/
pParse->nHeight += sqlite4SelectExprHeight(p);
isAggSub = (pSub->selFlags & SF_Aggregate)!=0;
if( flattenSubquery(pParse, p, i, isAgg, isAggSub) ){
/* This subquery can be absorbed into its parent. */
if( isAggSub ){
isAgg = 1;
p->selFlags |= SF_Aggregate;
}
i = -1;
}else{
/* Generate a subroutine that will fill an ephemeral table with
** the content of this subquery. pItem->addrFillSub will point
** to the address of the generated subroutine. pItem->regReturn
** is a register allocated to hold the subroutine return address
*/
int topAddr;
int onceAddr = 0;
int retAddr;
assert( pItem->addrFillSub==0 );
pItem->regReturn = ++pParse->nMem;
topAddr = sqlite4VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn);
pItem->addrFillSub = topAddr+1;
VdbeNoopComment((v, "materialize %s", pItem->pTab->zName));
if( pItem->isCorrelated==0 ){
/* If the subquery is no correlated and if we are not inside of
** a trigger, then we only need to compute the value of the subquery
** once. */
onceAddr = sqlite4CodeOnce(pParse);
}
sqlite4SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
sqlite4Select(pParse, pSub, &dest);
pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow;
if( onceAddr ) sqlite4VdbeJumpHere(v, onceAddr);
retAddr = sqlite4VdbeAddOp1(v, OP_Return, pItem->regReturn);
VdbeComment((v, "end %s", pItem->pTab->zName));
sqlite4VdbeChangeP1(v, topAddr, retAddr);
sqlite4ClearTempRegCache(pParse);
}
if( /*pParse->nErr ||*/ db->mallocFailed ){
goto select_end;
}
pParse->nHeight -= sqlite4SelectExprHeight(p);
pTabList = p->pSrc;
if( !IgnorableOrderby(pDest) ){
pOrderBy = p->pOrderBy;
}
}
pEList = p->pEList;
#endif
pWhere = p->pWhere;
pGroupBy = p->pGroupBy;
pHaving = p->pHaving;
isDistinct = (p->selFlags & SF_Distinct)!=0;
#ifndef SQLITE_OMIT_COMPOUND_SELECT
/* If there is are a sequence of queries, do the earlier ones first.
*/
if( p->pPrior ){
if( p->pRightmost==0 ){
Select *pLoop, *pRight = 0;
int cnt = 0;
int mxSelect;
for(pLoop=p; pLoop; pLoop=pLoop->pPrior, cnt++){
pLoop->pRightmost = p;
pLoop->pNext = pRight;
pRight = pLoop;
}
mxSelect = db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT];
if( mxSelect && cnt>mxSelect ){
sqlite4ErrorMsg(pParse, "too many terms in compound SELECT");
goto select_end;
}
}
rc = multiSelect(pParse, p, pDest);
explainSetInteger(pParse->iSelectId, iRestoreSelectId);
return rc;
}
#endif
/* If there is both a GROUP BY and an ORDER BY clause and they are
** identical, then disable the ORDER BY clause since the GROUP BY
** will cause elements to come out in the correct order. This is
** an optimization - the correct answer should result regardless.
** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER
** to disable this optimization for testing purposes.
*/
if( sqlite4ExprListCompare(p->pGroupBy, pOrderBy)==0
&& (db->flags & SQLITE_GroupByOrder)==0 ){
pOrderBy = 0;
}
/* If the query is DISTINCT with an ORDER BY but is not an aggregate, and
** if the select-list is the same as the ORDER BY list, then this query
** can be rewritten as a GROUP BY. In other words, this:
**
** SELECT DISTINCT xyz FROM ... ORDER BY xyz
**
** is transformed to:
**
** SELECT xyz FROM ... GROUP BY xyz
**
** The second form is preferred as a single index (or temp-table) may be
** used for both the ORDER BY and DISTINCT processing. As originally
** written the query must use a temp-table for at least one of the ORDER
** BY and DISTINCT, and an index or separate temp-table for the other.
*/
if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct
&& sqlite4ExprListCompare(pOrderBy, p->pEList)==0
){
p->selFlags &= ~SF_Distinct;
p->pGroupBy = sqlite4ExprListDup(db, p->pEList, 0);
pGroupBy = p->pGroupBy;
pOrderBy = 0;
}
/* If there is an ORDER BY clause, then this sorting
** index might end up being unused if the data can be
** extracted in pre-sorted order. If that is the case, then the
** OP_OpenEphemeral instruction will be changed to an OP_Noop once
** we figure out that the sorting index is not needed. The addrSortIndex
** variable is used to facilitate that change.
*/
if( pOrderBy ){
KeyInfo *pKeyInfo;
pKeyInfo = keyInfoFromExprList(pParse, pOrderBy, 1);
if( pKeyInfo ) pKeyInfo->nData = pEList->nExpr;
pOrderBy->iECursor = pParse->nTab++;
p->addrOpenEphm[2] = addrSortIndex =
sqlite4VdbeAddOp4(v, OP_OpenEphemeral,
pOrderBy->iECursor, pOrderBy->nExpr+2, 0,
(char*)pKeyInfo, P4_KEYINFO_HANDOFF);
}else{
addrSortIndex = -1;
}
/* If the output is destined for a temporary table, open that table.
*/
if( pDest->eDest==SRT_EphemTab ){
sqlite4VdbeAddOp2(v, OP_OpenEphemeral, pDest->iParm, pEList->nExpr);
}
/* Set the limiter.
*/
iEnd = sqlite4VdbeMakeLabel(v);
p->nSelectRow = (double)LARGEST_INT64;
computeLimitRegisters(pParse, p, iEnd);
if( p->iLimit==0 && addrSortIndex>=0 ){
sqlite4VdbeGetOp(v, addrSortIndex)->opcode = OP_SorterOpen;
p->selFlags |= SF_UseSorter;
}
/* Open a virtual index to use for the distinct set.
*/
if( p->selFlags & SF_Distinct ){
KeyInfo *pKeyInfo;
distinct = pParse->nTab++;
pKeyInfo = keyInfoFromExprList(pParse, p->pEList, 0);
addrDistinctIndex = sqlite4VdbeAddOp4(v, OP_OpenEphemeral, distinct, 0, 0,
(char*)pKeyInfo, P4_KEYINFO_HANDOFF);
}else{
distinct = addrDistinctIndex = -1;
}
/* Aggregate and non-aggregate queries are handled differently */
if( !isAgg && pGroupBy==0 ){
ExprList *pDist = (isDistinct ? p->pEList : 0);
/* Begin the database scan. */
pWInfo = sqlite4WhereBegin(pParse, pTabList, pWhere, &pOrderBy, pDist, 0);
if( pWInfo==0 ) goto select_end;
if( pWInfo->nRowOut < p->nSelectRow ) p->nSelectRow = pWInfo->nRowOut;
/* If sorting index that was created by a prior OP_OpenEphemeral
** instruction ended up not being needed, then change the OP_OpenEphemeral
** into an OP_Noop.
*/
if( addrSortIndex>=0 && pOrderBy==0 ){
sqlite4VdbeChangeToNoop(v, addrSortIndex);
p->addrOpenEphm[2] = -1;
}
if( pWInfo->eDistinct ){
VdbeOp *pOp; /* No longer required OpenEphemeral instr. */
assert( addrDistinctIndex>=0 );
pOp = sqlite4VdbeGetOp(v, addrDistinctIndex);
assert( isDistinct );
assert( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED
|| pWInfo->eDistinct==WHERE_DISTINCT_UNIQUE
);
distinct = -1;
if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED ){
int iJump;
int iExpr;
int iFlag = ++pParse->nMem;
int iBase = pParse->nMem+1;
int iBase2 = iBase + pEList->nExpr;
pParse->nMem += (pEList->nExpr*2);
/* Change the OP_OpenEphemeral coded earlier to an OP_Integer. The
** OP_Integer initializes the "first row" flag. */
pOp->opcode = OP_Integer;
pOp->p1 = 1;
pOp->p2 = iFlag;
sqlite4ExprCodeExprList(pParse, pEList, iBase, 1);
iJump = sqlite4VdbeCurrentAddr(v) + 1 + pEList->nExpr + 1 + 1;
sqlite4VdbeAddOp2(v, OP_If, iFlag, iJump-1);
for(iExpr=0; iExpr<pEList->nExpr; iExpr++){
CollSeq *pColl = sqlite4ExprCollSeq(pParse, pEList->a[iExpr].pExpr);
sqlite4VdbeAddOp3(v, OP_Ne, iBase+iExpr, iJump, iBase2+iExpr);
sqlite4VdbeChangeP4(v, -1, (const char *)pColl, P4_COLLSEQ);
sqlite4VdbeChangeP5(v, SQLITE_NULLEQ);
}
sqlite4VdbeAddOp2(v, OP_Goto, 0, pWInfo->iContinue);
sqlite4VdbeAddOp2(v, OP_Integer, 0, iFlag);
assert( sqlite4VdbeCurrentAddr(v)==iJump );
sqlite4VdbeAddOp3(v, OP_Move, iBase, iBase2, pEList->nExpr);
}else{
pOp->opcode = OP_Noop;
}
}
/* Use the standard inner loop. */
selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, pDest,
pWInfo->iContinue, pWInfo->iBreak);
/* End the database scan loop.
*/
sqlite4WhereEnd(pWInfo);
}else{
/* This is the processing for aggregate queries */
NameContext sNC; /* Name context for processing aggregate information */
int iAMem; /* First Mem address for storing current GROUP BY */
int iBMem; /* First Mem address for previous GROUP BY */
int iUseFlag; /* Mem address holding flag indicating that at least
** one row of the input to the aggregator has been
** processed */
int iAbortFlag; /* Mem address which causes query abort if positive */
int groupBySort; /* Rows come from source in GROUP BY order */
int addrEnd; /* End of processing for this SELECT */
/* Remove any and all aliases between the result set and the
** GROUP BY clause.
*/
if( pGroupBy ){
int k; /* Loop counter */
struct ExprList_item *pItem; /* For looping over expression in a list */
for(k=p->pEList->nExpr, pItem=p->pEList->a; k>0; k--, pItem++){
pItem->iAlias = 0;
}
for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){
pItem->iAlias = 0;
}
if( p->nSelectRow>(double)100 ) p->nSelectRow = (double)100;
}else{
p->nSelectRow = (double)1;
}
/* Create a label to jump to when we want to abort the query */
addrEnd = sqlite4VdbeMakeLabel(v);
/* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in
** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the
** SELECT statement.
*/
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = pParse;
sNC.pSrcList = pTabList;
sNC.pAggInfo = &sAggInfo;
sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr+1 : 0;
sAggInfo.pGroupBy = pGroupBy;
sqlite4ExprAnalyzeAggList(&sNC, pEList);
sqlite4ExprAnalyzeAggList(&sNC, pOrderBy);
if( pHaving ){
sqlite4ExprAnalyzeAggregates(&sNC, pHaving);
}
sAggInfo.nAccumulator = sAggInfo.nColumn;
for(i=0; i<sAggInfo.nFunc; i++){
assert( !ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_xIsSelect) );
sqlite4ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->x.pList);
}
if( db->mallocFailed ) goto select_end;
/* 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 j1; /* 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 */
int addrTopOfLoop; /* Top of the input loop */
int addrSortingIdx; /* The OP_OpenEphemeral for the sorting index */
int addrReset; /* Subroutine for resetting the accumulator */
int regReset; /* Return address register for reset subroutine */
/* If there is a GROUP BY clause we might need a sorting index to
** implement it. Allocate that sorting index now. If it turns out
** that we do not need it after all, the OP_SorterOpen instruction
** will be converted into a Noop.
*/
sAggInfo.sortingIdx = pParse->nTab++;
pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0);
addrSortingIdx = sqlite4VdbeAddOp4(v, OP_SorterOpen,
sAggInfo.sortingIdx, sAggInfo.nSortingColumn,
0, (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
/* Initialize memory locations used by GROUP BY aggregate processing
*/
iUseFlag = ++pParse->nMem;
iAbortFlag = ++pParse->nMem;
regOutputRow = ++pParse->nMem;
addrOutputRow = sqlite4VdbeMakeLabel(v);
regReset = ++pParse->nMem;
addrReset = sqlite4VdbeMakeLabel(v);
iAMem = pParse->nMem + 1;
pParse->nMem += pGroupBy->nExpr;
iBMem = pParse->nMem + 1;
pParse->nMem += pGroupBy->nExpr;
sqlite4VdbeAddOp2(v, OP_Integer, 0, iAbortFlag);
VdbeComment((v, "clear abort flag"));
sqlite4VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
VdbeComment((v, "indicate accumulator empty"));
sqlite4VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1);
/* Begin a loop that will extract all source rows in GROUP BY order.
** This might involve two separate loops with an OP_Sort in between, or
** it might be a single loop that uses an index to extract information
** in the right order to begin with.
*/
sqlite4VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
pWInfo = sqlite4WhereBegin(pParse, pTabList, pWhere, &pGroupBy, 0, 0);
if( pWInfo==0 ) goto select_end;
if( pGroupBy==0 ){
/* The optimizer is able to deliver rows in group by order so
** we do not have to sort. The OP_OpenEphemeral table will be
** cancelled later because we still need to use the pKeyInfo
*/
pGroupBy = p->pGroupBy;
groupBySort = 0;
/* Evaluate the current GROUP BY terms and store in b0, b1, b2...
** (b0 is memory location iBMem+0, b1 is iBMem+1, and so forth)
** Then compare the current GROUP BY terms against the GROUP BY terms
** from the previous row currently stored in a0, a1, a2...
*/
sAggInfo.directMode = 1;
addrTopOfLoop = sqlite4VdbeCurrentAddr(v);
sqlite4ExprCacheClear(pParse);
for(j=0; j<pGroupBy->nExpr; j++){
sqlite4ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
}
sqlite4VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr,
(char*)pKeyInfo, P4_KEYINFO);
j1 = sqlite4VdbeCurrentAddr(v);
sqlite4VdbeAddOp3(v, OP_Jump, j1+1, 0, j1+1);
}else{
/* Rows are coming out in undetermined order. We have to push
** each row into a sorting index, terminate the first loop,
** then loop over the sorting index in order to get the output
** in sorted order */
int regBase;
int nCol = sAggInfo.nColumn;
int nGroup = pGroupBy->nExpr;
int regKey = ++pParse->nMem;
int regRecord = 0;
groupBySort = 1;
explainTempTable(pParse,
isDistinct && !(p->selFlags&SF_Distinct)?"DISTINCT":"GROUP BY");
/* Encode the key for the sorting index. The key consists of each
** of the expressions in the GROUP BY list followed by a sequence
** number (to ensure each key is unique - the point of this is just
** to sort the rows, not to eliminate duplicates). */
sqlite4ExprCacheClear(pParse);
regBase = sqlite4GetTempRange(pParse, nGroup);
sqlite4ExprCodeExprList(pParse, pGroupBy, regBase, 0);
sqlite4VdbeAddOp3(v, OP_MakeIdxKey, sAggInfo.sortingIdx,regBase,regKey);
sqlite4VdbeChangeP5(v, 1);
sqlite4ReleaseTempRange(pParse, regBase, nGroup);
/* Encode the record for the sorting index. The record contains all
** required column values from the elements of the FROM clause.
** If no column values are required, insert a NULL into the sorting
** index instead of a record. No column values are required for
** queries such as "SELECT count(*) FROM ..." */
if( nCol>0 ){
regRecord = ++pParse->nMem;
regBase = sqlite4GetTempRange(pParse, nCol);
for(i=0; i<nCol; i++){
struct AggInfo_col *pCol = &sAggInfo.aCol[i];
int regDest = i + regBase;
int regValue = sqlite4ExprCodeGetColumn(
pParse, pCol->pTab, pCol->iColumn, pCol->iTable, regDest
);
if( regDest!=regValue ){
sqlite4VdbeAddOp2(v, OP_SCopy, regValue, regDest);
}
}
sqlite4VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord);
sqlite4ReleaseTempRange(pParse, regBase, nCol);
}
/* Insert the key/value into the sorting index and end the loop
** generated by where.c code. */
sqlite4VdbeAddOp3(
v, OP_SorterInsert, sAggInfo.sortingIdx, regRecord, regKey
);
sqlite4WhereEnd(pWInfo);
sqlite4VdbeAddOp2(v, OP_Null, 0, regKey);
sqlite4VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd);
VdbeComment((v, "GROUP BY sort"));
sAggInfo.useSortingIdx = 1;
sqlite4ExprCacheClear(pParse);
j1 = sqlite4VdbeAddOp3(v, OP_GrpCompare, sAggInfo.sortingIdx, 0,regKey);
addrTopOfLoop = j1;
}
/* Generate code that runs whenever the GROUP BY changes.
** Changes in the GROUP BY are detected by the previous code
** block. If there were no changes, this block is skipped.
**
** This code copies current group by terms in b0,b1,b2,...
** over to a0,a1,a2. It then calls the output subroutine
** and resets the aggregate accumulator registers in preparation
** for the next GROUP BY batch.
*/
if( groupBySort==0 ){
sqlite4ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr);
}
sqlite4VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow);
VdbeComment((v, "output one row"));
sqlite4VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd);
VdbeComment((v, "check abort flag"));
sqlite4VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
VdbeComment((v, "reset accumulator"));
/* Update the aggregate accumulators based on the content of
** the current row
*/
sqlite4VdbeJumpHere(v, j1);
updateAccumulator(pParse, &sAggInfo);
sqlite4VdbeAddOp2(v, OP_Integer, 1, iUseFlag);
VdbeComment((v, "indicate data in accumulator"));
/* End of the loop
*/
if( groupBySort ){
sqlite4VdbeAddOp2(v, OP_SorterNext, sAggInfo.sortingIdx, addrTopOfLoop);
}else{
sqlite4WhereEnd(pWInfo);
sqlite4VdbeChangeToNoop(v, addrSortingIdx);
}
/* Output the final row of result
*/
sqlite4VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow);
VdbeComment((v, "output final row"));
/* Jump over the subroutines
*/
sqlite4VdbeAddOp2(v, OP_Goto, 0, addrEnd);
/* Generate a subroutine that outputs a single row of the result
** set. This subroutine first looks at the iUseFlag. If iUseFlag
** is less than or equal to zero, the subroutine is a no-op. If
** the processing calls for the query to abort, this subroutine
** increments the iAbortFlag memory location before returning in
** order to signal the caller to abort.
*/
addrSetAbort = sqlite4VdbeCurrentAddr(v);
sqlite4VdbeAddOp2(v, OP_Integer, 1, iAbortFlag);
VdbeComment((v, "set abort flag"));
sqlite4VdbeAddOp1(v, OP_Return, regOutputRow);
sqlite4VdbeResolveLabel(v, addrOutputRow);
addrOutputRow = sqlite4VdbeCurrentAddr(v);
sqlite4VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2);
VdbeComment((v, "Groupby result generator entry point"));
sqlite4VdbeAddOp1(v, OP_Return, regOutputRow);
finalizeAggFunctions(pParse, &sAggInfo);
sqlite4ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy,
distinct, pDest,
addrOutputRow+1, addrSetAbort);
sqlite4VdbeAddOp1(v, OP_Return, regOutputRow);
VdbeComment((v, "end groupby result generator"));
/* Generate a subroutine that will reset the group-by accumulator
*/
sqlite4VdbeResolveLabel(v, addrReset);
resetAccumulator(pParse, &sAggInfo);
sqlite4VdbeAddOp1(v, OP_Return, regReset);
} /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
else {
ExprList *pDel = 0;
{
/* Check if the query is of one of the following forms:
**
** SELECT min(x) FROM ...
** SELECT max(x) FROM ...
**
** If it is, then ask the code in where.c to attempt to sort results
** as if there was an "ORDER ON x" or "ORDER ON x DESC" clause.
** If where.c is able to produce results sorted in this order, then
** add vdbe code to break out of the processing loop after the
** first iteration (since the first iteration of the loop is
** guaranteed to operate on the row with the minimum or maximum
** value of x, the only row required).
**
** A special flag must be passed to sqlite4WhereBegin() to slightly
** modify behaviour as follows:
**
** + If the query is a "SELECT min(x)", then the loop coded by
** where.c should not iterate over any values with a NULL value
** for x.
**
** + The optimizer code in where.c (the thing that decides which
** index or indices to use) should place a different priority on
** satisfying the 'ORDER BY' clause than it does in other cases.
** Refer to code and comments in where.c for details.
*/
ExprList *pMinMax = 0;
u8 flag = minMaxQuery(p);
if( flag ){
assert( !ExprHasProperty(p->pEList->a[0].pExpr, EP_xIsSelect) );
pMinMax = sqlite4ExprListDup(db, p->pEList->a[0].pExpr->x.pList,0);
pDel = pMinMax;
if( pMinMax && !db->mallocFailed ){
pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0;
pMinMax->a[0].pExpr->op = TK_COLUMN;
}
}
/* This case runs if the aggregate has no GROUP BY clause. The
** processing is much simpler since there is only a single row
** of output.
*/
resetAccumulator(pParse, &sAggInfo);
pWInfo = sqlite4WhereBegin(pParse, pTabList, pWhere, &pMinMax, 0, flag);
if( pWInfo==0 ){
sqlite4ExprListDelete(db, pDel);
goto select_end;
}
updateAccumulator(pParse, &sAggInfo);
if( !pMinMax && flag ){
sqlite4VdbeAddOp2(v, OP_Goto, 0, pWInfo->iBreak);
VdbeComment((v, "%s() by index",
(flag==WHERE_ORDERBY_MIN?"min":"max")));
}
sqlite4WhereEnd(pWInfo);
finalizeAggFunctions(pParse, &sAggInfo);
}
pOrderBy = 0;
sqlite4ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL);
selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, -1,
pDest, addrEnd, addrEnd);
sqlite4ExprListDelete(db, pDel);
}
sqlite4VdbeResolveLabel(v, addrEnd);
} /* endif aggregate query */
if( distinct>=0 ){
explainTempTable(pParse, "DISTINCT");
}
/* If there is an ORDER BY clause, then we need to sort the results
** and send them to the callback one by one.
*/
if( pOrderBy ){
explainTempTable(pParse, "ORDER BY");
generateSortTail(pParse, p, v, pEList->nExpr, pDest);
}
/* Jump here to skip this query
*/
sqlite4VdbeResolveLabel(v, iEnd);
/* The SELECT was successfully coded. Set the return code to 0
** to indicate no errors.
*/
rc = 0;
/* Control jumps to here if an error is encountered above, or upon
** successful coding of the SELECT.
*/
select_end:
explainSetInteger(pParse->iSelectId, iRestoreSelectId);
/* Identify column names if results of the SELECT are to be output.
*/
if( rc==SQLITE_OK && pDest->eDest==SRT_Output ){
generateColumnNames(pParse, pTabList, pEList);
}
sqlite4DbFree(db, sAggInfo.aCol);
sqlite4DbFree(db, sAggInfo.aFunc);
return rc;
}
#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
/*
** Generate a human-readable description of a the Select object.
*/
static void explainOneSelect(Vdbe *pVdbe, Select *p){
sqlite4ExplainPrintf(pVdbe, "SELECT ");
if( p->selFlags & (SF_Distinct|SF_Aggregate) ){
if( p->selFlags & SF_Distinct ){
sqlite4ExplainPrintf(pVdbe, "DISTINCT ");
}
if( p->selFlags & SF_Aggregate ){
sqlite4ExplainPrintf(pVdbe, "agg_flag ");
}
sqlite4ExplainNL(pVdbe);
sqlite4ExplainPrintf(pVdbe, " ");
}
sqlite4ExplainExprList(pVdbe, p->pEList);
sqlite4ExplainNL(pVdbe);
if( p->pSrc && p->pSrc->nSrc ){
int i;
sqlite4ExplainPrintf(pVdbe, "FROM ");
sqlite4ExplainPush(pVdbe);
for(i=0; i<p->pSrc->nSrc; i++){
struct SrcList_item *pItem = &p->pSrc->a[i];
sqlite4ExplainPrintf(pVdbe, "{%d,*} = ", pItem->iCursor);
if( pItem->pSelect ){
sqlite4ExplainSelect(pVdbe, pItem->pSelect);
if( pItem->pTab ){
sqlite4ExplainPrintf(pVdbe, " (tabname=%s)", pItem->pTab->zName);
}
}else if( pItem->zName ){
sqlite4ExplainPrintf(pVdbe, "%s", pItem->zName);
}
if( pItem->zAlias ){
sqlite4ExplainPrintf(pVdbe, " (AS %s)", pItem->zAlias);
}
if( pItem->jointype & JT_LEFT ){
sqlite4ExplainPrintf(pVdbe, " LEFT-JOIN");
}
sqlite4ExplainNL(pVdbe);
}
sqlite4ExplainPop(pVdbe);
}
if( p->pWhere ){
sqlite4ExplainPrintf(pVdbe, "WHERE ");
sqlite4ExplainExpr(pVdbe, p->pWhere);
sqlite4ExplainNL(pVdbe);
}
if( p->pGroupBy ){
sqlite4ExplainPrintf(pVdbe, "GROUPBY ");
sqlite4ExplainExprList(pVdbe, p->pGroupBy);
sqlite4ExplainNL(pVdbe);
}
if( p->pHaving ){
sqlite4ExplainPrintf(pVdbe, "HAVING ");
sqlite4ExplainExpr(pVdbe, p->pHaving);
sqlite4ExplainNL(pVdbe);
}
if( p->pOrderBy ){
sqlite4ExplainPrintf(pVdbe, "ORDERBY ");
sqlite4ExplainExprList(pVdbe, p->pOrderBy);
sqlite4ExplainNL(pVdbe);
}
if( p->pLimit ){
sqlite4ExplainPrintf(pVdbe, "LIMIT ");
sqlite4ExplainExpr(pVdbe, p->pLimit);
sqlite4ExplainNL(pVdbe);
}
if( p->pOffset ){
sqlite4ExplainPrintf(pVdbe, "OFFSET ");
sqlite4ExplainExpr(pVdbe, p->pOffset);
sqlite4ExplainNL(pVdbe);
}
}
SQLITE_PRIVATE void sqlite4ExplainSelect(Vdbe *pVdbe, Select *p){
if( p==0 ){
sqlite4ExplainPrintf(pVdbe, "(null-select)");
return;
}
while( p->pPrior ) p = p->pPrior;
sqlite4ExplainPush(pVdbe);
while( p ){
explainOneSelect(pVdbe, p);
p = p->pNext;
if( p==0 ) break;
sqlite4ExplainNL(pVdbe);
sqlite4ExplainPrintf(pVdbe, "%s\n", selectOpName(p->op));
}
sqlite4ExplainPrintf(pVdbe, "END");
sqlite4ExplainPop(pVdbe);
}
/* End of the structure debug printing code
*****************************************************************************/
#endif /* defined(SQLITE_ENABLE_TREE_EXPLAIN) */
/************** End of select.c **********************************************/
/************** Begin file trigger.c *****************************************/
/*
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the implementation for TRIGGERs
*/
#ifndef SQLITE_OMIT_TRIGGER
/*
** Delete a linked list of TriggerStep structures.
*/
SQLITE_PRIVATE void sqlite4DeleteTriggerStep(sqlite4 *db, TriggerStep *pTriggerStep){
while( pTriggerStep ){
TriggerStep * pTmp = pTriggerStep;
pTriggerStep = pTriggerStep->pNext;
sqlite4ExprDelete(db, pTmp->pWhere);
sqlite4ExprListDelete(db, pTmp->pExprList);
sqlite4SelectDelete(db, pTmp->pSelect);
sqlite4IdListDelete(db, pTmp->pIdList);
sqlite4DbFree(db, pTmp);
}
}
/*
** Given table pTab, return a list of all the triggers attached to
** the table. The list is connected by Trigger.pNext pointers.
**
** All of the triggers on pTab that are in the same database as pTab
** are already attached to pTab->pTrigger. But there might be additional
** triggers on pTab in the TEMP schema. This routine prepends all
** TEMP triggers on pTab to the beginning of the pTab->pTrigger list
** and returns the combined list.
**
** To state it another way: This routine returns a list of all triggers
** that fire off of pTab. The list will include any TEMP triggers on
** pTab as well as the triggers lised in pTab->pTrigger.
*/
SQLITE_PRIVATE Trigger *sqlite4TriggerList(Parse *pParse, Table *pTab){
Schema * const pTmpSchema = pParse->db->aDb[1].pSchema;
Trigger *pList = 0; /* List of triggers to return */
if( pParse->disableTriggers ){
return 0;
}
if( pTmpSchema!=pTab->pSchema ){
HashElem *p;
for(p=sqliteHashFirst(&pTmpSchema->trigHash); p; p=sqliteHashNext(p)){
Trigger *pTrig = (Trigger *)sqliteHashData(p);
if( pTrig->pTabSchema==pTab->pSchema
&& 0==sqlite4StrICmp(pTrig->table, pTab->zName)
){
pTrig->pNext = (pList ? pList : pTab->pTrigger);
pList = pTrig;
}
}
}
return (pList ? pList : pTab->pTrigger);
}
/*
** This is called by the parser when it sees a CREATE TRIGGER statement
** up to the point of the BEGIN before the trigger actions. A Trigger
** structure is generated based on the information available and stored
** in pParse->pNewTrigger. After the trigger actions have been parsed, the
** sqlite4FinishTrigger() function is called to complete the trigger
** construction process.
*/
SQLITE_PRIVATE void sqlite4BeginTrigger(
Parse *pParse, /* The parse context of the CREATE TRIGGER statement */
Token *pName1, /* The name of the trigger */
Token *pName2, /* The name of the trigger */
int tr_tm, /* One of TK_BEFORE, TK_AFTER, TK_INSTEAD */
int op, /* One of TK_INSERT, TK_UPDATE, TK_DELETE */
IdList *pColumns, /* column list if this is an UPDATE OF trigger */
SrcList *pTableName,/* The name of the table/view the trigger applies to */
Expr *pWhen, /* WHEN clause */
int isTemp, /* True if the TEMPORARY keyword is present */
int noErr /* Suppress errors if the trigger already exists */
){
Trigger *pTrigger = 0; /* The new trigger */
Table *pTab; /* Table that the trigger fires off of */
char *zName = 0; /* Name of the trigger */
sqlite4 *db = pParse->db; /* The database connection */
int iDb; /* The database to store the trigger in */
Token *pName; /* The unqualified db name */
DbFixer sFix; /* State vector for the DB fixer */
int iTabDb; /* Index of the database holding pTab */
assert( pName1!=0 ); /* pName1->z might be NULL, but not pName1 itself */
assert( pName2!=0 );
assert( op==TK_INSERT || op==TK_UPDATE || op==TK_DELETE );
assert( op>0 && op<0xff );
if( isTemp ){
/* If TEMP was specified, then the trigger name may not be qualified. */
if( pName2->n>0 ){
sqlite4ErrorMsg(pParse, "temporary trigger may not have qualified name");
goto trigger_cleanup;
}
iDb = 1;
pName = pName1;
}else{
/* Figure out the db that the the trigger will be created in */
iDb = sqlite4TwoPartName(pParse, pName1, pName2, &pName);
if( iDb<0 ){
goto trigger_cleanup;
}
}
if( !pTableName || db->mallocFailed ){
goto trigger_cleanup;
}
/* A long-standing parser bug is that this syntax was allowed:
**
** CREATE TRIGGER attached.demo AFTER INSERT ON attached.tab ....
** ^^^^^^^^
**
** To maintain backwards compatibility, ignore the database
** name on pTableName if we are reparsing our of SQLITE_MASTER.
*/
if( db->init.busy && iDb!=1 ){
sqlite4DbFree(db, pTableName->a[0].zDatabase);
pTableName->a[0].zDatabase = 0;
}
/* If the trigger name was unqualified, and the table is a temp table,
** then set iDb to 1 to create the trigger in the temporary database.
** If sqlite4SrcListLookup() returns 0, indicating the table does not
** exist, the error is caught by the block below.
*/
pTab = sqlite4SrcListLookup(pParse, pTableName);
if( db->init.busy==0 && pName2->n==0 && pTab
&& pTab->pSchema==db->aDb[1].pSchema ){
iDb = 1;
}
/* Ensure the table name matches database name and that the table exists */
if( db->mallocFailed ) goto trigger_cleanup;
assert( pTableName->nSrc==1 );
if( sqlite4FixInit(&sFix, pParse, iDb, "trigger", pName) &&
sqlite4FixSrcList(&sFix, pTableName) ){
goto trigger_cleanup;
}
pTab = sqlite4SrcListLookup(pParse, pTableName);
if( !pTab ){
/* The table does not exist. */
if( db->init.iDb==1 ){
/* Ticket #3810.
** Normally, whenever a table is dropped, all associated triggers are
** dropped too. But if a TEMP trigger is created on a non-TEMP table
** and the table is dropped by a different database connection, the
** trigger is not visible to the database connection that does the
** drop so the trigger cannot be dropped. This results in an
** "orphaned trigger" - a trigger whose associated table is missing.
*/
db->init.orphanTrigger = 1;
}
goto trigger_cleanup;
}
if( IsVirtual(pTab) ){
sqlite4ErrorMsg(pParse, "cannot create triggers on virtual tables");
goto trigger_cleanup;
}
/* Check that the trigger name is not reserved and that no trigger of the
** specified name exists */
zName = sqlite4NameFromToken(db, pName);
if( !zName || SQLITE_OK!=sqlite4CheckObjectName(pParse, zName) ){
goto trigger_cleanup;
}
if( sqlite4HashFind(&(db->aDb[iDb].pSchema->trigHash),
zName, sqlite4Strlen30(zName)) ){
if( !noErr ){
sqlite4ErrorMsg(pParse, "trigger %T already exists", pName);
}else{
assert( !db->init.busy );
sqlite4CodeVerifySchema(pParse, iDb);
}
goto trigger_cleanup;
}
/* Do not create a trigger on a system table */
if( sqlite4StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
sqlite4ErrorMsg(pParse, "cannot create trigger on system table");
pParse->nErr++;
goto trigger_cleanup;
}
/* INSTEAD of triggers are only for views and views only support INSTEAD
** of triggers.
*/
if( pTab->pSelect && tr_tm!=TK_INSTEAD ){
sqlite4ErrorMsg(pParse, "cannot create %s trigger on view: %S",
(tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName, 0);
goto trigger_cleanup;
}
if( !pTab->pSelect && tr_tm==TK_INSTEAD ){
sqlite4ErrorMsg(pParse, "cannot create INSTEAD OF"
" trigger on table: %S", pTableName, 0);
goto trigger_cleanup;
}
iTabDb = sqlite4SchemaToIndex(db, pTab->pSchema);
#ifndef SQLITE_OMIT_AUTHORIZATION
{
int code = SQLITE_CREATE_TRIGGER;
const char *zDb = db->aDb[iTabDb].zName;
const char *zDbTrig = isTemp ? db->aDb[1].zName : zDb;
if( iTabDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
if( sqlite4AuthCheck(pParse, code, zName, pTab->zName, zDbTrig) ){
goto trigger_cleanup;
}
if( sqlite4AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iTabDb),0,zDb)){
goto trigger_cleanup;
}
}
#endif
/* INSTEAD OF triggers can only appear on views and BEFORE triggers
** cannot appear on views. So we might as well translate every
** INSTEAD OF trigger into a BEFORE trigger. It simplifies code
** elsewhere.
*/
if (tr_tm == TK_INSTEAD){
tr_tm = TK_BEFORE;
}
/* Build the Trigger object */
pTrigger = (Trigger*)sqlite4DbMallocZero(db, sizeof(Trigger));
if( pTrigger==0 ) goto trigger_cleanup;
pTrigger->zName = zName;
zName = 0;
pTrigger->table = sqlite4DbStrDup(db, pTableName->a[0].zName);
pTrigger->pSchema = db->aDb[iDb].pSchema;
pTrigger->pTabSchema = pTab->pSchema;
pTrigger->op = (u8)op;
pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER;
pTrigger->pWhen = sqlite4ExprDup(db, pWhen, EXPRDUP_REDUCE);
pTrigger->pColumns = sqlite4IdListDup(db, pColumns);
assert( pParse->pNewTrigger==0 );
pParse->pNewTrigger = pTrigger;
trigger_cleanup:
sqlite4DbFree(db, zName);
sqlite4SrcListDelete(db, pTableName);
sqlite4IdListDelete(db, pColumns);
sqlite4ExprDelete(db, pWhen);
if( !pParse->pNewTrigger ){
sqlite4DeleteTrigger(db, pTrigger);
}else{
assert( pParse->pNewTrigger==pTrigger );
}
}
/*
** This routine is called after all of the trigger actions have been parsed
** in order to complete the process of building the trigger.
*/
SQLITE_PRIVATE void sqlite4FinishTrigger(
Parse *pParse, /* Parser context */
TriggerStep *pStepList, /* The triggered program */
Token *pAll /* Token that describes the complete CREATE TRIGGER */
){
Trigger *pTrig = pParse->pNewTrigger; /* Trigger being finished */
char *zName; /* Name of trigger */
sqlite4 *db = pParse->db; /* The database */
DbFixer sFix; /* Fixer object */
int iDb; /* Database containing the trigger */
Token nameToken; /* Trigger name for error reporting */
pParse->pNewTrigger = 0;
if( NEVER(pParse->nErr) || !pTrig ) goto triggerfinish_cleanup;
zName = pTrig->zName;
iDb = sqlite4SchemaToIndex(pParse->db, pTrig->pSchema);
pTrig->step_list = pStepList;
while( pStepList ){
pStepList->pTrig = pTrig;
pStepList = pStepList->pNext;
}
nameToken.z = pTrig->zName;
nameToken.n = sqlite4Strlen30(nameToken.z);
if( sqlite4FixInit(&sFix, pParse, iDb, "trigger", &nameToken)
&& sqlite4FixTriggerStep(&sFix, pTrig->step_list) ){
goto triggerfinish_cleanup;
}
/* if we are not initializing,
** build the sqlite_master entry
*/
if( !db->init.busy ){
Vdbe *v;
char *z;
/* Make an entry in the sqlite_master table */
v = sqlite4GetVdbe(pParse);
if( v==0 ) goto triggerfinish_cleanup;
sqlite4BeginWriteOperation(pParse, 0, iDb);
z = sqlite4DbStrNDup(db, (char*)pAll->z, pAll->n);
sqlite4NestedParse(pParse,
"INSERT INTO %Q.%s VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
db->aDb[iDb].zName, SCHEMA_TABLE(iDb), zName,
pTrig->table, z);
sqlite4DbFree(db, z);
sqlite4ChangeCookie(pParse, iDb);
sqlite4VdbeAddParseSchemaOp(v, iDb,
sqlite4MPrintf(db, "type='trigger' AND name='%q'", zName));
}
if( db->init.busy ){
Trigger *pLink = pTrig;
Hash *pHash = &db->aDb[iDb].pSchema->trigHash;
pTrig = sqlite4HashInsert(pHash, zName, sqlite4Strlen30(zName), pTrig);
if( pTrig ){
db->mallocFailed = 1;
}else if( pLink->pSchema==pLink->pTabSchema ){
Table *pTab;
int n = sqlite4Strlen30(pLink->table);
pTab = sqlite4HashFind(&pLink->pTabSchema->tblHash, pLink->table, n);
assert( pTab!=0 );
pLink->pNext = pTab->pTrigger;
pTab->pTrigger = pLink;
}
}
triggerfinish_cleanup:
sqlite4DeleteTrigger(db, pTrig);
assert( !pParse->pNewTrigger );
sqlite4DeleteTriggerStep(db, pStepList);
}
/*
** 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 *sqlite4TriggerSelectStep(sqlite4 *db, Select *pSelect){
TriggerStep *pTriggerStep = sqlite4DbMallocZero(db, sizeof(TriggerStep));
if( pTriggerStep==0 ) {
sqlite4SelectDelete(db, pSelect);
return 0;
}
pTriggerStep->op = TK_SELECT;
pTriggerStep->pSelect = pSelect;
pTriggerStep->orconf = OE_Default;
return pTriggerStep;
}
/*
** Allocate space to hold a new trigger step. The allocated space
** holds both the TriggerStep object and the TriggerStep.target.z string.
**
** If an OOM error occurs, NULL is returned and db->mallocFailed is set.
*/
static TriggerStep *triggerStepAllocate(
sqlite4 *db, /* Database connection */
u8 op, /* Trigger opcode */
Token *pName /* The target name */
){
TriggerStep *pTriggerStep;
pTriggerStep = sqlite4DbMallocZero(db, sizeof(TriggerStep) + pName->n);
if( pTriggerStep ){
char *z = (char*)&pTriggerStep[1];
memcpy(z, pName->z, pName->n);
pTriggerStep->target.z = z;
pTriggerStep->target.n = pName->n;
pTriggerStep->op = op;
}
return pTriggerStep;
}
/*
** Build a trigger step out of an INSERT statement. Return a pointer
** to the new trigger step.
**
** The parser calls this routine when it sees an INSERT inside the
** body of a trigger.
*/
SQLITE_PRIVATE TriggerStep *sqlite4TriggerInsertStep(
sqlite4 *db, /* The database connection */
Token *pTableName, /* Name of the table into which we insert */
IdList *pColumn, /* List of columns in pTableName to insert into */
ExprList *pEList, /* The VALUE clause: a list of values to be inserted */
Select *pSelect, /* A SELECT statement that supplies values */
u8 orconf /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
){
TriggerStep *pTriggerStep;
assert(pEList == 0 || pSelect == 0);
assert(pEList != 0 || pSelect != 0 || db->mallocFailed);
pTriggerStep = triggerStepAllocate(db, TK_INSERT, pTableName);
if( pTriggerStep ){
pTriggerStep->pSelect = sqlite4SelectDup(db, pSelect, EXPRDUP_REDUCE);
pTriggerStep->pIdList = pColumn;
pTriggerStep->pExprList = sqlite4ExprListDup(db, pEList, EXPRDUP_REDUCE);
pTriggerStep->orconf = orconf;
}else{
sqlite4IdListDelete(db, pColumn);
}
sqlite4ExprListDelete(db, pEList);
sqlite4SelectDelete(db, pSelect);
return pTriggerStep;
}
/*
** Construct a trigger step that implements an UPDATE statement and return
** a pointer to that trigger step. The parser calls this routine when it
** sees an UPDATE statement inside the body of a CREATE TRIGGER.
*/
SQLITE_PRIVATE TriggerStep *sqlite4TriggerUpdateStep(
sqlite4 *db, /* The database connection */
Token *pTableName, /* Name of the table to be updated */
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) */
){
TriggerStep *pTriggerStep;
pTriggerStep = triggerStepAllocate(db, TK_UPDATE, pTableName);
if( pTriggerStep ){
pTriggerStep->pExprList = sqlite4ExprListDup(db, pEList, EXPRDUP_REDUCE);
pTriggerStep->pWhere = sqlite4ExprDup(db, pWhere, EXPRDUP_REDUCE);
pTriggerStep->orconf = orconf;
}
sqlite4ExprListDelete(db, pEList);
sqlite4ExprDelete(db, pWhere);
return pTriggerStep;
}
/*
** Construct a trigger step that implements a DELETE statement and return
** a pointer to that trigger step. The parser calls this routine when it
** sees a DELETE statement inside the body of a CREATE TRIGGER.
*/
SQLITE_PRIVATE TriggerStep *sqlite4TriggerDeleteStep(
sqlite4 *db, /* Database connection */
Token *pTableName, /* The table from which rows are deleted */
Expr *pWhere /* The WHERE clause */
){
TriggerStep *pTriggerStep;
pTriggerStep = triggerStepAllocate(db, TK_DELETE, pTableName);
if( pTriggerStep ){
pTriggerStep->pWhere = sqlite4ExprDup(db, pWhere, EXPRDUP_REDUCE);
pTriggerStep->orconf = OE_Default;
}
sqlite4ExprDelete(db, pWhere);
return pTriggerStep;
}
/*
** Recursively delete a Trigger structure
*/
SQLITE_PRIVATE void sqlite4DeleteTrigger(sqlite4 *db, Trigger *pTrigger){
if( pTrigger==0 ) return;
sqlite4DeleteTriggerStep(db, pTrigger->step_list);
sqlite4DbFree(db, pTrigger->zName);
sqlite4DbFree(db, pTrigger->table);
sqlite4ExprDelete(db, pTrigger->pWhen);
sqlite4IdListDelete(db, pTrigger->pColumns);
sqlite4DbFree(db, pTrigger);
}
/*
** This function is called to drop a trigger from the database schema.
**
** This may be called directly from the parser and therefore identifies
** the trigger by name. The sqlite4DropTriggerPtr() routine does the
** same job as this routine except it takes a pointer to the trigger
** instead of the trigger name.
**/
SQLITE_PRIVATE void sqlite4DropTrigger(Parse *pParse, SrcList *pName, int noErr){
Trigger *pTrigger = 0;
int i;
const char *zDb;
const char *zName;
int nName;
sqlite4 *db = pParse->db;
if( db->mallocFailed ) goto drop_trigger_cleanup;
if( SQLITE_OK!=sqlite4ReadSchema(pParse) ){
goto drop_trigger_cleanup;
}
assert( pName->nSrc==1 );
zDb = pName->a[0].zDatabase;
zName = pName->a[0].zName;
nName = sqlite4Strlen30(zName);
for(i=OMIT_TEMPDB; i<db->nDb; i++){
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
if( zDb && sqlite4StrICmp(db->aDb[j].zName, zDb) ) continue;
pTrigger = sqlite4HashFind(&(db->aDb[j].pSchema->trigHash), zName, nName);
if( pTrigger ) break;
}
if( !pTrigger ){
if( !noErr ){
sqlite4ErrorMsg(pParse, "no such trigger: %S", pName, 0);
}else{
sqlite4CodeVerifyNamedSchema(pParse, zDb);
}
pParse->checkSchema = 1;
goto drop_trigger_cleanup;
}
sqlite4DropTriggerPtr(pParse, pTrigger);
drop_trigger_cleanup:
sqlite4SrcListDelete(db, pName);
}
/*
** Return a pointer to the Table structure for the table that a trigger
** is set on.
*/
static Table *tableOfTrigger(Trigger *pTrigger){
int n = sqlite4Strlen30(pTrigger->table);
return sqlite4HashFind(&pTrigger->pTabSchema->tblHash, pTrigger->table, n);
}
/*
** Drop a trigger given a pointer to that trigger.
*/
SQLITE_PRIVATE void sqlite4DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
Table *pTable;
Vdbe *v;
sqlite4 *db = pParse->db;
int iDb;
iDb = sqlite4SchemaToIndex(pParse->db, pTrigger->pSchema);
assert( iDb>=0 && iDb<db->nDb );
pTable = tableOfTrigger(pTrigger);
assert( pTable );
assert( pTable->pSchema==pTrigger->pSchema || iDb==1 );
#ifndef SQLITE_OMIT_AUTHORIZATION
{
int code = SQLITE_DROP_TRIGGER;
const char *zDb = db->aDb[iDb].zName;
const char *zTab = SCHEMA_TABLE(iDb);
if( iDb==1 ) code = SQLITE_DROP_TEMP_TRIGGER;
if( sqlite4AuthCheck(pParse, code, pTrigger->zName, pTable->zName, zDb) ||
sqlite4AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
return;
}
}
#endif
/* Generate code to destroy the database record of the trigger.
*/
assert( pTable!=0 );
if( (v = sqlite4GetVdbe(pParse))!=0 ){
int base;
static const VdbeOpList dropTrigger[] = {
{ OP_Rewind, 0, ADDR(9), 0},
{ OP_String8, 0, 1, 0}, /* 1 */
{ OP_Column, 0, 1, 2},
{ OP_Ne, 2, ADDR(8), 1},
{ OP_String8, 0, 1, 0}, /* 4: "trigger" */
{ OP_Column, 0, 0, 2},
{ OP_Ne, 2, ADDR(8), 1},
{ OP_Delete, 0, 0, 0},
{ OP_Next, 0, ADDR(1), 0}, /* 8 */
};
sqlite4BeginWriteOperation(pParse, 0, iDb);
sqlite4OpenMasterTable(pParse, iDb);
base = sqlite4VdbeAddOpList(v, ArraySize(dropTrigger), dropTrigger);
sqlite4VdbeChangeP4(v, base+1, pTrigger->zName, P4_TRANSIENT);
sqlite4VdbeChangeP4(v, base+4, "trigger", P4_STATIC);
sqlite4ChangeCookie(pParse, iDb);
sqlite4VdbeAddOp2(v, OP_Close, 0, 0);
sqlite4VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0);
if( pParse->nMem<3 ){
pParse->nMem = 3;
}
}
}
/*
** Remove a trigger from the hash tables of the sqlite* pointer.
*/
SQLITE_PRIVATE void sqlite4UnlinkAndDeleteTrigger(sqlite4 *db, int iDb, const char *zName){
Trigger *pTrigger;
Hash *pHash;
pHash = &(db->aDb[iDb].pSchema->trigHash);
pTrigger = sqlite4HashInsert(pHash, zName, sqlite4Strlen30(zName), 0);
if( ALWAYS(pTrigger) ){
if( pTrigger->pSchema==pTrigger->pTabSchema ){
Table *pTab = tableOfTrigger(pTrigger);
Trigger **pp;
for(pp=&pTab->pTrigger; *pp!=pTrigger; pp=&((*pp)->pNext));
*pp = (*pp)->pNext;
}
sqlite4DeleteTrigger(db, pTrigger);
db->flags |= SQLITE_InternChanges;
}
}
/*
** pEList is the SET clause of an UPDATE statement. Each entry
** in pEList is of the format <id>=<expr>. If any of the entries
** in pEList have an <id> which matches an identifier in pIdList,
** then return TRUE. If pIdList==NULL, then it is considered a
** wildcard that matches anything. Likewise if pEList==NULL then
** it matches anything so always return true. Return false only
** if there is no match.
*/
static int checkColumnOverlap(IdList *pIdList, ExprList *pEList){
int e;
if( pIdList==0 || NEVER(pEList==0) ) return 1;
for(e=0; e<pEList->nExpr; e++){
if( sqlite4IdListIndex(pIdList, pEList->a[e].zName)>=0 ) return 1;
}
return 0;
}
/*
** Return a list of all triggers on table pTab if there exists at least
** one trigger that must be fired when an operation of type 'op' is
** performed on the table, and, if that operation is an UPDATE, if at
** least one of the columns in pChanges is being modified.
*/
SQLITE_PRIVATE Trigger *sqlite4TriggersExist(
Parse *pParse, /* Parse context */
Table *pTab, /* The table the contains the triggers */
int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */
ExprList *pChanges, /* Columns that change in an UPDATE statement */
int *pMask /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */
){
int mask = 0;
Trigger *pList = 0;
Trigger *p;
if( (pParse->db->flags & SQLITE_EnableTrigger)!=0 ){
pList = sqlite4TriggerList(pParse, pTab);
}
assert( pList==0 || IsVirtual(pTab)==0 );
for(p=pList; p; p=p->pNext){
if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){
mask |= p->tr_tm;
}
}
if( pMask ){
*pMask = mask;
}
return (mask ? pList : 0);
}
/*
** Convert the pStep->target token into a SrcList and return a pointer
** to that SrcList.
**
** This routine adds a specific database name, if needed, to the target when
** forming the SrcList. This prevents a trigger in one database from
** referring to a target in another database. An exception is when the
** trigger is in TEMP in which case it can refer to any other database it
** wants.
*/
static SrcList *targetSrcList(
Parse *pParse, /* The parsing context */
TriggerStep *pStep /* The trigger containing the target token */
){
int iDb; /* Index of the database to use */
SrcList *pSrc; /* SrcList to be returned */
pSrc = sqlite4SrcListAppend(pParse->db, 0, &pStep->target, 0);
if( pSrc ){
assert( pSrc->nSrc>0 );
assert( pSrc->a!=0 );
iDb = sqlite4SchemaToIndex(pParse->db, pStep->pTrig->pSchema);
if( iDb==0 || iDb>=2 ){
sqlite4 *db = pParse->db;
assert( iDb<pParse->db->nDb );
pSrc->a[pSrc->nSrc-1].zDatabase = sqlite4DbStrDup(db, db->aDb[iDb].zName);
}
}
return pSrc;
}
/*
** Generate VDBE code for the statements inside the body of a single
** trigger.
*/
static int codeTriggerProgram(
Parse *pParse, /* The parser context */
TriggerStep *pStepList, /* List of statements inside the trigger body */
int orconf /* Conflict algorithm. (OE_Abort, etc) */
){
TriggerStep *pStep;
Vdbe *v = pParse->pVdbe;
sqlite4 *db = pParse->db;
assert( pParse->pTriggerTab && pParse->pToplevel );
assert( pStepList );
assert( v!=0 );
for(pStep=pStepList; pStep; pStep=pStep->pNext){
/* Figure out the ON CONFLICT policy that will be used for this step
** of the trigger program. If the statement that caused this trigger
** to fire had an explicit ON CONFLICT, then use it. Otherwise, use
** the ON CONFLICT policy that was specified as part of the trigger
** step statement. Example:
**
** CREATE TRIGGER AFTER INSERT ON t1 BEGIN;
** INSERT OR REPLACE INTO t2 VALUES(new.a, new.b);
** END;
**
** INSERT INTO t1 ... ; -- insert into t2 uses REPLACE policy
** INSERT OR IGNORE INTO t1 ... ; -- insert into t2 uses IGNORE policy
*/
pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf;
switch( pStep->op ){
case TK_UPDATE: {
sqlite4Update(pParse,
targetSrcList(pParse, pStep),
sqlite4ExprListDup(db, pStep->pExprList, 0),
sqlite4ExprDup(db, pStep->pWhere, 0),
pParse->eOrconf
);
break;
}
case TK_INSERT: {
sqlite4Insert(pParse,
targetSrcList(pParse, pStep),
sqlite4ExprListDup(db, pStep->pExprList, 0),
sqlite4SelectDup(db, pStep->pSelect, 0),
sqlite4IdListDup(db, pStep->pIdList),
pParse->eOrconf
);
break;
}
case TK_DELETE: {
sqlite4DeleteFrom(pParse,
targetSrcList(pParse, pStep),
sqlite4ExprDup(db, pStep->pWhere, 0)
);
break;
}
default: assert( pStep->op==TK_SELECT ); {
SelectDest sDest;
Select *pSelect = sqlite4SelectDup(db, pStep->pSelect, 0);
sqlite4SelectDestInit(&sDest, SRT_Discard, 0);
sqlite4Select(pParse, pSelect, &sDest);
sqlite4SelectDelete(db, pSelect);
break;
}
}
if( pStep->op!=TK_SELECT ){
sqlite4VdbeAddOp0(v, OP_ResetCount);
}
}
return 0;
}
#ifdef SQLITE_DEBUG
/*
** This function is used to add VdbeComment() annotations to a VDBE
** program. It is not used in production code, only for debugging.
*/
static const char *onErrorText(int onError){
switch( onError ){
case OE_Abort: return "abort";
case OE_Rollback: return "rollback";
case OE_Fail: return "fail";
case OE_Replace: return "replace";
case OE_Ignore: return "ignore";
case OE_Default: return "default";
}
return "n/a";
}
#endif
/*
** Parse context structure pFrom has just been used to create a sub-vdbe
** (trigger program). If an error has occurred, transfer error information
** from pFrom to pTo.
*/
static void transferParseError(Parse *pTo, Parse *pFrom){
assert( pFrom->zErrMsg==0 || pFrom->nErr );
assert( pTo->zErrMsg==0 || pTo->nErr );
if( pTo->nErr==0 ){
pTo->zErrMsg = pFrom->zErrMsg;
pTo->nErr = pFrom->nErr;
}else{
sqlite4DbFree(pFrom->db, pFrom->zErrMsg);
}
}
/*
** Create and populate a new TriggerPrg object with a sub-program
** implementing trigger pTrigger with ON CONFLICT policy orconf.
*/
static TriggerPrg *codeRowTrigger(
Parse *pParse, /* Current parse context */
Trigger *pTrigger, /* Trigger to code */
Table *pTab, /* The table pTrigger is attached to */
int orconf /* ON CONFLICT policy to code trigger program with */
){
Parse *pTop = sqlite4ParseToplevel(pParse);
sqlite4 *db = pParse->db; /* Database handle */
TriggerPrg *pPrg; /* Value to return */
Expr *pWhen = 0; /* Duplicate of trigger WHEN expression */
Vdbe *v; /* Temporary VM */
NameContext sNC; /* Name context for sub-vdbe */
SubProgram *pProgram = 0; /* Sub-vdbe for trigger program */
Parse *pSubParse; /* Parse context for sub-vdbe */
int iEndTrigger = 0; /* Label to jump to if WHEN is false */
assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) );
assert( pTop->pVdbe );
/* Allocate the TriggerPrg and SubProgram objects. To ensure that they
** are freed if an error occurs, link them into the Parse.pTriggerPrg
** list of the top-level Parse object sooner rather than later. */
pPrg = sqlite4DbMallocZero(db, sizeof(TriggerPrg));
if( !pPrg ) return 0;
pPrg->pNext = pTop->pTriggerPrg;
pTop->pTriggerPrg = pPrg;
pPrg->pProgram = pProgram = sqlite4DbMallocZero(db, sizeof(SubProgram));
if( !pProgram ) return 0;
sqlite4VdbeLinkSubProgram(pTop->pVdbe, pProgram);
pPrg->pTrigger = pTrigger;
pPrg->orconf = orconf;
pPrg->aColmask[0] = 0xffffffff;
pPrg->aColmask[1] = 0xffffffff;
/* Allocate and populate a new Parse context to use for coding the
** trigger sub-program. */
pSubParse = sqlite4StackAllocZero(db, sizeof(Parse));
if( !pSubParse ) return 0;
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = pSubParse;
pSubParse->db = db;
pSubParse->pTriggerTab = pTab;
pSubParse->pToplevel = pTop;
pSubParse->zAuthContext = pTrigger->zName;
pSubParse->eTriggerOp = pTrigger->op;
pSubParse->nQueryLoop = pParse->nQueryLoop;
v = sqlite4GetVdbe(pSubParse);
if( v ){
VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)",
pTrigger->zName, onErrorText(orconf),
(pTrigger->tr_tm==TRIGGER_BEFORE ? "BEFORE" : "AFTER"),
(pTrigger->op==TK_UPDATE ? "UPDATE" : ""),
(pTrigger->op==TK_INSERT ? "INSERT" : ""),
(pTrigger->op==TK_DELETE ? "DELETE" : ""),
pTab->zName
));
#ifndef SQLITE_OMIT_TRACE
sqlite4VdbeChangeP4(v, -1,
sqlite4MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC
);
#endif
/* If one was specified, code the WHEN clause. If it evaluates to false
** (or NULL) the sub-vdbe is immediately halted by jumping to the
** OP_Halt inserted at the end of the program. */
if( pTrigger->pWhen ){
pWhen = sqlite4ExprDup(db, pTrigger->pWhen, 0);
if( SQLITE_OK==sqlite4ResolveExprNames(&sNC, pWhen)
&& db->mallocFailed==0
){
iEndTrigger = sqlite4VdbeMakeLabel(v);
sqlite4ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL);
}
sqlite4ExprDelete(db, pWhen);
}
/* Code the trigger program into the sub-vdbe. */
codeTriggerProgram(pSubParse, pTrigger->step_list, orconf);
/* Insert an OP_Halt at the end of the sub-program. */
if( iEndTrigger ){
sqlite4VdbeResolveLabel(v, iEndTrigger);
}
sqlite4VdbeAddOp0(v, OP_Halt);
VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf)));
transferParseError(pParse, pSubParse);
if( db->mallocFailed==0 ){
pProgram->aOp = sqlite4VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg);
}
pProgram->nMem = pSubParse->nMem;
pProgram->nCsr = pSubParse->nTab;
pProgram->nOnce = pSubParse->nOnce;
pProgram->token = (void *)pTrigger;
pPrg->aColmask[0] = pSubParse->oldmask;
pPrg->aColmask[1] = pSubParse->newmask;
sqlite4VdbeDelete(v);
}
assert( !pSubParse->pAinc && !pSubParse->pZombieTab );
assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg );
sqlite4StackFree(db, pSubParse);
return pPrg;
}
/*
** Return a pointer to a TriggerPrg object containing the sub-program for
** trigger pTrigger with default ON CONFLICT algorithm orconf. If no such
** TriggerPrg object exists, a new object is allocated and populated before
** being returned.
*/
static TriggerPrg *getRowTrigger(
Parse *pParse, /* Current parse context */
Trigger *pTrigger, /* Trigger to code */
Table *pTab, /* The table trigger pTrigger is attached to */
int orconf /* ON CONFLICT algorithm. */
){
Parse *pRoot = sqlite4ParseToplevel(pParse);
TriggerPrg *pPrg;
assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) );
/* It may be that this trigger has already been coded (or is in the
** process of being coded). If this is the case, then an entry with
** a matching TriggerPrg.pTrigger field will be present somewhere
** in the Parse.pTriggerPrg list. Search for such an entry. */
for(pPrg=pRoot->pTriggerPrg;
pPrg && (pPrg->pTrigger!=pTrigger || pPrg->orconf!=orconf);
pPrg=pPrg->pNext
);
/* If an existing TriggerPrg could not be located, create a new one. */
if( !pPrg ){
pPrg = codeRowTrigger(pParse, pTrigger, pTab, orconf);
}
return pPrg;
}
/*
** Generate code for the trigger program associated with trigger p on
** table pTab. The reg, orconf and ignoreJump parameters passed to this
** function are the same as those described in the header function for
** sqlite4CodeRowTrigger()
*/
SQLITE_PRIVATE void sqlite4CodeRowTriggerDirect(
Parse *pParse, /* Parse context */
Trigger *p, /* Trigger to code */
Table *pTab, /* The table to code triggers from */
int reg, /* Reg array containing OLD.* and NEW.* values */
int orconf, /* ON CONFLICT policy */
int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */
){
Vdbe *v = sqlite4GetVdbe(pParse); /* Main VM */
TriggerPrg *pPrg;
pPrg = getRowTrigger(pParse, p, pTab, orconf);
assert( pPrg || pParse->nErr || pParse->db->mallocFailed );
/* Code the OP_Program opcode in the parent VDBE. P4 of the OP_Program
** is a pointer to the sub-vdbe containing the trigger program. */
if( pPrg ){
sqlite4VdbeAddOp3(v, OP_Program, reg, ignoreJump, ++pParse->nMem);
sqlite4VdbeChangeP4(v, -1, (const char *)pPrg->pProgram, P4_SUBPROGRAM);
VdbeComment(
(v, "Call: %s.%s", (p->zName?p->zName:"fkey"), onErrorText(orconf)));
}
}
/*
** This is called to code the required FOR EACH ROW triggers for an operation
** on table pTab. The operation to code triggers for (INSERT, UPDATE or DELETE)
** is given by the op paramater. The tr_tm parameter determines whether the
** BEFORE or AFTER triggers are coded. If the operation is an UPDATE, then
** parameter pChanges is passed the list of columns being modified.
**
** If there are no triggers that fire at the specified time for the specified
** operation on pTab, this function is a no-op.
**
** The reg argument is the address of the first in an array of registers
** that contain the values substituted for the new.* and old.* references
** in the trigger program. If N is the number of columns in table pTab
** (a copy of pTab->nCol), then registers are populated as follows:
**
** Register Contains
** ------------------------------------------------------
** reg+0 OLD.rowid
** reg+1 OLD.* value of left-most column of pTab
** ... ...
** reg+N OLD.* value of right-most column of pTab
** reg+N+1 NEW.rowid
** reg+N+2 OLD.* value of left-most column of pTab
** ... ...
** reg+N+N+1 NEW.* value of right-most column of pTab
**
** For ON DELETE triggers, the registers containing the NEW.* values will
** never be accessed by the trigger program, so they are not allocated or
** populated by the caller (there is no data to populate them with anyway).
** Similarly, for ON INSERT triggers the values stored in the OLD.* registers
** are never accessed, and so are not allocated by the caller. So, for an
** ON INSERT trigger, the value passed to this function as parameter reg
** is not a readable register, although registers (reg+N) through
** (reg+N+N+1) are.
**
** Parameter orconf is the default conflict resolution algorithm for the
** trigger program to use (REPLACE, IGNORE etc.). Parameter ignoreJump
** is the instruction that control should jump to if a trigger program
** raises an IGNORE exception.
*/
SQLITE_PRIVATE void sqlite4CodeRowTrigger(
Parse *pParse, /* Parse context */
Trigger *pTrigger, /* List of triggers on table pTab */
int op, /* One of TK_UPDATE, TK_INSERT, TK_DELETE */
ExprList *pChanges, /* Changes list for any UPDATE OF triggers */
int tr_tm, /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
Table *pTab, /* The table to code triggers from */
int reg, /* The first in an array of registers (see above) */
int orconf, /* ON CONFLICT policy */
int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */
){
Trigger *p; /* Used to iterate through pTrigger list */
assert( op==TK_UPDATE || op==TK_INSERT || op==TK_DELETE );
assert( tr_tm==TRIGGER_BEFORE || tr_tm==TRIGGER_AFTER );
assert( (op==TK_UPDATE)==(pChanges!=0) );
for(p=pTrigger; p; p=p->pNext){
/* Sanity checking: The schema for the trigger and for the table are
** always defined. The trigger must be in the same schema as the table
** or else it must be a TEMP trigger. */
assert( p->pSchema!=0 );
assert( p->pTabSchema!=0 );
assert( p->pSchema==p->pTabSchema
|| p->pSchema==pParse->db->aDb[1].pSchema );
/* Determine whether we should code this trigger */
if( p->op==op
&& p->tr_tm==tr_tm
&& checkColumnOverlap(p->pColumns, pChanges)
){
sqlite4CodeRowTriggerDirect(pParse, p, pTab, reg, orconf, ignoreJump);
}
}
}
/*
** Triggers may access values stored in the old.* or new.* pseudo-table.
** This function returns a 32-bit bitmask indicating which columns of the
** old.* or new.* tables actually are used by triggers. This information
** may be used by the caller, for example, to avoid having to load the entire
** old.* record into memory when executing an UPDATE or DELETE command.
**
** Bit 0 of the returned mask is set if the left-most column of the
** table may be accessed using an [old|new].<col> reference. Bit 1 is set if
** the second leftmost column value is required, and so on. If there
** are more than 32 columns in the table, and at least one of the columns
** with an index greater than 32 may be accessed, 0xffffffff is returned.
**
** It is not possible to determine if the old.rowid or new.rowid column is
** accessed by triggers. The caller must always assume that it is.
**
** Parameter isNew must be either 1 or 0. If it is 0, then the mask returned
** applies to the old.* table. If 1, the new.* table.
**
** Parameter tr_tm must be a mask with one or both of the TRIGGER_BEFORE
** and TRIGGER_AFTER bits set. Values accessed by BEFORE triggers are only
** included in the returned mask if the TRIGGER_BEFORE bit is set in the
** tr_tm parameter. Similarly, values accessed by AFTER triggers are only
** included in the returned mask if the TRIGGER_AFTER bit is set in tr_tm.
*/
SQLITE_PRIVATE u32 sqlite4TriggerColmask(
Parse *pParse, /* Parse context */
Trigger *pTrigger, /* List of triggers on table pTab */
ExprList *pChanges, /* Changes list for any UPDATE OF triggers */
int isNew, /* 1 for new.* ref mask, 0 for old.* ref mask */
int tr_tm, /* Mask of TRIGGER_BEFORE|TRIGGER_AFTER */
Table *pTab, /* The table to code triggers from */
int orconf /* Default ON CONFLICT policy for trigger steps */
){
const int op = pChanges ? TK_UPDATE : TK_DELETE;
u32 mask = 0;
Trigger *p;
assert( isNew==1 || isNew==0 );
for(p=pTrigger; p; p=p->pNext){
if( p->op==op && (tr_tm&p->tr_tm)
&& checkColumnOverlap(p->pColumns,pChanges)
){
TriggerPrg *pPrg;
pPrg = getRowTrigger(pParse, p, pTab, orconf);
if( pPrg ){
mask |= pPrg->aColmask[isNew];
}
}
}
return mask;
}
#endif /* !defined(SQLITE_OMIT_TRIGGER) */
/************** End of trigger.c *********************************************/
/************** Begin file update.c ******************************************/
/*
** 2001 September 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.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Forward declaration */
static void updateVirtualTable(
Parse *pParse, /* The parsing context */
SrcList *pSrc, /* The virtual table to be modified */
Table *pTab, /* The virtual table */
ExprList *pChanges, /* The columns to change in the UPDATE statement */
Expr *pRowidExpr, /* Expression used to recompute the rowid */
int *aXRef, /* Mapping from columns of pTab to entries in pChanges */
Expr *pWhere, /* WHERE clause of the UPDATE statement */
int onError /* ON CONFLICT strategy */
);
#endif /* SQLITE_OMIT_VIRTUALTABLE */
/*
** The most recently coded instruction was an OP_Column to retrieve the
** i-th column of table pTab. This routine sets the P4 parameter of the
** OP_Column to the default value, if any.
**
** The default value of a column is specified by a DEFAULT clause in the
** column definition. This was either supplied by the user when the table
** was created, or added later to the table definition by an ALTER TABLE
** command. If the latter, then the row-records in the table btree on disk
** may not contain a value for the column and the default value, taken
** from the P4 parameter of the OP_Column instruction, is returned instead.
** If the former, then all row-records are guaranteed to include a value
** for the column and the P4 value is not required.
**
** Column definitions created by an ALTER TABLE command may only have
** literal default values specified: a number, null or a string. (If a more
** complicated default expression value was provided, it is evaluated
** when the ALTER TABLE is executed and one of the literal values written
** into the sqlite_master table.)
**
** Therefore, the P4 parameter is only required if the default value for
** the column is a literal number, string or null. The sqlite4ValueFromExpr()
** function is capable of transforming these types of expressions into
** sqlite4_value objects.
**
** If parameter iReg is not negative, code an OP_RealAffinity instruction
** on register iReg. This is used when an equivalent integer value is
** stored in place of an 8-byte floating point value in order to save
** space.
*/
SQLITE_PRIVATE void sqlite4ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
assert( pTab!=0 );
if( !pTab->pSelect ){
sqlite4_value *pValue;
u8 enc = ENC(sqlite4VdbeDb(v));
Column *pCol = &pTab->aCol[i];
VdbeComment((v, "%s.%s", pTab->zName, pCol->zName));
assert( i<pTab->nCol );
sqlite4ValueFromExpr(sqlite4VdbeDb(v), pCol->pDflt, enc,
pCol->affinity, &pValue);
if( pValue ){
sqlite4VdbeChangeP4(v, -1, (const char *)pValue, P4_MEM);
}
#ifndef SQLITE_OMIT_FLOATING_POINT
if( iReg>=0 && pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
sqlite4VdbeAddOp1(v, OP_RealAffinity, iReg);
}
#endif
}
}
/*
** Process an UPDATE statement.
**
** UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
** \_______/ \________/ \______/ \________________/
* onError pSrc pChanges pWhere
*/
SQLITE_PRIVATE void sqlite4Update(
Parse *pParse, /* The parser context */
SrcList *pSrc, /* 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 */
){
int i, j; /* Loop counters */
Table *pTab; /* The table to be updated */
int addr = 0; /* VDBE instruction address of the start of the loop */
WhereInfo *pWInfo; /* Information about the WHERE clause */
Vdbe *v; /* The virtual database engine */
Index *pIdx; /* Iterator variable */
int nIdx; /* Total number of indexes on table (incl. PK) */
int iCur; /* VDBE Cursor number of pTab */
sqlite4 *db; /* The database structure */
int *aRegIdx = 0; /* One register assigned to each index to be updated */
int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the
** an expression for the i-th column of the table.
** aXRef[i]==-1 if the i-th column is not changed. */
AuthContext sContext; /* The authorization context */
NameContext sNC; /* The name-context to resolve expressions in */
int iDb; /* Database containing the table being updated */
int okOnePass; /* True for one-pass algorithm without the FIFO */
int hasFK; /* True if foreign key processing is required */
#ifndef SQLITE_OMIT_TRIGGER
int isView; /* True when updating a view (INSTEAD OF trigger) */
Trigger *pTrigger; /* List of triggers on pTab, if required */
int tmask; /* Mask of TRIGGER_BEFORE|TRIGGER_AFTER */
#endif
int newmask; /* Mask of NEW.* columns accessed by BEFORE triggers */
int regOldKey; /* Register containing the original PK */
int regNew; /* Content of the NEW.* table in triggers */
int regOld = 0; /* Content of OLD.* table in triggers */
int regRowSet = 0; /* Register containing RowSet object */
Index *pPk = 0; /* The primary key index of this table */
int iPk = 0; /* Offset of primary key in aRegIdx[] */
int bChngPk = 0; /* True if any PK columns are updated */
int bOpenAll = 0; /* True if all indexes were opened */
int bImplicitPk = 0; /* True if pTab has an implicit PK */
int regOldTr = 0; /* Content of OLD.* table including IPK */
int regNewTr = 0; /* Content of NEW.* table including IPK */
memset(&sContext, 0, sizeof(sContext));
db = pParse->db;
if( pParse->nErr || db->mallocFailed ){
goto update_cleanup;
}
assert( pSrc->nSrc==1 );
/* Locate and analyze the table to be updated. This block sets:
**
** pTab
** iDb
** pPk
** bImplicitPk
*/
pTab = sqlite4SrcListLookup(pParse, pSrc);
if( pTab==0 ) goto update_cleanup;
iDb = sqlite4SchemaToIndex(pParse->db, pTab->pSchema);
if( IsView(pTab)==0 ){
pPk = sqlite4FindPrimaryKey(pTab, &iPk);
bImplicitPk = (pPk->aiColumn[0]<0);
}
/* Figure out if we have any triggers and if the table being
** updated is a view.
*/
#ifndef SQLITE_OMIT_TRIGGER
pTrigger = sqlite4TriggersExist(pParse, pTab, TK_UPDATE, pChanges, &tmask);
isView = pTab->pSelect!=0;
assert( pTrigger || tmask==0 );
#else
# define pTrigger 0
# define isView 0
# define tmask 0
#endif
#ifdef SQLITE_OMIT_VIEW
# undef isView
# define isView 0
#endif
if( sqlite4ViewGetColumnNames(pParse, pTab) ) goto update_cleanup;
if( sqlite4IsReadOnly(pParse, pTab, tmask) ) goto update_cleanup;
aXRef = sqlite4DbMallocRaw(db, sizeof(int) * pTab->nCol );
if( aXRef==0 ) goto update_cleanup;
for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
/* Allocate a cursors for the main database table and for all indices.
** The index cursors might not be used, but if they are used they
** need to occur right after the database cursor. So go ahead and
** allocate enough space, just in case. */
iCur = pParse->nTab;
pSrc->a[0].iCursor = iCur+iPk;
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
pParse->nTab++;
}
if( IsView(pTab) ) pParse->nTab++;
/* Initialize the name-context */
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = pParse;
sNC.pSrcList = pSrc;
/* Resolve the column names in all the expressions of the of the UPDATE
** statement. Also find the column index for each column to be updated in
** the pChanges array. For each column to be updated, make sure we have
** authorization to change that column.
**
** Also, if any columns that are part of the tables primary key are
** to be modified, set the bChngPk variable to true. This is significant
** because if the primary key changes, *all* index entries need to be
** replaced (not just those that index modified columns). */
for(i=0; i<pChanges->nExpr; i++){
int iPkCol; /* To iterate through PK columns */
/* Resolve any names in the expression for this assignment */
if( sqlite4ResolveExprNames(&sNC, pChanges->a[i].pExpr) ){
goto update_cleanup;
}
/* Resolve the column name on the left of the assignment */
for(j=0; j<pTab->nCol; j++){
if( sqlite4StrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ) break;
}
if( j==pTab->nCol ){
sqlite4ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName);
pParse->checkSchema = 1;
goto update_cleanup;
}
aXRef[j] = i;
/* Check if this column is part of the primary key. If so, set bChngPk. */
if( !IsView(pTab) ){
for(iPkCol=0; iPkCol<pPk->nColumn; iPkCol++){
if( pPk->aiColumn[iPkCol]==j ) bChngPk = 1;
}
}
#ifndef SQLITE_OMIT_AUTHORIZATION
{
int rc;
rc = sqlite4AuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
pTab->aCol[j].zName, db->aDb[iDb].zName);
if( rc==SQLITE_DENY ){
goto update_cleanup;
}else if( rc==SQLITE_IGNORE ){
aXRef[j] = -1;
}
}
#endif
}
/* Begin generating code. */
v = sqlite4GetVdbe(pParse);
if( v==0 ) goto update_cleanup;
if( pParse->nested==0 ) sqlite4VdbeCountChanges(v);
sqlite4BeginWriteOperation(pParse, 1, iDb);
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* TODO: This is currently broken */
/* Virtual tables must be handled separately */
if( IsVirtual(pTab) ){
updateVirtualTable(pParse, pSrc, pTab, pChanges, 0, aXRef, pWhere, onError);
pWhere = 0;
pSrc = 0;
goto update_cleanup;
}
#endif
hasFK = sqlite4FkRequired(pParse, pTab, aXRef);
/* Allocate memory for the array aRegIdx[]. There is one entry in the
** array for each index associated with table being updated. Fill in
** the value with a register number for indices that are to be used
** and with zero for unused indices. */
for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
aRegIdx = sqlite4DbMallocZero(db, sizeof(Index*) * nIdx );
if( aRegIdx==0 ) goto update_cleanup;
/* Allocate registers for and populate the aRegIdx array. */
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
if( pIdx==pPk || hasFK || bChngPk ){
aRegIdx[j] = ++pParse->nMem;
}else{
for(i=0; i<pIdx->nColumn; i++){
if( aXRef[pIdx->aiColumn[i]]>=0 ){
aRegIdx[j] = ++pParse->nMem;
break;
}
}
}
}
/* Allocate other required registers. Specifically:
**
** regRowSet: 1 register
** regOldKey: 1 register
** regOldTr: nCol+1 registers
** regNewTr: nCol+1 registers
**
** The regOldTr allocation is only required if there are either triggers
** or foreign keys to be processed.
**
** The regOldTr and regNewTr register arrays include space for the
** implicit primary key value if the table in question does not have an
** explicit PRIMARY KEY.
*/
regRowSet = ++pParse->nMem;
regOldKey = ++pParse->nMem;
if( pTrigger || hasFK ){
regOldTr = pParse->nMem + 1;
regOld = regOldTr+1;
pParse->nMem += (pTab->nCol + 1);
}
regNewTr = pParse->nMem + 1;
regNew = regNewTr+1;
pParse->nMem += (pTab->nCol+1);
/* Start the view context. */
if( isView ){
sqlite4AuthContextPush(pParse, &sContext, pTab->zName);
}
/* If we are trying to update a view, realize that view into
** a ephemeral table.
*/
#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
if( isView ){
sqlite4MaterializeView(pParse, pTab, pWhere, iCur);
}
#endif
/* Resolve the column names in all the expressions in the
** WHERE clause.
*/
if( sqlite4ResolveExprNames(&sNC, pWhere) ){
goto update_cleanup;
}
/* This block codes a loop that iterates through all rows of the table
** identified by the UPDATE statements WHERE clause. The primary key
** of each row visited by the loop is added to the RowSet object stored
** in register regRowSet.
**
** There is one exception to the above: If static analysis of the WHERE
** clause indicates that the loop will visit at most one row, then the
** RowSet object is bypassed and the primary key of the single row (if
** any) left in register regOldKey. This is called the "one-pass"
** approach. Set okOnePass to true if it can be used in this case. */
sqlite4VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldKey);
pWInfo = sqlite4WhereBegin(pParse, pSrc, pWhere, 0, 0, WHERE_ONEPASS_DESIRED);
if( pWInfo==0 ) goto update_cleanup;
okOnePass = pWInfo->okOnePass;
sqlite4VdbeAddOp2(v, OP_RowKey, iCur+iPk, regOldKey);
if( !okOnePass ){
sqlite4VdbeAddOp3(v, OP_RowSetAdd, regRowSet, 0, regOldKey);
}
sqlite4WhereEnd(pWInfo);
/* Open every index that needs updating. If any index could potentially
** invoke a REPLACE conflict resolution action, then we need to open all
** indices because we might need to be deleting some records. */
if( !isView ){
/* Set bOpenAll to true if this UPDATE might strike a REPLACE */
bOpenAll = (onError==OE_Replace);
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
if( aRegIdx[i] && pIdx->onError==OE_Replace ) bOpenAll = 1;
}
/* If bOpenAll is true, open all indexes. Otherwise, just open those
** indexes for which the corresponding aRegIdx[] entry is non-zero
** (those that index columns that will be modified by this UPDATE
** statement). Also, if the one-pass approach is being used, do not
** open the primary key index here - it is already open. */
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
if( (bOpenAll || aRegIdx[i]) && (okOnePass==0 || pIdx!=pPk) ){
sqlite4OpenIndex(pParse, iCur+i, iDb, pIdx, OP_OpenWrite);
}
}
}
/* The next instruction coded is the top of the update loop (executed once
** for each row to be updated).
**
** If okOnePass is true, then regOldKey either contains the encoded PK of
** the row to update, or it is NULL (indicating that this statement will
** update zero rows). If this is the case, jump to the end of the loop
** without doing anything. Otherwise - if okOnePass is true and regOldKey
** contains something other than NULL - proceed.
**
** Or, if okOnePass is false, then the RowSet object stored in register
** regRowSet contains the set of encoded PKs for the rows that will
** be updated by this statement. Read the next one into register regOldKey.
** Or, if the RowSet is already empty, jump to the end of the loop.
*/
if( okOnePass ){
int a1 = sqlite4VdbeAddOp1(v, OP_NotNull, regOldKey);
addr = sqlite4VdbeAddOp0(v, OP_Goto);
sqlite4VdbeJumpHere(v, a1);
}else{
addr = sqlite4VdbeAddOp3(v, OP_RowSetRead, regRowSet, 0, regOldKey);
}
/* Make cursor iCur point to the record that is being updated. If
** this record does not exist for some reason (deleted by a trigger,
** for example, then jump to the next iteration of the RowSet loop.
** TODO: If okOnePass is true, does iCur already point to this record? */
sqlite4VdbeAddOp4(v, OP_NotFound, iCur+iPk, addr, regOldKey, 0, P4_INT32);
/* If there are triggers on this table, populate an array of registers
** with the required old.* column data. */
if( hasFK || pTrigger ){
u32 oldmask = (hasFK ? sqlite4FkOldmask(pParse, pTab) : 0);
oldmask |= sqlite4TriggerColmask(pParse,
pTrigger, pChanges, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onError
);
if( bImplicitPk ){
sqlite4VdbeAddOp2(v, OP_Rowid, iCur+iPk, regOldTr);
}
for(i=0; i<pTab->nCol; i++){
if( aXRef[i]<0 || oldmask==0xffffffff || (i<32 && (oldmask & (1<<i))) ){
sqlite4ExprCodeGetColumnOfTable(v, pTab, iCur+iPk, i, regOld+i);
}else{
sqlite4VdbeAddOp2(v, OP_Null, 0, regOld+i);
}
}
}
/* Populate the array of registers beginning at regNew with the new
** row data. This array is used to check constaints, create the new
** table and index records, and as the values for any new.* references
** made by triggers.
**
** If there are one or more BEFORE triggers, then do not populate the
** registers associated with columns that are (a) not modified by
** this UPDATE statement and (b) not accessed by new.* references. The
** values for registers not modified by the UPDATE must be reloaded from
** the database after the BEFORE triggers are fired anyway (as the trigger
** may have modified them). So not loading those that are not going to
** be used eliminates some redundant opcodes.
*/
newmask = sqlite4TriggerColmask(
pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError
);
sqlite4VdbeAddOp3(v, OP_Null, 0, regNew, regNew+pTab->nCol-1);
for(i=0; i<pTab->nCol; i++){
j = aXRef[i];
if( j>=0 ){
sqlite4ExprCode(pParse, pChanges->a[j].pExpr, regNew+i);
}else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask&(1<<i)) ){
/* This branch loads the value of a column that will not be changed
** into a register. This is done if there are no BEFORE triggers, or
** if there are one or more BEFORE triggers that use this value via
** a new.* reference in a trigger program.
*/
testcase( i==31 );
testcase( i==32 );
sqlite4VdbeAddOp3(v, OP_Column, iCur+iPk, i, regNew+i);
sqlite4ColumnDefault(v, pTab, i, regNew+i);
}
}
if( bImplicitPk ){
sqlite4VdbeAddOp2(v, OP_Rowid, iCur+iPk, regNew-1);
}
/* Fire any BEFORE UPDATE triggers. This happens before constraints are
** verified. One could argue that this is wrong.
*/
if( tmask&TRIGGER_BEFORE ){
sqlite4VdbeAddOp2(v, OP_Affinity, regNew, pTab->nCol);
sqlite4TableAffinityStr(v, pTab);
sqlite4CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges,
TRIGGER_BEFORE, pTab, regOldTr, onError, addr);
/* The row-trigger may have deleted the row being updated. In this
** case, jump to the next row. No updates or AFTER triggers are
** required. This behaviour - what happens when the row being updated
** is deleted or renamed by a BEFORE trigger - is left undefined in the
** documentation.
*/
sqlite4VdbeAddOp4Int(v, OP_NotFound, iCur+iPk, addr, regOldKey, 0);
/* If it did not delete it, the row-trigger may still have modified
** some of the columns of the row being updated. Load the values for
** all columns not modified by the update statement into their
** registers in case this has happened.
*/
for(i=0; i<pTab->nCol; i++){
if( aXRef[i]<0 ){
sqlite4VdbeAddOp3(v, OP_Column, iCur+iPk, i, regNew+i);
sqlite4ColumnDefault(v, pTab, i, regNew+i);
}
}
}
if( !isView ){
int j1; /* Address of jump instruction */
/* Do constraint checks. */
assert( bChngPk==0 || bImplicitPk==0 );
if( bChngPk==0 ) aRegIdx[iPk] = 0;
sqlite4GenerateConstraintChecks(
pParse, pTab, iCur, regNew, aRegIdx, regOldKey, 1, onError, addr, 0
);
if( bChngPk==0 ) aRegIdx[iPk] = regOldKey;
/* Do FK constraint checks. */
if( hasFK ){
sqlite4FkCheck(pParse, pTab, regOld, 0);
}
/* Delete the index entries associated with the current record. */
j1 = sqlite4VdbeAddOp4(v, OP_NotFound, iCur+iPk, 0, regOldKey, 0, P4_INT32);
sqlite4GenerateRowIndexDelete(pParse, pTab, 0, iCur, aRegIdx);
/* Delete the old record */
if( hasFK || bChngPk ){
sqlite4VdbeAddOp2(v, OP_Delete, iCur, 0);
}
sqlite4VdbeJumpHere(v, j1);
if( hasFK ){
sqlite4FkCheck(pParse, pTab, 0, regNew);
}
/* Insert the new index entries and the new record. */
sqlite4CompleteInsertion(pParse, pTab, iCur, regNew, aRegIdx, 1, 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
** to the row just updated. */
if( hasFK ){
sqlite4FkActions(pParse, pTab, pChanges, regOldTr);
}
}
sqlite4CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges,
TRIGGER_AFTER, pTab, regOldTr, onError, addr);
/* Repeat the above with the next record to be updated, until
** all record selected by the WHERE clause have been updated.
*/
sqlite4VdbeAddOp2(v, OP_Goto, 0, addr);
sqlite4VdbeJumpHere(v, addr);
/* Close all cursors */
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
assert( aRegIdx );
if( bOpenAll || aRegIdx[i] ){
sqlite4VdbeAddOp2(v, OP_Close, iCur+i, 0);
}
}
/* Update the sqlite_sequence table by storing the content of the
** maximum rowid counter values recorded while inserting into
** autoincrement tables.
*/
if( pParse->nested==0 && pParse->pTriggerTab==0 ){
sqlite4AutoincrementEnd(pParse);
}
update_cleanup:
sqlite4AuthContextPop(&sContext);
sqlite4DbFree(db, aRegIdx);
sqlite4DbFree(db, aXRef);
sqlite4SrcListDelete(db, pSrc);
sqlite4ExprListDelete(db, pChanges);
sqlite4ExprDelete(db, pWhere);
return;
}
/* Make sure "isView" and other macros defined above are undefined. Otherwise
** thely may interfere with compilation of other functions in this file
** (or in another file, if this file becomes part of the amalgamation). */
#ifdef isView
#undef isView
#endif
#ifdef pTrigger
#undef pTrigger
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** Generate code for an UPDATE of a virtual table.
**
** The strategy is that we create an ephemerial table that contains
** for each row to be changed:
**
** (A) The original rowid of that row.
** (B) The revised rowid for the row. (note1)
** (C) The content of every column in the row.
**
** Then we loop over this ephemeral table and for each row in
** the ephermeral table call VUpdate.
**
** When finished, drop the ephemeral table.
**
** (note1) Actually, if we know in advance that (A) is always the same
** as (B) we only store (A), then duplicate (A) when pulling
** it out of the ephemeral table before calling VUpdate.
*/
static void updateVirtualTable(
Parse *pParse, /* The parsing context */
SrcList *pSrc, /* The virtual table to be modified */
Table *pTab, /* The virtual table */
ExprList *pChanges, /* The columns to change in the UPDATE statement */
Expr *pRowid, /* Expression used to recompute the rowid */
int *aXRef, /* Mapping from columns of pTab to entries in pChanges */
Expr *pWhere, /* WHERE clause of the UPDATE statement */
int onError /* ON CONFLICT strategy */
){
Vdbe *v = pParse->pVdbe; /* Virtual machine under construction */
ExprList *pEList = 0; /* The result set of the SELECT statement */
Select *pSelect = 0; /* The SELECT statement */
Expr *pExpr; /* Temporary expression */
int ephemTab; /* Table holding the result of the SELECT */
int i; /* Loop counter */
int addr; /* Address of top of loop */
int iReg; /* First register in set passed to OP_VUpdate */
sqlite4 *db = pParse->db; /* Database connection */
const char *pVTab = (const char*)sqlite4GetVTable(db, pTab);
SelectDest dest;
/* Construct the SELECT statement that will find the new values for
** all updated rows.
*/
pEList = sqlite4ExprListAppend(pParse, 0, sqlite4Expr(db, TK_ID, "_rowid_"));
if( pRowid ){
pEList = sqlite4ExprListAppend(pParse, pEList,
sqlite4ExprDup(db, pRowid, 0));
}
assert( pTab->iPKey<0 );
for(i=0; i<pTab->nCol; i++){
if( aXRef[i]>=0 ){
pExpr = sqlite4ExprDup(db, pChanges->a[aXRef[i]].pExpr, 0);
}else{
pExpr = sqlite4Expr(db, TK_ID, pTab->aCol[i].zName);
}
pEList = sqlite4ExprListAppend(pParse, pEList, pExpr);
}
pSelect = sqlite4SelectNew(pParse, pEList, pSrc, pWhere, 0, 0, 0, 0, 0, 0);
/* Create the ephemeral table into which the update results will
** be stored.
*/
assert( v );
ephemTab = pParse->nTab++;
sqlite4VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, pTab->nCol+1+(pRowid!=0));
/* fill the ephemeral table
*/
sqlite4SelectDestInit(&dest, SRT_Table, ephemTab);
sqlite4Select(pParse, pSelect, &dest);
/* Generate code to scan the ephemeral table and call VUpdate. */
iReg = ++pParse->nMem;
pParse->nMem += pTab->nCol+1;
addr = sqlite4VdbeAddOp2(v, OP_Rewind, ephemTab, 0);
sqlite4VdbeAddOp3(v, OP_Column, ephemTab, 0, iReg);
sqlite4VdbeAddOp3(v, OP_Column, ephemTab, (pRowid?1:0), iReg+1);
for(i=0; i<pTab->nCol; i++){
sqlite4VdbeAddOp3(v, OP_Column, ephemTab, i+1+(pRowid!=0), iReg+2+i);
}
sqlite4VtabMakeWritable(pParse, pTab);
sqlite4VdbeAddOp4(v, OP_VUpdate, 0, pTab->nCol+2, iReg, pVTab, P4_VTAB);
sqlite4VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError);
sqlite4MayAbort(pParse);
sqlite4VdbeAddOp2(v, OP_Next, ephemTab, addr+1);
sqlite4VdbeJumpHere(v, addr);
sqlite4VdbeAddOp2(v, OP_Close, ephemTab, 0);
/* Cleanup */
sqlite4SelectDelete(db, pSelect);
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
/************** End of update.c **********************************************/
/************** Begin file where.c *******************************************/
/*
** 2001 September 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.
**
*************************************************************************
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements. This module is responsible for
** generating the code that loops through a table looking for applicable
** rows. Indices are selected and used to speed the search when doing
** so is applicable. Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
*/
/*
** Trace output macros
*/
#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
SQLITE_PRIVATE int sqlite4WhereTrace = 0;
#endif
#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
# define WHERETRACE(X) if(sqlite4WhereTrace) sqlite4DebugPrintf X
#else
# define WHERETRACE(X)
#endif
/* Forward reference
*/
typedef struct WhereClause WhereClause;
typedef struct WhereMaskSet WhereMaskSet;
typedef struct WhereOrInfo WhereOrInfo;
typedef struct WhereAndInfo WhereAndInfo;
typedef struct WhereCost WhereCost;
/*
** The query generator uses an array of instances of this structure to
** help it analyze the subexpressions of the WHERE clause. Each WHERE
** clause subexpression is separated from the others by AND operators,
** usually, or sometimes subexpressions separated by OR.
**
** All WhereTerms are collected into a single WhereClause structure.
** The following identity holds:
**
** WhereTerm.pWC->a[WhereTerm.idx] == WhereTerm
**
** When a term is of the form:
**
** X <op> <expr>
**
** where X is a column name and <op> is one of certain operators,
** then WhereTerm.leftCursor and WhereTerm.u.leftColumn record the
** cursor number and column number for X. WhereTerm.eOperator records
** the <op> using a bitmask encoding defined by WO_xxx below. The
** use of a bitmask encoding for the operator allows us to search
** quickly for terms that match any of several different operators.
**
** A WhereTerm might also be two or more subterms connected by OR:
**
** (t1.X <op> <expr>) OR (t1.Y <op> <expr>) OR ....
**
** In this second case, wtFlag as the TERM_ORINFO set and eOperator==WO_OR
** and the WhereTerm.u.pOrInfo field points to auxiliary information that
** is collected about the
**
** If a term in the WHERE clause does not match either of the two previous
** categories, then eOperator==0. The WhereTerm.pExpr field is still set
** to the original subexpression content and wtFlags is set up appropriately
** but no other fields in the WhereTerm object are meaningful.
**
** When eOperator!=0, prereqRight and prereqAll record sets of cursor numbers,
** but they do so indirectly. A single WhereMaskSet structure translates
** cursor number into bits and the translated bit is stored in the prereq
** fields. The translation is used in order to maximize the number of
** bits that will fit in a Bitmask. The VDBE cursor numbers might be
** spread out over the non-negative integers. For example, the cursor
** numbers might be 3, 8, 9, 10, 20, 23, 41, and 45. The WhereMaskSet
** translates these sparse cursor numbers into consecutive integers
** beginning with 0 in order to make the best possible use of the available
** bits in the Bitmask. So, in the example above, the cursor numbers
** would be mapped into integers 0 through 7.
**
** The number of terms in a join is limited by the number of bits
** in prereqRight and prereqAll. The default is 64 bits, hence SQLite
** is only able to process joins with 64 or fewer tables.
*/
typedef struct WhereTerm WhereTerm;
struct WhereTerm {
Expr *pExpr; /* Pointer to the subexpression that is this term */
int iParent; /* Disable pWC->a[iParent] when this term disabled */
int leftCursor; /* Cursor number of X in "X <op> <expr>" */
union {
int leftColumn; /* Column number of X in "X <op> <expr>" */
WhereOrInfo *pOrInfo; /* Extra information if eOperator==WO_OR */
WhereAndInfo *pAndInfo; /* Extra information if eOperator==WO_AND */
} u;
u16 eOperator; /* A WO_xx value describing <op> */
u8 wtFlags; /* TERM_xxx bit flags. See below */
u8 nChild; /* Number of children that must disable us */
WhereClause *pWC; /* The clause this term is part of */
Bitmask prereqRight; /* Bitmask of tables used by pExpr->pRight */
Bitmask prereqAll; /* Bitmask of tables referenced by pExpr */
};
/*
** Allowed values of WhereTerm.wtFlags
*/
#define TERM_DYNAMIC 0x01 /* Need to call sqlite4ExprDelete(db, pExpr) */
#define TERM_VIRTUAL 0x02 /* Added by the optimizer. Do not code */
#define TERM_CODED 0x04 /* This term is already coded */
#define TERM_COPIED 0x08 /* Has a child */
#define TERM_ORINFO 0x10 /* Need to free the WhereTerm.u.pOrInfo object */
#define TERM_ANDINFO 0x20 /* Need to free the WhereTerm.u.pAndInfo obj */
#define TERM_OR_OK 0x40 /* Used during OR-clause processing */
#ifdef SQLITE_ENABLE_STAT3
# define TERM_VNULL 0x80 /* Manufactured x>NULL or x<=NULL term */
#else
# define TERM_VNULL 0x00 /* Disabled if not using stat3 */
#endif
/*
** An instance of the following structure holds all information about a
** WHERE clause. Mostly this is a container for one or more WhereTerms.
**
** Explanation of pOuter: For a WHERE clause of the form
**
** a AND ((b AND c) OR (d AND e)) AND f
**
** There are separate WhereClause objects for the whole clause and for
** the subclauses "(b AND c)" and "(d AND e)". The pOuter field of the
** subclauses points to the WhereClause object for the whole clause.
*/
struct WhereClause {
Parse *pParse; /* The parser context */
WhereMaskSet *pMaskSet; /* Mapping of table cursor numbers to bitmasks */
Bitmask vmask; /* Bitmask identifying virtual table cursors */
WhereClause *pOuter; /* Outer conjunction */
u8 op; /* Split operator. TK_AND or TK_OR */
u16 wctrlFlags; /* Might include WHERE_AND_ONLY */
int nTerm; /* Number of terms */
int nSlot; /* Number of entries in a[] */
WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */
#if defined(SQLITE_SMALL_STACK)
WhereTerm aStatic[1]; /* Initial static space for a[] */
#else
WhereTerm aStatic[8]; /* Initial static space for a[] */
#endif
};
/*
** A WhereTerm with eOperator==WO_OR has its u.pOrInfo pointer set to
** a dynamically allocated instance of the following structure.
*/
struct WhereOrInfo {
WhereClause wc; /* Decomposition into subterms */
Bitmask indexable; /* Bitmask of all indexable tables in the clause */
};
/*
** A WhereTerm with eOperator==WO_AND has its u.pAndInfo pointer set to
** a dynamically allocated instance of the following structure.
*/
struct WhereAndInfo {
WhereClause wc; /* The subexpression broken out */
};
/*
** An instance of the following structure keeps track of a mapping
** between VDBE cursor numbers and bits of the bitmasks in WhereTerm.
**
** The VDBE cursor numbers are small integers contained in
** SrcList_item.iCursor and Expr.iTable fields. For any given WHERE
** clause, the cursor numbers might not begin with 0 and they might
** contain gaps in the numbering sequence. But we want to make maximum
** use of the bits in our bitmasks. This structure provides a mapping
** from the sparse cursor numbers into consecutive integers beginning
** with 0.
**
** If WhereMaskSet.ix[A]==B it means that The A-th bit of a Bitmask
** corresponds VDBE cursor number B. The A-th bit of a bitmask is 1<<A.
**
** For example, if the WHERE clause expression used these VDBE
** cursors: 4, 5, 8, 29, 57, 73. Then the WhereMaskSet structure
** would map those cursor numbers into bits 0 through 5.
**
** Note that the mapping is not necessarily ordered. In the example
** above, the mapping might go like this: 4->3, 5->1, 8->2, 29->0,
** 57->5, 73->4. Or one of 719 other combinations might be used. It
** does not really matter. What is important is that sparse cursor
** numbers all get mapped into bit numbers that begin with 0 and contain
** no gaps.
*/
struct WhereMaskSet {
int n; /* Number of assigned cursor values */
int ix[BMS]; /* Cursor assigned to each bit */
};
/*
** A WhereCost object records a lookup strategy and the estimated
** cost of pursuing that strategy.
*/
struct WhereCost {
WherePlan plan; /* The lookup strategy */
double rCost; /* Overall cost of pursuing this search strategy */
Bitmask used; /* Bitmask of cursors used by this plan */
};
/*
** Bitmasks for the operators that indices are able to exploit. An
** OR-ed combination of these values can be used when searching for
** terms in the where clause.
*/
#define WO_IN 0x001
#define WO_EQ 0x002
#define WO_LT (WO_EQ<<(TK_LT-TK_EQ))
#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_MATCH 0x040
#define WO_ISNULL 0x080
#define WO_OR 0x100 /* Two or more OR-connected terms */
#define WO_AND 0x200 /* Two or more AND-connected terms */
#define WO_NOOP 0x800 /* This term does not restrict search space */
#define WO_ALL 0xfff /* Mask of all possible WO_* values */
#define WO_SINGLE 0x0ff /* Mask of all non-compound WO_* values */
/*
** Value for wsFlags returned by bestIndex() and stored in
** WhereLevel.wsFlags. These flags determine which search
** strategies are appropriate.
**
** The least significant 12 bits is reserved as a mask for WO_ values above.
** The WhereLevel.wsFlags field is usually set to WO_IN|WO_EQ|WO_ISNULL.
** But if the table is the right table of a left join, WhereLevel.wsFlags
** is set to WO_IN|WO_EQ. The WhereLevel.wsFlags field can then be used as
** the "op" parameter to findTerm when we are resolving equality constraints.
** ISNULL constraints will then not be used on the right table of a left
** join. Tickets #2177 and #2189.
*/
#define WHERE_COLUMN_EQ 0x00010000 /* x=EXPR or x IN (...) or x IS NULL */
#define WHERE_COLUMN_RANGE 0x00020000 /* x<EXPR and/or x>EXPR */
#define WHERE_COLUMN_IN 0x00040000 /* x IN (...) */
#define WHERE_COLUMN_NULL 0x00080000 /* x IS NULL */
#define WHERE_INDEXED 0x000f0000 /* Anything that uses an index */
#define WHERE_NOT_FULLSCAN 0x100f3000 /* Does not do a full table scan */
#define WHERE_IN_ABLE 0x000f1000 /* Able to support an IN operator */
#define WHERE_TOP_LIMIT 0x00100000 /* x<EXPR or x<=EXPR constraint */
#define WHERE_BTM_LIMIT 0x00200000 /* x>EXPR or x>=EXPR constraint */
#define WHERE_BOTH_LIMIT 0x00300000 /* Both x>EXPR and x<EXPR */
#define WHERE_IDX_ONLY 0x00800000 /* Use index only - omit table */
#define WHERE_ORDERBY 0x01000000 /* Output will appear in correct order */
#define WHERE_REVERSE 0x02000000 /* Scan in reverse order */
#define WHERE_UNIQUE 0x04000000 /* Selects no more than one row */
#define WHERE_VIRTUALTABLE 0x08000000 /* Use virtual-table processing */
#define WHERE_MULTI_OR 0x10000000 /* OR using multiple indices */
#define WHERE_TEMP_INDEX 0x20000000 /* Uses an ephemeral index */
#define WHERE_DISTINCT 0x40000000 /* Correct order for DISTINCT */
/*
** Initialize a preallocated WhereClause structure.
*/
static void whereClauseInit(
WhereClause *pWC, /* The WhereClause to be initialized */
Parse *pParse, /* The parsing context */
WhereMaskSet *pMaskSet, /* Mapping from table cursor numbers to bitmasks */
u16 wctrlFlags /* Might include WHERE_AND_ONLY */
){
pWC->pParse = pParse;
pWC->pMaskSet = pMaskSet;
pWC->pOuter = 0;
pWC->nTerm = 0;
pWC->nSlot = ArraySize(pWC->aStatic);
pWC->a = pWC->aStatic;
pWC->vmask = 0;
pWC->wctrlFlags = wctrlFlags;
}
/* Forward reference */
static void whereClauseClear(WhereClause*);
/*
** Deallocate all memory associated with a WhereOrInfo object.
*/
static void whereOrInfoDelete(sqlite4 *db, WhereOrInfo *p){
whereClauseClear(&p->wc);
sqlite4DbFree(db, p);
}
/*
** Deallocate all memory associated with a WhereAndInfo object.
*/
static void whereAndInfoDelete(sqlite4 *db, WhereAndInfo *p){
whereClauseClear(&p->wc);
sqlite4DbFree(db, p);
}
/*
** Deallocate a WhereClause structure. The WhereClause structure
** itself is not freed. This routine is the inverse of whereClauseInit().
*/
static void whereClauseClear(WhereClause *pWC){
int i;
WhereTerm *a;
sqlite4 *db = pWC->pParse->db;
for(i=pWC->nTerm-1, a=pWC->a; i>=0; i--, a++){
if( a->wtFlags & TERM_DYNAMIC ){
sqlite4ExprDelete(db, a->pExpr);
}
if( a->wtFlags & TERM_ORINFO ){
whereOrInfoDelete(db, a->u.pOrInfo);
}else if( a->wtFlags & TERM_ANDINFO ){
whereAndInfoDelete(db, a->u.pAndInfo);
}
}
if( pWC->a!=pWC->aStatic ){
sqlite4DbFree(db, pWC->a);
}
}
/*
** Add a single new WhereTerm entry to the WhereClause object pWC.
** The new WhereTerm object is constructed from Expr p and with wtFlags.
** The index in pWC->a[] of the new WhereTerm is returned on success.
** 0 is returned if the new WhereTerm could not be added due to a memory
** allocation error. The memory allocation failure will be recorded in
** the db->mallocFailed flag so that higher-level functions can detect it.
**
** This routine will increase the size of the pWC->a[] array as necessary.
**
** If the wtFlags argument includes TERM_DYNAMIC, then responsibility
** for freeing the expression p is assumed by the WhereClause object pWC.
** This is true even if this routine fails to allocate a new WhereTerm.
**
** WARNING: This routine might reallocate the space used to store
** WhereTerms. All pointers to WhereTerms should be invalidated after
** calling this routine. Such pointers may be reinitialized by referencing
** the pWC->a[] array.
*/
static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
WhereTerm *pTerm;
int idx;
testcase( wtFlags & TERM_VIRTUAL ); /* EV: R-00211-15100 */
if( pWC->nTerm>=pWC->nSlot ){
WhereTerm *pOld = pWC->a;
sqlite4 *db = pWC->pParse->db;
pWC->a = sqlite4DbMallocRaw(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
if( pWC->a==0 ){
if( wtFlags & TERM_DYNAMIC ){
sqlite4ExprDelete(db, p);
}
pWC->a = pOld;
return 0;
}
memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm);
if( pOld!=pWC->aStatic ){
sqlite4DbFree(db, pOld);
}
pWC->nSlot = sqlite4DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
}
pTerm = &pWC->a[idx = pWC->nTerm++];
pTerm->pExpr = p;
pTerm->wtFlags = wtFlags;
pTerm->pWC = pWC;
pTerm->iParent = -1;
return idx;
}
/*
** This routine identifies subexpressions in the WHERE clause where
** each subexpression is separated by the AND operator or some other
** operator specified in the op parameter. The WhereClause structure
** is filled with pointers to subexpressions. For example:
**
** WHERE a=='hello' AND coalesce(b,11)<10 AND (c+12!=d OR c==22)
** \________/ \_______________/ \________________/
** slot[0] slot[1] slot[2]
**
** The original WHERE clause in pExpr is unaltered. All this routine
** does is make slot[] entries point to substructure within pExpr.
**
** In the previous sentence and in the diagram, "slot[]" refers to
** the WhereClause.a[] array. The slot[] array grows as needed to contain
** all terms of the WHERE clause.
*/
static void whereSplit(WhereClause *pWC, Expr *pExpr, int op){
pWC->op = (u8)op;
if( pExpr==0 ) return;
if( pExpr->op!=op ){
whereClauseInsert(pWC, pExpr, 0);
}else{
whereSplit(pWC, pExpr->pLeft, op);
whereSplit(pWC, pExpr->pRight, op);
}
}
/*
** Initialize an expression mask set (a WhereMaskSet object)
*/
#define initMaskSet(P) memset(P, 0, sizeof(*P))
/*
** Return the bitmask for the given cursor number. Return 0 if
** iCursor is not in the set.
*/
static Bitmask getMask(WhereMaskSet *pMaskSet, int iCursor){
int i;
assert( pMaskSet->n<=(int)sizeof(Bitmask)*8 );
for(i=0; i<pMaskSet->n; i++){
if( pMaskSet->ix[i]==iCursor ){
return ((Bitmask)1)<<i;
}
}
return 0;
}
/*
** Create a new mask for cursor iCursor.
**
** There is one cursor per table in the FROM clause. The number of
** tables in the FROM clause is limited by a test early in the
** sqlite4WhereBegin() routine. So we know that the pMaskSet->ix[]
** array will never overflow.
*/
static void createMask(WhereMaskSet *pMaskSet, int iCursor){
assert( pMaskSet->n < ArraySize(pMaskSet->ix) );
pMaskSet->ix[pMaskSet->n++] = iCursor;
}
/*
** This routine walks (recursively) an expression tree and generates
** a bitmask indicating which tables are used in that expression
** tree.
**
** In order for this routine to work, the calling function must have
** previously invoked sqlite4ResolveExprNames() on the expression. See
** the header comment on that routine for additional information.
** The sqlite4ResolveExprNames() routines looks for column names and
** sets their opcodes to TK_COLUMN and their Expr.iTable fields to
** the VDBE cursor number of the table. This routine just has to
** translate the cursor numbers into bitmask values and OR all
** the bitmasks together.
*/
static Bitmask exprListTableUsage(WhereMaskSet*, ExprList*);
static Bitmask exprSelectTableUsage(WhereMaskSet*, Select*);
static Bitmask exprTableUsage(WhereMaskSet *pMaskSet, Expr *p){
Bitmask mask = 0;
if( p==0 ) return 0;
if( p->op==TK_COLUMN ){
mask = getMask(pMaskSet, p->iTable);
return mask;
}
mask = exprTableUsage(pMaskSet, p->pRight);
mask |= exprTableUsage(pMaskSet, p->pLeft);
if( ExprHasProperty(p, EP_xIsSelect) ){
mask |= exprSelectTableUsage(pMaskSet, p->x.pSelect);
}else{
mask |= exprListTableUsage(pMaskSet, p->x.pList);
}
return mask;
}
static Bitmask exprListTableUsage(WhereMaskSet *pMaskSet, ExprList *pList){
int i;
Bitmask mask = 0;
if( pList ){
for(i=0; i<pList->nExpr; i++){
mask |= exprTableUsage(pMaskSet, pList->a[i].pExpr);
}
}
return mask;
}
static Bitmask exprSelectTableUsage(WhereMaskSet *pMaskSet, Select *pS){
Bitmask mask = 0;
while( pS ){
SrcList *pSrc = pS->pSrc;
mask |= exprListTableUsage(pMaskSet, pS->pEList);
mask |= exprListTableUsage(pMaskSet, pS->pGroupBy);
mask |= exprListTableUsage(pMaskSet, pS->pOrderBy);
mask |= exprTableUsage(pMaskSet, pS->pWhere);
mask |= exprTableUsage(pMaskSet, pS->pHaving);
if( ALWAYS(pSrc!=0) ){
int i;
for(i=0; i<pSrc->nSrc; i++){
mask |= exprSelectTableUsage(pMaskSet, pSrc->a[i].pSelect);
mask |= exprTableUsage(pMaskSet, pSrc->a[i].pOn);
}
}
pS = pS->pPrior;
}
return mask;
}
/*
** Return TRUE if the given operator is one of the operators that is
** allowed for an indexable WHERE clause term. The allowed operators are
** "=", "<", ">", "<=", ">=", and "IN".
**
** IMPLEMENTATION-OF: R-59926-26393 To be usable by an index a term must be
** of one of the following forms: column = expression column > expression
** column >= expression column < expression column <= expression
** expression = column expression > column expression >= column
** expression < column expression <= column column IN
** (expression-list) column IN (subquery) column IS NULL
*/
static int allowedOp(int op){
assert( TK_GT>TK_EQ && TK_GT<TK_GE );
assert( TK_LT>TK_EQ && TK_LT<TK_GE );
assert( TK_LE>TK_EQ && TK_LE<TK_GE );
assert( TK_GE==TK_EQ+4 );
return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL;
}
/*
** Swap two objects of type TYPE.
*/
#define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
/*
** Commute a comparison operator. Expressions of the form "X op Y"
** are converted into "Y op X".
**
** If a collation sequence is associated with either the left or right
** side of the comparison, it remains associated with the same side after
** the commutation. So "Y collate NOCASE op X" becomes
** "X collate NOCASE op Y". This is because any collation sequence on
** the left hand side of a comparison overrides any collation sequence
** attached to the right. For the same reason the EP_ExpCollate flag
** is not commuted.
*/
static void exprCommute(Parse *pParse, Expr *pExpr){
u16 expRight = (pExpr->pRight->flags & EP_ExpCollate);
u16 expLeft = (pExpr->pLeft->flags & EP_ExpCollate);
assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN );
pExpr->pRight->pColl = sqlite4ExprCollSeq(pParse, pExpr->pRight);
pExpr->pLeft->pColl = sqlite4ExprCollSeq(pParse, pExpr->pLeft);
SWAP(CollSeq*,pExpr->pRight->pColl,pExpr->pLeft->pColl);
pExpr->pRight->flags = (pExpr->pRight->flags & ~EP_ExpCollate) | expLeft;
pExpr->pLeft->flags = (pExpr->pLeft->flags & ~EP_ExpCollate) | expRight;
SWAP(Expr*,pExpr->pRight,pExpr->pLeft);
if( pExpr->op>=TK_GT ){
assert( TK_LT==TK_GT+2 );
assert( TK_GE==TK_LE+2 );
assert( TK_GT>TK_EQ );
assert( TK_GT<TK_LE );
assert( pExpr->op>=TK_GT && pExpr->op<=TK_GE );
pExpr->op = ((pExpr->op-TK_GT)^2)+TK_GT;
}
}
/*
** Translate from TK_xx operator to WO_xx bitmask.
*/
static u16 operatorMask(int op){
u16 c;
assert( allowedOp(op) );
if( op==TK_IN ){
c = WO_IN;
}else if( op==TK_ISNULL ){
c = WO_ISNULL;
}else{
assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff );
c = (u16)(WO_EQ<<(op-TK_EQ));
}
assert( op!=TK_ISNULL || c==WO_ISNULL );
assert( op!=TK_IN || c==WO_IN );
assert( op!=TK_EQ || c==WO_EQ );
assert( op!=TK_LT || c==WO_LT );
assert( op!=TK_LE || c==WO_LE );
assert( op!=TK_GT || c==WO_GT );
assert( op!=TK_GE || c==WO_GE );
return c;
}
/*
** 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 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.
*/
static WhereTerm *findTerm(
WhereClause *pWC, /* The WHERE clause to be searched */
int iCur, /* Cursor number of LHS */
int iColumn, /* Column number of LHS */
Bitmask notReady, /* RHS must not overlap with this mask */
u32 op, /* Mask of WO_xx values describing operator */
Index *pIdx /* Must be compatible with this index, if not NULL */
){
sqlite4 *db = pWC->pParse->db; /* Database handle */
WhereTerm *pTerm;
int k;
assert( iCur>=0 );
op &= WO_ALL;
for(; pWC; pWC=pWC->pOuter){
for(pTerm=pWC->a, k=pWC->nTerm; k; k--, pTerm++){
if( pTerm->leftCursor==iCur
&& (pTerm->prereqRight & notReady)==0
&& pTerm->u.leftColumn==iColumn
&& (pTerm->eOperator & op)!=0
){
if( iColumn>=0 && pIdx && pTerm->eOperator!=WO_ISNULL ){
Table *pTab = pIdx->pTable;
const char *zColl; /* Collation sequence used by index */
CollSeq *pColl; /* Collation sequence used by expression */
Expr *pX = pTerm->pExpr;
int j;
Parse *pParse = pWC->pParse;
if( !sqlite4IndexAffinityOk(pX, pTab->aCol[iColumn].affinity) ){
continue;
}
/* Figure out the collation sequence used by expression pX. Store
** this in pColl. Also the collation sequence used by the index.
** Store this one in zColl. */
assert(pX->pLeft);
pColl = sqlite4BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
for(j=0; pIdx->aiColumn[j]!=iColumn && j<pIdx->nColumn; j++);
if( j>=pIdx->nColumn ){
zColl = pTab->aCol[iColumn].zColl;
}else{
zColl = pIdx->azColl[j];
}
/* If the collation sequence used by the index is not the same as
** that used by the expression, then this term is not a match. */
if( pColl!=sqlite4FindCollSeq(db, ENC(db), zColl, 0) ) continue;
}
return pTerm;
}
}
}
return 0;
}
/* Forward reference */
static void exprAnalyze(SrcList*, WhereClause*, int);
/*
** Call exprAnalyze on all terms in a WHERE clause.
**
** Note that exprAnalyze() might add new virtual terms onto the end of
** the WHERE clause. We do not want to analyze these virtual terms, so
** start analyzing at the end and work forward so that the added virtual
** terms are never processed.
*/
static void exprAnalyzeAll(
SrcList *pTabList, /* the FROM clause */
WhereClause *pWC /* the WHERE clause to be analyzed */
){
int i;
for(i=pWC->nTerm-1; i>=0; i--){
exprAnalyze(pTabList, pWC, i);
}
}
#ifndef SQLITE_OMIT_LIKE_OPTIMIZATION
/*
** Check to see if the given expression is a LIKE or GLOB operator that
** can be optimized using inequality constraints. Return TRUE if it is
** so and false if not.
**
** In order for the operator to be optimizible, the RHS must be a string
** literal that does not begin with a wildcard.
*/
static int isLikeOrGlob(
Parse *pParse, /* Parsing and code generating context */
Expr *pExpr, /* Test this expression */
Expr **ppPrefix, /* Pointer to TK_STRING expression with pattern prefix */
int *pisComplete, /* True if the only wildcard is % in the last character */
int *pnoCase /* True if uppercase is equivalent to lowercase */
){
const char *z = 0; /* String on RHS of LIKE operator */
Expr *pRight, *pLeft; /* Right and left size of LIKE operator */
ExprList *pList; /* List of operands to the LIKE operator */
int c; /* One character in z[] */
int cnt; /* Number of non-wildcard prefix characters */
char wc[3]; /* Wildcard characters */
sqlite4 *db = pParse->db; /* Database connection */
sqlite4_value *pVal = 0;
int op; /* Opcode of pRight */
if( !sqlite4IsLikeFunction(db, pExpr, pnoCase, wc) ){
return 0;
}
#ifdef SQLITE_EBCDIC
if( *pnoCase ) return 0;
#endif
pList = pExpr->x.pList;
pLeft = pList->a[1].pExpr;
if( pLeft->op!=TK_COLUMN || sqlite4ExprAffinity(pLeft)!=SQLITE_AFF_TEXT ){
/* IMP: R-02065-49465 The left-hand side of the LIKE or GLOB operator must
** be the name of an indexed column with TEXT affinity. */
return 0;
}
assert( pLeft->iColumn!=(-1) ); /* Because IPK never has AFF_TEXT */
pRight = pList->a[0].pExpr;
op = pRight->op;
if( op==TK_REGISTER ){
op = pRight->op2;
}
if( op==TK_VARIABLE ){
Vdbe *pReprepare = pParse->pReprepare;
int iCol = pRight->iColumn;
pVal = sqlite4VdbeGetValue(pReprepare, iCol, SQLITE_AFF_NONE);
if( pVal && sqlite4_value_type(pVal)==SQLITE_TEXT ){
z = (char *)sqlite4_value_text(pVal);
}
sqlite4VdbeSetVarmask(pParse->pVdbe, iCol);
assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER );
}else if( op==TK_STRING ){
z = pRight->u.zToken;
}
if( z ){
cnt = 0;
while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
cnt++;
}
if( cnt!=0 && 255!=(u8)z[cnt-1] ){
Expr *pPrefix;
*pisComplete = c==wc[0] && z[cnt+1]==0;
pPrefix = sqlite4Expr(db, TK_STRING, z);
if( pPrefix ) pPrefix->u.zToken[cnt] = 0;
*ppPrefix = pPrefix;
if( op==TK_VARIABLE ){
Vdbe *v = pParse->pVdbe;
sqlite4VdbeSetVarmask(v, pRight->iColumn);
if( *pisComplete && pRight->u.zToken[1] ){
/* If the rhs of the LIKE expression is a variable, and the current
** value of the variable means there is no need to invoke the LIKE
** function, then no OP_Variable will be added to the program.
** This causes problems for the sqlite4_bind_parameter_name()
** API. To workaround them, add a dummy OP_Variable here.
*/
int r1 = sqlite4GetTempReg(pParse);
sqlite4ExprCodeTarget(pParse, pRight, r1);
sqlite4VdbeChangeP3(v, sqlite4VdbeCurrentAddr(v)-1, 0);
sqlite4ReleaseTempReg(pParse, r1);
}
}
}else{
z = 0;
}
}
sqlite4ValueFree(pVal);
return (z!=0);
}
#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */
#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** Check to see if the given expression is of the form
**
** column MATCH expr
**
** If it is then return TRUE. If not, return FALSE.
*/
static int isMatchOfColumn(
Expr *pExpr /* Test this expression */
){
ExprList *pList;
if( pExpr->op!=TK_FUNCTION ){
return 0;
}
if( sqlite4StrICmp(pExpr->u.zToken,"match")!=0 ){
return 0;
}
pList = pExpr->x.pList;
if( pList->nExpr!=2 ){
return 0;
}
if( pList->a[1].pExpr->op != TK_COLUMN ){
return 0;
}
return 1;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
/*
** If the pBase expression originated in the ON or USING clause of
** a join, then transfer the appropriate markings over to derived.
*/
static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
pDerived->flags |= pBase->flags & EP_FromJoin;
pDerived->iRightJoinTable = pBase->iRightJoinTable;
}
#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY)
/*
** Analyze a term that consists of two or more OR-connected
** subterms. So in:
**
** ... WHERE (a=5) AND (b=7 OR c=9 OR d=13) AND (d=13)
** ^^^^^^^^^^^^^^^^^^^^
**
** This routine analyzes terms such as the middle term in the above example.
** A WhereOrTerm object is computed and attached to the term under
** analysis, regardless of the outcome of the analysis. Hence:
**
** WhereTerm.wtFlags |= TERM_ORINFO
** WhereTerm.u.pOrInfo = a dynamically allocated WhereOrTerm object
**
** The term being analyzed must have two or more of OR-connected subterms.
** A single subterm might be a set of AND-connected sub-subterms.
** Examples of terms under analysis:
**
** (A) t1.x=t2.y OR t1.x=t2.z OR t1.y=15 OR t1.z=t3.a+5
** (B) x=expr1 OR expr2=x OR x=expr3
** (C) t1.x=t2.y OR (t1.x=t2.z AND t1.y=15)
** (D) x=expr1 OR (y>11 AND y<22 AND z LIKE '*hello*')
** (E) (p.a=1 AND q.b=2 AND r.c=3) OR (p.x=4 AND q.y=5 AND r.z=6)
**
** CASE 1:
**
** If all subterms are of the form T.C=expr for some single column of C
** a single table T (as shown in example B above) then create a new virtual
** term that is an equivalent IN expression. In other words, if the term
** being analyzed is:
**
** x = expr1 OR expr2 = x OR x = expr3
**
** then create a new virtual term like this:
**
** x IN (expr1,expr2,expr3)
**
** CASE 2:
**
** If all subterms are indexable by a single table T, then set
**
** WhereTerm.eOperator = WO_OR
** WhereTerm.u.pOrInfo->indexable |= the cursor number for table T
**
** A subterm is "indexable" if it is of the form
** "T.C <op> <expr>" where C is any column of table T and
** <op> is one of "=", "<", "<=", ">", ">=", "IS NULL", or "IN".
** A subterm is also indexable if it is an AND of two or more
** subsubterms at least one of which is indexable. Indexable AND
** subterms have their eOperator set to WO_AND and they have
** u.pAndInfo set to a dynamically allocated WhereAndTerm object.
**
** From another point of view, "indexable" means that the subterm could
** potentially be used with an index if an appropriate index exists.
** This analysis does not consider whether or not the index exists; that
** is something the bestIndex() routine will determine. This analysis
** only looks at whether subterms appropriate for indexing exist.
**
** All examples A through E above all satisfy case 2. But if a term
** also statisfies case 1 (such as B) we know that the optimizer will
** always prefer case 1, so in that case we pretend that case 2 is not
** satisfied.
**
** It might be the case that multiple tables are indexable. For example,
** (E) above is indexable on tables P, Q, and R.
**
** Terms that satisfy case 2 are candidates for lookup by using
** separate indices to find rowids for each subterm and composing
** the union of all rowids using a RowSet object. This is similar
** to "bitmap indices" in other database engines.
**
** OTHERWISE:
**
** If neither case 1 nor case 2 apply, then leave the eOperator set to
** zero. This term is not useful for search.
*/
static void exprAnalyzeOrTerm(
SrcList *pSrc, /* the FROM clause */
WhereClause *pWC, /* the complete WHERE clause */
int idxTerm /* Index of the OR-term to be analyzed */
){
Parse *pParse = pWC->pParse; /* Parser context */
sqlite4 *db = pParse->db; /* Database connection */
WhereTerm *pTerm = &pWC->a[idxTerm]; /* The term to be analyzed */
Expr *pExpr = pTerm->pExpr; /* The expression of the term */
WhereMaskSet *pMaskSet = pWC->pMaskSet; /* Table use masks */
int i; /* Loop counters */
WhereClause *pOrWc; /* Breakup of pTerm into subterms */
WhereTerm *pOrTerm; /* A Sub-term within the pOrWc */
WhereOrInfo *pOrInfo; /* Additional information associated with pTerm */
Bitmask chngToIN; /* Tables that might satisfy case 1 */
Bitmask indexable; /* Tables that are indexable, satisfying case 2 */
/*
** Break the OR clause into its separate subterms. The subterms are
** stored in a WhereClause structure containing within the WhereOrInfo
** object that is attached to the original OR clause term.
*/
assert( (pTerm->wtFlags & (TERM_DYNAMIC|TERM_ORINFO|TERM_ANDINFO))==0 );
assert( pExpr->op==TK_OR );
pTerm->u.pOrInfo = pOrInfo = sqlite4DbMallocZero(db, sizeof(*pOrInfo));
if( pOrInfo==0 ) return;
pTerm->wtFlags |= TERM_ORINFO;
pOrWc = &pOrInfo->wc;
whereClauseInit(pOrWc, pWC->pParse, pMaskSet, pWC->wctrlFlags);
whereSplit(pOrWc, pExpr, TK_OR);
exprAnalyzeAll(pSrc, pOrWc);
if( db->mallocFailed ) return;
assert( pOrWc->nTerm>=2 );
/*
** Compute the set of tables that might satisfy cases 1 or 2.
*/
indexable = ~(Bitmask)0;
chngToIN = ~(pWC->vmask);
for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0 && indexable; i--, pOrTerm++){
if( (pOrTerm->eOperator & WO_SINGLE)==0 ){
WhereAndInfo *pAndInfo;
assert( pOrTerm->eOperator==0 );
assert( (pOrTerm->wtFlags & (TERM_ANDINFO|TERM_ORINFO))==0 );
chngToIN = 0;
pAndInfo = sqlite4DbMallocRaw(db, sizeof(*pAndInfo));
if( pAndInfo ){
WhereClause *pAndWC;
WhereTerm *pAndTerm;
int j;
Bitmask b = 0;
pOrTerm->u.pAndInfo = pAndInfo;
pOrTerm->wtFlags |= TERM_ANDINFO;
pOrTerm->eOperator = WO_AND;
pAndWC = &pAndInfo->wc;
whereClauseInit(pAndWC, pWC->pParse, pMaskSet, pWC->wctrlFlags);
whereSplit(pAndWC, pOrTerm->pExpr, TK_AND);
exprAnalyzeAll(pSrc, pAndWC);
pAndWC->pOuter = pWC;
testcase( db->mallocFailed );
if( !db->mallocFailed ){
for(j=0, pAndTerm=pAndWC->a; j<pAndWC->nTerm; j++, pAndTerm++){
assert( pAndTerm->pExpr );
if( allowedOp(pAndTerm->pExpr->op) ){
b |= getMask(pMaskSet, pAndTerm->leftCursor);
}
}
}
indexable &= b;
}
}else if( pOrTerm->wtFlags & TERM_COPIED ){
/* Skip this term for now. We revisit it when we process the
** corresponding TERM_VIRTUAL term */
}else{
Bitmask b;
b = getMask(pMaskSet, pOrTerm->leftCursor);
if( pOrTerm->wtFlags & TERM_VIRTUAL ){
WhereTerm *pOther = &pOrWc->a[pOrTerm->iParent];
b |= getMask(pMaskSet, pOther->leftCursor);
}
indexable &= b;
if( pOrTerm->eOperator!=WO_EQ ){
chngToIN = 0;
}else{
chngToIN &= b;
}
}
}
/*
** Record the set of tables that satisfy case 2. The set might be
** empty.
*/
pOrInfo->indexable = indexable;
pTerm->eOperator = indexable==0 ? 0 : WO_OR;
/*
** chngToIN holds a set of tables that *might* satisfy case 1. But
** we have to do some additional checking to see if case 1 really
** is satisfied.
**
** chngToIN will hold either 0, 1, or 2 bits. The 0-bit case means
** that there is no possibility of transforming the OR clause into an
** IN operator because one or more terms in the OR clause contain
** something other than == on a column in the single table. The 1-bit
** case means that every term of the OR clause is of the form
** "table.column=expr" for some single table. The one bit that is set
** will correspond to the common table. We still need to check to make
** sure the same column is used on all terms. The 2-bit case is when
** the all terms are of the form "table1.column=table2.column". It
** might be possible to form an IN operator with either table1.column
** or table2.column as the LHS if either is common to every term of
** the OR clause.
**
** Note that terms of the form "table.column1=table.column2" (the
** same table on both sizes of the ==) cannot be optimized.
*/
if( chngToIN ){
int okToChngToIN = 0; /* True if the conversion to IN is valid */
int iColumn = -1; /* Column index on lhs of IN operator */
int iCursor = -1; /* Table cursor common to all terms */
int j = 0; /* Loop counter */
/* Search for a table and column that appears on one side or the
** other of the == operator in every subterm. That table and column
** will be recorded in iCursor and iColumn. There might not be any
** such table and column. Set okToChngToIN if an appropriate table
** and column is found but leave okToChngToIN false if not found.
*/
for(j=0; j<2 && !okToChngToIN; j++){
pOrTerm = pOrWc->a;
for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){
assert( pOrTerm->eOperator==WO_EQ );
pOrTerm->wtFlags &= ~TERM_OR_OK;
if( pOrTerm->leftCursor==iCursor ){
/* This is the 2-bit case and we are on the second iteration and
** current term is from the first iteration. So skip this term. */
assert( j==1 );
continue;
}
if( (chngToIN & getMask(pMaskSet, pOrTerm->leftCursor))==0 ){
/* This term must be of the form t1.a==t2.b where t2 is in the
** chngToIN set but t1 is not. This term will be either preceeded
** or follwed by an inverted copy (t2.b==t1.a). Skip this term
** and use its inversion. */
testcase( pOrTerm->wtFlags & TERM_COPIED );
testcase( pOrTerm->wtFlags & TERM_VIRTUAL );
assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) );
continue;
}
iColumn = pOrTerm->u.leftColumn;
iCursor = pOrTerm->leftCursor;
break;
}
if( i<0 ){
/* No candidate table+column was found. This can only occur
** on the second iteration */
assert( j==1 );
assert( (chngToIN&(chngToIN-1))==0 );
assert( chngToIN==getMask(pMaskSet, iCursor) );
break;
}
testcase( j==1 );
/* We have found a candidate table and column. Check to see if that
** table and column is common to every term in the OR clause */
okToChngToIN = 1;
for(; i>=0 && okToChngToIN; i--, pOrTerm++){
assert( pOrTerm->eOperator==WO_EQ );
if( pOrTerm->leftCursor!=iCursor ){
pOrTerm->wtFlags &= ~TERM_OR_OK;
}else if( pOrTerm->u.leftColumn!=iColumn ){
okToChngToIN = 0;
}else{
int affLeft, affRight;
/* If the right-hand side is also a column, then the affinities
** of both right and left sides must be such that no type
** conversions are required on the right. (Ticket #2249)
*/
affRight = sqlite4ExprAffinity(pOrTerm->pExpr->pRight);
affLeft = sqlite4ExprAffinity(pOrTerm->pExpr->pLeft);
if( affRight!=0 && affRight!=affLeft ){
okToChngToIN = 0;
}else{
pOrTerm->wtFlags |= TERM_OR_OK;
}
}
}
}
/* At this point, okToChngToIN is true if original pTerm satisfies
** case 1. In that case, construct a new virtual term that is
** pTerm converted into an IN operator.
**
** EV: R-00211-15100
*/
if( okToChngToIN ){
Expr *pDup; /* A transient duplicate expression */
ExprList *pList = 0; /* The RHS of the IN operator */
Expr *pLeft = 0; /* The LHS of the IN operator */
Expr *pNew; /* The complete IN operator */
for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0; i--, pOrTerm++){
if( (pOrTerm->wtFlags & TERM_OR_OK)==0 ) continue;
assert( pOrTerm->eOperator==WO_EQ );
assert( pOrTerm->leftCursor==iCursor );
assert( pOrTerm->u.leftColumn==iColumn );
pDup = sqlite4ExprDup(db, pOrTerm->pExpr->pRight, 0);
pList = sqlite4ExprListAppend(pWC->pParse, pList, pDup);
pLeft = pOrTerm->pExpr->pLeft;
}
assert( pLeft!=0 );
pDup = sqlite4ExprDup(db, pLeft, 0);
pNew = sqlite4PExpr(pParse, TK_IN, pDup, 0, 0);
if( pNew ){
int idxNew;
transferJoinMarkings(pNew, pExpr);
assert( !ExprHasProperty(pNew, EP_xIsSelect) );
pNew->x.pList = pList;
idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew==0 );
exprAnalyze(pSrc, pWC, idxNew);
pTerm = &pWC->a[idxTerm];
pWC->a[idxNew].iParent = idxTerm;
pTerm->nChild = 1;
}else{
sqlite4ExprListDelete(db, pList);
}
pTerm->eOperator = WO_NOOP; /* case 1 trumps case 2 */
}
}
}
#endif /* !SQLITE_OMIT_OR_OPTIMIZATION && !SQLITE_OMIT_SUBQUERY */
/*
** 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
** structure.
**
** If the expression is of the form "<expr> <op> X" it gets commuted
** to the standard form of "X <op> <expr>".
**
** If the expression is of the form "X <op> Y" where both X and Y are
** columns, then the original expression is unchanged and a new virtual
** term of the form "Y <op> X" is added to the WHERE clause and
** analyzed separately. The original term is marked with TERM_COPIED
** and the new term is marked with TERM_DYNAMIC (because it's pExpr
** needs to be freed with the WhereClause) and TERM_VIRTUAL (because it
** is a commuted copy of a prior term.) The original term has nChild=1
** and the copy has idxParent set to the index of the original term.
*/
static void exprAnalyze(
SrcList *pSrc, /* the FROM clause */
WhereClause *pWC, /* the WHERE clause */
int idxTerm /* Index of the term to be analyzed */
){
WhereTerm *pTerm; /* The term to be analyzed */
WhereMaskSet *pMaskSet; /* Set of table index masks */
Expr *pExpr; /* The expression to be analyzed */
Bitmask prereqLeft; /* Prerequesites of the pExpr->pLeft */
Bitmask prereqAll; /* Prerequesites of pExpr */
Bitmask extraRight = 0; /* Extra dependencies on LEFT JOIN */
Expr *pStr1 = 0; /* RHS of LIKE/GLOB operator */
int isComplete = 0; /* RHS of LIKE/GLOB ends with wildcard */
int noCase = 0; /* LIKE/GLOB distinguishes case */
int op; /* Top-level operator. pExpr->op */
Parse *pParse = pWC->pParse; /* Parsing context */
sqlite4 *db = pParse->db; /* Database connection */
if( db->mallocFailed ){
return;
}
pTerm = &pWC->a[idxTerm];
pMaskSet = pWC->pMaskSet;
pExpr = pTerm->pExpr;
prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
op = pExpr->op;
if( op==TK_IN ){
assert( pExpr->pRight==0 );
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
pTerm->prereqRight = exprSelectTableUsage(pMaskSet, pExpr->x.pSelect);
}else{
pTerm->prereqRight = exprListTableUsage(pMaskSet, pExpr->x.pList);
}
}else if( op==TK_ISNULL ){
pTerm->prereqRight = 0;
}else{
pTerm->prereqRight = exprTableUsage(pMaskSet, pExpr->pRight);
}
prereqAll = exprTableUsage(pMaskSet, pExpr);
if( ExprHasProperty(pExpr, EP_FromJoin) ){
Bitmask x = getMask(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 */
}
pTerm->prereqAll = prereqAll;
pTerm->leftCursor = -1;
pTerm->iParent = -1;
pTerm->eOperator = 0;
if( allowedOp(op) && (pTerm->prereqRight & prereqLeft)==0 ){
Expr *pLeft = pExpr->pLeft;
Expr *pRight = pExpr->pRight;
if( pLeft->op==TK_COLUMN ){
pTerm->leftCursor = pLeft->iTable;
pTerm->u.leftColumn = pLeft->iColumn;
pTerm->eOperator = operatorMask(op);
}
if( pRight && pRight->op==TK_COLUMN ){
WhereTerm *pNew;
Expr *pDup;
if( pTerm->leftCursor>=0 ){
int idxNew;
pDup = sqlite4ExprDup(db, pExpr, 0);
if( db->mallocFailed ){
sqlite4ExprDelete(db, pDup);
return;
}
idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
if( idxNew==0 ) return;
pNew = &pWC->a[idxNew];
pNew->iParent = idxTerm;
pTerm = &pWC->a[idxTerm];
pTerm->nChild = 1;
pTerm->wtFlags |= TERM_COPIED;
}else{
pDup = pExpr;
pNew = pTerm;
}
exprCommute(pParse, pDup);
pLeft = pDup->pLeft;
pNew->leftCursor = pLeft->iTable;
pNew->u.leftColumn = pLeft->iColumn;
testcase( (prereqLeft | extraRight) != prereqLeft );
pNew->prereqRight = prereqLeft | extraRight;
pNew->prereqAll = prereqAll;
pNew->eOperator = operatorMask(pDup->op);
}
}
#ifndef SQLITE_OMIT_BETWEEN_OPTIMIZATION
/* If a term is the BETWEEN operator, create two new virtual terms
** that define the range that the BETWEEN implements. For example:
**
** a BETWEEN b AND c
**
** is converted into:
**
** (a BETWEEN b AND c) AND (a>=b) AND (a<=c)
**
** The two new terms are added onto the end of the WhereClause object.
** The new terms are "dynamic" and are children of the original BETWEEN
** term. That means that if the BETWEEN term is coded, the children are
** skipped. Or, if the children are satisfied by an index, the original
** BETWEEN term is skipped.
*/
else if( pExpr->op==TK_BETWEEN && pWC->op==TK_AND ){
ExprList *pList = pExpr->x.pList;
int i;
static const u8 ops[] = {TK_GE, TK_LE};
assert( pList!=0 );
assert( pList->nExpr==2 );
for(i=0; i<2; i++){
Expr *pNewExpr;
int idxNew;
pNewExpr = sqlite4PExpr(pParse, ops[i],
sqlite4ExprDup(db, pExpr->pLeft, 0),
sqlite4ExprDup(db, pList->a[i].pExpr, 0), 0);
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew==0 );
exprAnalyze(pSrc, pWC, idxNew);
pTerm = &pWC->a[idxTerm];
pWC->a[idxNew].iParent = idxTerm;
}
pTerm->nChild = 2;
}
#endif /* SQLITE_OMIT_BETWEEN_OPTIMIZATION */
#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY)
/* Analyze a term that is composed of two or more subterms connected by
** an OR operator.
*/
else if( pExpr->op==TK_OR ){
assert( pWC->op==TK_AND );
exprAnalyzeOrTerm(pSrc, pWC, idxTerm);
pTerm = &pWC->a[idxTerm];
}
#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
#ifndef SQLITE_OMIT_LIKE_OPTIMIZATION
/* Add constraints to reduce the search space on a LIKE or GLOB
** operator.
**
** A like pattern of the form "x LIKE 'abc%'" is changed into constraints
**
** x>='abc' AND x<'abd' AND x LIKE 'abc%'
**
** The last character of the prefix "abc" is incremented to form the
** termination condition "abd".
*/
if( pWC->op==TK_AND
&& isLikeOrGlob(pParse, pExpr, &pStr1, &isComplete, &noCase)
){
Expr *pLeft; /* LHS of LIKE/GLOB operator */
Expr *pStr2; /* Copy of pStr1 - RHS of LIKE/GLOB operator */
Expr *pNewExpr1;
Expr *pNewExpr2;
int idxNew1;
int idxNew2;
CollSeq *pColl; /* Collating sequence to use */
pLeft = pExpr->x.pList->a[1].pExpr;
pStr2 = sqlite4ExprDup(db, pStr1, 0);
if( !db->mallocFailed ){
u8 c, *pC; /* Last character before the first wildcard */
pC = (u8*)&pStr2->u.zToken[sqlite4Strlen30(pStr2->u.zToken)-1];
c = *pC;
if( noCase ){
/* The point is to increment the last character before the first
** wildcard. But if we increment '@', that will push it into the
** alphabetic range where case conversions will mess up the
** inequality. To avoid this, make sure to also run the full
** LIKE on all candidate expressions by clearing the isComplete flag
*/
if( c=='A'-1 ) isComplete = 0; /* EV: R-64339-08207 */
c = sqlite4UpperToLower[c];
}
*pC = c + 1;
}
pColl = sqlite4FindCollSeq(db, SQLITE_UTF8, noCase ? "NOCASE" : "BINARY",0);
pNewExpr1 = sqlite4PExpr(pParse, TK_GE,
sqlite4ExprSetColl(sqlite4ExprDup(db,pLeft,0), pColl),
pStr1, 0);
idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew1==0 );
exprAnalyze(pSrc, pWC, idxNew1);
pNewExpr2 = sqlite4PExpr(pParse, TK_LT,
sqlite4ExprSetColl(sqlite4ExprDup(db,pLeft,0), pColl),
pStr2, 0);
idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew2==0 );
exprAnalyze(pSrc, pWC, idxNew2);
pTerm = &pWC->a[idxTerm];
if( isComplete ){
pWC->a[idxNew1].iParent = idxTerm;
pWC->a[idxNew2].iParent = idxTerm;
pTerm->nChild = 2;
}
}
#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Add a WO_MATCH auxiliary term to the constraint set if the
** current expression is of the form: column MATCH expr.
** This information is used by the xBestIndex methods of
** virtual tables. The native query optimizer does not attempt
** to do anything with MATCH functions.
*/
if( isMatchOfColumn(pExpr) ){
int idxNew;
Expr *pRight, *pLeft;
WhereTerm *pNewTerm;
Bitmask prereqColumn, prereqExpr;
pRight = pExpr->x.pList->a[0].pExpr;
pLeft = pExpr->x.pList->a[1].pExpr;
prereqExpr = exprTableUsage(pMaskSet, pRight);
prereqColumn = exprTableUsage(pMaskSet, pLeft);
if( (prereqExpr & prereqColumn)==0 ){
Expr *pNewExpr;
pNewExpr = sqlite4PExpr(pParse, TK_MATCH,
0, sqlite4ExprDup(db, pRight, 0), 0);
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew==0 );
pNewTerm = &pWC->a[idxNew];
pNewTerm->prereqRight = prereqExpr;
pNewTerm->leftCursor = pLeft->iTable;
pNewTerm->u.leftColumn = pLeft->iColumn;
pNewTerm->eOperator = WO_MATCH;
pNewTerm->iParent = idxTerm;
pTerm = &pWC->a[idxTerm];
pTerm->nChild = 1;
pTerm->wtFlags |= TERM_COPIED;
pNewTerm->prereqAll = pTerm->prereqAll;
}
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifdef SQLITE_ENABLE_STAT3
/* When sqlite_stat3 histogram data is available an operator of the
** form "x IS NOT NULL" can sometimes be evaluated more efficiently
** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a
** virtual term of that form.
**
** Note that the virtual term must be tagged with TERM_VNULL. This
** TERM_VNULL tag will suppress the not-null check at the beginning
** of the loop. Without the TERM_VNULL flag, the not-null check at
** the start of the loop will prevent any results from being returned.
*/
if( pExpr->op==TK_NOTNULL
&& pExpr->pLeft->op==TK_COLUMN
&& pExpr->pLeft->iColumn>=0
){
Expr *pNewExpr;
Expr *pLeft = pExpr->pLeft;
int idxNew;
WhereTerm *pNewTerm;
pNewExpr = sqlite4PExpr(pParse, TK_GT,
sqlite4ExprDup(db, pLeft, 0),
sqlite4PExpr(pParse, TK_NULL, 0, 0, 0), 0);
idxNew = whereClauseInsert(pWC, pNewExpr,
TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL);
if( idxNew ){
pNewTerm = &pWC->a[idxNew];
pNewTerm->prereqRight = 0;
pNewTerm->leftCursor = pLeft->iTable;
pNewTerm->u.leftColumn = pLeft->iColumn;
pNewTerm->eOperator = WO_GT;
pNewTerm->iParent = idxTerm;
pTerm = &pWC->a[idxTerm];
pTerm->nChild = 1;
pTerm->wtFlags |= TERM_COPIED;
pNewTerm->prereqAll = pTerm->prereqAll;
}
}
#endif /* SQLITE_ENABLE_STAT */
/* Prevent ON clause terms of a LEFT JOIN from being used to drive
** an index for tables to the left of the join.
*/
pTerm->prereqRight |= extraRight;
}
/*
** Return TRUE if any of the expressions in pList->a[iFirst...] contain
** a reference to any table other than the iBase table.
*/
static int referencesOtherTables(
ExprList *pList, /* Search expressions in ths list */
WhereMaskSet *pMaskSet, /* Mapping from tables to bitmaps */
int iFirst, /* Be searching with the iFirst-th expression */
int iBase /* Ignore references to this table */
){
Bitmask allowed = ~getMask(pMaskSet, iBase);
while( iFirst<pList->nExpr ){
if( (exprTableUsage(pMaskSet, pList->a[iFirst++].pExpr)&allowed)!=0 ){
return 1;
}
}
return 0;
}
/*
** This function searches the expression list passed as the second argument
** for an expression of type TK_COLUMN that refers to the same column and
** uses the same collation sequence as the iCol'th column of index pIdx.
** Argument iBase is the cursor number used for the table that pIdx refers
** to.
**
** If such an expression is found, its index in pList->a[] is returned. If
** no expression is found, -1 is returned.
*/
static int findIndexCol(
Parse *pParse, /* Parse context */
ExprList *pList, /* Expression list to search */
int iBase, /* Cursor for table associated with pIdx */
Index *pIdx, /* Index to match column of */
int iCol /* Column of index to match */
){
int i;
const char *zColl = pIdx->azColl[iCol];
for(i=0; i<pList->nExpr; i++){
Expr *p = pList->a[i].pExpr;
if( p->op==TK_COLUMN
&& p->iColumn==pIdx->aiColumn[iCol]
&& p->iTable==iBase
){
CollSeq *pColl = sqlite4ExprCollSeq(pParse, p);
assert( pColl || p->iColumn==-1 );
if( 0==pColl || 0==sqlite4StrICmp(pColl->zName, zColl) ){
return i;
}
}
}
return -1;
}
/*
** This routine determines if pIdx can be used to assist in processing a
** DISTINCT qualifier. In other words, it tests whether or not using this
** index for the outer loop guarantees that rows with equal values for
** all expressions in the pDistinct list are delivered grouped together.
**
** For example, the query
**
** SELECT DISTINCT a, b, c FROM tbl WHERE a = ?
**
** can benefit from any index on columns "b" and "c".
*/
static int isDistinctIndex(
Parse *pParse, /* Parsing context */
WhereClause *pWC, /* The WHERE clause */
Index *pIdx, /* The index being considered */
int base, /* Cursor number for the table pIdx is on */
ExprList *pDistinct, /* The DISTINCT expressions */
int nEqCol /* Number of index columns with == */
){
Bitmask mask = 0; /* Mask of unaccounted for pDistinct exprs */
int i; /* Iterator variable */
if( pIdx->zName==0 || pDistinct==0 || pDistinct->nExpr>=BMS ) return 0;
testcase( pDistinct->nExpr==BMS-1 );
/* Loop through all the expressions in the distinct list. If any of them
** are not simple column references, return early. Otherwise, test if the
** WHERE clause contains a "col=X" clause. If it does, the expression
** can be ignored. If it does not, and the column does not belong to the
** same table as index pIdx, return early. Finally, if there is no
** matching "col=X" expression and the column is on the same table as pIdx,
** set the corresponding bit in variable mask.
*/
for(i=0; i<pDistinct->nExpr; i++){
WhereTerm *pTerm;
Expr *p = pDistinct->a[i].pExpr;
if( p->op!=TK_COLUMN ) return 0;
pTerm = findTerm(pWC, p->iTable, p->iColumn, ~(Bitmask)0, WO_EQ, 0);
if( pTerm ){
Expr *pX = pTerm->pExpr;
CollSeq *p1 = sqlite4BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
CollSeq *p2 = sqlite4ExprCollSeq(pParse, p);
if( p1==p2 ) continue;
}
if( p->iTable!=base ) return 0;
mask |= (((Bitmask)1) << i);
}
for(i=nEqCol; mask && i<pIdx->nColumn; i++){
int iExpr = findIndexCol(pParse, pDistinct, base, pIdx, i);
if( iExpr<0 ) break;
mask &= ~(((Bitmask)1) << iExpr);
}
return (mask==0);
}
/*
** Return true if the DISTINCT expression-list passed as the third argument
** is redundant. A DISTINCT list is redundant if the database contains a
** UNIQUE index that guarantees that the result of the query will be distinct
** anyway.
*/
static int isDistinctRedundant(
Parse *pParse,
SrcList *pTabList,
WhereClause *pWC,
ExprList *pDistinct
){
Table *pTab;
Index *pIdx;
int i;
int iBase;
/* If there is more than one table or sub-select in the FROM clause of
** this query, then it will not be possible to show that the DISTINCT
** clause is redundant. */
if( pTabList->nSrc!=1 ) return 0;
iBase = pTabList->a[0].iCursor;
pTab = pTabList->a[0].pTab;
/* If any of the expressions is an IPK column on table iBase, then return
** true. Note: The (p->iTable==iBase) part of this test may be false if the
** current SELECT is a correlated sub-query.
*/
for(i=0; i<pDistinct->nExpr; i++){
Expr *p = pDistinct->a[i].pExpr;
if( p->op==TK_COLUMN && p->iTable==iBase && p->iColumn<0 ) return 1;
}
/* Loop through all indices on the table, checking each to see if it makes
** the DISTINCT qualifier redundant. It does so if:
**
** 1. The index is itself UNIQUE, and
**
** 2. All of the columns in the index are either part of the pDistinct
** list, or else the WHERE clause contains a term of the form "col=X",
** where X is a constant value. The collation sequences of the
** comparison and select-list expressions must match those of the index.
*/
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( pIdx->onError==OE_None ) continue;
for(i=0; i<pIdx->nColumn; i++){
int iCol = pIdx->aiColumn[i];
if( 0==findTerm(pWC, iBase, iCol, ~(Bitmask)0, WO_EQ, pIdx)
&& 0>findIndexCol(pParse, pDistinct, iBase, pIdx, i)
){
break;
}
}
if( i==pIdx->nColumn ){
/* This index implies that the DISTINCT qualifier is redundant. */
return 1;
}
}
return 0;
}
/*
** Return the table column number of the iIdxCol'th field in the index
** keys used by index pIdx, including any appended PRIMARY KEY fields.
** If there is no iIdxCol'th field in index pIdx, return -2.
**
** Example:
**
** CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b));
** CREATE INDEX i1 ON t1(c);
**
** Index i1 in the example above consists of three fields - the indexed
** field "c" followed by the two primary key fields. The automatic PRIMARY
** KEY index consists of two fields only.
*/
static int idxColumnNumber(Index *pIdx, Index *pPk, int iIdxCol){
int iRet = -2;
if( iIdxCol<pIdx->nColumn ){
iRet = pIdx->aiColumn[iIdxCol];
}else if( pPk && iIdxCol<(pIdx->nColumn + pPk->nColumn) ){
iRet = pPk->aiColumn[iIdxCol - pIdx->nColumn];
}
return iRet;
}
/*
** Return the name of the iCol'th column of table pTab. Or, if iCol is less
** than zero, return a pointer to the constant string "rowid".
*/
static const char *tblColumnName(Table *pTab, int iCol){
if( iCol<0 ) return "rowid";
return pTab->aCol[iCol].zName;
}
/*
** This routine decides if pIdx can be used to satisfy the ORDER BY
** clause. If it can, it returns 1. If pIdx cannot satisfy the
** ORDER BY clause, this routine returns 0.
**
** pOrderBy is an ORDER BY clause from a SELECT statement. pTab is the
** left-most table in the FROM clause of that same SELECT statement and
** the table has a cursor number of "base". pIdx is an index on pTab.
**
** nEqCol is the number of columns of pIdx that are used as equality
** constraints. Any of these columns may be missing from the ORDER BY
** clause and the match can still be a success.
**
** All terms of the ORDER BY that match against the index must be either
** ASC or DESC. (Terms of the ORDER BY clause past the end of a UNIQUE
** index do not need to satisfy this constraint.) The *pbRev value is
** set to 1 if the ORDER BY clause is all DESC and it is set to 0 if
** the ORDER BY clause is all ASC.
*/
static int isSortingIndex(
Parse *pParse, /* Parsing context */
WhereMaskSet *pMaskSet, /* Mapping from table cursor numbers to bitmaps */
Index *pIdx, /* The index we are testing */
int base, /* Cursor number for the table to be sorted */
ExprList *pOrderBy, /* The ORDER BY clause */
int nEqCol, /* Number of index columns with == constraints */
int wsFlags, /* Index usages flags */
int *pbRev /* Set to 1 if ORDER BY is DESC */
){
sqlite4 *db = pParse->db; /* Database handle */
int sortOrder = 0; /* XOR of index and ORDER BY sort direction */
int nTerm; /* Number of ORDER BY terms */
int iTerm; /* Used to iterate through nTerm terms */
int iNext = nEqCol; /* Index of next unmatched column in index */
int nIdxCol; /* Number of columns in index, incl. PK */
Index *pPk;
Table *pTab;
if( !pOrderBy ) return 0;
if( wsFlags & WHERE_COLUMN_IN ) return 0;
if( pIdx->bUnordered ) return 0;
pTab = pIdx->pTable;
pPk = sqlite4FindPrimaryKey(pTab, 0);
nTerm = pOrderBy->nExpr;
nIdxCol = pIdx->nColumn + (pIdx==pPk ? 0 : pPk->nColumn);
assert( nTerm>0 );
assert( pIdx && pIdx->zName );
for(iTerm=0; iTerm<nTerm; iTerm++){
struct ExprList_item *pTerm; /* iTerm'th term of ORDER BY clause */
int iIdxCol; /* Index of column in index records */
Expr *pExpr; /* The expression of the ORDER BY pTerm */
CollSeq *pColl; /* The collating sequence of pExpr */
int iColumn; /* The i-th column of the index. -1 for rowid */
const char *zColl; /* Name of the collating sequence for i-th index term */
/* Can not use an index sort on anything that is not a column in the
** left-most table of the FROM clause. Break out of the loop if this
** expression is anything other than that. */
pTerm = &pOrderBy->a[iTerm];
pExpr = pTerm->pExpr;
if( pExpr->op!=TK_COLUMN || pExpr->iTable!=base ) break;
iColumn = pExpr->iColumn;
/* Check that column iColumn is a part of the index. If it is not, then
** this index may not be used as a sorting index. This block also checks
** that column iColumn is either the iNext'th column of the index, or
** else one of the nEqCol columns that the index guarantees will be
** constant. */
for(iIdxCol=0; iIdxCol<nIdxCol; iIdxCol++){
if( idxColumnNumber(pIdx, pPk, iIdxCol)==iColumn ) break;
}
if( iIdxCol==nIdxCol || (iIdxCol>=nEqCol && iIdxCol!=iNext) ) break;
/* Check that the collation sequence used by the expression is the same
** as the collation sequence used by the index. If not, this is not a
** sorting index. */
pColl = sqlite4ExprCollSeq(pParse, pExpr);
if( !pColl ) pColl = db->pDfltColl;
if( iIdxCol<pIdx->nColumn ){
zColl = pIdx->azColl[iIdxCol];
}else if( iColumn>=0 ) {
zColl = pTab->aCol[iColumn].zColl;
}else{
zColl = 0;
}
if( pColl!=sqlite4FindCollSeq(db, ENC(db), zColl, 0) ) break;
if( iIdxCol==iNext ){
u8 reqSortOrder;
u8 idxSortOrder = SQLITE_SO_ASC;
if( iIdxCol<pIdx->nColumn ) idxSortOrder = pIdx->aSortOrder[iIdxCol];
assert( idxSortOrder==SQLITE_SO_ASC || idxSortOrder==SQLITE_SO_DESC );
reqSortOrder = (idxSortOrder ^ pTerm->sortOrder);
if( iNext==nEqCol ){
sortOrder = reqSortOrder;
}else if( sortOrder!=reqSortOrder ){
break;
}
iNext++;
}
#if 0
if( iColumn<0 && !referencesOtherTables(pOrderBy, pMaskSet, j, base) ){
/* If the indexed column is the primary key and everything matches
** so far and none of the ORDER BY terms to the right reference other
** tables in the join, then we are assured that the index can be used
** to sort because the primary key is unique and so none of the other
** columns will make any difference
*/
j = nTerm;
}
#endif
}
*pbRev = sortOrder!=0;
if( iTerm>=nTerm ){
/* All terms of the ORDER BY clause are covered by this index. The
** index can therefore be used for sorting. */
return 1;
}
if( pIdx->onError!=OE_None
&& iNext>=pIdx->nColumn
&& (wsFlags & WHERE_COLUMN_NULL)==0
&& !referencesOtherTables(pOrderBy, pMaskSet, iTerm, base)
){
if( iNext==nIdxCol ){
/* All columns indexed by this UNIQUE index, and all PK columns are
** are matched by a prefix of the ORDER BY clause. And since the PK
** columns are guaranteed to be unique and NOT NULL, there is no way
** for the trailing ORDER BY terms to affect the sort order. Therefore,
** we have a sorting index. */
return 1;
}else{
int i;
for(i=nEqCol; i<pIdx->nColumn; i++){
int iCol = pIdx->aiColumn[i];
if( iCol>=0 && pTab->aCol[iCol].notNull==0 ) break;
}
/* All columns indexed by this UNIQUE index are matched by a prefix
** of the ORDER BY clause. And there is reason to believe that none
** of the expressions in the ORDER BY prefix will evalulate to NULL.
** The index may be used for sorting in this case too since it is
** guaranteed that none of the trailing, unmatched ORDER BY terms
** affect the sort order. */
return (i>=pIdx->nColumn);
}
}
return 0;
}
/*
** Prepare a crude estimate of the logarithm of the input value.
** The results need not be exact. This is only used for estimating
** the total cost of performing operations with O(logN) or O(NlogN)
** complexity. Because N is just a guess, it is no great tragedy if
** logN is a little off.
*/
static double estLog(double N){
double logN = 1;
double x = 10;
while( N>x ){
logN += 1;
x *= 10;
}
return logN;
}
/*
** Two routines for printing the content of an sqlite4_index_info
** structure. Used for testing and debugging only. If neither
** SQLITE_TEST or SQLITE_DEBUG are defined, then these routines
** are no-ops.
*/
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_DEBUG)
static void TRACE_IDX_INPUTS(sqlite4_index_info *p){
int i;
if( !sqlite4WhereTrace ) return;
for(i=0; i<p->nConstraint; i++){
sqlite4DebugPrintf(" constraint[%d]: col=%d termid=%d op=%d usabled=%d\n",
i,
p->aConstraint[i].iColumn,
p->aConstraint[i].iTermOffset,
p->aConstraint[i].op,
p->aConstraint[i].usable);
}
for(i=0; i<p->nOrderBy; i++){
sqlite4DebugPrintf(" orderby[%d]: col=%d desc=%d\n",
i,
p->aOrderBy[i].iColumn,
p->aOrderBy[i].desc);
}
}
static void TRACE_IDX_OUTPUTS(sqlite4_index_info *p){
int i;
if( !sqlite4WhereTrace ) return;
for(i=0; i<p->nConstraint; i++){
sqlite4DebugPrintf(" usage[%d]: argvIdx=%d omit=%d\n",
i,
p->aConstraintUsage[i].argvIndex,
p->aConstraintUsage[i].omit);
}
sqlite4DebugPrintf(" idxNum=%d\n", p->idxNum);
sqlite4DebugPrintf(" idxStr=%s\n", p->idxStr);
sqlite4DebugPrintf(" orderByConsumed=%d\n", p->orderByConsumed);
sqlite4DebugPrintf(" estimatedCost=%g\n", p->estimatedCost);
}
#else
#define TRACE_IDX_INPUTS(A)
#define TRACE_IDX_OUTPUTS(A)
#endif
/*
** Required because bestIndex() is called by bestOrClauseIndex()
*/
static void bestIndex(
Parse*, WhereClause*, struct SrcList_item*,
Bitmask, Bitmask, ExprList*, WhereCost*);
/*
** This routine attempts to find an scanning strategy that can be used
** to optimize an 'OR' expression that is part of a WHERE clause.
**
** The table associated with FROM clause term pSrc may be either a
** regular B-Tree table or a virtual table.
*/
static void bestOrClauseIndex(
Parse *pParse, /* The parsing context */
WhereClause *pWC, /* The WHERE clause */
struct SrcList_item *pSrc, /* The FROM clause term to search */
Bitmask notReady, /* Mask of cursors not available for indexing */
Bitmask notValid, /* Cursors not available for any purpose */
ExprList *pOrderBy, /* The ORDER BY clause */
WhereCost *pCost /* Lowest cost query plan */
){
#ifndef SQLITE_OMIT_OR_OPTIMIZATION
const int iCur = pSrc->iCursor; /* The cursor of the table to be accessed */
const Bitmask maskSrc = getMask(pWC->pMaskSet, iCur); /* Bitmask for pSrc */
WhereTerm * const pWCEnd = &pWC->a[pWC->nTerm]; /* End of pWC->a[] */
WhereTerm *pTerm; /* A single term of the WHERE clause */
/* The OR-clause optimization is disallowed if the INDEXED BY or
** NOT INDEXED clauses are used or if the WHERE_AND_ONLY bit is set. */
if( pSrc->notIndexed || pSrc->pIndex!=0 ){
return;
}
if( pWC->wctrlFlags & WHERE_AND_ONLY ){
return;
}
/* Search the WHERE clause terms for a usable WO_OR term. */
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
if( pTerm->eOperator==WO_OR
&& ((pTerm->prereqAll & ~maskSrc) & notReady)==0
&& (pTerm->u.pOrInfo->indexable & maskSrc)!=0
){
WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc;
WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm];
WhereTerm *pOrTerm;
int flags = WHERE_MULTI_OR;
double rTotal = 0;
double nRow = 0;
Bitmask used = 0;
for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
WhereCost sTermCost;
WHERETRACE(("... Multi-index OR testing for term %d of %d....\n",
(pOrTerm - pOrWC->a), (pTerm - pWC->a)
));
if( pOrTerm->eOperator==WO_AND ){
WhereClause *pAndWC = &pOrTerm->u.pAndInfo->wc;
bestIndex(pParse, pAndWC, pSrc, notReady, notValid, 0, &sTermCost);
}else if( pOrTerm->leftCursor==iCur ){
WhereClause tempWC;
tempWC.pParse = pWC->pParse;
tempWC.pMaskSet = pWC->pMaskSet;
tempWC.pOuter = pWC;
tempWC.op = TK_AND;
tempWC.a = pOrTerm;
tempWC.wctrlFlags = 0;
tempWC.nTerm = 1;
bestIndex(pParse, &tempWC, pSrc, notReady, notValid, 0, &sTermCost);
}else{
continue;
}
rTotal += sTermCost.rCost;
nRow += sTermCost.plan.nRow;
used |= sTermCost.used;
if( rTotal>=pCost->rCost ) break;
}
/* If there is an ORDER BY clause, increase the scan cost to account
** for the cost of the sort. */
if( pOrderBy!=0 ){
WHERETRACE(("... sorting increases OR cost %.9g to %.9g\n",
rTotal, rTotal+nRow*estLog(nRow)));
rTotal += nRow*estLog(nRow);
}
/* If the cost of scanning using this OR term for optimization is
** less than the current cost stored in pCost, replace the contents
** of pCost. */
WHERETRACE(("... multi-index OR cost=%.9g nrow=%.9g\n", rTotal, nRow));
if( rTotal<pCost->rCost ){
pCost->rCost = rTotal;
pCost->used = used;
pCost->plan.nRow = nRow;
pCost->plan.wsFlags = flags;
pCost->plan.u.pTerm = pTerm;
}
}
}
#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
}
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
/*
** Return TRUE if the WHERE clause term pTerm is of a form where it
** could be used with an index to access pSrc, assuming an appropriate
** index existed.
*/
static int termCanDriveIndex(
WhereTerm *pTerm, /* WHERE clause term to check */
struct SrcList_item *pSrc, /* Table we are trying to access */
Bitmask notReady /* Tables in outer loops of the join */
){
char aff;
if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
if( pTerm->eOperator!=WO_EQ ) return 0;
if( (pTerm->prereqRight & notReady)!=0 ) return 0;
aff = pSrc->pTab->aCol[pTerm->u.leftColumn].affinity;
if( !sqlite4IndexAffinityOk(pTerm->pExpr, aff) ) return 0;
return 1;
}
#endif
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
/*
** If the query plan for pSrc specified in pCost is a full table scan
** and indexing is allows (if there is no NOT INDEXED clause) and it
** possible to construct a transient index that would perform better
** than a full table scan even when the cost of constructing the index
** is taken into account, then alter the query plan to use the
** transient index.
*/
static void bestAutomaticIndex(
Parse *pParse, /* The parsing context */
WhereClause *pWC, /* The WHERE clause */
struct SrcList_item *pSrc, /* The FROM clause term to search */
Bitmask notReady, /* Mask of cursors that are not available */
WhereCost *pCost /* Lowest cost query plan */
){
double nTableRow; /* Rows in the input table */
double logN; /* log(nTableRow) */
double costTempIdx; /* per-query cost of the transient index */
WhereTerm *pTerm; /* A single term of the WHERE clause */
WhereTerm *pWCEnd; /* End of pWC->a[] */
Table *pTable; /* Table tht might be indexed */
if( pParse->nQueryLoop<=(double)1 ){
/* There is no point in building an automatic index for a single scan */
return;
}
if( (pParse->db->flags & SQLITE_AutoIndex)==0 ){
/* Automatic indices are disabled at run-time */
return;
}
if( (pWC->wctrlFlags & WHERE_NO_AUTOINDEX)!=0 ){
return;
}
if( (pCost->plan.wsFlags & WHERE_NOT_FULLSCAN)!=0 ){
/* We already have some kind of index in use for this query. */
return;
}
if( pSrc->notIndexed ){
/* The NOT INDEXED clause appears in the SQL. */
return;
}
if( pSrc->isCorrelated ){
/* The source is a correlated sub-query. No point in indexing it. */
return;
}
assert( pParse->nQueryLoop >= (double)1 );
pTable = pSrc->pTab;
nTableRow = pTable->nRowEst;
logN = estLog(nTableRow);
costTempIdx = 2*logN*(nTableRow/pParse->nQueryLoop + 1);
if( costTempIdx>=pCost->rCost ){
/* The cost of creating the transient table would be greater than
** doing the full table scan */
return;
}
/* Search for any equality comparison term */
pWCEnd = &pWC->a[pWC->nTerm];
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
if( termCanDriveIndex(pTerm, pSrc, notReady) ){
WHERETRACE(("auto-index reduces cost from %.1f to %.1f\n",
pCost->rCost, costTempIdx));
pCost->rCost = costTempIdx;
pCost->plan.nRow = logN + 1;
pCost->plan.wsFlags = WHERE_TEMP_INDEX;
pCost->plan.u.pIdx = 0;
pCost->used = pTerm->prereqRight;
break;
}
}
}
#else
# define bestAutomaticIndex(A,B,C,D,E) /* no-op */
#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
/*
** Generate code to construct the Index object for an automatic index
** and to set up the WhereLevel object pLevel so that the code generator
** makes use of the automatic index.
*/
static void constructAutomaticIndex(
Parse *pParse, /* The parsing context */
WhereClause *pWC, /* The WHERE clause */
struct SrcList_item *pSrc, /* The FROM clause term to get the next index */
Bitmask notReady, /* Mask of cursors that are not available */
WhereLevel *pLevel /* Write new index here */
){
int nCol = 0; /* Number of columns in index keys */
WhereTerm *pTerm; /* A single term of the WHERE clause */
WhereTerm *pWCEnd; /* End of pWC->a[] */
int nByte; /* Byte of memory needed for pIdx */
Index *pIdx; /* Object describing the transient index */
Vdbe *v; /* Prepared statement under construction */
int addrOnce; /* Address of the initialization bypass jump */
Table *pTable; /* The table being indexed */
KeyInfo *pKeyinfo; /* Key information for the index */
int addrRewind; /* Top of the index fill loop */
int regRecord; /* Register holding an index record */
int regKey; /* Register holding an index key */
int n; /* Column counter */
CollSeq *pColl; /* Collating sequence to on a column */
Bitmask idxCols; /* Bitmap of columns used for indexing */
int iPkCur = pLevel->iTabCur; /* Primary key cursor to read data from */
/* 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 );
addrOnce = sqlite4CodeOnce(pParse);
/* Count the number of columns that will be encoded into the index keys.
** set nCol to this value. Use the idxCols mask to ensure that the same
** column is not added to the index more than once. */
pTable = pSrc->pTab;
pWCEnd = &pWC->a[pWC->nTerm];
idxCols = 0;
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
if( termCanDriveIndex(pTerm, pSrc, notReady) ){
int iCol = pTerm->u.leftColumn;
Bitmask cMask = iCol>=BMS ? ((Bitmask)1)<<(BMS-1) : ((Bitmask)1)<<iCol;
testcase( iCol==BMS );
testcase( iCol==BMS-1 );
if( (idxCols & cMask)==0 ){
nCol++;
idxCols |= cMask;
}
}
}
assert( nCol>0 );
pLevel->plan.nEq = nCol;
pLevel->plan.wsFlags |= WHERE_COLUMN_EQ | WHERE_IDX_ONLY | WO_EQ;
/* Construct the Index object to describe this index */
nByte = sizeof(Index); /* Index */
nByte += nCol*sizeof(int); /* Index.aiColumn */
nByte += nCol*sizeof(char*); /* Index.azColl */
nByte += nCol; /* Index.aSortOrder */
pIdx = sqlite4DbMallocZero(pParse->db, nByte);
if( pIdx==0 ) return;
pLevel->plan.u.pIdx = pIdx;
pIdx->eIndexType = SQLITE_INDEX_TEMP;
pIdx->azColl = (char**)&pIdx[1];
pIdx->aiColumn = (int*)&pIdx->azColl[nCol];
pIdx->aSortOrder = (u8*)&pIdx->aiColumn[nCol];
pIdx->zName = "auto-index";
pIdx->nColumn = nCol;
pIdx->pTable = pTable;
n = 0;
idxCols = 0;
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
if( termCanDriveIndex(pTerm, pSrc, notReady) ){
int iCol = pTerm->u.leftColumn;
Bitmask cMask = iCol>=BMS ? ((Bitmask)1)<<(BMS-1) : ((Bitmask)1)<<iCol;
if( (idxCols & cMask)==0 ){
Expr *pX = pTerm->pExpr;
idxCols |= cMask;
pIdx->aiColumn[n] = pTerm->u.leftColumn;
pColl = sqlite4BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
pIdx->azColl[n] = ALWAYS(pColl) ? pColl->zName : "BINARY";
n++;
}
}
}
assert( (u32)n==pLevel->plan.nEq );
/* Open the automatic index cursor */
pKeyinfo = sqlite4IndexKeyinfo(pParse, pIdx);
assert( pLevel->iIdxCur>=0 );
sqlite4VdbeAddOp3(v, OP_OpenAutoindex, pLevel->iIdxCur, 0, 0);
sqlite4VdbeChangeP4(v, -1, (char*)pKeyinfo, P4_KEYINFO_HANDOFF);
VdbeComment((v, "for %s", pTable->zName));
/* Populate the automatic index */
regRecord = sqlite4GetTempRange(pParse, 2);
regKey = regRecord+1;
addrRewind = sqlite4VdbeAddOp1(v, OP_Rewind, iPkCur);
sqlite4EncodeIndexKey(pParse, 0, iPkCur, pIdx, pLevel->iIdxCur, 1, regKey);
sqlite4VdbeAddOp2(v, OP_RowData, iPkCur, regRecord);
sqlite4VdbeAddOp3(v, OP_IdxInsert, pLevel->iIdxCur, regRecord, regKey);
sqlite4VdbeAddOp2(v, OP_Next, iPkCur, addrRewind+1);
sqlite4VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
sqlite4VdbeJumpHere(v, addrRewind);
sqlite4ReleaseTempRange(pParse, regRecord, 2);
/* Jump here when skipping the initialization */
sqlite4VdbeJumpHere(v, addrOnce);
}
#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */
#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** Allocate and populate an sqlite4_index_info structure. It is the
** responsibility of the caller to eventually release the structure
** by passing the pointer returned by this function to sqlite4_free().
*/
static sqlite4_index_info *allocateIndexInfo(
Parse *pParse,
WhereClause *pWC,
struct SrcList_item *pSrc,
ExprList *pOrderBy
){
int i, j;
int nTerm;
struct sqlite4_index_constraint *pIdxCons;
struct sqlite4_index_orderby *pIdxOrderBy;
struct sqlite4_index_constraint_usage *pUsage;
WhereTerm *pTerm;
int nOrderBy;
sqlite4_index_info *pIdxInfo;
WHERETRACE(("Recomputing index info for %s...\n", pSrc->pTab->zName));
/* Count the number of possible WHERE clause constraints referring
** to this virtual table */
for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
if( pTerm->leftCursor != pSrc->iCursor ) continue;
assert( (pTerm->eOperator&(pTerm->eOperator-1))==0 );
testcase( pTerm->eOperator==WO_IN );
testcase( pTerm->eOperator==WO_ISNULL );
if( pTerm->eOperator & (WO_IN|WO_ISNULL) ) continue;
if( pTerm->wtFlags & TERM_VNULL ) continue;
nTerm++;
}
/* If the ORDER BY clause contains only columns in the current
** virtual table then allocate space for the aOrderBy part of
** the sqlite4_index_info structure.
*/
nOrderBy = 0;
if( pOrderBy ){
for(i=0; i<pOrderBy->nExpr; i++){
Expr *pExpr = pOrderBy->a[i].pExpr;
if( pExpr->op!=TK_COLUMN || pExpr->iTable!=pSrc->iCursor ) break;
}
if( i==pOrderBy->nExpr ){
nOrderBy = pOrderBy->nExpr;
}
}
/* Allocate the sqlite4_index_info structure
*/
pIdxInfo = sqlite4DbMallocZero(pParse->db, sizeof(*pIdxInfo)
+ (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm
+ sizeof(*pIdxOrderBy)*nOrderBy );
if( pIdxInfo==0 ){
sqlite4ErrorMsg(pParse, "out of memory");
/* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
return 0;
}
/* Initialize the structure. The sqlite4_index_info structure contains
** many fields that are declared "const" to prevent xBestIndex from
** changing them. We have to do some funky casting in order to
** initialize those fields.
*/
pIdxCons = (struct sqlite4_index_constraint*)&pIdxInfo[1];
pIdxOrderBy = (struct sqlite4_index_orderby*)&pIdxCons[nTerm];
pUsage = (struct sqlite4_index_constraint_usage*)&pIdxOrderBy[nOrderBy];
*(int*)&pIdxInfo->nConstraint = nTerm;
*(int*)&pIdxInfo->nOrderBy = nOrderBy;
*(struct sqlite4_index_constraint**)&pIdxInfo->aConstraint = pIdxCons;
*(struct sqlite4_index_orderby**)&pIdxInfo->aOrderBy = pIdxOrderBy;
*(struct sqlite4_index_constraint_usage**)&pIdxInfo->aConstraintUsage =
pUsage;
for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
if( pTerm->leftCursor != pSrc->iCursor ) continue;
assert( (pTerm->eOperator&(pTerm->eOperator-1))==0 );
testcase( pTerm->eOperator==WO_IN );
testcase( pTerm->eOperator==WO_ISNULL );
if( pTerm->eOperator & (WO_IN|WO_ISNULL) ) continue;
if( pTerm->wtFlags & TERM_VNULL ) continue;
pIdxCons[j].iColumn = pTerm->u.leftColumn;
pIdxCons[j].iTermOffset = i;
pIdxCons[j].op = (u8)pTerm->eOperator;
/* 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( WO_MATCH==SQLITE_INDEX_CONSTRAINT_MATCH );
assert( pTerm->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) );
j++;
}
for(i=0; i<nOrderBy; i++){
Expr *pExpr = pOrderBy->a[i].pExpr;
pIdxOrderBy[i].iColumn = pExpr->iColumn;
pIdxOrderBy[i].desc = pOrderBy->a[i].sortOrder;
}
return pIdxInfo;
}
/*
** The table object reference passed as the second argument to this function
** must represent a virtual table. This function invokes the xBestIndex()
** method of the virtual table with the sqlite4_index_info pointer passed
** as the argument.
**
** If an error occurs, pParse is populated with an error message and a
** non-zero value is returned. Otherwise, 0 is returned and the output
** part of the sqlite4_index_info structure is left populated.
**
** Whether or not an error is returned, it is the responsibility of the
** caller to eventually free p->idxStr if p->needToFreeIdxStr indicates
** that this is required.
*/
static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite4_index_info *p){
sqlite4_vtab *pVtab = sqlite4GetVTable(pParse->db, pTab)->pVtab;
int i;
int rc;
WHERETRACE(("xBestIndex for %s\n", pTab->zName));
TRACE_IDX_INPUTS(p);
rc = pVtab->pModule->xBestIndex(pVtab, p);
TRACE_IDX_OUTPUTS(p);
if( rc!=SQLITE_OK ){
if( rc==SQLITE_NOMEM ){
pParse->db->mallocFailed = 1;
}else if( !pVtab->zErrMsg ){
sqlite4ErrorMsg(pParse, "%s", sqlite4ErrStr(rc));
}else{
sqlite4ErrorMsg(pParse, "%s", pVtab->zErrMsg);
}
}
sqlite4_free(pVtab->zErrMsg);
pVtab->zErrMsg = 0;
for(i=0; i<p->nConstraint; i++){
if( !p->aConstraint[i].usable && p->aConstraintUsage[i].argvIndex>0 ){
sqlite4ErrorMsg(pParse,
"table %s: xBestIndex returned an invalid plan", pTab->zName);
}
}
return pParse->nErr;
}
/*
** Compute the best index for a virtual table.
**
** The best index is computed by the xBestIndex method of the virtual
** table module. This routine is really just a wrapper that sets up
** the sqlite4_index_info structure that is used to communicate with
** xBestIndex.
**
** In a join, this routine might be called multiple times for the
** same virtual table. The sqlite4_index_info structure is created
** and initialized on the first invocation and reused on all subsequent
** invocations. The sqlite4_index_info structure is also used when
** code is generated to access the virtual table. The whereInfoDelete()
** routine takes care of freeing the sqlite4_index_info structure after
** everybody has finished with it.
*/
static void bestVirtualIndex(
Parse *pParse, /* The parsing context */
WhereClause *pWC, /* The WHERE clause */
struct SrcList_item *pSrc, /* The FROM clause term to search */
Bitmask notReady, /* Mask of cursors not available for index */
Bitmask notValid, /* Cursors not valid for any purpose */
ExprList *pOrderBy, /* The order by clause */
WhereCost *pCost, /* Lowest cost query plan */
sqlite4_index_info **ppIdxInfo /* Index information passed to xBestIndex */
){
Table *pTab = pSrc->pTab;
sqlite4_index_info *pIdxInfo;
struct sqlite4_index_constraint *pIdxCons;
struct sqlite4_index_constraint_usage *pUsage;
WhereTerm *pTerm;
int i, j;
int nOrderBy;
double rCost;
/* Make sure wsFlags is initialized to some sane value. Otherwise, if the
** malloc in allocateIndexInfo() fails and this function returns leaving
** wsFlags in an uninitialized state, the caller may behave unpredictably.
*/
memset(pCost, 0, sizeof(*pCost));
pCost->plan.wsFlags = WHERE_VIRTUALTABLE;
/* If the sqlite4_index_info structure has not been previously
** allocated and initialized, then allocate and initialize it now.
*/
pIdxInfo = *ppIdxInfo;
if( pIdxInfo==0 ){
*ppIdxInfo = pIdxInfo = allocateIndexInfo(pParse, pWC, pSrc, pOrderBy);
}
if( pIdxInfo==0 ){
return;
}
/* At this point, the sqlite4_index_info structure that pIdxInfo points
** to will have been initialized, either during the current invocation or
** during some prior invocation. Now we just have to customize the
** details of pIdxInfo for the current invocation and pass it to
** xBestIndex.
*/
/* The module name must be defined. Also, by this point there must
** be a pointer to an sqlite4_vtab structure. Otherwise
** sqlite4ViewGetColumnNames() would have picked up the error.
*/
assert( pTab->azModuleArg && pTab->azModuleArg[0] );
assert( sqlite4GetVTable(pParse->db, pTab) );
/* Set the aConstraint[].usable fields and initialize all
** output variables to zero.
**
** aConstraint[].usable is true for constraints where the right-hand
** side contains only references to tables to the left of the current
** table. In other words, if the constraint is of the form:
**
** column = expr
**
** and we are evaluating a join, then the constraint on column is
** only valid if all tables referenced in expr occur to the left
** of the table containing column.
**
** The aConstraints[] array contains entries for all constraints
** on the current table. That way we only have to compute it once
** even though we might try to pick the best index multiple times.
** For each attempt at picking an index, the order of tables in the
** join might be different so we have to recompute the usable flag
** each time.
*/
pIdxCons = *(struct sqlite4_index_constraint**)&pIdxInfo->aConstraint;
pUsage = pIdxInfo->aConstraintUsage;
for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
j = pIdxCons->iTermOffset;
pTerm = &pWC->a[j];
pIdxCons->usable = (pTerm->prereqRight¬Ready) ? 0 : 1;
}
memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint);
if( pIdxInfo->needToFreeIdxStr ){
sqlite4_free(pIdxInfo->idxStr);
}
pIdxInfo->idxStr = 0;
pIdxInfo->idxNum = 0;
pIdxInfo->needToFreeIdxStr = 0;
pIdxInfo->orderByConsumed = 0;
/* ((double)2) In case of SQLITE_OMIT_FLOATING_POINT... */
pIdxInfo->estimatedCost = SQLITE_BIG_DBL / ((double)2);
nOrderBy = pIdxInfo->nOrderBy;
if( !pOrderBy ){
pIdxInfo->nOrderBy = 0;
}
if( vtabBestIndex(pParse, pTab, pIdxInfo) ){
return;
}
pIdxCons = *(struct sqlite4_index_constraint**)&pIdxInfo->aConstraint;
for(i=0; i<pIdxInfo->nConstraint; i++){
if( pUsage[i].argvIndex>0 ){
pCost->used |= pWC->a[pIdxCons[i].iTermOffset].prereqRight;
}
}
/* If there is an ORDER BY clause, and the selected virtual table index
** does not satisfy it, increase the cost of the scan accordingly. This
** matches the processing for non-virtual tables in bestKVIndex().
*/
rCost = pIdxInfo->estimatedCost;
if( pOrderBy && pIdxInfo->orderByConsumed==0 ){
rCost += estLog(rCost)*rCost;
}
/* The cost is not allowed to be larger than SQLITE_BIG_DBL (the
** inital value of lowestCost in this loop. If it is, then the
** (cost<lowestCost) test below will never be true.
**
** Use "(double)2" instead of "2.0" in case OMIT_FLOATING_POINT
** is defined.
*/
if( (SQLITE_BIG_DBL/((double)2))<rCost ){
pCost->rCost = (SQLITE_BIG_DBL/((double)2));
}else{
pCost->rCost = rCost;
}
pCost->plan.u.pVtabIdx = pIdxInfo;
if( pIdxInfo->orderByConsumed ){
pCost->plan.wsFlags |= WHERE_ORDERBY;
}
pCost->plan.nEq = 0;
pIdxInfo->nOrderBy = nOrderBy;
/* Try to find a more efficient access pattern by using multiple indexes
** to optimize an OR expression within the WHERE clause.
*/
bestOrClauseIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost);
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifdef SQLITE_ENABLE_STAT3
/*
** Estimate the location of a particular key among all keys in an
** index. Store the results in aStat as follows:
**
** aStat[0] Est. number of rows less than pVal
** aStat[1] Est. number of rows equal to pVal
**
** Return SQLITE_OK on success.
*/
static int whereKeyStats(
Parse *pParse, /* Database connection */
Index *pIdx, /* Index to consider domain of */
sqlite4_value *pVal, /* Value to consider */
int roundUp, /* Round up if true. Round down if false */
tRowcnt *aStat /* OUT: stats written here */
){
tRowcnt n;
IndexSample *aSample;
int i, eType;
int isEq = 0;
i64 v;
double r, rS;
assert( roundUp==0 || roundUp==1 );
assert( pIdx->nSample>0 );
if( pVal==0 ) return SQLITE_ERROR;
n = pIdx->aiRowEst[0];
aSample = pIdx->aSample;
eType = sqlite4_value_type(pVal);
if( eType==SQLITE_INTEGER ){
v = sqlite4_value_int64(pVal);
r = (i64)v;
for(i=0; i<pIdx->nSample; i++){
if( aSample[i].eType==SQLITE_NULL ) continue;
if( aSample[i].eType>=SQLITE_TEXT ) break;
if( aSample[i].eType==SQLITE_INTEGER ){
if( aSample[i].u.i>=v ){
isEq = aSample[i].u.i==v;
break;
}
}else{
assert( aSample[i].eType==SQLITE_FLOAT );
if( aSample[i].u.r>=r ){
isEq = aSample[i].u.r==r;
break;
}
}
}
}else if( eType==SQLITE_FLOAT ){
r = sqlite4_value_double(pVal);
for(i=0; i<pIdx->nSample; i++){
if( aSample[i].eType==SQLITE_NULL ) continue;
if( aSample[i].eType>=SQLITE_TEXT ) break;
if( aSample[i].eType==SQLITE_FLOAT ){
rS = aSample[i].u.r;
}else{
rS = aSample[i].u.i;
}
if( rS>=r ){
isEq = rS==r;
break;
}
}
}else if( eType==SQLITE_NULL ){
i = 0;
if( aSample[0].eType==SQLITE_NULL ) isEq = 1;
}else{
assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
for(i=0; i<pIdx->nSample; i++){
if( aSample[i].eType==SQLITE_TEXT || aSample[i].eType==SQLITE_BLOB ){
break;
}
}
if( i<pIdx->nSample ){
sqlite4 *db = pParse->db;
CollSeq *pColl;
const u8 *z;
if( eType==SQLITE_BLOB ){
z = (const u8 *)sqlite4_value_blob(pVal);
pColl = db->pDfltColl;
assert( pColl->enc==SQLITE_UTF8 );
}else{
pColl = sqlite4GetCollSeq(db, SQLITE_UTF8, 0, *pIdx->azColl);
if( pColl==0 ){
sqlite4ErrorMsg(pParse, "no such collation sequence: %s",
*pIdx->azColl);
return SQLITE_ERROR;
}
z = (const u8 *)sqlite4ValueText(pVal, pColl->enc);
if( !z ){
return SQLITE_NOMEM;
}
assert( z && pColl && pColl->xCmp );
}
n = sqlite4ValueBytes(pVal, pColl->enc);
for(; i<pIdx->nSample; i++){
int c;
int eSampletype = aSample[i].eType;
if( eSampletype<eType ) continue;
if( eSampletype!=eType ) break;
#ifndef SQLITE_OMIT_UTF16
if( pColl->enc!=SQLITE_UTF8 ){
int nSample;
char *zSample = sqlite4Utf8to16(
db, pColl->enc, aSample[i].u.z, aSample[i].nByte, &nSample
);
if( !zSample ){
assert( db->mallocFailed );
return SQLITE_NOMEM;
}
c = pColl->xCmp(pColl->pUser, nSample, zSample, n, z);
sqlite4DbFree(db, zSample);
}else
#endif
{
c = pColl->xCmp(pColl->pUser, aSample[i].nByte, aSample[i].u.z, n, z);
}
if( c>=0 ){
if( c==0 ) isEq = 1;
break;
}
}
}
}
/* At this point, aSample[i] is the first sample that is greater than
** or equal to pVal. Or if i==pIdx->nSample, then all samples are less
** than pVal. If aSample[i]==pVal, then isEq==1.
*/
if( isEq ){
assert( i<pIdx->nSample );
aStat[0] = aSample[i].nLt;
aStat[1] = aSample[i].nEq;
}else{
tRowcnt iLower, iUpper, iGap;
if( i==0 ){
iLower = 0;
iUpper = aSample[0].nLt;
}else{
iUpper = i>=pIdx->nSample ? n : aSample[i].nLt;
iLower = aSample[i-1].nEq + aSample[i-1].nLt;
}
aStat[1] = pIdx->avgEq;
if( iLower>=iUpper ){
iGap = 0;
}else{
iGap = iUpper - iLower;
}
if( roundUp ){
iGap = (iGap*2)/3;
}else{
iGap = iGap/3;
}
aStat[0] = iLower + iGap;
}
return SQLITE_OK;
}
#endif /* SQLITE_ENABLE_STAT3 */
/*
** If expression pExpr represents a literal value, set *pp to point to
** an sqlite4_value structure containing the same value, with affinity
** aff applied to it, before returning. It is the responsibility of the
** caller to eventually release this structure by passing it to
** sqlite4ValueFree().
**
** If the current parse is a recompile (sqlite4Reprepare()) and pExpr
** is an SQL variable that currently has a non-NULL value bound to it,
** create an sqlite4_value structure containing this value, again with
** affinity aff applied to it, instead.
**
** If neither of the above apply, set *pp to NULL.
**
** If an error occurs, return an error code. Otherwise, SQLITE_OK.
*/
#ifdef SQLITE_ENABLE_STAT3
static int valueFromExpr(
Parse *pParse,
Expr *pExpr,
u8 aff,
sqlite4_value **pp
){
if( pExpr->op==TK_VARIABLE
|| (pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE)
){
int iVar = pExpr->iColumn;
sqlite4VdbeSetVarmask(pParse->pVdbe, iVar);
*pp = sqlite4VdbeGetValue(pParse->pReprepare, iVar, aff);
return SQLITE_OK;
}
return sqlite4ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, aff, pp);
}
#endif
/*
** This function is used to estimate the number of rows that will be visited
** by scanning an index for a range of values. The range may have an upper
** bound, a lower bound, or both. The WHERE clause terms that set the upper
** and lower bounds are represented by pLower and pUpper respectively. For
** example, assuming that index p is on t1(a):
**
** ... FROM t1 WHERE a > ? AND a < ? ...
** |_____| |_____|
** | |
** pLower pUpper
**
** If either of the upper or lower bound is not present, then NULL is passed in
** place of the corresponding WhereTerm.
**
** The nEq parameter is passed the index of the index column subject to the
** range constraint. Or, equivalently, the number of equality constraints
** optimized by the proposed index scan. For example, assuming index p is
** on t1(a, b), and the SQL query is:
**
** ... FROM t1 WHERE a = ? AND b > ? AND b < ? ...
**
** then nEq should be passed the value 1 (as the range restricted column,
** b, is the second left-most column of the index). Or, if the query is:
**
** ... FROM t1 WHERE a > ? AND a < ? ...
**
** then nEq should be passed 0.
**
** The returned value is an integer divisor to reduce the estimated
** search space. A return value of 1 means that range constraints are
** no help at all. A return value of 2 means range constraints are
** expected to reduce the search space by half. And so forth...
**
** In the absence of sqlite_stat3 ANALYZE data, each range inequality
** reduces the search space by a factor of 4. Hence a single constraint (x>?)
** results in a return of 4 and a range constraint (x>? AND x<?) results
** in a return of 16.
*/
static int whereRangeScanEst(
Parse *pParse, /* Parsing & code generating context */
Index *p, /* The index containing the range-compared column; "x" */
int nEq, /* index into p->aCol[] of the range-compared column */
WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */
WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */
double *pRangeDiv /* OUT: Reduce search space by this divisor */
){
int rc = SQLITE_OK;
#ifdef SQLITE_ENABLE_STAT3
if( nEq==0 && p->nSample ){
sqlite4_value *pRangeVal;
tRowcnt iLower = 0;
tRowcnt iUpper = p->aiRowEst[0];
tRowcnt a[2];
u8 aff = p->pTable->aCol[p->aiColumn[0]].affinity;
if( pLower ){
Expr *pExpr = pLower->pExpr->pRight;
rc = valueFromExpr(pParse, pExpr, aff, &pRangeVal);
assert( pLower->eOperator==WO_GT || pLower->eOperator==WO_GE );
if( rc==SQLITE_OK
&& whereKeyStats(pParse, p, pRangeVal, 0, a)==SQLITE_OK
){
iLower = a[0];
if( pLower->eOperator==WO_GT ) iLower += a[1];
}
sqlite4ValueFree(pRangeVal);
}
if( rc==SQLITE_OK && pUpper ){
Expr *pExpr = pUpper->pExpr->pRight;
rc = valueFromExpr(pParse, pExpr, aff, &pRangeVal);
assert( pUpper->eOperator==WO_LT || pUpper->eOperator==WO_LE );
if( rc==SQLITE_OK
&& whereKeyStats(pParse, p, pRangeVal, 1, a)==SQLITE_OK
){
iUpper = a[0];
if( pUpper->eOperator==WO_LE ) iUpper += a[1];
}
sqlite4ValueFree(pRangeVal);
}
if( rc==SQLITE_OK ){
if( iUpper<=iLower ){
*pRangeDiv = (double)p->aiRowEst[0];
}else{
*pRangeDiv = (double)p->aiRowEst[0]/(double)(iUpper - iLower);
}
WHERETRACE(("range scan regions: %u..%u div=%g\n",
(u32)iLower, (u32)iUpper, *pRangeDiv));
return SQLITE_OK;
}
}
#else
UNUSED_PARAMETER(pParse);
UNUSED_PARAMETER(p);
UNUSED_PARAMETER(nEq);
#endif
assert( pLower || pUpper );
*pRangeDiv = (double)1;
if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ) *pRangeDiv *= (double)4;
if( pUpper ) *pRangeDiv *= (double)4;
return rc;
}
#ifdef SQLITE_ENABLE_STAT3
/*
** Estimate the number of rows that will be returned based on
** an equality constraint x=VALUE and where that VALUE occurs in
** the histogram data. This only works when x is the left-most
** column of an index and sqlite_stat3 histogram data is available
** for that index. When pExpr==NULL that means the constraint is
** "x IS NULL" instead of "x=VALUE".
**
** Write the estimated row count into *pnRow and return SQLITE_OK.
** If unable to make an estimate, leave *pnRow unchanged and return
** non-zero.
**
** This routine can fail if it is unable to load a collating sequence
** required for string comparison, or if unable to allocate memory
** for a UTF conversion required for comparison. The error is stored
** in the pParse structure.
*/
static int whereEqualScanEst(
Parse *pParse, /* Parsing & code generating context */
Index *p, /* The index whose left-most column is pTerm */
Expr *pExpr, /* Expression for VALUE in the x=VALUE constraint */
double *pnRow /* Write the revised row estimate here */
){
sqlite4_value *pRhs = 0; /* VALUE on right-hand side of pTerm */
u8 aff; /* Column affinity */
int rc; /* Subfunction return code */
tRowcnt a[2]; /* Statistics */
assert( p->aSample!=0 );
assert( p->nSample>0 );
aff = p->pTable->aCol[p->aiColumn[0]].affinity;
if( pExpr ){
rc = valueFromExpr(pParse, pExpr, aff, &pRhs);
if( rc ) goto whereEqualScanEst_cancel;
}else{
pRhs = sqlite4ValueNew(pParse->db);
}
if( pRhs==0 ) return SQLITE_NOTFOUND;
rc = whereKeyStats(pParse, p, pRhs, 0, a);
if( rc==SQLITE_OK ){
WHERETRACE(("equality scan regions: %d\n", (int)a[1]));
*pnRow = a[1];
}
whereEqualScanEst_cancel:
sqlite4ValueFree(pRhs);
return rc;
}
#endif /* defined(SQLITE_ENABLE_STAT3) */
#ifdef SQLITE_ENABLE_STAT3
/*
** Estimate the number of rows that will be returned based on
** an IN constraint where the right-hand side of the IN operator
** is a list of values. Example:
**
** WHERE x IN (1,2,3,4)
**
** Write the estimated row count into *pnRow and return SQLITE_OK.
** If unable to make an estimate, leave *pnRow unchanged and return
** non-zero.
**
** This routine can fail if it is unable to load a collating sequence
** required for string comparison, or if unable to allocate memory
** for a UTF conversion required for comparison. The error is stored
** in the pParse structure.
*/
static int whereInScanEst(
Parse *pParse, /* Parsing & code generating context */
Index *p, /* The index whose left-most column is pTerm */
ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */
double *pnRow /* Write the revised row estimate here */
){
int rc = SQLITE_OK; /* Subfunction return code */
double nEst; /* Number of rows for a single term */
double nRowEst = (double)0; /* New estimate of the number of rows */
int i; /* Loop counter */
assert( p->aSample!=0 );
for(i=0; rc==SQLITE_OK && i<pList->nExpr; i++){
nEst = p->aiRowEst[0];
rc = whereEqualScanEst(pParse, p, pList->a[i].pExpr, &nEst);
nRowEst += nEst;
}
if( rc==SQLITE_OK ){
if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0];
*pnRow = nRowEst;
WHERETRACE(("IN row estimate: est=%g\n", nRowEst));
}
return rc;
}
#endif /* defined(SQLITE_ENABLE_STAT3) */
/*
** Find the best query plan for accessing a particular table. Write the
** best query plan and its cost into the WhereCost object supplied as the
** last parameter.
**
** The lowest cost plan wins. The cost is an estimate of the amount of
** CPU and disk I/O needed to process the requested result.
** Factors that influence cost include:
**
** * The estimated number of rows that will be retrieved. (The
** fewer the better.)
**
** * Whether or not sorting must occur.
**
** * Whether or not there must be separate lookups in the
** index and in the main table.
**
** If there was an INDEXED BY clause (pSrc->pIndex) attached to the table in
** the SQL statement, then this function only considers plans using the
** named index. If no such plan is found, then the returned cost is
** SQLITE_BIG_DBL. If a plan is found that uses the named index,
** then the cost is calculated in the usual way.
**
** If a NOT INDEXED clause (pSrc->notIndexed!=0) was attached to the table
** in the SELECT statement, then no indexes are considered. However, the
** selected plan may still take advantage of the built-in rowid primary key
** index.
*/
static void bestKVIndex(
Parse *pParse, /* The parsing context */
WhereClause *pWC, /* The WHERE clause */
struct SrcList_item *pSrc, /* The FROM clause term to search */
Bitmask notReady, /* Mask of cursors not available for indexing */
Bitmask notValid, /* Cursors not available for any purpose */
ExprList *pOrderBy, /* The ORDER BY clause */
ExprList *pDistinct, /* The select-list if query is DISTINCT */
WhereCost *pCost /* Lowest cost query plan */
){
int iCur = pSrc->iCursor; /* The cursor of the table to be accessed */
Index *pProbe; /* An index we are evaluating */
Index *pFirst; /* First index to evaluate */
Index *pPk; /* Primary Key index */
int eqTermMask; /* Current mask of valid equality operators */
int idxEqTermMask; /* Index mask of valid equality operators */
/* Initialize the cost to a worst-case value */
memset(pCost, 0, sizeof(*pCost));
pCost->rCost = SQLITE_BIG_DBL;
pPk = sqlite4FindPrimaryKey(pSrc->pTab, 0);
/* If the pSrc table is the right table of a LEFT JOIN then we may not
** use an index to satisfy IS NULL constraints on that table. This is
** because columns might end up being NULL if the table does not match -
** a circumstance which the index cannot help us discover. Ticket #2177.
*/
if( pSrc->jointype & JT_LEFT ){
idxEqTermMask = WO_EQ|WO_IN;
}else{
idxEqTermMask = WO_EQ|WO_IN|WO_ISNULL;
}
/* Normally, this function considers all indexes attached to the table
** being queried. Except, if an INDEXED BY clause is specified then only
** the named index is considered. And if a NOT INDEXED clause was present
** only the PRIMARY KEY index may be considered.
*/
if( pSrc->notIndexed ){
pFirst = pPk;
}else if( pSrc->pIndex ){
pFirst = pSrc->pIndex;
}else{
pFirst = pSrc->pTab->pIndex;
}
eqTermMask = idxEqTermMask;
/* Loop over all indices looking for the best one to use */
for(pProbe=pFirst; pProbe; pProbe=pProbe->pNext){
const tRowcnt * const aiRowEst = pProbe->aiRowEst;
double cost; /* Cost of using pProbe */
double nRow; /* Estimated number of rows in result set */
double log10N = (double)1; /* base-10 logarithm of nRow (inexact) */
int rev; /* True to scan in reverse order */
int wsFlags = 0;
Bitmask used = 0;
/* The following variables are populated based on the properties of
** index being evaluated. They are then used to determine the expected
** cost and number of rows returned.
**
** nEq:
** Number of equality terms that can be implemented using the index.
** In other words, the number of initial fields in the index that
** are used in == or IN or NOT NULL constraints of the WHERE clause.
**
** nInMul:
** The "in-multiplier". This is an estimate of how many seek operations
** SQLite must perform on the index in question. For example, if the
** WHERE clause is:
**
** WHERE a IN (1, 2, 3) AND b IN (4, 5, 6)
**
** SQLite must perform 9 lookups on an index on (a, b), so nInMul is
** set to 9. Given the same schema and either of the following WHERE
** clauses:
**
** WHERE a = 1
** WHERE a >= 2
**
** nInMul is set to 1.
**
** If there exists a WHERE term of the form "x IN (SELECT ...)", then
** the sub-select is assumed to return 25 rows for the purposes of
** determining nInMul.
**
** bInEst:
** Set to true if there was at least one "x IN (SELECT ...)" term used
** in determining the value of nInMul. Note that the RHS of the
** IN operator must be a SELECT, not a value list, for this variable
** to be true.
**
** rangeDiv:
** An estimate of a divisor by which to reduce the search space due
** to inequality constraints. In the absence of sqlite_stat3 ANALYZE
** data, a single inequality reduces the search space to 1/4rd its
** original size (rangeDiv==4). Two inequalities reduce the search
** space to 1/16th of its original size (rangeDiv==16).
**
** bSort:
** Boolean. True if there is an ORDER BY clause that will require an
** external sort (i.e. scanning the index being evaluated will not
** correctly order records).
**
** bLookup:
** Boolean. True if a table lookup is required for each index entry
** visited. In other words, true if this is not a covering index.
** This is always false for the rowid primary key index of a table.
** For other indexes, it is true unless all the columns of the table
** used by the SELECT statement are present in the index (such an
** index is sometimes described as a covering index).
** For example, given the index on (a, b), the second of the following
** two queries requires table b-tree lookups in order to find the value
** of column c, but the first does not because columns a and b are
** both available in the index.
**
** SELECT a, b FROM tbl WHERE a = 1;
** SELECT a, b, c FROM tbl WHERE a = 1;
*/
int nEq; /* Number of == or IN terms matching index */
int bInEst = 0; /* True if "x IN (SELECT...)" seen */
int nInMul = 1; /* Number of distinct equalities to lookup */
double rangeDiv = (double)1; /* Estimated reduction in search space */
int nBound = 0; /* Number of range constraints seen */
int bSort = !!pOrderBy; /* True if external sort required */
int bDist = !!pDistinct; /* True if index cannot help with DISTINCT */
int bLookup = 0; /* True if not the PK index */
WhereTerm *pTerm; /* A single term of the WHERE clause */
#ifdef SQLITE_ENABLE_STAT3
WhereTerm *pFirstTerm = 0; /* First term matching the index */
#endif
int nCol = pProbe->nColumn; /* Total columns in index record */
/* Unless pProbe is the primary key index, then the encoded PK column
** values are at the end of each record. Set variable nCol to the total
** number of columns encoded into each index record, including the PK
** columns. */
if( pProbe!=pPk ) nCol += pPk->nColumn;
/* Determine the values of nEq and nInMul */
for(nEq=0; nEq<nCol; nEq++){
int iCol; /* Table column of nEq'th index field */
iCol = idxColumnNumber(pProbe, pPk, nEq);
pTerm = findTerm(pWC, iCur, iCol, notReady, eqTermMask, pProbe);
if( pTerm==0 ) break;
wsFlags |= WHERE_COLUMN_EQ;
testcase( pTerm->pWC!=pWC );
if( pTerm->eOperator & WO_IN ){
Expr *pExpr = pTerm->pExpr;
wsFlags |= WHERE_COLUMN_IN;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
/* "x IN (SELECT ...)": Assume the SELECT returns 25 rows */
nInMul *= 25;
bInEst = 1;
}else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){
/* "x IN (value, value, ...)" */
nInMul *= pExpr->x.pList->nExpr;
}
}else if( pTerm->eOperator & WO_ISNULL ){
wsFlags |= WHERE_COLUMN_NULL;
}
#ifdef SQLITE_ENABLE_STAT3
if( nEq==0 && pProbe->aSample ) pFirstTerm = pTerm;
#endif
used |= pTerm->prereqRight;
}
/* If the index being considered is UNIQUE, and there is an equality
** constraint for all columns in the index, then this search will find
** at most a single row. In this case set the WHERE_UNIQUE flag to
** indicate this to the caller.
**
** Otherwise, if the search may find more than one row, test to see if
** there is a range constraint on indexed column (nEq+1) that can be
** optimized using the index.
*/
if( nEq>=pProbe->nColumn && pProbe->onError!=OE_None ){
testcase( wsFlags & WHERE_COLUMN_IN );
testcase( wsFlags & WHERE_COLUMN_NULL );
if( (wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0 ){
wsFlags |= WHERE_UNIQUE;
}
}else if( pProbe->bUnordered==0 ){
int j = idxColumnNumber(pProbe, pPk, nEq);
if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pProbe) ){
WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pProbe);
WhereTerm *pBtm = findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pProbe);
whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &rangeDiv);
if( pTop ){
nBound = 1;
wsFlags |= WHERE_TOP_LIMIT;
used |= pTop->prereqRight;
testcase( pTop->pWC!=pWC );
}
if( pBtm ){
nBound++;
wsFlags |= WHERE_BTM_LIMIT;
used |= pBtm->prereqRight;
testcase( pBtm->pWC!=pWC );
}
wsFlags |= WHERE_COLUMN_RANGE;
}
}
/* If there is an ORDER BY clause and the index being considered will
** naturally scan rows in the required order, set the appropriate flags
** in wsFlags. Otherwise, if there is an ORDER BY clause but the index
** will scan rows in a different order, set the bSort variable. */
if( isSortingIndex(
pParse, pWC->pMaskSet, pProbe, iCur, pOrderBy, nEq, wsFlags, &rev)
){
bSort = 0;
wsFlags |= WHERE_COLUMN_RANGE|WHERE_ORDERBY;
wsFlags |= (rev ? WHERE_REVERSE : 0);
}
/* If there is a DISTINCT qualifier and this index will scan rows in
** order of the DISTINCT expressions, clear bDist and set the appropriate
** flags in wsFlags. */
if( isDistinctIndex(pParse, pWC, pProbe, iCur, pDistinct, nEq) ){
bDist = 0;
wsFlags |= WHERE_COLUMN_RANGE|WHERE_DISTINCT;
}
/* If currently calculating the cost of using an index (not the PK
** index), determine if all required column data may be obtained without
** using the main table (i.e. if the index is a covering
** index for this query). If it is, set the WHERE_IDX_ONLY flag in
** wsFlags. Otherwise, set the bLookup variable to true.
**
** TODO: Not clear if this optimization can be applied in SQLite 4. Fix
** this block once that is figured out.
*/
#if 0
if( wsFlags ){
Bitmask m = pSrc->colUsed;
int j;
for(j=0; j<pProbe->nColumn; j++){
int x = pProbe->aiColumn[j];
if( x<BMS-1 ){
m &= ~(((Bitmask)1)<<x);
}
}
if( m==0 ){
wsFlags |= WHERE_IDX_ONLY;
}else{
bLookup = 1;
}
}
#endif
bLookup = (pProbe->eIndexType!=SQLITE_INDEX_PRIMARYKEY);
/*
** Estimate the number of rows of output. For an "x IN (SELECT...)"
** constraint, do not let the estimate exceed half the rows in the table.
*/
nRow = (double)(aiRowEst[nEq] * nInMul);
if( bInEst && nRow*2>aiRowEst[0] ){
nRow = aiRowEst[0]/2;
nInMul = (int)(nRow / aiRowEst[nEq]);
}
#ifdef SQLITE_ENABLE_STAT3
/* If the constraint is of the form x=VALUE or x IN (E1,E2,...)
** and we do not think that values of x are unique and if histogram
** data is available for column x, then it might be possible
** to get a better estimate on the number of rows based on
** VALUE and how common that value is according to the histogram.
*/
if( nRow>(double)1 && nEq==1 && pFirstTerm!=0 && aiRowEst[1]>1 ){
assert( (pFirstTerm->eOperator & (WO_EQ|WO_ISNULL|WO_IN))!=0 );
if( pFirstTerm->eOperator & (WO_EQ|WO_ISNULL) ){
testcase( pFirstTerm->eOperator==WO_EQ );
testcase( pFirstTerm->eOperator==WO_ISNULL );
whereEqualScanEst(pParse, pProbe, pFirstTerm->pExpr->pRight, &nRow);
}else if( bInEst==0 ){
assert( pFirstTerm->eOperator==WO_IN );
whereInScanEst(pParse, pProbe, pFirstTerm->pExpr->x.pList, &nRow);
}
}
#endif /* SQLITE_ENABLE_STAT3 */
/* Adjust the number of output rows and downward to reflect rows
** that are excluded by range constraints.
*/
nRow = nRow/rangeDiv;
if( nRow<1 ) nRow = 1;
/* Experiments run on real SQLite databases show that the time needed
** to do a binary search to locate a row in a table or index is roughly
** log10(N) times the time to move from one row to the next row within
** a table or index. The actual times can vary, with the size of
** records being an important factor. Both moves and searches are
** slower with larger records, presumably because fewer records fit
** on one page and hence more pages have to be fetched.
**
** The ANALYZE command and the sqlite_stat1 and sqlite_stat3 tables do
** not give us data on the relative sizes of table and index records.
** So this computation assumes table records are about twice as big
** as index records
*/
if( (wsFlags & WHERE_NOT_FULLSCAN)==0 ){
/* The cost of a full table scan is a number of move operations equal
** to the number of rows in the table.
**
** We add an additional 4x penalty to full table scans. This causes
** the cost function to err on the side of choosing an index over
** choosing a full scan. This 4x full-scan penalty is an arguable
** decision and one which we expect to revisit in the future. But
** it seems to be working well enough at the moment.
*/
cost = aiRowEst[0]*4;
}else{
log10N = estLog(aiRowEst[0]);
cost = nRow;
if( bLookup ){
/* For an index lookup followed by a table lookup:
** nInMul index searches to find the start of each index range
** + nRow steps through the index
** + nRow table searches to lookup the table entry using the PK
*/
cost += (nInMul + nRow)*log10N;
}else{
/* For a covering index:
** nInMul index searches to find the initial entry
** + nRow steps through the index
*/
cost += nInMul*log10N;
}
}
/* Add in the estimated cost of sorting the result. Actual experimental
** measurements of sorting performance in SQLite show that sorting time
** adds C*N*log10(N) to the cost, where N is the number of rows to be
** sorted and C is a factor between 1.95 and 4.3. We will split the
** difference and select C of 3.0.
*/
if( bSort ){
cost += nRow*estLog(nRow)*3;
}
if( bDist ){
cost += nRow*estLog(nRow)*3;
}
/**** Cost of using this index has now been computed ****/
/* If there are additional constraints on this table that cannot
** be used with the current index, but which might lower the number
** of output rows, adjust the nRow value accordingly. This only
** matters if the current index is the least costly, so do not bother
** with this step if we already know this index will not be chosen.
** Also, never reduce the output row count below 2 using this step.
**
** It is critical that the notValid mask be used here instead of
** the notReady mask. When computing an "optimal" index, the notReady
** mask will only have one bit set - the bit for the current table.
** The notValid mask, on the other hand, always has all bits set for
** tables that are not in outer loops. If notReady is used here instead
** of notValid, then a optimal index that depends on inner joins loops
** might be selected even when there exists an optimal index that has
** no such dependency.
*/
if( nRow>2 && cost<=pCost->rCost ){
int k; /* Loop counter */
int nSkipEq = nEq; /* Number of == constraints to skip */
int nSkipRange = nBound; /* Number of < constraints to skip */
Bitmask thisTab; /* Bitmap for pSrc */
thisTab = getMask(pWC->pMaskSet, iCur);
for(pTerm=pWC->a, k=pWC->nTerm; nRow>2 && k; k--, pTerm++){
if( pTerm->wtFlags & TERM_VIRTUAL ) continue;
if( (pTerm->prereqAll & notValid)!=thisTab ) continue;
if( pTerm->eOperator & (WO_EQ|WO_IN|WO_ISNULL) ){
if( nSkipEq ){
/* Ignore the first nEq equality matches since the index
** has already accounted for these */
nSkipEq--;
}else{
/* Assume each additional equality match reduces the result
** set size by a factor of 10 */
nRow /= 10;
}
}else if( pTerm->eOperator & (WO_LT|WO_LE|WO_GT|WO_GE) ){
if( nSkipRange ){
/* Ignore the first nSkipRange range constraints since the index
** has already accounted for these */
nSkipRange--;
}else{
/* Assume each additional range constraint reduces the result
** set size by a factor of 3. Indexed range constraints reduce
** the search space by a larger factor: 4. We make indexed range
** more selective intentionally because of the subjective
** observation that indexed range constraints really are more
** selective in practice, on average. */
nRow /= 3;
}
}else if( pTerm->eOperator!=WO_NOOP ){
/* Any other expression lowers the output row count by half */
nRow /= 2;
}
}
if( nRow<2 ) nRow = 2;
}
WHERETRACE((
"%s(%s): nEq=%d nInMul=%d rangeDiv=%d bSort=%d bLookup=%d wsFlags=0x%x\n"
" notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f used=0x%llx\n",
pSrc->pTab->zName, pProbe->zName,
nEq, nInMul, (int)rangeDiv, bSort, bLookup, wsFlags,
notReady, log10N, nRow, cost, used
));
/* If this index is the best we have seen so far, then record this
** index and its cost in the pCost structure.
*/
if( (pProbe==pFirst || wsFlags)
&& (cost<pCost->rCost || (cost<=pCost->rCost && nRow<pCost->plan.nRow))
){
pCost->rCost = cost;
pCost->used = used;
pCost->plan.nRow = nRow;
pCost->plan.wsFlags = wsFlags;
pCost->plan.nEq = nEq;
pCost->plan.u.pIdx = pProbe;
}
/* If there was an INDEXED BY or NOT INDEXED clause, only one index is
** considered. */
if( pSrc->pIndex || pSrc->notIndexed ) break;
}
/* If there is no ORDER BY clause and the SQLITE_ReverseOrder flag
** is set, then reverse the order that the index will be scanned
** in. This is used for application testing, to help find cases
** where application behaviour depends on the (undefined) order that
** SQLite outputs rows in in the absence of an ORDER BY clause. */
if( !pOrderBy && pParse->db->flags & SQLITE_ReverseOrder ){
pCost->plan.wsFlags |= WHERE_REVERSE;
}
assert( pOrderBy || (pCost->plan.wsFlags&WHERE_ORDERBY)==0 );
assert( pSrc->pIndex==0
|| pCost->plan.u.pIdx==0
|| pCost->plan.u.pIdx==pSrc->pIndex
);
WHERETRACE(("best index is: %s\n",
((pCost->plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ? "none" :
pCost->plan.u.pIdx ? pCost->plan.u.pIdx->zName : "ipk")
));
bestOrClauseIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost);
bestAutomaticIndex(pParse, pWC, pSrc, notReady, pCost);
pCost->plan.wsFlags |= eqTermMask;
}
/*
** Find the query plan for accessing table pSrc->pTab. Write the
** best query plan and its cost into the WhereCost object supplied
** as the last parameter. This function may calculate the cost of
** both real and virtual table scans.
*/
static void bestIndex(
Parse *pParse, /* The parsing context */
WhereClause *pWC, /* The WHERE clause */
struct SrcList_item *pSrc, /* The FROM clause term to search */
Bitmask notReady, /* Mask of cursors not available for indexing */
Bitmask notValid, /* Cursors not available for any purpose */
ExprList *pOrderBy, /* The ORDER BY clause */
WhereCost *pCost /* Lowest cost query plan */
){
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( IsVirtual(pSrc->pTab) ){
sqlite4_index_info *p = 0;
bestVirtualIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost,&p);
if( p->needToFreeIdxStr ){
sqlite4_free(p->idxStr);
}
sqlite4DbFree(pParse->db, p);
}else
#endif
{
bestKVIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, 0, pCost);
}
}
/*
** Disable a term in the WHERE clause. Except, do not disable the term
** if it controls a LEFT OUTER JOIN and it did not originate in the ON
** or USING clause of that join.
**
** Consider the term t2.z='ok' in the following queries:
**
** (1) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x WHERE t2.z='ok'
** (2) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x AND t2.z='ok'
** (3) SELECT * FROM t1, t2 WHERE t1.a=t2.x AND t2.z='ok'
**
** The t2.z='ok' is disabled in the in (2) because it originates
** in the ON clause. The term is disabled in (3) because it is not part
** of a LEFT OUTER JOIN. In (1), the term is not disabled.
**
** IMPLEMENTATION-OF: R-24597-58655 No tests are done for terms that are
** completely satisfied by indices.
**
** Disabling a term causes that term to not be tested in the inner loop
** of the join. Disabling is an optimization. When terms are satisfied
** by indices, we disable them to prevent redundant tests in the inner
** loop. We would get the correct results if nothing were ever disabled,
** but joins might run a little slower. The trick is to disable as much
** as we can without disabling too much. If we disabled in (1), we'd get
** the wrong answer. See ticket #813.
*/
static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
if( pTerm
&& (pTerm->wtFlags & TERM_CODED)==0
&& (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin))
){
pTerm->wtFlags |= TERM_CODED;
if( pTerm->iParent>=0 ){
WhereTerm *pOther = &pTerm->pWC->a[pTerm->iParent];
if( (--pOther->nChild)==0 ){
disableTerm(pLevel, pOther);
}
}
}
}
/*
** Code an OP_Affinity opcode to apply the column affinity string zAff
** to the n registers starting at base.
**
** As an optimization, SQLITE_AFF_NONE entries (which are no-ops) at the
** beginning and end of zAff are ignored. If all entries in zAff are
** SQLITE_AFF_NONE, then no code gets generated.
**
** This routine makes its own copy of zAff so that the caller is free
** to modify zAff after this routine returns.
*/
static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){
Vdbe *v = pParse->pVdbe;
if( zAff==0 ){
assert( pParse->db->mallocFailed );
return;
}
assert( v!=0 );
/* Adjust base and n to skip over SQLITE_AFF_NONE entries at the beginning
** and end of the affinity string.
*/
while( n>0 && zAff[0]==SQLITE_AFF_NONE ){
n--;
base++;
zAff++;
}
while( n>1 && zAff[n-1]==SQLITE_AFF_NONE ){
n--;
}
/* Code the OP_Affinity opcode if there is anything left to do. */
if( n>0 ){
sqlite4VdbeAddOp2(v, OP_Affinity, base, n);
sqlite4VdbeChangeP4(v, -1, zAff, n);
sqlite4ExprCacheAffinityChange(pParse, base, n);
}
}
/*
** 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 register iReg.
**
** For a constraint of the form X=expr, the expression is evaluated and its
** result is left on the stack. For constraints of the form X IN (...)
** this routine sets up a loop that will iterate over all values of X.
*/
static int codeEqualityTerm(
Parse *pParse, /* The parsing context */
WhereTerm *pTerm, /* The term of the WHERE clause to be coded */
WhereLevel *pLevel, /* When level of the FROM clause we are working on */
int iTarget /* Attempt to leave results in this register */
){
Expr *pX = pTerm->pExpr;
Vdbe *v = pParse->pVdbe;
int iReg; /* Register holding results */
assert( iTarget>0 );
if( pX->op==TK_EQ ){
iReg = sqlite4ExprCodeTarget(pParse, pX->pRight, iTarget);
}else if( pX->op==TK_ISNULL ){
iReg = iTarget;
sqlite4VdbeAddOp2(v, OP_Null, 0, iReg);
#ifndef SQLITE_OMIT_SUBQUERY
}else{
/* Code a loop that iterates through the set of distinct, non-null
** values in the set on the right-hand-side of the IN(...) operator.
** There are two ways to do this:
**
** * If the SELECT statement is of the form "SELECT x FROM tbl",
** and column x is subject to a UNIQUE constraint, and the
** default affinity and collation sequence of column "x" match
** those required by the comparison, iterate through the PK
** index.
**
** * Otherwise, materialize the set into an ephemeral index using
** "x" as both the key and value. Then loop through the contents
** of the ephemeral index.
*/
sqlite4 *db = pParse->db;
int iTab;
int iCol; /* Column to read from cursor iTab */
struct InLoop *pIn;
assert( pX->op==TK_IN );
iReg = iTarget;
if( sqlite4FindExistingInIndex(pParse, pX, 1) ){
/* This branch is taken if the rhs of the IN is a select of the
** form "SELECT x FROM tble" and column x is subject to a UNIQUE
** constraint that uses the same collation sequence and affinity as
** this IN (...) test. In this case just loop through all values of
** "x", skipping any NULLs. */
Table *pTab = pX->x.pSelect->pSrc->a[0].pTab;
int iDb = sqlite4SchemaToIndex(db, pTab->pSchema);
iTab = pX->iTable = pParse->nTab++;
sqlite4OpenPrimaryKey(pParse, iTab, iDb, pTab, OP_OpenRead);
iCol = pX->pLeft->iColumn;
}else{
/* Set Parse.nQueryLoop to 1 before calling sqlite4CodeSubselect().
** This informs the optimizer that there is no point in constructing
** any automatic indexes for the outer loop of the sub-select, as it
** will only be run once. See also bestAutomaticIndex(). */
int nQueryLoopSave = pParse->nQueryLoop;
pParse->nQueryLoop = (double)1;
sqlite4CodeSubselect(pParse, pX, 0, 0);
pParse->nQueryLoop = nQueryLoopSave;
iTab = pX->iTable;
iCol = 0;
}
sqlite4VdbeAddOp2(v, OP_Rewind, iTab, 0);
assert( pLevel->plan.wsFlags & WHERE_IN_ABLE );
if( pLevel->u.in.nIn==0 ) pLevel->addrNxt = sqlite4VdbeMakeLabel(v);
pLevel->u.in.nIn++;
pLevel->u.in.aInLoop = sqlite4DbReallocOrFree(db, pLevel->u.in.aInLoop,
(sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn)
);
pIn = pLevel->u.in.aInLoop;
if( pIn ){
pIn += pLevel->u.in.nIn - 1;
pIn->iCur = iTab;
pIn->addrInTop = sqlite4VdbeAddOp3(v, OP_Column, iTab, iCol, iReg);
sqlite4VdbeAddOp1(v, OP_IsNull, iReg);
}else{
assert( db->mallocFailed );
pLevel->u.in.nIn = 0;
}
#endif
}
disableTerm(pLevel, pTerm);
return iReg;
}
/*
** Generate code that will evaluate all == and IN constraints for an
** index.
**
** For example, consider table t1(a,b,c,d,e,f) with index i1(a,b,c).
** Suppose the WHERE clause is this: a==5 AND b IN (1,2,3) AND c>5 AND c<10
** The index has as many as three equality constraints, but in this
** example, the third "c" value is an inequality. So only two
** constraints are coded. This routine will generate code to evaluate
** a==5 and b IN (1,2,3). The current values for a and b will be stored
** in consecutive registers and the index of the first register is returned.
**
** In the example above nEq==2. But this subroutine works for any value
** of nEq including 0. If nEq==0, this routine is nearly a no-op.
** The only thing it does is allocate the pLevel->iMem memory cell and
** compute the affinity string.
**
** This routine always allocates at least one memory cell and returns
** the index of that memory cell. The code that
** calls this routine will use that memory cell to store the termination
** key value of the loop. If one or more IN operators appear, then
** this routine allocates an additional nEq memory cells for internal
** use.
**
** Before returning, *pzAff is set to point to a buffer containing a
** copy of the column affinity string of the index allocated using
** sqlite4DbMalloc(). Except, entries in the copy of the string associated
** with equality constraints that use NONE affinity are set to
** SQLITE_AFF_NONE. This is to deal with SQL such as the following:
**
** CREATE TABLE t1(a TEXT PRIMARY KEY, b);
** SELECT ... FROM t1 AS t2, t1 WHERE t1.a = t2.b;
**
** In the example above, the index on t1(a) has TEXT affinity. But since
** the right hand side of the equality constraint (t2.b) has NONE affinity,
** no conversion should be attempted before using a t2.b value as part of
** a key to search the index. Hence the first byte in the returned affinity
** string in this example would be set to SQLITE_AFF_NONE.
*/
static int codeAllEqualityTerms(
Parse *pParse, /* Parsing context */
WhereLevel *pLevel, /* Which nested loop of the FROM we are coding */
WhereClause *pWC, /* The WHERE clause */
Bitmask notReady, /* Which parts of FROM have not yet been coded */
int nExtraReg, /* Number of extra registers to allocate */
char **pzAff /* OUT: Set to point to affinity string */
){
int nEq = pLevel->plan.nEq; /* The number of == or IN constraints to code */
Vdbe *v = pParse->pVdbe; /* The vm under construction */
Index *pIdx; /* The index being used for this loop */
int iCur = pLevel->iTabCur; /* The cursor of the table */
WhereTerm *pTerm; /* A single constraint term */
int j; /* Loop counter */
int regBase; /* Base register */
int nReg; /* Number of registers to allocate */
char *zAff; /* Affinity string to return */
/* This module is only called on query plans that use an index. */
assert( pLevel->plan.wsFlags & WHERE_INDEXED );
pIdx = pLevel->plan.u.pIdx;
/* Figure out how many memory cells we will need then allocate them.
*/
regBase = pParse->nMem + 1;
nReg = pLevel->plan.nEq + nExtraReg;
pParse->nMem += nReg;
zAff = sqlite4DbStrDup(pParse->db, sqlite4IndexAffinityStr(v, pIdx));
if( !zAff ){
pParse->db->mallocFailed = 1;
}
/* Evaluate the equality constraints
*/
assert( pIdx->nColumn>=nEq );
for(j=0; j<nEq; j++){
int r1;
int k = pIdx->aiColumn[j];
pTerm = findTerm(pWC, iCur, k, notReady, pLevel->plan.wsFlags, pIdx);
if( NEVER(pTerm==0) ) break;
/* The following true for indices with redundant columns.
** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */
testcase( (pTerm->wtFlags & TERM_CODED)!=0 );
testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
r1 = codeEqualityTerm(pParse, pTerm, pLevel, regBase+j);
if( r1!=regBase+j ){
if( nReg==1 ){
sqlite4ReleaseTempReg(pParse, regBase);
regBase = r1;
}else{
sqlite4VdbeAddOp2(v, OP_SCopy, r1, regBase+j);
}
}
testcase( pTerm->eOperator & WO_ISNULL );
testcase( pTerm->eOperator & WO_IN );
if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){
Expr *pRight = pTerm->pExpr->pRight;
sqlite4ExprCodeIsNullJump(v, pRight, regBase+j, pLevel->addrBrk);
if( zAff ){
if( sqlite4CompareAffinity(pRight, zAff[j])==SQLITE_AFF_NONE ){
zAff[j] = SQLITE_AFF_NONE;
}
if( sqlite4ExprNeedsNoAffinityChange(pRight, zAff[j]) ){
zAff[j] = SQLITE_AFF_NONE;
}
}
}
}
*pzAff = zAff;
return regBase;
}
#ifndef SQLITE_OMIT_EXPLAIN
/*
** This routine is a helper for explainIndexRange() below
**
** pStr holds the text of an expression that we are building up one term
** at a time. This routine adds a new term to the end of the expression.
** Terms are separated by AND so add the "AND" text for second and subsequent
** terms only.
*/
static void explainAppendTerm(
StrAccum *pStr, /* The text expression being built */
int iTerm, /* Index of this term. First is zero */
const char *zColumn, /* Name of the column */
const char *zOp /* Name of the operator */
){
if( iTerm ) sqlite4StrAccumAppend(pStr, " AND ", 5);
sqlite4StrAccumAppend(pStr, zColumn, -1);
sqlite4StrAccumAppend(pStr, zOp, 1);
sqlite4StrAccumAppend(pStr, "?", 1);
}
/*
** Argument pLevel describes a strategy for scanning table pTab. This
** function returns a pointer to a string buffer containing a description
** of the subset of table rows scanned by the strategy in the form of an
** SQL expression. Or, if all rows are scanned, NULL is returned.
**
** For example, if the query:
**
** SELECT * FROM t1 WHERE a=1 AND b>2;
**
** is run and there is an index on (a, b), then this function returns a
** string similar to:
**
** "a=? AND b>?"
**
** The returned pointer points to memory obtained from sqlite4DbMalloc().
** It is the responsibility of the caller to free the buffer when it is
** no longer required.
*/
static char *explainIndexRange(sqlite4 *db, WhereLevel *pLevel, Table *pTab){
WherePlan *pPlan = &pLevel->plan;
Index *pPk;
Index *pIdx = pPlan->u.pIdx;
int nEq = pPlan->nEq;
int i, j;
Column *aCol = pTab->aCol;
int *aiColumn = pIdx->aiColumn;
StrAccum txt;
pPk = sqlite4FindPrimaryKey(pTab, 0);
if( nEq==0 && (pPlan->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){
return 0;
}
sqlite4StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH);
txt.db = db;
txt.pEnv = db->pEnv;
sqlite4StrAccumAppend(&txt, " (", 2);
for(i=0; i<nEq; i++){
const char *zCol = tblColumnName(pTab, idxColumnNumber(pIdx, pPk, i));
explainAppendTerm(&txt, i, zCol, "=");
}
if( pPlan->wsFlags&WHERE_BTM_LIMIT ){
const char *zCol = tblColumnName(pTab, idxColumnNumber(pIdx, pPk, nEq));
explainAppendTerm(&txt, i++, zCol, ">");
}
if( pPlan->wsFlags&WHERE_TOP_LIMIT ){
const char *zCol = tblColumnName(pTab, idxColumnNumber(pIdx, pPk, nEq));
explainAppendTerm(&txt, i, zCol, "<");
}
sqlite4StrAccumAppend(&txt, ")", 1);
return sqlite4StrAccumFinish(&txt);
}
/*
** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN
** command. If the query being compiled is an EXPLAIN QUERY PLAN, a single
** record is added to the output to describe the table scan strategy in
** pLevel.
*/
static void explainOneScan(
Parse *pParse, /* Parse context */
SrcList *pTabList, /* Table list this loop refers to */
WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */
int iLevel, /* Value for "level" column of output */
int iFrom, /* Value for "from" column of output */
u16 wctrlFlags /* Flags passed to sqlite4WhereBegin() */
){
if( pParse->explain==2 ){
u32 flags = pLevel->plan.wsFlags;
struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
Vdbe *v = pParse->pVdbe; /* VM being constructed */
sqlite4 *db = pParse->db; /* Database handle */
char *zMsg; /* Text to add to EQP output */
sqlite4_int64 nRow; /* Expected number of rows visited by scan */
int iId = pParse->iSelectId; /* Select id (left-most output column) */
int isSearch; /* True for a SEARCH. False for SCAN. */
if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return;
isSearch = (pLevel->plan.nEq>0)
|| (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
|| (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
zMsg = sqlite4MPrintf(db, "%s", isSearch?"SEARCH":"SCAN");
if( pItem->pSelect ){
zMsg = sqlite4MAppendf(db, zMsg, "%s SUBQUERY %d", zMsg,pItem->iSelectId);
}else{
zMsg = sqlite4MAppendf(db, zMsg, "%s TABLE %s", zMsg, pItem->zName);
}
if( pItem->zAlias ){
zMsg = sqlite4MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias);
}
if( (flags & WHERE_INDEXED)!=0 ){
char *zWhere = explainIndexRange(db, pLevel, pItem->pTab);
Index *pIdx = pLevel->plan.u.pIdx;
const char *zName = "";
const char *zType = "INDEX";
if( pIdx->eIndexType==SQLITE_INDEX_PRIMARYKEY ){
zType = "PRIMARY KEY";
}else if( 0==(flags & WHERE_TEMP_INDEX) ){
zName = pIdx->zName;
}
zMsg = sqlite4MAppendf(db, zMsg, "%s USING %s%s%s%s%s", zMsg,
((flags & WHERE_TEMP_INDEX)?"AUTOMATIC ":""),
zType, (zName[0] ? " " : ""), zName, zWhere
);
sqlite4DbFree(db, zWhere);
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
sqlite4_index_info *pVtabIdx = pLevel->plan.u.pVtabIdx;
zMsg = sqlite4MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg,
pVtabIdx->idxNum, pVtabIdx->idxStr);
}
#endif
if( wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX) ){
testcase( wctrlFlags & WHERE_ORDERBY_MIN );
nRow = 1;
}else{
nRow = (sqlite4_int64)pLevel->plan.nRow;
}
zMsg = sqlite4MAppendf(db, zMsg, "%s (~%lld rows)", zMsg, nRow);
sqlite4VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC);
}
}
#else
# define explainOneScan(u,v,w,x,y,z)
#endif /* SQLITE_OMIT_EXPLAIN */
/*
** Generate code for the start of the iLevel-th loop in the WHERE clause
** implementation described by pWInfo.
*/
static Bitmask codeOneLoopStart(
WhereInfo *pWInfo, /* Complete information about the WHERE clause */
int iLevel, /* Which level of pWInfo->a[] should be coded */
u16 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */
Bitmask notReady, /* Which tables are currently available */
Expr *pWhere /* Complete WHERE clause */
){
int j, k; /* Loop counters */
int iCur; /* The VDBE cursor for the table */
int addrNxt; /* Where to jump to continue with the next IN case */
int bRev; /* True if we need to scan in reverse order */
WhereLevel *pLevel; /* The where level to be coded */
WhereClause *pWC; /* Decomposition of the entire WHERE clause */
WhereTerm *pTerm; /* A WHERE clause term */
Parse *pParse; /* Parsing context */
Vdbe *v; /* The prepared stmt under constructions */
struct SrcList_item *pTabItem; /* FROM clause term being coded */
int addrBrk; /* Jump here to break out of the loop */
int addrCont; /* Jump here to continue with next cycle */
int iReleaseReg = 0; /* Temp register to free before returning */
pParse = pWInfo->pParse;
v = pParse->pVdbe;
pWC = pWInfo->pWC;
pLevel = &pWInfo->a[iLevel];
pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
iCur = pTabItem->iCursor;
bRev = (pLevel->plan.wsFlags & WHERE_REVERSE)!=0;
/* Create labels for the "break" and "continue" instructions
** for the current loop. Jump to addrBrk to break out of a loop.
** Jump to cont to go immediately to the next iteration of the
** loop.
**
** When there is an IN operator, we also have a "addrNxt" label that
** means to continue with the next IN value combination. When
** there are no IN operators in the constraints, the "addrNxt" label
** is the same as "addrBrk".
*/
addrBrk = pLevel->addrBrk = pLevel->addrNxt = sqlite4VdbeMakeLabel(v);
addrCont = pLevel->addrCont = sqlite4VdbeMakeLabel(v);
/* If this is the right table of a LEFT OUTER JOIN, allocate and
** initialize a memory cell that records if this table matches any
** row of the left table of the join.
*/
if( pLevel->iFrom>0 && (pTabItem[0].jointype & JT_LEFT)!=0 ){
pLevel->iLeftJoin = ++pParse->nMem;
sqlite4VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin);
VdbeComment((v, "init LEFT JOIN no-match flag"));
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
/* Case 0: The table is a virtual-table. Use the VFilter and VNext
** to access the data.
*/
int iReg; /* P3 Value for OP_VFilter */
sqlite4_index_info *pVtabIdx = pLevel->plan.u.pVtabIdx;
int nConstraint = pVtabIdx->nConstraint;
struct sqlite4_index_constraint_usage *aUsage =
pVtabIdx->aConstraintUsage;
const struct sqlite4_index_constraint *aConstraint =
pVtabIdx->aConstraint;
sqlite4ExprCachePush(pParse);
iReg = sqlite4GetTempRange(pParse, nConstraint+2);
for(j=1; j<=nConstraint; j++){
for(k=0; k<nConstraint; k++){
if( aUsage[k].argvIndex==j ){
int iTerm = aConstraint[k].iTermOffset;
sqlite4ExprCode(pParse, pWC->a[iTerm].pExpr->pRight, iReg+j+1);
break;
}
}
if( k==nConstraint ) break;
}
sqlite4VdbeAddOp2(v, OP_Integer, pVtabIdx->idxNum, iReg);
sqlite4VdbeAddOp2(v, OP_Integer, j-1, iReg+1);
sqlite4VdbeAddOp4(v, OP_VFilter, iCur, addrBrk, iReg, pVtabIdx->idxStr,
pVtabIdx->needToFreeIdxStr ? P4_MPRINTF : P4_STATIC);
pVtabIdx->needToFreeIdxStr = 0;
for(j=0; j<nConstraint; j++){
if( aUsage[j].omit ){
int iTerm = aConstraint[j].iTermOffset;
disableTerm(pLevel, &pWC->a[iTerm]);
}
}
pLevel->op = OP_VNext;
pLevel->p1 = iCur;
pLevel->p2 = sqlite4VdbeCurrentAddr(v);
sqlite4ReleaseTempRange(pParse, iReg, nConstraint+2);
sqlite4ExprCachePop(pParse, 1);
}else
#endif /* SQLITE_OMIT_VIRTUALTABLE */
if( pLevel->plan.wsFlags & (WHERE_COLUMN_RANGE|WHERE_COLUMN_EQ) ){
/* Case 3: A scan using an index.
**
** The WHERE clause may contain zero or more equality
** terms ("==" or "IN" operators) that refer to the N
** left-most columns of the index. It may also contain
** inequality constraints (>, <, >= or <=) on the indexed
** column that immediately follows the N equalities. Only
** the right-most column can be an inequality - the rest must
** use the "==" and "IN" operators. For example, if the
** index is on (x,y,z), then the following clauses are all
** optimized:
**
** x=5
** x=5 AND y=10
** x=5 AND y<10
** x=5 AND y>5 AND y<10
** x=5 AND y=5 AND z<=10
**
** The z<10 term of the following cannot be used, only
** the x=5 term:
**
** x=5 AND z<10
**
** N may be zero if there are inequality constraints.
** If there are no inequality constraints, then N is at
** least one.
**
** This case is also used when there are no WHERE clause
** constraints but an index is selected anyway, in order
** to force the output order to conform to an ORDER BY.
*/
static const u8 aStartOp[] = {
0,
0,
OP_Rewind, /* 2: (!start_constraints && startEq && !bRev) */
OP_Last, /* 3: (!start_constraints && startEq && bRev) */
OP_SeekGt, /* 4: (start_constraints && !startEq && !bRev) */
OP_SeekLt, /* 5: (start_constraints && !startEq && bRev) */
OP_SeekGe, /* 6: (start_constraints && startEq && !bRev) */
OP_SeekLe /* 7: (start_constraints && startEq && bRev) */
};
static const u8 aEndOp[] = {
OP_Noop, /* 0: (!end_constraints) */
OP_IdxGE, /* 1: (end_constraints && !endEq && !bRev) */
OP_IdxLE, /* 2: (end_constraints && !endEq && bRev) */
OP_IdxGT, /* 3: (end_constraints && endEq && !bRev) */
OP_IdxLT /* 4: (end_constraints && endEq && bRev) */
};
int nEq = pLevel->plan.nEq; /* Number of == or IN terms */
int isMinQuery = 0; /* If this is an optimized SELECT min(x).. */
int regBase; /* Base register holding constraint values */
int r1; /* Temp register */
WhereTerm *pRangeStart = 0; /* Inequality constraint at range start */
WhereTerm *pRangeEnd = 0; /* Inequality constraint at range end */
int startEq; /* True if range start uses ==, >= or <= */
int endEq; /* True if range end uses ==, >= or <= */
int start_constraints; /* Start of range is constrained */
int nConstraint; /* Number of constraint terms */
Index *pIdx; /* The index we will be using */
int iIdxCur; /* The VDBE cursor for the index */
int nExtraReg = 0; /* Number of extra registers needed */
int op; /* Instruction opcode */
char *zStartAff; /* Affinity for start of range constraint */
char *zEndAff; /* Affinity for end of range constraint */
int regEndKey; /* Register for end-key */
int iIneq; /* The table column subject to inequality */
Index *pPk; /* Primary key index on same table as pIdx */
pIdx = pLevel->plan.u.pIdx;
pPk = sqlite4FindPrimaryKey(pIdx->pTable, 0);
iIneq = idxColumnNumber(pIdx, pPk, nEq);
iIdxCur = pLevel->iIdxCur;
assert( iCur==pLevel->iTabCur );
/* If this loop satisfies a sort order (pOrderBy) request that
** was passed to this function to implement a "SELECT min(x) ..."
** query, then the caller will only allow the loop to run for
** a single iteration. This means that the first row returned
** should not have a NULL value stored in 'x'. If column 'x' is
** the first one after the nEq equality constraints in the index,
** this requires some special handling.
*/
if( (wctrlFlags&WHERE_ORDERBY_MIN)!=0
&& (pLevel->plan.wsFlags&WHERE_ORDERBY)
&& (pIdx->nColumn>nEq)
){
/* assert( pOrderBy->nExpr==1 ); */
/* assert( pOrderBy->a[0].pExpr->iColumn==pIdx->aiColumn[nEq] ); */
isMinQuery = 1;
nExtraReg = 1;
}
/* Find any inequality constraint terms for the start and end
** of the range. */
if( pLevel->plan.wsFlags & WHERE_TOP_LIMIT ){
pRangeEnd = findTerm(pWC, iCur, iIneq, notReady, (WO_LT|WO_LE), pIdx);
nExtraReg = 1;
}
if( pLevel->plan.wsFlags & WHERE_BTM_LIMIT ){
pRangeStart = findTerm(pWC, iCur, iIneq, notReady, (WO_GT|WO_GE), pIdx);
nExtraReg = 1;
}
/* 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. Ensure that nExtraReg registers are allocated
** immediately following the array.
*/
regBase = codeAllEqualityTerms(
pParse, pLevel, pWC, notReady, nExtraReg, &zStartAff
);
assert( (regBase+nEq+nExtraReg-1)<=pParse->nMem );
zEndAff = sqlite4DbStrDup(pParse->db, zStartAff);
addrNxt = pLevel->addrNxt;
/* If we are doing a reverse order scan on an ascending index, or
** a forward order scan on a descending index, interchange the
** start and end terms (pRangeStart and pRangeEnd). */
if( (nEq<pIdx->nColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC))
|| (bRev && pIdx->nColumn==nEq)
){
SWAP(WhereTerm *, pRangeEnd, pRangeStart);
}
testcase( pRangeStart && pRangeStart->eOperator & WO_LE );
testcase( pRangeStart && pRangeStart->eOperator & WO_GE );
testcase( pRangeEnd && pRangeEnd->eOperator & WO_LE );
testcase( pRangeEnd && pRangeEnd->eOperator & WO_GE );
startEq = !pRangeStart || pRangeStart->eOperator & (WO_LE|WO_GE);
endEq = !pRangeEnd || pRangeEnd->eOperator & (WO_LE|WO_GE);
start_constraints = pRangeStart || nEq>0;
/* Seek the index cursor to the start of the range. */
nConstraint = nEq;
if( pRangeStart ){
Expr *pRight = pRangeStart->pExpr->pRight;
sqlite4ExprCode(pParse, pRight, regBase+nEq);
if( (pRangeStart->wtFlags & TERM_VNULL)==0 ){
sqlite4ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt);
}
if( zStartAff ){
if( sqlite4CompareAffinity(pRight, zStartAff[nEq])==SQLITE_AFF_NONE){
/* Since the comparison is to be performed with no conversions
** applied to the operands, set the affinity to apply to pRight to
** SQLITE_AFF_NONE. */
zStartAff[nEq] = SQLITE_AFF_NONE;
}
if( sqlite4ExprNeedsNoAffinityChange(pRight, zStartAff[nEq]) ){
zStartAff[nEq] = SQLITE_AFF_NONE;
}
}
nConstraint++;
testcase( pRangeStart->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
}else if( isMinQuery ){
sqlite4VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
nConstraint++;
startEq = 0;
start_constraints = 1;
}
codeApplyAffinity(pParse, regBase, nConstraint, zStartAff);
op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
assert( op!=0 );
testcase( op==OP_Rewind );
testcase( op==OP_Last );
testcase( op==OP_SeekGt );
testcase( op==OP_SeekGe );
testcase( op==OP_SeekLe );
testcase( op==OP_SeekLt );
sqlite4VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
/* Set variable op to the instruction required to determine if the
** cursor is passed the end of the range. If the range is unbounded,
** then set op to OP_Noop. Nothing to do in this case. */
assert( (endEq==0 || endEq==1) );
op = aEndOp[(pRangeEnd || nEq) * (1 + (endEq+endEq) + bRev)];
testcase( op==OP_Noop );
testcase( op==OP_IdxGE );
testcase( op==OP_IdxLT );
testcase( op==OP_IdxLE );
testcase( op==OP_IdxGT );
if( op!=OP_Noop ){
/* If there is an inequality at the end of this range, compute its
** value here. */
nConstraint = nEq;
if( pRangeEnd ){
Expr *pRight = pRangeEnd->pExpr->pRight;
sqlite4ExprCacheRemove(pParse, regBase+nEq, 1);
sqlite4ExprCode(pParse, pRight, regBase+nEq);
if( (pRangeEnd->wtFlags & TERM_VNULL)==0 ){
sqlite4ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt);
}
if( zEndAff ){
if( sqlite4CompareAffinity(pRight, zEndAff[nEq])==SQLITE_AFF_NONE){
/* Since the comparison is to be performed with no conversions
** applied to the operands, set the affinity to apply to pRight to
** SQLITE_AFF_NONE. */
zEndAff[nEq] = SQLITE_AFF_NONE;
}
if( sqlite4ExprNeedsNoAffinityChange(pRight, zEndAff[nEq]) ){
zEndAff[nEq] = SQLITE_AFF_NONE;
}
}
codeApplyAffinity(pParse, regBase, nEq+1, zEndAff);
nConstraint++;
testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
}
/* Now compute an end-key using OP_MakeIdxKey */
regEndKey = ++pParse->nMem;
sqlite4VdbeAddOp4Int(
v, OP_MakeIdxKey, iIdxCur, regBase, regEndKey, nConstraint
);
}
sqlite4DbFree(pParse->db, zStartAff);
sqlite4DbFree(pParse->db, zEndAff);
/* Top of the loop body */
pLevel->p2 = sqlite4VdbeCurrentAddr(v);
if( op!=OP_Noop ){
sqlite4VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regEndKey, nConstraint);
}
/* Seek the PK cursor, if required */
disableTerm(pLevel, pRangeStart);
disableTerm(pLevel, pRangeEnd);
if( pIdx->eIndexType!=SQLITE_INDEX_PRIMARYKEY
&& pIdx->eIndexType!=SQLITE_INDEX_TEMP
){
sqlite4VdbeAddOp3(v, OP_SeekPk, iCur, 0, iIdxCur);
}
/* If there are inequality constraints, check that the value
** of the table column that the inequality constrains is not NULL.
** If it is, jump to the next iteration of the loop. */
r1 = sqlite4GetTempReg(pParse);
testcase( pLevel->plan.wsFlags & WHERE_BTM_LIMIT );
testcase( pLevel->plan.wsFlags & WHERE_TOP_LIMIT );
if( (pLevel->plan.wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 ){
sqlite4VdbeAddOp3(v, OP_Column, iCur, iIneq, r1);
sqlite4VdbeAddOp2(v, OP_IsNull, r1, addrCont);
}
sqlite4ReleaseTempReg(pParse, r1);
/* Record the instruction used to terminate the loop. Disable
** WHERE clause terms made redundant by the index range scan.
*/
if( pLevel->plan.wsFlags & WHERE_UNIQUE ){
pLevel->op = OP_Noop;
}else if( bRev ){
pLevel->op = OP_Prev;
}else{
pLevel->op = OP_Next;
}
pLevel->p1 = iIdxCur;
}else
#ifndef SQLITE_OMIT_OR_OPTIMIZATION
if( pLevel->plan.wsFlags & WHERE_MULTI_OR ){
/* Case 4: Two or more separately indexed terms connected by OR
**
** Example:
**
** CREATE TABLE t1(a,b,c,d);
** CREATE INDEX i1 ON t1(a);
** CREATE INDEX i2 ON t1(b);
** CREATE INDEX i3 ON t1(c);
**
** SELECT * FROM t1 WHERE a=5 OR b=7 OR (c=11 AND d=13)
**
** In the example, there are three indexed terms connected by OR.
** The top of the loop looks like this:
**
** Null 1 # Zero the rowset in reg 1
**
** Then, for each indexed term, the following. The arguments to
** RowSetTest are such that the rowid of the current row is inserted
** into the RowSet. If it is already present, control skips the
** Gosub opcode and jumps straight to the code generated by WhereEnd().
**
** sqlite4WhereBegin(<term>)
** RowSetTest # Insert rowid into rowset
** Gosub 2 A
** sqlite4WhereEnd()
**
** Following the above, code to terminate the loop. Label A, the target
** of the Gosub above, jumps to the instruction right after the Goto.
**
** Null 1 # Zero the rowset in reg 1
** Goto B # The loop is finished.
**
** A: <loop body> # Return data, whatever.
**
** Return 2 # Jump back to the Gosub
**
** B: <after the loop>
**
*/
WhereClause *pOrWc; /* The OR-clause broken out into subterms */
SrcList *pOrTab; /* Shortened table list or OR-clause generation */
int regReturn = ++pParse->nMem; /* Register used with OP_Gosub */
int regKeyset = 0; /* Register for RowSet object */
int regKey = 0; /* Register holding key */
int iLoopBody = sqlite4VdbeMakeLabel(v); /* Start of loop body */
int iRetInit; /* Address of regReturn init */
int untestedTerms = 0; /* Some terms not completely tested */
int ii; /* Loop counter */
Expr *pAndExpr = 0; /* An ".. AND (...)" expression */
pTerm = pLevel->plan.u.pTerm;
assert( pTerm!=0 );
assert( pTerm->eOperator==WO_OR );
assert( (pTerm->wtFlags & TERM_ORINFO)!=0 );
pOrWc = &pTerm->u.pOrInfo->wc;
pLevel->op = OP_Return;
pLevel->p1 = regReturn;
/* Set up a new SrcList in pOrTab containing the table being scanned
** by this loop in the a[0] slot and all notReady tables in a[1..] slots.
** This becomes the SrcList in the recursive call to sqlite4WhereBegin().
*/
if( pWInfo->nLevel>1 ){
int nNotReady; /* The number of notReady tables */
struct SrcList_item *origSrc; /* Original list of tables */
nNotReady = pWInfo->nLevel - iLevel - 1;
pOrTab = sqlite4StackAllocRaw(pParse->db,
sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0]));
if( pOrTab==0 ) return notReady;
pOrTab->nAlloc = (i16)(nNotReady + 1);
pOrTab->nSrc = pOrTab->nAlloc;
memcpy(pOrTab->a, pTabItem, sizeof(*pTabItem));
origSrc = pWInfo->pTabList->a;
for(k=1; k<=nNotReady; k++){
memcpy(&pOrTab->a[k], &origSrc[pLevel[k].iFrom], sizeof(pOrTab->a[k]));
}
}else{
pOrTab = pWInfo->pTabList;
}
/* Initialize the keyset register to contain NULL. An SQL NULL is
** equivalent to an empty rowset.
**
** Also initialize regReturn to contain the address of the instruction
** immediately following the OP_Return at the bottom of the loop. This
** is required in a few obscure LEFT JOIN cases where control jumps
** over the top of the loop into the body of it. In this case the
** correct response for the end-of-loop code (the OP_Return) is to
** fall through to the next instruction, just as an OP_Next does if
** called on an uninitialized cursor.
*/
if( (wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
regKeyset = ++pParse->nMem;
regKey = ++pParse->nMem;
sqlite4VdbeAddOp2(v, OP_Null, 0, regKeyset);
}
iRetInit = sqlite4VdbeAddOp2(v, OP_Integer, 0, regReturn);
/* If the original WHERE clause is z of the form: (x1 OR x2 OR ...) AND y
** Then for every term xN, evaluate as the subexpression: xN AND z
** That way, terms in y that are factored into the disjunction will
** be picked up by the recursive calls to sqlite4WhereBegin() below.
*/
if( pWC->nTerm>1 ){
pAndExpr = sqlite4ExprAlloc(pParse->db, TK_AND, 0, 0);
pAndExpr->pRight = pWhere;
}
for(ii=0; ii<pOrWc->nTerm; ii++){
WhereTerm *pOrTerm = &pOrWc->a[ii];
if( pOrTerm->leftCursor==iCur || pOrTerm->eOperator==WO_AND ){
WhereInfo *pSubWInfo; /* Info for single OR-term scan */
Expr *pOrExpr = pOrTerm->pExpr;
if( pAndExpr ){
pAndExpr->pLeft = pOrExpr;
pOrExpr = pAndExpr;
}
/* Loop through table entries that match term pOrTerm. */
pSubWInfo = sqlite4WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY |
WHERE_NO_AUTOINDEX | WHERE_ONETABLE_ONLY);
if( pSubWInfo ){
explainOneScan(
pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
);
if( (wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
int addrJump;
sqlite4VdbeAddOp2(v, OP_RowKey, iCur, regKey);
addrJump = sqlite4VdbeCurrentAddr(v) + 2;
sqlite4VdbeAddOp4Int(v, OP_RowSetTest,
regKeyset, addrJump, regKey, ((ii==pOrWc->nTerm-1)?-1:ii)
);
}
sqlite4VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody);
/* The pSubWInfo->untestedTerms flag means that this OR term
** contained one or more AND term from a notReady table. The
** terms from the notReady table could not be tested and will
** need to be tested later.
*/
if( pSubWInfo->untestedTerms ) untestedTerms = 1;
/* Finish the loop through table entries that match term pOrTerm. */
sqlite4WhereEnd(pSubWInfo);
}
}
}
sqlite4DbFree(pParse->db, pAndExpr);
sqlite4VdbeChangeP1(v, iRetInit, sqlite4VdbeCurrentAddr(v));
sqlite4VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk);
sqlite4VdbeResolveLabel(v, iLoopBody);
if( pWInfo->nLevel>1 ) sqlite4StackFree(pParse->db, pOrTab);
if( !untestedTerms ) disableTerm(pLevel, pTerm);
}else
#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
{
/* Case 5: There is no usable index. We must do a complete
** scan of the entire table.
*/
static const u8 aStep[] = { OP_Next, OP_Prev };
static const u8 aStart[] = { OP_Rewind, OP_Last };
assert( bRev==0 || bRev==1 );
pLevel->op = aStep[bRev];
pLevel->p1 = iCur;
pLevel->p2 = 1 + sqlite4VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
}
notReady &= ~getMask(pWC->pMaskSet, iCur);
/* Insert code to test every subexpression that can be completely
** computed using the current set of tables.
**
** IMPLEMENTATION-OF: R-49525-50935 Terms that cannot be satisfied through
** the use of indices become tests that are evaluated against each row of
** the relevant input tables.
*/
for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
Expr *pE;
testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */
testcase( pTerm->wtFlags & TERM_CODED );
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
if( (pTerm->prereqAll & notReady)!=0 ){
testcase( pWInfo->untestedTerms==0
&& (pWInfo->wctrlFlags & WHERE_ONETABLE_ONLY)!=0 );
pWInfo->untestedTerms = 1;
continue;
}
pE = pTerm->pExpr;
assert( pE!=0 );
if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
continue;
}
sqlite4ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL);
pTerm->wtFlags |= TERM_CODED;
}
/* For a LEFT OUTER JOIN, generate code that will record the fact that
** at least one row of the right table has matched the left table.
*/
if( pLevel->iLeftJoin ){
pLevel->addrFirst = sqlite4VdbeCurrentAddr(v);
sqlite4VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
VdbeComment((v, "record LEFT JOIN hit"));
sqlite4ExprCacheClear(pParse);
for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){
testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */
testcase( pTerm->wtFlags & TERM_CODED );
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
if( (pTerm->prereqAll & notReady)!=0 ){
assert( pWInfo->untestedTerms );
continue;
}
assert( pTerm->pExpr );
sqlite4ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
pTerm->wtFlags |= TERM_CODED;
}
}
sqlite4ReleaseTempReg(pParse, iReleaseReg);
return notReady;
}
#if defined(SQLITE_TEST)
/*
** The following variable holds a text description of query plan generated
** by the most recent call to sqlite4WhereBegin(). Each call to WhereBegin
** overwrites the previous. This information is used for testing and
** analysis only.
*/
SQLITE_API char sqlite4_query_plan[BMS*2*40]; /* Text of the join */
static int nQPlan = 0; /* Next free slow in _query_plan[] */
#endif /* SQLITE_TEST */
/*
** Free a WhereInfo structure
*/
static void whereInfoFree(sqlite4 *db, WhereInfo *pWInfo){
if( ALWAYS(pWInfo) ){
int i;
for(i=0; i<pWInfo->nLevel; i++){
sqlite4_index_info *pInfo = pWInfo->a[i].pIdxInfo;
if( pInfo ){
/* assert( pInfo->needToFreeIdxStr==0 || db->mallocFailed ); */
if( pInfo->needToFreeIdxStr ){
sqlite4_free(db->pEnv, pInfo->idxStr);
}
sqlite4DbFree(db, pInfo);
}
if( pWInfo->a[i].plan.wsFlags & WHERE_TEMP_INDEX ){
Index *pIdx = pWInfo->a[i].plan.u.pIdx;
if( pIdx ){
assert( pIdx->eIndexType==SQLITE_INDEX_TEMP );
sqlite4DbFree(db, pIdx->zColAff);
sqlite4DbFree(db, pIdx);
}
}
}
whereClauseClear(pWInfo->pWC);
sqlite4DbFree(db, pWInfo);
}
}
/*
** Generate the beginning of the loop used for WHERE clause processing.
** The return value is a pointer to an opaque structure that contains
** information needed to terminate the loop. Later, the calling routine
** should invoke sqlite4WhereEnd() with the return value of this function
** in order to complete the WHERE clause processing.
**
** If an error occurs, this routine returns NULL.
**
** The basic idea is to do a nested loop, one loop for each table in
** the FROM clause of a select. (INSERT and UPDATE statements are the
** same as a SELECT with only a single table in the FROM clause.) For
** example, if the SQL is this:
**
** SELECT * FROM t1, t2, t3 WHERE ...;
**
** Then the code generated is conceptually like the following:
**
** foreach row1 in t1 do \ Code generated
** foreach row2 in t2 do |-- by sqlite4WhereBegin()
** foreach row3 in t3 do /
** ...
** end \ Code generated
** end |-- by sqlite4WhereEnd()
** end /
**
** Note that the loops might not be nested in the order in which they
** appear in the FROM clause if a different order is better able to make
** use of indices. Note also that when the IN operator appears in
** the WHERE clause, it might result in additional nested loops for
** scanning through all values on the right-hand side of the IN.
**
** There are cursors associated with each table. t1 uses cursor
** number pTabList->a[0].iCursor. t2 uses the cursor pTabList->a[1].iCursor.
** And so forth. This routine generates code to open those VDBE cursors
** and sqlite4WhereEnd() generates the code to close them.
**
** The code that sqlite4WhereBegin() generates leaves the cursors named
** in pTabList pointing at their appropriate entries. The [...] code
** can use OP_Column and OP_Rowid opcodes on these cursors to extract
** data from the various tables of the loop.
**
** If the WHERE clause is empty, the foreach loops must each scan their
** entire tables. Thus a three-way join is an O(N^3) operation. But if
** the tables have indices and there are terms in the WHERE clause that
** refer to those indices, a complete table scan can be avoided and the
** code will run much faster. Most of the work of this routine is checking
** to see if there are indices that can be used to speed up the loop.
**
** Terms of the WHERE clause are also used to limit which rows actually
** make it to the "..." in the middle of the loop. After each "foreach",
** terms of the WHERE clause that use only terms in that loop and outer
** loops are evaluated and if false a jump is made around all subsequent
** inner loops (or around the "..." if the test occurs within the inner-
** most loop)
**
** OUTER JOINS
**
** An outer join of tables t1 and t2 is conceptally coded as follows:
**
** foreach row1 in t1 do
** flag = 0
** foreach row2 in t2 do
** start:
** ...
** flag = 1
** end
** if flag==0 then
** move the row2 cursor to a null row
** goto start
** fi
** end
**
** ORDER BY CLAUSE PROCESSING
**
** *ppOrderBy is a pointer to the ORDER BY clause of a SELECT statement,
** if there is one. If there is no ORDER BY clause or if this routine
** is called from an UPDATE or DELETE statement, then ppOrderBy is NULL.
**
** If an index can be used so that the natural output order of the table
** scan is correct for the ORDER BY clause, then that index is used and
** *ppOrderBy is set to NULL. This is an optimization that prevents an
** unnecessary sort of the result set if an index appropriate for the
** ORDER BY clause already exists.
**
** If the where clause loops cannot be arranged to provide the correct
** output order, then the *ppOrderBy is unchanged.
*/
SQLITE_PRIVATE WhereInfo *sqlite4WhereBegin(
Parse *pParse, /* The parser context */
SrcList *pTabList, /* A list of all tables to be scanned */
Expr *pWhere, /* The WHERE clause */
ExprList **ppOrderBy, /* An ORDER BY clause, or NULL */
ExprList *pDistinct, /* The select-list for DISTINCT queries - or NULL */
u16 wctrlFlags /* One of the WHERE_* flags defined in sqliteInt.h */
){
int i; /* Loop counter */
int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */
int nTabList; /* Number of elements in pTabList */
WhereInfo *pWInfo; /* Will become the return value of this function */
Vdbe *v = pParse->pVdbe; /* The virtual database engine */
Bitmask notReady; /* Cursors that are not yet positioned */
WhereMaskSet *pMaskSet; /* The expression mask set */
WhereClause *pWC; /* Decomposition of the WHERE clause */
struct SrcList_item *pTabItem; /* A single entry from pTabList */
WhereLevel *pLevel; /* A single level in the pWInfo list */
int iFrom; /* First unused FROM clause element */
int andFlags; /* AND-ed combination of all pWC->a[].wtFlags */
sqlite4 *db; /* Database connection */
/* The number of tables in the FROM clause is limited by the number of
** bits in a Bitmask
*/
testcase( pTabList->nSrc==BMS );
if( pTabList->nSrc>BMS ){
sqlite4ErrorMsg(pParse, "at most %d tables in a join", BMS);
return 0;
}
/* This function normally generates a nested loop for all tables in
** pTabList. But if the WHERE_ONETABLE_ONLY 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_ONETABLE_ONLY) ? 1 : pTabList->nSrc;
/* Allocate and initialize the WhereInfo structure that will become the
** return value. A single allocation is used to store the WhereInfo
** struct, the contents of WhereInfo.a[], the WhereClause structure
** and the WhereMaskSet structure. Since WhereClause contains an 8-byte
** field (type Bitmask) it must be aligned on an 8-byte boundary on
** some architectures. Hence the ROUND8() below.
*/
db = pParse->db;
nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel));
pWInfo = sqlite4DbMallocZero(db,
nByteWInfo +
sizeof(WhereClause) +
sizeof(WhereMaskSet)
);
if( db->mallocFailed ){
sqlite4DbFree(db, pWInfo);
pWInfo = 0;
goto whereBeginError;
}
pWInfo->nLevel = nTabList;
pWInfo->pParse = pParse;
pWInfo->pTabList = pTabList;
pWInfo->iBreak = sqlite4VdbeMakeLabel(v);
pWInfo->pWC = pWC = (WhereClause *)&((u8 *)pWInfo)[nByteWInfo];
pWInfo->wctrlFlags = wctrlFlags;
pWInfo->savedNQueryLoop = pParse->nQueryLoop;
pMaskSet = (WhereMaskSet*)&pWC[1];
/* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via
** sqlite4_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */
if( db->flags & SQLITE_DistinctOpt ) pDistinct = 0;
/* Split the WHERE clause into separate subexpressions where each
** subexpression is separated by an AND operator.
*/
initMaskSet(pMaskSet);
whereClauseInit(pWC, pParse, pMaskSet, wctrlFlags);
sqlite4ExprCodeConstants(pParse, pWhere);
whereSplit(pWC, pWhere, TK_AND); /* IMP: R-15842-53296 */
/* Special case: a WHERE clause that is constant. Evaluate the
** expression and either jump over all of the code or fall thru.
*/
if( pWhere && (nTabList==0 || sqlite4ExprIsConstantNotJoin(pWhere)) ){
sqlite4ExprIfFalse(pParse, pWhere, pWInfo->iBreak, SQLITE_JUMPIFNULL);
pWhere = 0;
}
/* Assign a bit from the bitmask to every term in the FROM clause.
**
** When assigning bitmask values to FROM clause cursors, it must be
** the case that if X is the bitmask for the N-th FROM clause term then
** the bitmask for all FROM clause terms to the left of the N-th term
** is (X-1). An expression from the ON clause of a LEFT JOIN can use
** its Expr.iRightJoinTable value to find the bitmask of the right table
** of the join. Subtracting one from the right table bitmask gives a
** bitmask for all tables to the left of the join. Knowing the bitmask
** for all tables to the left of a left join is important. Ticket #3015.
**
** Configure the WhereClause.vmask variable so that bits that correspond
** to virtual table cursors are set. This is used to selectively disable
** the OR-to-IN transformation in exprAnalyzeOrTerm(). It is not helpful
** with virtual tables.
**
** 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_ONETABLE_ONLY flag is set.
*/
assert( pWC->vmask==0 && pMaskSet->n==0 );
for(i=0; i<pTabList->nSrc; i++){
createMask(pMaskSet, pTabList->a[i].iCursor);
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( ALWAYS(pTabList->a[i].pTab) && IsVirtual(pTabList->a[i].pTab) ){
pWC->vmask |= ((Bitmask)1 << i);
}
#endif
}
#ifndef NDEBUG
{
Bitmask toTheLeft = 0;
for(i=0; i<pTabList->nSrc; i++){
Bitmask m = getMask(pMaskSet, pTabList->a[i].iCursor);
assert( (m-1)==toTheLeft );
toTheLeft |= m;
}
}
#endif
/* Analyze all of the subexpressions. */
exprAnalyzeAll(pTabList, pWC);
if( db->mallocFailed ){
goto whereBeginError;
}
/* Check if the DISTINCT qualifier, if there is one, is redundant.
** If it is, then set pDistinct to NULL and WhereInfo.eDistinct to
** WHERE_DISTINCT_UNIQUE to tell the caller to ignore the DISTINCT.
*/
if( pDistinct && isDistinctRedundant(pParse, pTabList, pWC, pDistinct) ){
pDistinct = 0;
pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
}
/* Chose the best index to use for each table in the FROM clause.
**
** This loop fills in the following fields:
**
** pWInfo->a[].pIdx The index to use for this level of the loop.
** pWInfo->a[].wsFlags WHERE_xxx flags associated with pIdx
** pWInfo->a[].nEq The number of == and IN constraints
** pWInfo->a[].iFrom Which term of the FROM clause is being coded
** pWInfo->a[].iTabCur The VDBE cursor for the database table
** pWInfo->a[].iIdxCur The VDBE cursor for the index
** pWInfo->a[].pTerm When wsFlags==WO_OR, the OR-clause term
**
** This loop also figures out the nesting order of tables in the FROM
** clause.
*/
notReady = ~(Bitmask)0;
andFlags = ~0;
WHERETRACE(("*** Optimizer Start ***\n"));
for(i=iFrom=0, pLevel=pWInfo->a; i<nTabList; i++, pLevel++){
WhereCost bestPlan; /* Most efficient plan seen so far */
Index *pIdx; /* Index for FROM table at pTabItem */
int j; /* For looping over FROM tables */
int bestJ = -1; /* The value of j */
Bitmask m; /* Bitmask value for j or bestJ */
int isOptimal; /* Iterator for optimal/non-optimal search */
int nUnconstrained; /* Number tables without INDEXED BY */
Bitmask notIndexed; /* Mask of tables that cannot use an index */
memset(&bestPlan, 0, sizeof(bestPlan));
bestPlan.rCost = SQLITE_BIG_DBL;
WHERETRACE(("*** Begin search for loop %d ***\n", i));
/* Loop through the remaining entries in the FROM clause to find the
** next nested loop. The loop tests all FROM clause entries
** either once or twice.
**
** The first test is always performed if there are two or more entries
** remaining and never performed if there is only one FROM clause entry
** to choose from. The first test looks for an "optimal" scan. In
** this context an optimal scan is one that uses the same strategy
** for the given FROM clause entry as would be selected if the entry
** were used as the innermost nested loop. In other words, a table
** is chosen such that the cost of running that table cannot be reduced
** by waiting for other tables to run first. This "optimal" test works
** by first assuming that the FROM clause is on the inner loop and finding
** its query plan, then checking to see if that query plan uses any
** other FROM clause terms that are notReady. If no notReady terms are
** used then the "optimal" query plan works.
**
** Note that the WhereCost.nRow parameter for an optimal scan might
** not be as small as it would be if the table really were the innermost
** join. The nRow value can be reduced by WHERE clause constraints
** that do not use indices. But this nRow reduction only happens if the
** table really is the innermost join.
**
** The second loop iteration is only performed if no optimal scan
** strategies were found by the first iteration. This second iteration
** is used to search for the lowest cost scan overall.
**
** Previous versions of SQLite performed only the second iteration -
** the next outermost loop was always that with the lowest overall
** cost. However, this meant that SQLite could select the wrong plan
** for scripts such as the following:
**
** CREATE TABLE t1(a, b);
** CREATE TABLE t2(c, d);
** SELECT * FROM t2, t1 WHERE t2.rowid = t1.a;
**
** The best strategy is to iterate through table t1 first. However it
** is not possible to determine this with a simple greedy algorithm.
** Since the cost of a linear scan through table t2 is the same
** as the cost of a linear scan through table t1, a simple greedy
** algorithm may choose to use t2 for the outer loop, which is a much
** costlier approach.
*/
nUnconstrained = 0;
notIndexed = 0;
for(isOptimal=(iFrom<nTabList-1); isOptimal>=0 && bestJ<0; isOptimal--){
Bitmask mask; /* Mask of tables not yet ready */
for(j=iFrom, pTabItem=&pTabList->a[j]; j<nTabList; j++, pTabItem++){
int doNotReorder; /* True if this table should not be reordered */
WhereCost sCost; /* Cost information from best[Virtual]Index() */
ExprList *pOrderBy; /* ORDER BY clause for index to optimize */
ExprList *pDist; /* DISTINCT clause for index to optimize */
doNotReorder = (pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0;
if( j!=iFrom && doNotReorder ) break;
m = getMask(pMaskSet, pTabItem->iCursor);
if( (m & notReady)==0 ){
if( j==iFrom ) iFrom++;
continue;
}
mask = (isOptimal ? m : notReady);
pOrderBy = ((i==0 && ppOrderBy )?*ppOrderBy:0);
pDist = (i==0 ? pDistinct : 0);
if( pTabItem->pIndex==0 ) nUnconstrained++;
WHERETRACE(("=== trying table %d with isOptimal=%d ===\n",
j, isOptimal));
assert( pTabItem->pTab );
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( IsVirtual(pTabItem->pTab) ){
sqlite4_index_info **pp = &pWInfo->a[j].pIdxInfo;
bestVirtualIndex(pParse, pWC, pTabItem, mask, notReady, pOrderBy,
&sCost, pp);
}else
#endif
{
bestKVIndex(pParse, pWC, pTabItem, mask, notReady, pOrderBy,
pDist, &sCost);
}
assert( isOptimal || (sCost.used¬Ready)==0 );
/* If an INDEXED BY clause is present, then the plan must use that
** index if it uses any index at all */
assert( pTabItem->pIndex==0
|| (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0
|| sCost.plan.u.pIdx==pTabItem->pIndex );
if( isOptimal && (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ){
notIndexed |= m;
}
/* Conditions under which this table becomes the best so far:
**
** (1) The table must not depend on other tables that have not
** yet run.
**
** (2) A full-table-scan plan cannot supercede indexed plan unless
** the full-table-scan is an "optimal" plan as defined above.
**
** (3) All tables have an INDEXED BY clause or this table lacks an
** INDEXED BY clause or this table uses the specific
** index specified by its INDEXED BY clause. This rule ensures
** that a best-so-far is always selected even if an impossible
** combination of INDEXED BY clauses are given. The error
** will be detected and relayed back to the application later.
** The NEVER() comes about because rule (2) above prevents
** An indexable full-table-scan from reaching rule (3).
**
** (4) The plan cost must be lower than prior plans or else the
** cost must be the same and the number of rows must be lower.
*/
if( (sCost.used¬Ready)==0 /* (1) */
&& (bestJ<0 || (notIndexed&m)!=0 /* (2) */
|| (bestPlan.plan.wsFlags & WHERE_NOT_FULLSCAN)==0
|| (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0)
&& (nUnconstrained==0 || pTabItem->pIndex==0 /* (3) */
|| NEVER((sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0))
&& (bestJ<0 || sCost.rCost<bestPlan.rCost /* (4) */
|| (sCost.rCost<=bestPlan.rCost
&& sCost.plan.nRow<bestPlan.plan.nRow))
){
WHERETRACE(("=== table %d is best so far"
" with cost=%g and nRow=%g\n",
j, sCost.rCost, sCost.plan.nRow));
bestPlan = sCost;
bestJ = j;
}
if( doNotReorder ) break;
}
}
assert( bestJ>=0 );
assert( notReady & getMask(pMaskSet, pTabList->a[bestJ].iCursor) );
WHERETRACE(("*** Optimizer selects table %d for loop %d"
" with cost=%g and nRow=%g\n",
bestJ, pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow));
/* The ALWAYS() that follows was added to hush up clang scan-build */
if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 && ALWAYS(ppOrderBy) ){
*ppOrderBy = 0;
}
if( (bestPlan.plan.wsFlags & WHERE_DISTINCT)!=0 ){
assert( pWInfo->eDistinct==0 );
pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
}
andFlags &= bestPlan.plan.wsFlags;
pLevel->plan = bestPlan.plan;
testcase( bestPlan.plan.wsFlags & WHERE_INDEXED );
testcase( bestPlan.plan.wsFlags & WHERE_TEMP_INDEX );
if( bestPlan.plan.wsFlags & (WHERE_INDEXED|WHERE_TEMP_INDEX) ){
pLevel->iIdxCur = pParse->nTab++;
}else{
pLevel->iIdxCur = -1;
}
notReady &= ~getMask(pMaskSet, pTabList->a[bestJ].iCursor);
pLevel->iFrom = (u8)bestJ;
if( bestPlan.plan.nRow>=(double)1 ){
pParse->nQueryLoop *= bestPlan.plan.nRow;
}
/* Check that if the table scanned by this loop iteration had an
** INDEXED BY clause attached to it, that the named index is being
** used for the scan. If not, then query compilation has failed.
** Return an error.
*/
pIdx = pTabList->a[bestJ].pIndex;
if( pIdx ){
if( (bestPlan.plan.wsFlags & WHERE_INDEXED)==0 ){
sqlite4ErrorMsg(pParse, "cannot use index: %s", pIdx->zName);
goto whereBeginError;
}else{
/* If an INDEXED BY clause is used, the bestIndex() function is
** guaranteed to find the index specified in the INDEXED BY clause
** if it find an index at all. */
assert( bestPlan.plan.u.pIdx==pIdx );
}
}
}
WHERETRACE(("*** Optimizer Finished ***\n"));
if( pParse->nErr || db->mallocFailed ){
goto whereBeginError;
}
/* If the total query only selects a single row, then the ORDER BY
** clause is irrelevant.
*/
if( (andFlags & WHERE_UNIQUE)!=0 && ppOrderBy ){
*ppOrderBy = 0;
}
/* If the caller is an UPDATE or DELETE statement that is requesting
** to use a one-pass algorithm, determine if this is appropriate.
** The one-pass algorithm only works if the WHERE clause constraints
** the statement to update a single row.
*/
assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 );
if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 && (andFlags & WHERE_UNIQUE)!=0 ){
pWInfo->okOnePass = 1;
pWInfo->a[0].plan.wsFlags &= ~WHERE_IDX_ONLY;
}
/* Open all tables in the pTabList and any indices selected for
** searching those tables.
*/
sqlite4CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
notReady = ~(Bitmask)0;
pWInfo->nRowOut = (double)1;
for(i=0, pLevel=pWInfo->a; i<nTabList; i++, pLevel++){
Table *pTab; /* Table to open */
int iDb; /* Index of database containing table/index */
pTabItem = &pTabList->a[pLevel->iFrom];
pTab = pTabItem->pTab;
pLevel->iTabCur = pTabItem->iCursor;
pWInfo->nRowOut *= pLevel->plan.nRow;
iDb = sqlite4SchemaToIndex(db, pTab->pSchema);
if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){
/* Do nothing */
}else
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
const char *pVTab = (const char *)sqlite4GetVTable(db, pTab);
int iCur = pTabItem->iCursor;
sqlite4VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB);
}else
#endif
if( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0
&& (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 ){
int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead;
sqlite4OpenPrimaryKey(pParse, pTabItem->iCursor, iDb, pTab, op);
testcase( pTab->nCol==BMS-1 );
testcase( pTab->nCol==BMS );
}
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
if( (pLevel->plan.wsFlags & WHERE_TEMP_INDEX)!=0 ){
constructAutomaticIndex(pParse, pWC, pTabItem, notReady, pLevel);
}else
#endif
if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){
Index *pIx = pLevel->plan.u.pIdx;
if( pIx->eIndexType==SQLITE_INDEX_PRIMARYKEY ){
pLevel->iIdxCur = pTabItem->iCursor;
}else{
KeyInfo *pKey = sqlite4IndexKeyinfo(pParse, pIx);
int iIdxCur = pLevel->iIdxCur;
assert( pIx->pSchema==pTab->pSchema );
assert( iIdxCur>=0 );
sqlite4VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIx->tnum, iDb,
(char*)pKey, P4_KEYINFO_HANDOFF);
VdbeComment((v, "%s", pIx->zName));
}
}
sqlite4CodeVerifySchema(pParse, iDb);
notReady &= ~getMask(pWC->pMaskSet, pTabItem->iCursor);
}
pWInfo->iTop = sqlite4VdbeCurrentAddr(v);
if( db->mallocFailed ) goto whereBeginError;
/* Generate the code to do the search. Each iteration of the for
** loop below generates code for a single nested loop of the VM
** program.
*/
notReady = ~(Bitmask)0;
for(i=0; i<nTabList; i++){
pLevel = &pWInfo->a[i];
explainOneScan(pParse, pTabList, pLevel, i, pLevel->iFrom, wctrlFlags);
notReady = codeOneLoopStart(pWInfo, i, wctrlFlags, notReady, pWhere);
pWInfo->iContinue = pLevel->addrCont;
}
#ifdef SQLITE_TEST /* For testing and debugging use only */
/* Record in the query plan information about the current table
** and the index used to access it (if any). If the table itself
** is not used, its name is just '{}'. If no index is used
** the index is listed as "{}". If the primary key is used the
** index name is '*'.
*/
for(i=0; i<nTabList; i++){
char *z;
int n;
pLevel = &pWInfo->a[i];
pTabItem = &pTabList->a[pLevel->iFrom];
z = pTabItem->zAlias;
if( z==0 ) z = pTabItem->pTab->zName;
n = sqlite4Strlen30(z);
if( n+nQPlan < sizeof(sqlite4_query_plan)-10 ){
if( pLevel->plan.wsFlags & WHERE_IDX_ONLY ){
memcpy(&sqlite4_query_plan[nQPlan], "{}", 2);
nQPlan += 2;
}else{
memcpy(&sqlite4_query_plan[nQPlan], z, n);
nQPlan += n;
}
sqlite4_query_plan[nQPlan++] = ' ';
}
if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){
n = sqlite4Strlen30(pLevel->plan.u.pIdx->zName);
if( n+nQPlan < sizeof(sqlite4_query_plan)-2 ){
memcpy(&sqlite4_query_plan[nQPlan], pLevel->plan.u.pIdx->zName, n);
nQPlan += n;
sqlite4_query_plan[nQPlan++] = ' ';
}
}else{
memcpy(&sqlite4_query_plan[nQPlan], "{} ", 3);
nQPlan += 3;
}
}
while( nQPlan>0 && sqlite4_query_plan[nQPlan-1]==' ' ){
sqlite4_query_plan[--nQPlan] = 0;
}
sqlite4_query_plan[nQPlan] = 0;
nQPlan = 0;
#endif /* SQLITE_TEST // Testing and debugging use only */
/* Record the continuation address in the WhereInfo structure. Then
** clean up and return.
*/
return pWInfo;
/* Jump here if malloc fails */
whereBeginError:
if( pWInfo ){
pParse->nQueryLoop = pWInfo->savedNQueryLoop;
whereInfoFree(db, pWInfo);
}
return 0;
}
/*
** Generate the end of the WHERE loop. See comments on
** sqlite4WhereBegin() for additional information.
*/
SQLITE_PRIVATE void sqlite4WhereEnd(WhereInfo *pWInfo){
Parse *pParse = pWInfo->pParse;
Vdbe *v = pParse->pVdbe;
int i;
WhereLevel *pLevel;
SrcList *pTabList = pWInfo->pTabList;
sqlite4 *db = pParse->db;
/* Generate loop termination code.
*/
sqlite4ExprCacheClear(pParse);
for(i=pWInfo->nLevel-1; i>=0; i--){
pLevel = &pWInfo->a[i];
sqlite4VdbeResolveLabel(v, pLevel->addrCont);
if( pLevel->op!=OP_Noop ){
sqlite4VdbeAddOp2(v, pLevel->op, pLevel->p1, pLevel->p2);
sqlite4VdbeChangeP5(v, pLevel->p5);
}
if( pLevel->plan.wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){
struct InLoop *pIn;
int j;
sqlite4VdbeResolveLabel(v, pLevel->addrNxt);
for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){
sqlite4VdbeJumpHere(v, pIn->addrInTop+1);
sqlite4VdbeAddOp2(v, OP_Next, pIn->iCur, pIn->addrInTop);
sqlite4VdbeJumpHere(v, pIn->addrInTop-1);
}
sqlite4DbFree(db, pLevel->u.in.aInLoop);
}
sqlite4VdbeResolveLabel(v, pLevel->addrBrk);
if( pLevel->iLeftJoin ){
int addr;
addr = sqlite4VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin);
assert( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0
|| (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 );
if( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0 ){
sqlite4VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor);
}
if( pLevel->iIdxCur>=0 ){
sqlite4VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur);
}
if( pLevel->op==OP_Return ){
sqlite4VdbeAddOp2(v, OP_Gosub, pLevel->p1, pLevel->addrFirst);
}else{
sqlite4VdbeAddOp2(v, OP_Goto, 0, pLevel->addrFirst);
}
sqlite4VdbeJumpHere(v, addr);
}
}
/* The "break" point is here, just past the end of the outer loop.
** Set it.
*/
sqlite4VdbeResolveLabel(v, pWInfo->iBreak);
/* Close all of the cursors that were opened by sqlite4WhereBegin.
*/
assert( pWInfo->nLevel==1 || pWInfo->nLevel==pTabList->nSrc );
for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){
struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom];
Table *pTab = pTabItem->pTab;
assert( pTab!=0 );
if( (pTab->tabFlags & TF_Ephemeral)==0
&& pTab->pSelect==0
&& (pWInfo->wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0
){
int ws = pLevel->plan.wsFlags;
if( !pWInfo->okOnePass && (ws & WHERE_IDX_ONLY)==0 ){
sqlite4VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
}
if( (ws & WHERE_INDEXED)!=0 && (ws & WHERE_TEMP_INDEX)==0 ){
if( pLevel->iIdxCur!=pTabItem->iCursor ){
sqlite4VdbeAddOp1(v, OP_Close, pLevel->iIdxCur);
}
}
}
/* If this scan uses an index, make code substitutions to read data
** from the index in preference to the table. Sometimes, this means
** the table need never be read from. This is a performance boost,
** as the vdbe level waits until the table is read before actually
** seeking the table cursor to the record corresponding to the current
** position in the index.
**
** Calls to the code generator in between sqlite4WhereBegin and
** sqlite4WhereEnd will have created code that references the table
** directly. This loop scans all that code looking for opcodes
** that reference the table and converts them into opcodes that
** reference the index.
*/
if( (pLevel->plan.wsFlags & WHERE_TEMP_INDEX) && !db->mallocFailed ){
VdbeOp *pOp;
VdbeOp *pEnd;
assert( pLevel->plan.u.pIdx );
assert( pLevel->iTabCur!=pLevel->iIdxCur );
pOp = sqlite4VdbeGetOp(v, pWInfo->iTop);
pEnd = &pOp[sqlite4VdbeCurrentAddr(v) - pWInfo->iTop];
while( pOp<pEnd ){
if( pOp->p1==pLevel->iTabCur && pOp->opcode==OP_Column ){
pOp->p1 = pLevel->iIdxCur;
}
pOp++;
}
}
}
/* Final cleanup
*/
pParse->nQueryLoop = pWInfo->savedNQueryLoop;
whereInfoFree(db, pWInfo);
return;
}
/************** End of where.c ***********************************************/
/************** Begin file parse.c *******************************************/
/* Driver template for the LEMON parser generator.
** The author disclaims copyright to this source code.
**
** This version of "lempar.c" is modified, slightly, for use by SQLite.
** The only modifications are the addition of a couple of NEVER()
** macros to disable tests that are needed in the case of a general
** LALR(1) grammar but which are always false in the
** specific grammar used by SQLite.
*/
/* First off, code is included that follows the "include" declaration
** in the input grammar file. */
/* #include <stdio.h> */
/*
** Disable all error recovery processing in the parser push-down
** automaton.
*/
#define YYNOERRORRECOVERY 1
/*
** Make yytestcase() the same as testcase()
*/
#define yytestcase(X) testcase(X)
/*
** An instance of this structure holds information about the
** LIMIT clause of a SELECT statement.
*/
struct LimitVal {
Expr *pLimit; /* The LIMIT expression. NULL if there is no limit */
Expr *pOffset; /* The OFFSET expression. NULL if there is none */
};
/*
** An instance of this structure is used to store the LIKE,
** GLOB, NOT LIKE, and NOT GLOB operators.
*/
struct LikeOp {
Token eOperator; /* "like" or "glob" or "regexp" */
int not; /* True if the NOT keyword is present */
};
/*
** 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
**
** UPDATE ON (a,b,c)
**
** Then the "b" IdList records the list "a,b,c".
*/
struct TrigEvent { int a; IdList * b; };
/*
** An instance of this structure holds the ATTACH key and the key type.
*/
struct AttachKey { int type; Token key; };
/* This is a utility routine used to set the ExprSpan.zStart and
** ExprSpan.zEnd values of pOut so that the span covers the complete
** range of text beginning with pStart and going to the end of pEnd.
*/
static void spanSet(ExprSpan *pOut, Token *pStart, Token *pEnd){
pOut->zStart = pStart->z;
pOut->zEnd = &pEnd->z[pEnd->n];
}
/* Construct a new Expr object from a single identifier. Use the
** new Expr to populate pOut. Set the span of pOut to be the identifier
** that created the expression.
*/
static void spanExpr(ExprSpan *pOut, Parse *pParse, int op, Token *pValue){
pOut->pExpr = sqlite4PExpr(pParse, op, 0, 0, pValue);
pOut->zStart = pValue->z;
pOut->zEnd = &pValue->z[pValue->n];
}
/* This routine constructs a binary expression node out of two ExprSpan
** objects and uses the result to populate a new ExprSpan object.
*/
static void spanBinaryExpr(
ExprSpan *pOut, /* Write the result here */
Parse *pParse, /* The parsing context. Errors accumulate here */
int op, /* The binary operation */
ExprSpan *pLeft, /* The left operand */
ExprSpan *pRight /* The right operand */
){
pOut->pExpr = sqlite4PExpr(pParse, op, pLeft->pExpr, pRight->pExpr, 0);
pOut->zStart = pLeft->zStart;
pOut->zEnd = pRight->zEnd;
}
/* Construct an expression node for a unary postfix operator
*/
static void spanUnaryPostfix(
ExprSpan *pOut, /* Write the new expression node here */
Parse *pParse, /* Parsing context to record errors */
int op, /* The operator */
ExprSpan *pOperand, /* The operand */
Token *pPostOp /* The operand token for setting the span */
){
pOut->pExpr = sqlite4PExpr(pParse, op, pOperand->pExpr, 0, 0);
pOut->zStart = pOperand->zStart;
pOut->zEnd = &pPostOp->z[pPostOp->n];
}
/* A routine to convert a binary TK_IS or TK_ISNOT expression into a
** unary TK_ISNULL or TK_NOTNULL expression. */
static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){
sqlite4 *db = pParse->db;
if( db->mallocFailed==0 && pY->op==TK_NULL ){
pA->op = (u8)op;
sqlite4ExprDelete(db, pA->pRight);
pA->pRight = 0;
}
}
/* Construct an expression node for a unary prefix operator
*/
static void spanUnaryPrefix(
ExprSpan *pOut, /* Write the new expression node here */
Parse *pParse, /* Parsing context to record errors */
int op, /* The operator */
ExprSpan *pOperand, /* The operand */
Token *pPreOp /* The operand token for setting the span */
){
pOut->pExpr = sqlite4PExpr(pParse, op, pOperand->pExpr, 0, 0);
pOut->zStart = pPreOp->z;
pOut->zEnd = pOperand->zEnd;
}
/* Next is all token values, in a form suitable for use by makeheaders.
** This section will be null unless lemon is run with the -m switch.
*/
/*
** These constants (all generated automatically by the parser generator)
** specify the various kinds of tokens (terminals) that the parser
** understands.
**
** Each symbol here is a terminal symbol in the grammar.
*/
/* Make sure the INTERFACE macro is defined.
*/
#ifndef INTERFACE
# define INTERFACE 1
#endif
/* The next thing included is series of defines which control
** various aspects of the generated parser.
** YYCODETYPE is the data type used for storing terminal
** and nonterminal numbers. "unsigned char" is
** used if there are fewer than 250 terminals
** and nonterminals. "int" is used otherwise.
** YYNOCODE is a number of type YYCODETYPE which corresponds
** to no legal terminal or nonterminal number. This
** number is used to fill in empty slots of the hash
** table.
** YYFALLBACK If defined, this indicates that one or more tokens
** have fall-back values which should be used if the
** original value of the token will not parse.
** YYACTIONTYPE is the data type used for storing terminal
** and nonterminal numbers. "unsigned char" is
** used if there are fewer than 250 rules and
** states combined. "int" is used otherwise.
** sqlite4ParserTOKENTYPE is the data type used for minor tokens given
** directly to the parser from the tokenizer.
** YYMINORTYPE is the data type used for all minor tokens.
** This is typically a union of many types, one of
** which is sqlite4ParserTOKENTYPE. The entry in the union
** for base tokens is called "yy0".
** YYSTACKDEPTH is the maximum depth of the parser's stack. If
** zero the stack is dynamically sized using realloc()
** sqlite4ParserARG_SDECL A static variable declaration for the %extra_argument
** sqlite4ParserARG_PDECL A parameter declaration for the %extra_argument
** sqlite4ParserARG_STORE Code to store %extra_argument into yypParser
** sqlite4ParserARG_FETCH Code to extract %extra_argument from yypParser
** YYNSTATE the combined number of states.
** YYNRULE the number of rules in the grammar
** YYERRORSYMBOL is the code number of the error symbol. If not
** defined, then do no error processing.
*/
#define YYCODETYPE unsigned char
#define YYNOCODE 246
#define YYACTIONTYPE unsigned short int
#define YYWILDCARD 66
#define sqlite4ParserTOKENTYPE Token
typedef union {
int yyinit;
sqlite4ParserTOKENTYPE yy0;
TriggerStep* yy7;
int yy32;
struct {int value; int mask;} yy47;
struct LikeOp yy118;
ExprSpan yy132;
Select* yy149;
struct TrigEvent yy160;
SrcList* yy287;
Expr* yy342;
u8 yy378;
IdList* yy440;
ExprList* yy462;
struct LimitVal yy474;
} YYMINORTYPE;
#ifndef YYSTACKDEPTH
#define YYSTACKDEPTH 100
#endif
#define sqlite4ParserARG_SDECL Parse *pParse;
#define sqlite4ParserARG_PDECL ,Parse *pParse
#define sqlite4ParserARG_FETCH Parse *pParse = yypParser->pParse
#define sqlite4ParserARG_STORE yypParser->pParse = pParse
#define YYNSTATE 602
#define YYNRULE 312
#define YYFALLBACK 1
#define YY_NO_ACTION (YYNSTATE+YYNRULE+2)
#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1)
#define YY_ERROR_ACTION (YYNSTATE+YYNRULE)
/* The yyzerominor constant is used to initialize instances of
** YYMINORTYPE objects to zero. */
static const YYMINORTYPE yyzerominor = { 0 };
/* Define the yytestcase() macro to be a no-op if is not already defined
** otherwise.
**
** Applications can choose to define yytestcase() in the %include section
** to a macro that can assist in verifying code coverage. For production
** code the yytestcase() macro should be turned off. But it is useful
** for testing.
*/
#ifndef yytestcase
# define yytestcase(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 < YYNSTATE Shift N. That is, push the lookahead
** token onto the stack and goto state N.
**
** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE.
**
** N == YYNSTATE+YYNRULE A syntax error has occurred.
**
** N == YYNSTATE+YYNRULE+1 The parser accepts its input.
**
** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused
** slots in the yy_action[] table.
**
** The action table is constructed as a single large table named yy_action[].
** Given state S and lookahead X, the action is computed as
**
** yy_action[ yy_shift_ofst[S] + X ]
**
** If the index value yy_shift_ofst[S]+X is out of range or if the value
** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S]
** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
** and that yy_default[S] should be used instead.
**
** The formula above is 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 and YY_REDUCE_USE_DFLT is used in place of
** YY_SHIFT_USE_DFLT.
**
** The following are the tables generated in this section:
**
** yy_action[] A single table containing all actions.
** yy_lookahead[] A table containing the lookahead for each entry in
** yy_action. Used to detect hash collisions.
** yy_shift_ofst[] For each state, the offset into yy_action for
** shifting terminals.
** 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.
*/
#define YY_ACTTAB_COUNT (1502)
static const YYACTIONTYPE yy_action[] = {
/* 0 */ 301, 915, 180, 401, 2, 166, 599, 569, 55, 55,
/* 10 */ 55, 55, 48, 53, 53, 53, 53, 52, 52, 51,
/* 20 */ 51, 51, 50, 231, 574, 65, 595, 594, 575, 569,
/* 30 */ 562, 556, 55, 55, 55, 55, 293, 53, 53, 53,
/* 40 */ 53, 52, 52, 51, 51, 51, 50, 231, 56, 57,
/* 50 */ 47, 554, 553, 555, 555, 54, 54, 55, 55, 55,
/* 60 */ 55, 580, 53, 53, 53, 53, 52, 52, 51, 51,
/* 70 */ 51, 50, 231, 301, 569, 261, 315, 488, 487, 32,
/* 80 */ 53, 53, 53, 53, 52, 52, 51, 51, 51, 50,
/* 90 */ 231, 315, 526, 592, 591, 160, 569, 6, 364, 361,
/* 100 */ 360, 525, 300, 562, 556, 540, 464, 209, 58, 359,
/* 110 */ 478, 479, 52, 52, 51, 51, 51, 50, 231, 257,
/* 120 */ 259, 56, 57, 47, 554, 553, 555, 555, 54, 54,
/* 130 */ 55, 55, 55, 55, 596, 53, 53, 53, 53, 52,
/* 140 */ 52, 51, 51, 51, 50, 231, 301, 437, 219, 593,
/* 150 */ 7, 133, 171, 139, 275, 367, 270, 366, 163, 538,
/* 160 */ 393, 369, 161, 219, 393, 266, 595, 594, 139, 275,
/* 170 */ 367, 270, 366, 163, 210, 396, 562, 556, 160, 396,
/* 180 */ 266, 364, 361, 360, 573, 79, 574, 498, 573, 87,
/* 190 */ 575, 567, 359, 438, 56, 57, 47, 554, 553, 555,
/* 200 */ 555, 54, 54, 55, 55, 55, 55, 643, 53, 53,
/* 210 */ 53, 53, 52, 52, 51, 51, 51, 50, 231, 301,
/* 220 */ 463, 151, 565, 565, 565, 542, 229, 190, 378, 226,
/* 230 */ 307, 579, 66, 592, 591, 593, 411, 443, 393, 485,
/* 240 */ 250, 333, 249, 413, 414, 412, 400, 598, 644, 562,
/* 250 */ 556, 233, 234, 396, 132, 187, 454, 578, 465, 593,
/* 260 */ 201, 44, 573, 94, 415, 416, 468, 56, 57, 47,
/* 270 */ 554, 553, 555, 555, 54, 54, 55, 55, 55, 55,
/* 280 */ 504, 53, 53, 53, 53, 52, 52, 51, 51, 51,
/* 290 */ 50, 231, 301, 414, 572, 393, 391, 160, 551, 551,
/* 300 */ 364, 361, 360, 303, 380, 199, 521, 326, 593, 370,
/* 310 */ 396, 359, 1, 415, 324, 441, 595, 594, 328, 573,
/* 320 */ 73, 30, 562, 556, 417, 230, 233, 67, 317, 547,
/* 330 */ 546, 595, 594, 203, 645, 38, 595, 594, 327, 572,
/* 340 */ 56, 57, 47, 554, 553, 555, 555, 54, 54, 55,
/* 350 */ 55, 55, 55, 847, 53, 53, 53, 53, 52, 52,
/* 360 */ 51, 51, 51, 50, 231, 301, 170, 572, 391, 503,
/* 370 */ 551, 551, 169, 325, 230, 146, 346, 595, 594, 595,
/* 380 */ 594, 343, 274, 592, 591, 51, 51, 51, 50, 231,
/* 390 */ 230, 335, 197, 273, 463, 562, 556, 505, 592, 591,
/* 400 */ 521, 438, 291, 592, 591, 453, 66, 61, 35, 593,
/* 410 */ 548, 569, 332, 56, 57, 47, 554, 553, 555, 555,
/* 420 */ 54, 54, 55, 55, 55, 55, 572, 53, 53, 53,
/* 430 */ 53, 52, 52, 51, 51, 51, 50, 231, 301, 523,
/* 440 */ 552, 393, 500, 550, 592, 591, 592, 591, 250, 333,
/* 450 */ 249, 184, 393, 49, 46, 147, 396, 539, 393, 233,
/* 460 */ 393, 537, 193, 192, 191, 573, 93, 396, 562, 556,
/* 470 */ 520, 536, 519, 396, 408, 396, 573, 87, 569, 516,
/* 480 */ 195, 196, 573, 94, 573, 79, 56, 57, 47, 554,
/* 490 */ 553, 555, 555, 54, 54, 55, 55, 55, 55, 246,
/* 500 */ 53, 53, 53, 53, 52, 52, 51, 51, 51, 50,
/* 510 */ 231, 301, 178, 533, 572, 483, 284, 227, 507, 595,
/* 520 */ 594, 177, 533, 521, 376, 535, 194, 144, 534, 532,
/* 530 */ 306, 391, 185, 551, 551, 49, 46, 147, 532, 456,
/* 540 */ 482, 562, 556, 243, 245, 531, 457, 492, 549, 391,
/* 550 */ 64, 551, 551, 514, 531, 165, 384, 162, 491, 56,
/* 560 */ 57, 47, 554, 553, 555, 555, 54, 54, 55, 55,
/* 570 */ 55, 55, 168, 53, 53, 53, 53, 52, 52, 51,
/* 580 */ 51, 51, 50, 231, 301, 356, 592, 591, 263, 477,
/* 590 */ 530, 472, 146, 161, 463, 233, 389, 547, 546, 166,
/* 600 */ 391, 569, 551, 551, 365, 404, 66, 334, 445, 593,
/* 610 */ 304, 476, 446, 518, 562, 556, 162, 521, 232, 16,
/* 620 */ 244, 183, 590, 589, 588, 18, 347, 447, 447, 349,
/* 630 */ 512, 34, 56, 57, 47, 554, 553, 555, 555, 54,
/* 640 */ 54, 55, 55, 55, 55, 593, 53, 53, 53, 53,
/* 650 */ 52, 52, 51, 51, 51, 50, 231, 301, 230, 4,
/* 660 */ 313, 255, 21, 544, 544, 393, 267, 393, 569, 304,
/* 670 */ 393, 602, 600, 319, 266, 577, 593, 49, 46, 147,
/* 680 */ 396, 593, 396, 468, 39, 396, 37, 562, 556, 573,
/* 690 */ 72, 573, 68, 316, 573, 96, 208, 144, 203, 540,
/* 700 */ 388, 209, 516, 312, 322, 56, 57, 47, 554, 553,
/* 710 */ 555, 555, 54, 54, 55, 55, 55, 55, 393, 53,
/* 720 */ 53, 53, 53, 52, 52, 51, 51, 51, 50, 231,
/* 730 */ 301, 267, 572, 396, 393, 496, 267, 341, 13, 267,
/* 740 */ 372, 225, 573, 99, 576, 339, 593, 393, 373, 396,
/* 750 */ 393, 593, 593, 340, 593, 320, 335, 12, 573, 97,
/* 760 */ 562, 556, 396, 20, 131, 396, 510, 264, 218, 161,
/* 770 */ 143, 573, 106, 311, 573, 105, 310, 342, 56, 57,
/* 780 */ 47, 554, 553, 555, 555, 54, 54, 55, 55, 55,
/* 790 */ 55, 393, 53, 53, 53, 53, 52, 52, 51, 51,
/* 800 */ 51, 50, 231, 301, 393, 267, 396, 393, 164, 207,
/* 810 */ 341, 393, 357, 206, 161, 573, 108, 494, 493, 396,
/* 820 */ 593, 502, 396, 512, 393, 593, 396, 217, 573, 109,
/* 830 */ 512, 573, 134, 562, 556, 573, 135, 501, 593, 396,
/* 840 */ 601, 2, 309, 572, 202, 593, 142, 572, 573, 100,
/* 850 */ 28, 56, 57, 47, 554, 553, 555, 555, 54, 54,
/* 860 */ 55, 55, 55, 55, 393, 53, 53, 53, 53, 52,
/* 870 */ 52, 51, 51, 51, 50, 231, 301, 393, 572, 396,
/* 880 */ 393, 341, 224, 336, 393, 442, 348, 161, 573, 104,
/* 890 */ 440, 493, 396, 308, 475, 396, 593, 393, 593, 396,
/* 900 */ 248, 573, 103, 584, 573, 95, 562, 556, 573, 102,
/* 910 */ 363, 431, 396, 165, 542, 229, 516, 430, 593, 23,
/* 920 */ 516, 573, 76, 129, 56, 45, 47, 554, 553, 555,
/* 930 */ 555, 54, 54, 55, 55, 55, 55, 393, 53, 53,
/* 940 */ 53, 53, 52, 52, 51, 51, 51, 50, 231, 301,
/* 950 */ 216, 583, 396, 393, 419, 279, 23, 393, 200, 277,
/* 960 */ 265, 573, 98, 50, 231, 128, 593, 27, 396, 393,
/* 970 */ 336, 215, 396, 582, 140, 561, 560, 573, 138, 562,
/* 980 */ 556, 573, 137, 127, 396, 593, 358, 159, 593, 593,
/* 990 */ 600, 319, 572, 573, 136, 273, 558, 557, 57, 47,
/* 1000 */ 554, 553, 555, 555, 54, 54, 55, 55, 55, 55,
/* 1010 */ 393, 53, 53, 53, 53, 52, 52, 51, 51, 51,
/* 1020 */ 50, 231, 301, 559, 393, 396, 393, 125, 392, 566,
/* 1030 */ 393, 382, 354, 182, 573, 75, 451, 212, 350, 396,
/* 1040 */ 124, 396, 393, 593, 593, 396, 593, 529, 573, 92,
/* 1050 */ 573, 91, 562, 556, 573, 74, 517, 396, 448, 165,
/* 1060 */ 252, 154, 593, 444, 123, 15, 573, 90, 513, 436,
/* 1070 */ 153, 593, 47, 554, 553, 555, 555, 54, 54, 55,
/* 1080 */ 55, 55, 55, 593, 53, 53, 53, 53, 52, 52,
/* 1090 */ 51, 51, 51, 50, 231, 43, 387, 255, 3, 393,
/* 1100 */ 255, 511, 397, 594, 152, 269, 433, 121, 25, 120,
/* 1110 */ 24, 11, 593, 390, 396, 593, 593, 428, 43, 387,
/* 1120 */ 593, 3, 393, 573, 89, 397, 594, 393, 425, 393,
/* 1130 */ 481, 111, 385, 118, 393, 113, 390, 396, 110, 63,
/* 1140 */ 254, 538, 396, 426, 396, 593, 573, 101, 10, 396,
/* 1150 */ 393, 573, 88, 573, 86, 385, 393, 255, 573, 85,
/* 1160 */ 410, 40, 41, 506, 538, 396, 418, 255, 42, 395,
/* 1170 */ 394, 396, 593, 567, 573, 84, 409, 321, 148, 268,
/* 1180 */ 573, 71, 593, 235, 40, 41, 318, 461, 402, 107,
/* 1190 */ 223, 42, 395, 394, 593, 597, 567, 262, 260, 126,
/* 1200 */ 424, 175, 593, 258, 565, 565, 565, 564, 563, 14,
/* 1210 */ 423, 587, 593, 593, 233, 586, 43, 387, 593, 3,
/* 1220 */ 399, 174, 255, 397, 594, 585, 393, 565, 565, 565,
/* 1230 */ 564, 563, 14, 256, 390, 172, 198, 593, 398, 33,
/* 1240 */ 387, 396, 3, 393, 251, 344, 397, 594, 593, 393,
/* 1250 */ 573, 94, 8, 385, 571, 233, 288, 390, 396, 593,
/* 1260 */ 593, 30, 538, 393, 396, 422, 435, 573, 70, 434,
/* 1270 */ 572, 393, 377, 573, 83, 286, 385, 287, 396, 31,
/* 1280 */ 228, 593, 40, 41, 593, 538, 396, 573, 82, 42,
/* 1290 */ 395, 394, 380, 285, 567, 573, 81, 381, 379, 60,
/* 1300 */ 337, 239, 59, 595, 594, 40, 41, 236, 393, 405,
/* 1310 */ 36, 570, 42, 395, 394, 593, 593, 567, 528, 283,
/* 1320 */ 393, 167, 593, 396, 593, 565, 565, 565, 564, 563,
/* 1330 */ 14, 211, 573, 80, 593, 396, 296, 295, 294, 173,
/* 1340 */ 292, 393, 538, 427, 573, 69, 179, 280, 565, 565,
/* 1350 */ 565, 564, 563, 14, 393, 29, 396, 255, 515, 238,
/* 1360 */ 255, 374, 189, 188, 278, 573, 17, 393, 237, 396,
/* 1370 */ 498, 509, 593, 371, 567, 593, 276, 495, 573, 78,
/* 1380 */ 255, 150, 396, 438, 145, 508, 375, 282, 396, 149,
/* 1390 */ 368, 573, 77, 489, 490, 593, 314, 573, 9, 593,
/* 1400 */ 214, 593, 593, 213, 271, 565, 565, 565, 485, 486,
/* 1410 */ 130, 484, 299, 222, 221, 220, 466, 460, 459, 458,
/* 1420 */ 158, 355, 452, 240, 298, 157, 351, 353, 156, 253,
/* 1430 */ 250, 330, 241, 449, 205, 450, 302, 26, 155, 439,
/* 1440 */ 345, 233, 141, 122, 181, 119, 429, 117, 331, 116,
/* 1450 */ 115, 114, 421, 305, 22, 112, 407, 176, 19, 62,
/* 1460 */ 406, 581, 403, 186, 323, 568, 289, 527, 524, 281,
/* 1470 */ 272, 545, 471, 386, 482, 470, 543, 469, 467, 362,
/* 1480 */ 432, 297, 242, 329, 420, 5, 541, 522, 352, 338,
/* 1490 */ 247, 204, 290, 480, 474, 383, 473, 499, 497, 231,
/* 1500 */ 462, 455,
};
static const YYCODETYPE yy_lookahead[] = {
/* 0 */ 19, 141, 142, 143, 144, 24, 1, 26, 76, 77,
/* 10 */ 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
/* 20 */ 88, 89, 90, 91, 112, 22, 26, 27, 116, 26,
/* 30 */ 49, 50, 76, 77, 78, 79, 15, 81, 82, 83,
/* 40 */ 84, 85, 86, 87, 88, 89, 90, 91, 67, 68,
/* 50 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
/* 60 */ 79, 23, 81, 82, 83, 84, 85, 86, 87, 88,
/* 70 */ 89, 90, 91, 19, 93, 16, 19, 7, 8, 25,
/* 80 */ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
/* 90 */ 91, 19, 32, 93, 94, 95, 93, 22, 98, 99,
/* 100 */ 100, 41, 162, 49, 50, 165, 166, 167, 54, 109,
/* 110 */ 96, 97, 85, 86, 87, 88, 89, 90, 91, 60,
/* 120 */ 61, 67, 68, 69, 70, 71, 72, 73, 74, 75,
/* 130 */ 76, 77, 78, 79, 149, 81, 82, 83, 84, 85,
/* 140 */ 86, 87, 88, 89, 90, 91, 19, 11, 91, 164,
/* 150 */ 75, 24, 95, 96, 97, 98, 99, 100, 101, 65,
/* 160 */ 149, 87, 25, 91, 149, 108, 26, 27, 96, 97,
/* 170 */ 98, 99, 100, 101, 22, 164, 49, 50, 95, 164,
/* 180 */ 108, 98, 99, 100, 173, 174, 112, 93, 173, 174,
/* 190 */ 116, 97, 109, 57, 67, 68, 69, 70, 71, 72,
/* 200 */ 73, 74, 75, 76, 77, 78, 79, 117, 81, 82,
/* 210 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 19,
/* 220 */ 149, 25, 128, 129, 130, 85, 86, 25, 213, 214,
/* 230 */ 219, 160, 161, 93, 94, 164, 96, 21, 149, 102,
/* 240 */ 104, 105, 106, 103, 149, 105, 145, 146, 117, 49,
/* 250 */ 50, 115, 151, 164, 153, 184, 185, 171, 172, 164,
/* 260 */ 159, 22, 173, 174, 169, 170, 180, 67, 68, 69,
/* 270 */ 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
/* 280 */ 23, 81, 82, 83, 84, 85, 86, 87, 88, 89,
/* 290 */ 90, 91, 19, 149, 193, 149, 111, 95, 113, 114,
/* 300 */ 98, 99, 100, 154, 215, 159, 25, 96, 164, 220,
/* 310 */ 164, 109, 22, 169, 170, 99, 26, 27, 217, 173,
/* 320 */ 174, 125, 49, 50, 229, 230, 115, 22, 168, 169,
/* 330 */ 170, 26, 27, 159, 117, 135, 26, 27, 127, 193,
/* 340 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
/* 350 */ 77, 78, 79, 137, 81, 82, 83, 84, 85, 86,
/* 360 */ 87, 88, 89, 90, 91, 19, 117, 193, 111, 23,
/* 370 */ 113, 114, 117, 229, 230, 94, 227, 26, 27, 26,
/* 380 */ 27, 232, 97, 93, 94, 87, 88, 89, 90, 91,
/* 390 */ 230, 217, 159, 108, 149, 49, 50, 87, 93, 94,
/* 400 */ 119, 57, 157, 93, 94, 160, 161, 233, 135, 164,
/* 410 */ 23, 26, 238, 67, 68, 69, 70, 71, 72, 73,
/* 420 */ 74, 75, 76, 77, 78, 79, 193, 81, 82, 83,
/* 430 */ 84, 85, 86, 87, 88, 89, 90, 91, 19, 25,
/* 440 */ 112, 149, 23, 23, 93, 94, 93, 94, 104, 105,
/* 450 */ 106, 22, 149, 221, 222, 223, 164, 23, 149, 115,
/* 460 */ 149, 23, 104, 105, 106, 173, 174, 164, 49, 50,
/* 470 */ 119, 11, 119, 164, 242, 164, 173, 174, 93, 165,
/* 480 */ 159, 22, 173, 174, 173, 174, 67, 68, 69, 70,
/* 490 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 16,
/* 500 */ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
/* 510 */ 91, 19, 23, 12, 193, 23, 224, 214, 204, 26,
/* 520 */ 27, 23, 12, 25, 215, 23, 205, 206, 23, 28,
/* 530 */ 219, 111, 118, 113, 114, 221, 222, 223, 28, 180,
/* 540 */ 181, 49, 50, 60, 61, 44, 187, 46, 23, 111,
/* 550 */ 25, 113, 114, 23, 44, 25, 46, 50, 57, 67,
/* 560 */ 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
/* 570 */ 78, 79, 25, 81, 82, 83, 84, 85, 86, 87,
/* 580 */ 88, 89, 90, 91, 19, 19, 93, 94, 23, 36,
/* 590 */ 23, 23, 94, 25, 149, 115, 168, 169, 170, 24,
/* 600 */ 111, 26, 113, 114, 51, 160, 161, 127, 30, 164,
/* 610 */ 103, 58, 34, 119, 49, 50, 50, 119, 196, 22,
/* 620 */ 137, 24, 7, 8, 9, 203, 48, 104, 105, 106,
/* 630 */ 149, 25, 67, 68, 69, 70, 71, 72, 73, 74,
/* 640 */ 75, 76, 77, 78, 79, 164, 81, 82, 83, 84,
/* 650 */ 85, 86, 87, 88, 89, 90, 91, 19, 230, 35,
/* 660 */ 107, 149, 24, 128, 129, 149, 149, 149, 93, 103,
/* 670 */ 149, 0, 1, 2, 108, 172, 164, 221, 222, 223,
/* 680 */ 164, 164, 164, 180, 134, 164, 136, 49, 50, 173,
/* 690 */ 174, 173, 174, 212, 173, 174, 205, 206, 159, 165,
/* 700 */ 166, 167, 165, 186, 192, 67, 68, 69, 70, 71,
/* 710 */ 72, 73, 74, 75, 76, 77, 78, 79, 149, 81,
/* 720 */ 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
/* 730 */ 19, 149, 193, 164, 149, 164, 149, 149, 25, 149,
/* 740 */ 19, 204, 173, 174, 173, 19, 164, 149, 27, 164,
/* 750 */ 149, 164, 164, 27, 164, 243, 217, 35, 173, 174,
/* 760 */ 49, 50, 164, 52, 22, 164, 27, 23, 186, 25,
/* 770 */ 117, 173, 174, 186, 173, 174, 186, 238, 67, 68,
/* 780 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
/* 790 */ 79, 149, 81, 82, 83, 84, 85, 86, 87, 88,
/* 800 */ 89, 90, 91, 19, 149, 149, 164, 149, 35, 159,
/* 810 */ 149, 149, 23, 159, 25, 173, 174, 189, 190, 164,
/* 820 */ 164, 23, 164, 149, 149, 164, 164, 239, 173, 174,
/* 830 */ 149, 173, 174, 49, 50, 173, 174, 23, 164, 164,
/* 840 */ 143, 144, 186, 193, 159, 164, 39, 193, 173, 174,
/* 850 */ 22, 67, 68, 69, 70, 71, 72, 73, 74, 75,
/* 860 */ 76, 77, 78, 79, 149, 81, 82, 83, 84, 85,
/* 870 */ 86, 87, 88, 89, 90, 91, 19, 149, 193, 164,
/* 880 */ 149, 149, 52, 149, 149, 23, 212, 25, 173, 174,
/* 890 */ 189, 190, 164, 212, 29, 164, 164, 149, 164, 164,
/* 900 */ 239, 173, 174, 149, 173, 174, 49, 50, 173, 174,
/* 910 */ 52, 23, 164, 25, 85, 86, 165, 23, 164, 25,
/* 920 */ 165, 173, 174, 22, 67, 68, 69, 70, 71, 72,
/* 930 */ 73, 74, 75, 76, 77, 78, 79, 149, 81, 82,
/* 940 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 19,
/* 950 */ 216, 149, 164, 149, 23, 204, 25, 149, 159, 204,
/* 960 */ 23, 173, 174, 90, 91, 22, 164, 22, 164, 149,
/* 970 */ 149, 239, 164, 149, 149, 49, 50, 173, 174, 49,
/* 980 */ 50, 173, 174, 22, 164, 164, 52, 101, 164, 164,
/* 990 */ 1, 2, 193, 173, 174, 108, 70, 71, 68, 69,
/* 1000 */ 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
/* 1010 */ 149, 81, 82, 83, 84, 85, 86, 87, 88, 89,
/* 1020 */ 90, 91, 19, 97, 149, 164, 149, 103, 149, 149,
/* 1030 */ 149, 149, 19, 24, 173, 174, 20, 216, 43, 164,
/* 1040 */ 53, 164, 149, 164, 164, 164, 164, 149, 173, 174,
/* 1050 */ 173, 174, 49, 50, 173, 174, 149, 164, 59, 25,
/* 1060 */ 137, 103, 164, 53, 22, 5, 173, 174, 149, 1,
/* 1070 */ 117, 164, 69, 70, 71, 72, 73, 74, 75, 76,
/* 1080 */ 77, 78, 79, 164, 81, 82, 83, 84, 85, 86,
/* 1090 */ 87, 88, 89, 90, 91, 19, 20, 149, 22, 149,
/* 1100 */ 149, 149, 26, 27, 35, 149, 27, 107, 75, 126,
/* 1110 */ 75, 22, 164, 37, 164, 164, 164, 1, 19, 20,
/* 1120 */ 164, 22, 149, 173, 174, 26, 27, 149, 20, 149,
/* 1130 */ 149, 107, 56, 118, 149, 118, 37, 164, 126, 16,
/* 1140 */ 192, 65, 164, 192, 164, 164, 173, 174, 22, 164,
/* 1150 */ 149, 173, 174, 173, 174, 56, 149, 149, 173, 174,
/* 1160 */ 23, 85, 86, 87, 65, 164, 127, 149, 92, 93,
/* 1170 */ 94, 164, 164, 97, 173, 174, 23, 64, 15, 149,
/* 1180 */ 173, 174, 164, 139, 85, 86, 3, 149, 4, 163,
/* 1190 */ 179, 92, 93, 94, 164, 148, 97, 149, 149, 179,
/* 1200 */ 192, 6, 164, 149, 128, 129, 130, 131, 132, 133,
/* 1210 */ 192, 148, 164, 164, 115, 148, 19, 20, 164, 22,
/* 1220 */ 148, 150, 149, 26, 27, 13, 149, 128, 129, 130,
/* 1230 */ 131, 132, 133, 149, 37, 150, 159, 164, 158, 19,
/* 1240 */ 20, 164, 22, 149, 149, 149, 26, 27, 164, 149,
/* 1250 */ 173, 174, 25, 56, 193, 115, 198, 37, 164, 164,
/* 1260 */ 164, 125, 65, 149, 164, 192, 149, 173, 174, 149,
/* 1270 */ 193, 149, 122, 173, 174, 200, 56, 199, 164, 123,
/* 1280 */ 225, 164, 85, 86, 164, 65, 164, 173, 174, 92,
/* 1290 */ 93, 94, 215, 201, 97, 173, 174, 220, 121, 22,
/* 1300 */ 149, 149, 124, 26, 27, 85, 86, 149, 149, 149,
/* 1310 */ 134, 202, 92, 93, 94, 164, 164, 97, 156, 149,
/* 1320 */ 149, 117, 164, 164, 164, 128, 129, 130, 131, 132,
/* 1330 */ 133, 5, 173, 174, 164, 164, 10, 11, 12, 13,
/* 1340 */ 14, 149, 65, 17, 173, 174, 156, 209, 128, 129,
/* 1350 */ 130, 131, 132, 133, 149, 103, 164, 149, 210, 33,
/* 1360 */ 149, 120, 85, 86, 209, 173, 174, 149, 42, 164,
/* 1370 */ 93, 210, 164, 149, 97, 164, 209, 175, 173, 174,
/* 1380 */ 149, 55, 164, 57, 149, 210, 149, 149, 164, 63,
/* 1390 */ 103, 173, 174, 183, 175, 164, 47, 173, 174, 164,
/* 1400 */ 192, 164, 164, 192, 175, 128, 129, 130, 102, 177,
/* 1410 */ 22, 175, 178, 228, 91, 228, 183, 175, 175, 175,
/* 1420 */ 155, 18, 156, 192, 178, 155, 45, 156, 155, 236,
/* 1430 */ 104, 105, 106, 237, 156, 156, 110, 134, 155, 188,
/* 1440 */ 156, 115, 67, 188, 218, 22, 198, 191, 18, 191,
/* 1450 */ 191, 191, 198, 156, 241, 188, 40, 218, 241, 244,
/* 1460 */ 156, 152, 38, 195, 138, 165, 197, 176, 176, 208,
/* 1470 */ 176, 231, 176, 226, 181, 165, 231, 176, 165, 177,
/* 1480 */ 198, 147, 208, 208, 198, 195, 165, 207, 235, 240,
/* 1490 */ 240, 234, 194, 182, 182, 190, 182, 173, 173, 91,
/* 1500 */ 185, 185,
};
#define YY_SHIFT_USE_DFLT (-89)
#define YY_SHIFT_COUNT (400)
#define YY_SHIFT_MIN (-88)
#define YY_SHIFT_MAX (1430)
static const short yy_shift_ofst[] = {
/* 0 */ 989, 1099, 1326, 1099, 1197, 1197, 140, 140, 0, -19,
/* 10 */ 1197, 1197, 1197, 1197, 1197, 344, 493, 711, 1076, 1197,
/* 20 */ 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197,
/* 30 */ 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197,
/* 40 */ 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1220, 1197, 1197,
/* 50 */ 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197,
/* 60 */ 1197, 136, 493, 493, 829, 829, 385, 1140, 54, 638,
/* 70 */ 565, 492, 419, 346, 273, 200, 127, 784, 784, 784,
/* 80 */ 784, 784, 784, 784, 784, 784, 784, 784, 784, 784,
/* 90 */ 784, 784, 784, 784, 784, 857, 784, 930, 1003, 1003,
/* 100 */ -68, -44, -44, -44, -44, -44, -1, 57, 27, 298,
/* 110 */ 493, 493, 493, 493, 493, 493, 493, 493, 493, 493,
/* 120 */ 493, 493, 493, 493, 493, 493, 566, 493, 493, 493,
/* 130 */ 493, 493, 216, 385, 873, 1408, -89, -89, -89, 1277,
/* 140 */ 72, 501, 501, 310, 305, 353, 351, 290, 493, 493,
/* 150 */ 493, 493, 493, 493, 493, 493, 493, 493, 493, 493,
/* 160 */ 493, 493, 493, 493, 493, 493, 493, 493, 493, 493,
/* 170 */ 493, 493, 493, 493, 493, 493, 211, 575, 575, 575,
/* 180 */ 671, 480, 1140, 1140, 1140, -89, -89, 202, 94, 94,
/* 190 */ 83, 553, 553, 553, 498, 489, 510, 438, 420, 257,
/* 200 */ 185, 185, 185, 185, 523, 578, 185, 185, 281, 3,
/* 210 */ 74, 615, 196, 721, 721, 726, 196, 726, 137, 385,
/* 220 */ 60, 385, 60, 507, 60, 721, 60, 60, 550, 535,
/* 230 */ 535, 385, 414, -88, 597, 1424, 1204, 1416, 1416, 1204,
/* 240 */ 1423, 1375, 1136, 1430, 1430, 1430, 1430, 1136, 1423, 1375,
/* 250 */ 1375, 1204, 1403, 1303, 1381, 1204, 1204, 1403, 1204, 1403,
/* 260 */ 1204, 1403, 1388, 1287, 1287, 1287, 1349, 1323, 1323, 1388,
/* 270 */ 1287, 1306, 1287, 1349, 1287, 1287, 1241, 1252, 1241, 1252,
/* 280 */ 1241, 1252, 1204, 1204, 1176, 1178, 1177, 1156, 1150, 1136,
/* 290 */ 1140, 1227, 1212, 1212, 1195, 1195, 1195, 1195, -89, -89,
/* 300 */ -89, 926, 483, 59, 358, 75, 931, 894, 888, 862,
/* 310 */ 789, 744, 568, 14, 70, 285, 530, 525, 1184, 1183,
/* 320 */ 1044, 1163, 1113, 1123, 1153, 1137, 1039, 1126, 1012, 1024,
/* 330 */ 1017, 1108, 1116, 1015, 1089, 983, 1035, 1033, 1000, 1079,
/* 340 */ 1069, 953, 1068, 1060, 1042, 958, 923, 1010, 1034, 987,
/* 350 */ 999, 995, 924, 1009, 1016, 1013, 887, 886, 961, 934,
/* 360 */ 945, 943, 937, 901, 858, 865, 828, 830, 807, 814,
/* 370 */ 798, 653, 739, 773, 742, 494, 606, 722, 713, 624,
/* 380 */ 606, 567, 505, 547, 502, 459, 460, 429, 434, 387,
/* 390 */ 239, 328, 255, 249, 217, 131, 90, 152, 38, 21,
/* 400 */ 5,
};
#define YY_REDUCE_USE_DFLT (-141)
#define YY_REDUCE_COUNT (300)
#define YY_REDUCE_MIN (-140)
#define YY_REDUCE_MAX (1334)
static const short yy_reduce_ofst[] = {
/* 0 */ -140, 1077, 101, 146, 15, 89, 144, 95, 71, 314,
/* 10 */ 311, 11, 309, 303, 292, 174, 245, 232, 1224, 1218,
/* 20 */ 1205, 1192, 1171, 1159, 1122, 1114, 1100, 1094, 1007, 1001,
/* 30 */ 985, 980, 978, 973, 950, 893, 881, 877, 875, 861,
/* 40 */ 820, 808, 804, 788, 748, 735, 731, 728, 715, 675,
/* 50 */ 662, 658, 655, 642, 601, 598, 585, 569, 521, 518,
/* 60 */ 516, 539, 445, 512, 428, 160, -60, 321, 456, 456,
/* 70 */ 456, 456, 456, 456, 456, 456, 456, 456, 456, 456,
/* 80 */ 456, 456, 456, 456, 456, 456, 456, 456, 456, 456,
/* 90 */ 456, 456, 456, 456, 456, 456, 456, 456, 456, 456,
/* 100 */ 456, 456, 456, 456, 456, 456, 456, 86, 456, 456,
/* 110 */ 1231, 821, 1211, 1208, 1073, 1018, 1008, 951, 732, 681,
/* 120 */ 661, 734, 588, 656, 674, 948, 359, 590, 587, 582,
/* 130 */ 517, 481, 149, 534, 456, 456, 456, 456, 456, 571,
/* 140 */ 503, 701, 628, 879, 1238, 1237, 1235, 1170, 1160, 1158,
/* 150 */ 1152, 1151, 1120, 1117, 1096, 1095, 1084, 1054, 1049, 1048,
/* 160 */ 1038, 1030, 981, 956, 952, 919, 907, 898, 882, 880,
/* 170 */ 879, 825, 824, 802, 754, -15, 799, 755, 751, 537,
/* 180 */ 697, 685, 654, 650, 233, 491, 422, 1316, 1325, 1324,
/* 190 */ 1315, 1314, 1312, 1311, 1280, 1298, 1305, 1298, 1298, 1298,
/* 200 */ 1298, 1298, 1298, 1298, 1253, 1257, 1298, 1298, 1280, 1321,
/* 210 */ 1290, 1334, 1286, 1275, 1274, 1250, 1282, 1249, 1302, 1313,
/* 220 */ 1301, 1310, 1296, 1293, 1294, 1261, 1292, 1291, 1247, 1245,
/* 230 */ 1240, 1300, 1269, 1268, 1309, 1215, 1304, 1217, 1213, 1297,
/* 240 */ 1239, 1267, 1254, 1260, 1259, 1258, 1256, 1248, 1226, 1255,
/* 250 */ 1251, 1284, 1283, 1196, 1193, 1279, 1278, 1273, 1271, 1270,
/* 260 */ 1266, 1265, 1246, 1244, 1243, 1242, 1233, 1187, 1185, 1234,
/* 270 */ 1236, 1232, 1229, 1210, 1219, 1202, 1175, 1167, 1161, 1155,
/* 280 */ 1148, 1138, 1190, 1162, 1055, 1109, 1092, 1075, 1078, 1058,
/* 290 */ 1061, 1080, 1085, 1071, 1072, 1067, 1063, 1047, 1020, 1011,
/* 300 */ 1026,
};
static const YYACTIONTYPE yy_default[] = {
/* 0 */ 607, 842, 914, 914, 914, 842, 869, 869, 914, 731,
/* 10 */ 914, 914, 914, 914, 840, 914, 914, 903, 914, 914,
/* 20 */ 914, 914, 914, 914, 914, 914, 914, 914, 914, 914,
/* 30 */ 914, 914, 914, 914, 914, 914, 914, 914, 914, 914,
/* 40 */ 914, 914, 914, 914, 914, 914, 914, 914, 914, 914,
/* 50 */ 914, 914, 914, 914, 914, 914, 914, 914, 914, 914,
/* 60 */ 914, 914, 914, 914, 869, 869, 646, 735, 766, 914,
/* 70 */ 914, 914, 914, 914, 914, 914, 914, 902, 904, 781,
/* 80 */ 780, 774, 773, 882, 746, 771, 764, 757, 768, 843,
/* 90 */ 836, 837, 835, 839, 844, 914, 767, 803, 820, 802,
/* 100 */ 814, 819, 826, 818, 815, 805, 804, 638, 806, 807,
/* 110 */ 914, 914, 914, 914, 914, 914, 914, 914, 914, 914,
/* 120 */ 914, 914, 914, 914, 914, 914, 700, 914, 914, 914,
/* 130 */ 914, 914, 633, 914, 808, 809, 823, 822, 821, 914,
/* 140 */ 914, 914, 914, 914, 914, 914, 914, 914, 914, 907,
/* 150 */ 914, 914, 914, 914, 914, 914, 914, 914, 914, 914,
/* 160 */ 914, 914, 914, 914, 914, 914, 914, 914, 914, 914,
/* 170 */ 914, 914, 914, 914, 914, 613, 914, 731, 731, 731,
/* 180 */ 607, 914, 914, 914, 914, 735, 725, 691, 914, 914,
/* 190 */ 914, 914, 914, 914, 914, 914, 914, 914, 914, 914,
/* 200 */ 776, 714, 892, 894, 914, 875, 712, 635, 733, 648,
/* 210 */ 723, 615, 770, 748, 748, 887, 770, 887, 672, 914,
/* 220 */ 760, 914, 760, 669, 760, 748, 760, 760, 838, 914,
/* 230 */ 914, 914, 732, 723, 914, 912, 739, 906, 906, 739,
/* 240 */ 782, 704, 770, 711, 711, 711, 711, 770, 782, 704,
/* 250 */ 704, 739, 630, 881, 879, 739, 739, 630, 739, 630,
/* 260 */ 739, 630, 848, 702, 702, 702, 687, 852, 852, 848,
/* 270 */ 702, 672, 702, 687, 702, 702, 752, 747, 752, 747,
/* 280 */ 752, 747, 739, 739, 914, 765, 753, 763, 761, 770,
/* 290 */ 914, 690, 623, 623, 612, 612, 612, 612, 674, 674,
/* 300 */ 656, 914, 914, 914, 914, 855, 914, 914, 914, 914,
/* 310 */ 914, 914, 914, 914, 914, 914, 914, 914, 914, 608,
/* 320 */ 914, 914, 911, 914, 914, 914, 914, 914, 914, 914,
/* 330 */ 914, 914, 914, 914, 914, 914, 914, 914, 914, 914,
/* 340 */ 914, 885, 914, 914, 914, 914, 914, 914, 878, 877,
/* 350 */ 914, 914, 914, 914, 914, 914, 914, 914, 914, 914,
/* 360 */ 914, 914, 914, 914, 914, 914, 914, 914, 914, 914,
/* 370 */ 914, 914, 914, 914, 914, 914, 762, 914, 754, 914,
/* 380 */ 841, 914, 914, 914, 914, 914, 914, 914, 914, 914,
/* 390 */ 914, 717, 791, 914, 790, 794, 789, 640, 914, 621,
/* 400 */ 914, 604, 609, 913, 910, 909, 908, 905, 901, 859,
/* 410 */ 857, 864, 863, 862, 861, 860, 858, 856, 777, 775,
/* 420 */ 772, 769, 900, 854, 713, 710, 709, 629, 884, 893,
/* 430 */ 891, 783, 890, 889, 888, 886, 883, 870, 779, 778,
/* 440 */ 705, 846, 845, 632, 874, 873, 872, 876, 880, 871,
/* 450 */ 741, 631, 628, 637, 694, 693, 701, 699, 698, 697,
/* 460 */ 696, 695, 692, 639, 647, 658, 686, 671, 670, 851,
/* 470 */ 853, 850, 849, 679, 678, 684, 683, 682, 681, 680,
/* 480 */ 677, 676, 675, 668, 667, 673, 666, 689, 688, 685,
/* 490 */ 665, 708, 707, 706, 703, 664, 663, 662, 794, 661,
/* 500 */ 660, 800, 799, 787, 830, 728, 727, 726, 738, 737,
/* 510 */ 750, 749, 785, 784, 751, 736, 730, 729, 745, 744,
/* 520 */ 743, 742, 734, 724, 756, 759, 758, 755, 832, 740,
/* 530 */ 829, 899, 898, 897, 896, 895, 834, 833, 801, 798,
/* 540 */ 651, 652, 868, 866, 867, 865, 654, 653, 650, 649,
/* 550 */ 831, 719, 718, 827, 824, 816, 812, 828, 825, 817,
/* 560 */ 813, 811, 810, 796, 795, 793, 792, 788, 797, 642,
/* 570 */ 720, 716, 715, 786, 722, 721, 659, 657, 655, 636,
/* 580 */ 634, 627, 625, 624, 626, 622, 620, 619, 618, 617,
/* 590 */ 616, 645, 644, 643, 641, 640, 614, 611, 610, 606,
/* 600 */ 605, 603,
};
/* The next table maps tokens 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.
*/
#ifdef YYFALLBACK
static const YYCODETYPE yyFallback[] = {
0, /* $ => nothing */
0, /* SEMI => nothing */
26, /* EXPLAIN => ID */
26, /* QUERY => ID */
26, /* PLAN => ID */
26, /* BEGIN => ID */
0, /* TRANSACTION => nothing */
26, /* DEFERRED => ID */
26, /* IMMEDIATE => ID */
26, /* EXCLUSIVE => ID */
0, /* COMMIT => nothing */
26, /* END => ID */
26, /* ROLLBACK => ID */
26, /* SAVEPOINT => ID */
26, /* RELEASE => ID */
0, /* TO => nothing */
0, /* TABLE => nothing */
0, /* CREATE => nothing */
26, /* IF => ID */
0, /* NOT => nothing */
0, /* EXISTS => nothing */
26, /* TEMP => ID */
0, /* LP => nothing */
0, /* RP => nothing */
0, /* AS => nothing */
0, /* COMMA => nothing */
0, /* ID => nothing */
0, /* INDEXED => nothing */
26, /* ABORT => ID */
26, /* ACTION => ID */
26, /* AFTER => ID */
26, /* ANALYZE => ID */
26, /* ASC => ID */
26, /* ATTACH => ID */
26, /* BEFORE => ID */
26, /* BY => ID */
26, /* CASCADE => ID */
26, /* CAST => ID */
26, /* COLUMNKW => ID */
26, /* CONFLICT => ID */
26, /* DATABASE => ID */
26, /* DESC => ID */
26, /* DETACH => ID */
26, /* EACH => ID */
26, /* FAIL => ID */
26, /* FOR => ID */
26, /* IGNORE => ID */
26, /* INITIALLY => ID */
26, /* INSTEAD => ID */
26, /* LIKE_KW => ID */
26, /* MATCH => ID */
26, /* NO => ID */
26, /* KEY => ID */
26, /* OF => ID */
26, /* OFFSET => ID */
26, /* PRAGMA => ID */
26, /* RAISE => ID */
26, /* REPLACE => ID */
26, /* RESTRICT => ID */
26, /* ROW => ID */
26, /* TRIGGER => ID */
26, /* VIEW => ID */
26, /* VIRTUAL => ID */
26, /* REINDEX => ID */
26, /* RENAME => ID */
26, /* CTIME_KW => ID */
};
#endif /* YYFALLBACK */
/* 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.
*/
struct yyStackEntry {
YYACTIONTYPE stateno; /* The state-number */
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
** is the value of the token */
};
typedef struct yyStackEntry yyStackEntry;
/* The state of the parser is completely contained in an instance of
** the following structure */
struct yyParser {
int yyidx; /* Index of top element in stack */
#ifdef YYTRACKMAXSTACKDEPTH
int yyidxMax; /* Maximum value of yyidx */
#endif
int yyerrcnt; /* Shifts left before out of the error */
sqlite4ParserARG_SDECL /* A place to hold %extra_argument */
#if YYSTACKDEPTH<=0
int yystksz; /* Current side of the stack */
yyStackEntry *yystack; /* The parser's stack */
#else
yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */
#endif
void *pEnv; /* Malloc context */
};
typedef struct yyParser yyParser;
#ifndef NDEBUG
/* #include <stdio.h> */
static FILE *yyTraceFILE = 0;
static char *yyTracePrompt = 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.
*/
SQLITE_PRIVATE void sqlite4ParserTrace(FILE *TraceFILE, char *zTracePrompt){
yyTraceFILE = TraceFILE;
yyTracePrompt = zTracePrompt;
if( yyTraceFILE==0 ) yyTracePrompt = 0;
else if( yyTracePrompt==0 ) yyTraceFILE = 0;
}
#endif /* NDEBUG */
#ifndef NDEBUG
/* For tracing shifts, the names of all terminals and nonterminals
** are required. The following table supplies these names */
static const char *const yyTokenName[] = {
"$", "SEMI", "EXPLAIN", "QUERY",
"PLAN", "BEGIN", "TRANSACTION", "DEFERRED",
"IMMEDIATE", "EXCLUSIVE", "COMMIT", "END",
"ROLLBACK", "SAVEPOINT", "RELEASE", "TO",
"TABLE", "CREATE", "IF", "NOT",
"EXISTS", "TEMP", "LP", "RP",
"AS", "COMMA", "ID", "INDEXED",
"ABORT", "ACTION", "AFTER", "ANALYZE",
"ASC", "ATTACH", "BEFORE", "BY",
"CASCADE", "CAST", "COLUMNKW", "CONFLICT",
"DATABASE", "DESC", "DETACH", "EACH",
"FAIL", "FOR", "IGNORE", "INITIALLY",
"INSTEAD", "LIKE_KW", "MATCH", "NO",
"KEY", "OF", "OFFSET", "PRAGMA",
"RAISE", "REPLACE", "RESTRICT", "ROW",
"TRIGGER", "VIEW", "VIRTUAL", "REINDEX",
"RENAME", "CTIME_KW", "ANY", "OR",
"AND", "IS", "BETWEEN", "IN",
"ISNULL", "NOTNULL", "NE", "EQ",
"GT", "LE", "LT", "GE",
"ESCAPE", "BITAND", "BITOR", "LSHIFT",
"RSHIFT", "PLUS", "MINUS", "STAR",
"SLASH", "REM", "CONCAT", "COLLATE",
"BITNOT", "STRING", "JOIN_KW", "CONSTRAINT",
"DEFAULT", "NULL", "PRIMARY", "UNIQUE",
"CHECK", "REFERENCES", "AUTOINCR", "ON",
"INSERT", "DELETE", "UPDATE", "SET",
"DEFERRABLE", "FOREIGN", "DROP", "UNION",
"ALL", "EXCEPT", "INTERSECT", "SELECT",
"DISTINCT", "DOT", "FROM", "JOIN",
"USING", "ORDER", "GROUP", "HAVING",
"LIMIT", "WHERE", "INTO", "VALUES",
"INTEGER", "FLOAT", "BLOB", "REGISTER",
"VARIABLE", "CASE", "WHEN", "THEN",
"ELSE", "INDEX", "ALTER", "ADD",
"error", "input", "cmdlist", "ecmd",
"explain", "cmdx", "cmd", "transtype",
"trans_opt", "nm", "savepoint_opt", "create_table",
"create_table_args", "createkw", "temp", "ifnotexists",
"dbnm", "columnlist", "conslist_opt", "select",
"column", "columnid", "type", "carglist",
"id", "ids", "typetoken", "typename",
"signed", "plus_num", "minus_num", "carg",
"ccons", "term", "expr", "onconf",
"sortorder", "autoinc", "idxlist_opt", "refargs",
"defer_subclause", "refarg", "refact", "init_deferred_pred_opt",
"conslist", "tcons", "idxlist", "defer_subclause_opt",
"orconf", "resolvetype", "raisetype", "ifexists",
"fullname", "oneselect", "multiselect_op", "distinct",
"selcollist", "from", "where_opt", "groupby_opt",
"having_opt", "orderby_opt", "limit_opt", "sclp",
"as", "seltablist", "stl_prefix", "joinop",
"indexed_opt", "on_opt", "using_opt", "joinop2",
"inscollist", "sortlist", "sortitem", "nexprlist",
"setlist", "insert_cmd", "inscollist_opt", "itemlist",
"exprlist", "likeop", "between_op", "in_op",
"case_operand", "case_exprlist", "case_else", "uniqueflag",
"collate", "nmnum", "plus_opt", "number",
"trigger_decl", "trigger_cmd_list", "trigger_time", "trigger_event",
"foreach_clause", "when_clause", "trigger_cmd", "trnm",
"tridxby", "database_kw_opt", "key_opt", "add_column_fullname",
"kwcolumn_opt",
};
#endif /* NDEBUG */
#ifndef NDEBUG
/* For tracing reduce actions, the names of all rules are required.
*/
static const char *const yyRuleName[] = {
/* 0 */ "input ::= cmdlist",
/* 1 */ "cmdlist ::= cmdlist ecmd",
/* 2 */ "cmdlist ::= ecmd",
/* 3 */ "ecmd ::= SEMI",
/* 4 */ "ecmd ::= explain cmdx SEMI",
/* 5 */ "explain ::=",
/* 6 */ "explain ::= EXPLAIN",
/* 7 */ "explain ::= EXPLAIN QUERY PLAN",
/* 8 */ "cmdx ::= cmd",
/* 9 */ "cmd ::= BEGIN transtype trans_opt",
/* 10 */ "trans_opt ::=",
/* 11 */ "trans_opt ::= TRANSACTION",
/* 12 */ "trans_opt ::= TRANSACTION nm",
/* 13 */ "transtype ::=",
/* 14 */ "transtype ::= DEFERRED",
/* 15 */ "transtype ::= IMMEDIATE",
/* 16 */ "transtype ::= EXCLUSIVE",
/* 17 */ "cmd ::= COMMIT trans_opt",
/* 18 */ "cmd ::= END trans_opt",
/* 19 */ "cmd ::= ROLLBACK trans_opt",
/* 20 */ "savepoint_opt ::= SAVEPOINT",
/* 21 */ "savepoint_opt ::=",
/* 22 */ "cmd ::= SAVEPOINT nm",
/* 23 */ "cmd ::= RELEASE savepoint_opt nm",
/* 24 */ "cmd ::= ROLLBACK trans_opt TO savepoint_opt nm",
/* 25 */ "cmd ::= create_table create_table_args",
/* 26 */ "create_table ::= createkw temp TABLE ifnotexists nm dbnm",
/* 27 */ "createkw ::= CREATE",
/* 28 */ "ifnotexists ::=",
/* 29 */ "ifnotexists ::= IF NOT EXISTS",
/* 30 */ "temp ::= TEMP",
/* 31 */ "temp ::=",
/* 32 */ "create_table_args ::= LP columnlist conslist_opt RP",
/* 33 */ "create_table_args ::= AS select",
/* 34 */ "columnlist ::= columnlist COMMA column",
/* 35 */ "columnlist ::= column",
/* 36 */ "column ::= columnid type carglist",
/* 37 */ "columnid ::= nm",
/* 38 */ "id ::= ID",
/* 39 */ "id ::= INDEXED",
/* 40 */ "ids ::= ID|STRING",
/* 41 */ "nm ::= id",
/* 42 */ "nm ::= STRING",
/* 43 */ "nm ::= JOIN_KW",
/* 44 */ "type ::=",
/* 45 */ "type ::= typetoken",
/* 46 */ "typetoken ::= typename",
/* 47 */ "typetoken ::= typename LP signed RP",
/* 48 */ "typetoken ::= typename LP signed COMMA signed RP",
/* 49 */ "typename ::= ids",
/* 50 */ "typename ::= typename ids",
/* 51 */ "signed ::= plus_num",
/* 52 */ "signed ::= minus_num",
/* 53 */ "carglist ::= carglist carg",
/* 54 */ "carglist ::=",
/* 55 */ "carg ::= CONSTRAINT nm ccons",
/* 56 */ "carg ::= ccons",
/* 57 */ "ccons ::= DEFAULT term",
/* 58 */ "ccons ::= DEFAULT LP expr RP",
/* 59 */ "ccons ::= DEFAULT PLUS term",
/* 60 */ "ccons ::= DEFAULT MINUS term",
/* 61 */ "ccons ::= DEFAULT id",
/* 62 */ "ccons ::= NULL onconf",
/* 63 */ "ccons ::= NOT NULL onconf",
/* 64 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
/* 65 */ "ccons ::= UNIQUE onconf",
/* 66 */ "ccons ::= CHECK LP expr RP",
/* 67 */ "ccons ::= REFERENCES nm idxlist_opt refargs",
/* 68 */ "ccons ::= defer_subclause",
/* 69 */ "ccons ::= COLLATE ids",
/* 70 */ "autoinc ::=",
/* 71 */ "autoinc ::= AUTOINCR",
/* 72 */ "refargs ::=",
/* 73 */ "refargs ::= refargs refarg",
/* 74 */ "refarg ::= MATCH nm",
/* 75 */ "refarg ::= ON INSERT refact",
/* 76 */ "refarg ::= ON DELETE refact",
/* 77 */ "refarg ::= ON UPDATE refact",
/* 78 */ "refact ::= SET NULL",
/* 79 */ "refact ::= SET DEFAULT",
/* 80 */ "refact ::= CASCADE",
/* 81 */ "refact ::= RESTRICT",
/* 82 */ "refact ::= NO ACTION",
/* 83 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
/* 84 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
/* 85 */ "init_deferred_pred_opt ::=",
/* 86 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
/* 87 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
/* 88 */ "conslist_opt ::=",
/* 89 */ "conslist_opt ::= COMMA conslist",
/* 90 */ "conslist ::= conslist COMMA tcons",
/* 91 */ "conslist ::= conslist tcons",
/* 92 */ "conslist ::= tcons",
/* 93 */ "tcons ::= CONSTRAINT nm",
/* 94 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf",
/* 95 */ "tcons ::= UNIQUE LP idxlist RP onconf",
/* 96 */ "tcons ::= CHECK LP expr RP onconf",
/* 97 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt",
/* 98 */ "defer_subclause_opt ::=",
/* 99 */ "defer_subclause_opt ::= defer_subclause",
/* 100 */ "onconf ::=",
/* 101 */ "onconf ::= ON CONFLICT resolvetype",
/* 102 */ "orconf ::=",
/* 103 */ "orconf ::= OR resolvetype",
/* 104 */ "resolvetype ::= raisetype",
/* 105 */ "resolvetype ::= IGNORE",
/* 106 */ "resolvetype ::= REPLACE",
/* 107 */ "cmd ::= DROP TABLE ifexists fullname",
/* 108 */ "ifexists ::= IF EXISTS",
/* 109 */ "ifexists ::=",
/* 110 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select",
/* 111 */ "cmd ::= DROP VIEW ifexists fullname",
/* 112 */ "cmd ::= select",
/* 113 */ "select ::= oneselect",
/* 114 */ "select ::= select multiselect_op oneselect",
/* 115 */ "multiselect_op ::= UNION",
/* 116 */ "multiselect_op ::= UNION ALL",
/* 117 */ "multiselect_op ::= EXCEPT|INTERSECT",
/* 118 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
/* 119 */ "distinct ::= DISTINCT",
/* 120 */ "distinct ::= ALL",
/* 121 */ "distinct ::=",
/* 122 */ "sclp ::= selcollist COMMA",
/* 123 */ "sclp ::=",
/* 124 */ "selcollist ::= sclp expr as",
/* 125 */ "selcollist ::= sclp STAR",
/* 126 */ "selcollist ::= sclp nm DOT STAR",
/* 127 */ "as ::= AS nm",
/* 128 */ "as ::= ids",
/* 129 */ "as ::=",
/* 130 */ "from ::=",
/* 131 */ "from ::= FROM seltablist",
/* 132 */ "stl_prefix ::= seltablist joinop",
/* 133 */ "stl_prefix ::=",
/* 134 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
/* 135 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
/* 136 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
/* 137 */ "dbnm ::=",
/* 138 */ "dbnm ::= DOT nm",
/* 139 */ "fullname ::= nm dbnm",
/* 140 */ "joinop ::= COMMA|JOIN",
/* 141 */ "joinop ::= JOIN_KW JOIN",
/* 142 */ "joinop ::= JOIN_KW nm JOIN",
/* 143 */ "joinop ::= JOIN_KW nm nm JOIN",
/* 144 */ "on_opt ::= ON expr",
/* 145 */ "on_opt ::=",
/* 146 */ "indexed_opt ::=",
/* 147 */ "indexed_opt ::= INDEXED BY nm",
/* 148 */ "indexed_opt ::= NOT INDEXED",
/* 149 */ "using_opt ::= USING LP inscollist RP",
/* 150 */ "using_opt ::=",
/* 151 */ "orderby_opt ::=",
/* 152 */ "orderby_opt ::= ORDER BY sortlist",
/* 153 */ "sortlist ::= sortlist COMMA sortitem sortorder",
/* 154 */ "sortlist ::= sortitem sortorder",
/* 155 */ "sortitem ::= expr",
/* 156 */ "sortorder ::= ASC",
/* 157 */ "sortorder ::= DESC",
/* 158 */ "sortorder ::=",
/* 159 */ "groupby_opt ::=",
/* 160 */ "groupby_opt ::= GROUP BY nexprlist",
/* 161 */ "having_opt ::=",
/* 162 */ "having_opt ::= HAVING expr",
/* 163 */ "limit_opt ::=",
/* 164 */ "limit_opt ::= LIMIT expr",
/* 165 */ "limit_opt ::= LIMIT expr OFFSET expr",
/* 166 */ "limit_opt ::= LIMIT expr COMMA expr",
/* 167 */ "cmd ::= DELETE FROM fullname indexed_opt where_opt",
/* 168 */ "where_opt ::=",
/* 169 */ "where_opt ::= WHERE expr",
/* 170 */ "cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt",
/* 171 */ "setlist ::= setlist COMMA nm EQ expr",
/* 172 */ "setlist ::= nm EQ expr",
/* 173 */ "cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP",
/* 174 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select",
/* 175 */ "cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES",
/* 176 */ "insert_cmd ::= INSERT orconf",
/* 177 */ "insert_cmd ::= REPLACE",
/* 178 */ "itemlist ::= itemlist COMMA expr",
/* 179 */ "itemlist ::= expr",
/* 180 */ "inscollist_opt ::=",
/* 181 */ "inscollist_opt ::= LP inscollist RP",
/* 182 */ "inscollist ::= inscollist COMMA nm",
/* 183 */ "inscollist ::= nm",
/* 184 */ "expr ::= term",
/* 185 */ "expr ::= LP expr RP",
/* 186 */ "term ::= NULL",
/* 187 */ "expr ::= id",
/* 188 */ "expr ::= JOIN_KW",
/* 189 */ "expr ::= nm DOT nm",
/* 190 */ "expr ::= nm DOT nm DOT nm",
/* 191 */ "term ::= INTEGER|FLOAT|BLOB",
/* 192 */ "term ::= STRING",
/* 193 */ "expr ::= REGISTER",
/* 194 */ "expr ::= VARIABLE",
/* 195 */ "expr ::= expr COLLATE ids",
/* 196 */ "expr ::= CAST LP expr AS typetoken RP",
/* 197 */ "expr ::= ID LP distinct exprlist RP",
/* 198 */ "expr ::= ID LP STAR RP",
/* 199 */ "term ::= CTIME_KW",
/* 200 */ "expr ::= expr AND expr",
/* 201 */ "expr ::= expr OR expr",
/* 202 */ "expr ::= expr LT|GT|GE|LE expr",
/* 203 */ "expr ::= expr EQ|NE expr",
/* 204 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
/* 205 */ "expr ::= expr PLUS|MINUS expr",
/* 206 */ "expr ::= expr STAR|SLASH|REM expr",
/* 207 */ "expr ::= expr CONCAT expr",
/* 208 */ "likeop ::= LIKE_KW",
/* 209 */ "likeop ::= NOT LIKE_KW",
/* 210 */ "likeop ::= MATCH",
/* 211 */ "likeop ::= NOT MATCH",
/* 212 */ "expr ::= expr likeop expr",
/* 213 */ "expr ::= expr likeop expr ESCAPE expr",
/* 214 */ "expr ::= expr ISNULL|NOTNULL",
/* 215 */ "expr ::= expr NOT NULL",
/* 216 */ "expr ::= expr IS expr",
/* 217 */ "expr ::= expr IS NOT expr",
/* 218 */ "expr ::= NOT expr",
/* 219 */ "expr ::= BITNOT expr",
/* 220 */ "expr ::= MINUS expr",
/* 221 */ "expr ::= PLUS expr",
/* 222 */ "between_op ::= BETWEEN",
/* 223 */ "between_op ::= NOT BETWEEN",
/* 224 */ "expr ::= expr between_op expr AND expr",
/* 225 */ "in_op ::= IN",
/* 226 */ "in_op ::= NOT IN",
/* 227 */ "expr ::= expr in_op LP exprlist RP",
/* 228 */ "expr ::= LP select RP",
/* 229 */ "expr ::= expr in_op LP select RP",
/* 230 */ "expr ::= expr in_op nm dbnm",
/* 231 */ "expr ::= EXISTS LP select RP",
/* 232 */ "expr ::= CASE case_operand case_exprlist case_else END",
/* 233 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
/* 234 */ "case_exprlist ::= WHEN expr THEN expr",
/* 235 */ "case_else ::= ELSE expr",
/* 236 */ "case_else ::=",
/* 237 */ "case_operand ::= expr",
/* 238 */ "case_operand ::=",
/* 239 */ "exprlist ::= nexprlist",
/* 240 */ "exprlist ::=",
/* 241 */ "nexprlist ::= nexprlist COMMA expr",
/* 242 */ "nexprlist ::= expr",
/* 243 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP",
/* 244 */ "uniqueflag ::= UNIQUE",
/* 245 */ "uniqueflag ::=",
/* 246 */ "idxlist_opt ::=",
/* 247 */ "idxlist_opt ::= LP idxlist RP",
/* 248 */ "idxlist ::= idxlist COMMA nm collate sortorder",
/* 249 */ "idxlist ::= nm collate sortorder",
/* 250 */ "collate ::=",
/* 251 */ "collate ::= COLLATE ids",
/* 252 */ "cmd ::= DROP INDEX ifexists fullname",
/* 253 */ "cmd ::= PRAGMA nm dbnm",
/* 254 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
/* 255 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
/* 256 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
/* 257 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
/* 258 */ "nmnum ::= plus_num",
/* 259 */ "nmnum ::= nm",
/* 260 */ "nmnum ::= ON",
/* 261 */ "nmnum ::= DELETE",
/* 262 */ "nmnum ::= DEFAULT",
/* 263 */ "plus_num ::= plus_opt number",
/* 264 */ "minus_num ::= MINUS number",
/* 265 */ "number ::= INTEGER|FLOAT",
/* 266 */ "plus_opt ::= PLUS",
/* 267 */ "plus_opt ::=",
/* 268 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
/* 269 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
/* 270 */ "trigger_time ::= BEFORE",
/* 271 */ "trigger_time ::= AFTER",
/* 272 */ "trigger_time ::= INSTEAD OF",
/* 273 */ "trigger_time ::=",
/* 274 */ "trigger_event ::= DELETE|INSERT",
/* 275 */ "trigger_event ::= UPDATE",
/* 276 */ "trigger_event ::= UPDATE OF inscollist",
/* 277 */ "foreach_clause ::=",
/* 278 */ "foreach_clause ::= FOR EACH ROW",
/* 279 */ "when_clause ::=",
/* 280 */ "when_clause ::= WHEN expr",
/* 281 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
/* 282 */ "trigger_cmd_list ::= trigger_cmd SEMI",
/* 283 */ "trnm ::= nm",
/* 284 */ "trnm ::= nm DOT nm",
/* 285 */ "tridxby ::=",
/* 286 */ "tridxby ::= INDEXED BY nm",
/* 287 */ "tridxby ::= NOT INDEXED",
/* 288 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
/* 289 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt VALUES LP itemlist RP",
/* 290 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select",
/* 291 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
/* 292 */ "trigger_cmd ::= select",
/* 293 */ "expr ::= RAISE LP IGNORE RP",
/* 294 */ "expr ::= RAISE LP raisetype COMMA nm RP",
/* 295 */ "raisetype ::= ROLLBACK",
/* 296 */ "raisetype ::= ABORT",
/* 297 */ "raisetype ::= FAIL",
/* 298 */ "cmd ::= DROP TRIGGER ifexists fullname",
/* 299 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
/* 300 */ "cmd ::= DETACH database_kw_opt expr",
/* 301 */ "key_opt ::=",
/* 302 */ "key_opt ::= KEY expr",
/* 303 */ "database_kw_opt ::= DATABASE",
/* 304 */ "database_kw_opt ::=",
/* 305 */ "cmd ::= REINDEX",
/* 306 */ "cmd ::= REINDEX nm dbnm",
/* 307 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
/* 308 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column",
/* 309 */ "add_column_fullname ::= fullname",
/* 310 */ "kwcolumn_opt ::=",
/* 311 */ "kwcolumn_opt ::= COLUMNKW",
};
#endif /* NDEBUG */
#if YYSTACKDEPTH<=0
/*
** Try to increase the size of the parser stack.
*/
static void yyGrowStack(yyParser *p){
int newSize;
yyStackEntry *pNew;
newSize = p->yystksz*2 + 100;
pNew = realloc(p->yystack, newSize*sizeof(pNew[0]));
if( pNew ){
p->yystack = pNew;
p->yystksz = newSize;
#ifndef NDEBUG
if( yyTraceFILE ){
fprintf(yyTraceFILE,"%sStack grows to %d entries!\n",
yyTracePrompt, p->yystksz);
}
#endif
}
}
#endif
/*
** 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 sqlite4Parser and sqlite4ParserFree.
*/
SQLITE_PRIVATE void *sqlite4ParserAlloc(void *(*mallocProc)(void*,size_t), void *pEnv){
yyParser *pParser;
pParser = (yyParser*)(*mallocProc)(pEnv, (size_t)sizeof(yyParser) );
if( pParser ){
pParser->yyidx = -1;
#ifdef YYTRACKMAXSTACKDEPTH
pParser->yyidxMax = 0;
#endif
#if YYSTACKDEPTH<=0
pParser->yystack = NULL;
pParser->yystksz = 0;
yyGrowStack(pParser);
#endif
pParser->pEnv = pEnv;
}
return pParser;
}
/* The following function deletes the 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.
*/
static void yy_destructor(
yyParser *yypParser, /* The parser */
YYCODETYPE yymajor, /* Type code for object to destroy */
YYMINORTYPE *yypminor /* The object to be destroyed */
){
sqlite4ParserARG_FETCH;
switch( yymajor ){
/* 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.
*/
case 159: /* select */
case 193: /* oneselect */
{
sqlite4SelectDelete(pParse->db, (yypminor->yy149));
}
break;
case 173: /* term */
case 174: /* expr */
{
sqlite4ExprDelete(pParse->db, (yypminor->yy132).pExpr);
}
break;
case 178: /* idxlist_opt */
case 186: /* idxlist */
case 196: /* selcollist */
case 199: /* groupby_opt */
case 201: /* orderby_opt */
case 203: /* sclp */
case 213: /* sortlist */
case 215: /* nexprlist */
case 216: /* setlist */
case 219: /* itemlist */
case 220: /* exprlist */
case 225: /* case_exprlist */
{
sqlite4ExprListDelete(pParse->db, (yypminor->yy462));
}
break;
case 192: /* fullname */
case 197: /* from */
case 205: /* seltablist */
case 206: /* stl_prefix */
{
sqlite4SrcListDelete(pParse->db, (yypminor->yy287));
}
break;
case 198: /* where_opt */
case 200: /* having_opt */
case 209: /* on_opt */
case 214: /* sortitem */
case 224: /* case_operand */
case 226: /* case_else */
case 237: /* when_clause */
case 242: /* key_opt */
{
sqlite4ExprDelete(pParse->db, (yypminor->yy342));
}
break;
case 210: /* using_opt */
case 212: /* inscollist */
case 218: /* inscollist_opt */
{
sqlite4IdListDelete(pParse->db, (yypminor->yy440));
}
break;
case 233: /* trigger_cmd_list */
case 238: /* trigger_cmd */
{
sqlite4DeleteTriggerStep(pParse->db, (yypminor->yy7));
}
break;
case 235: /* trigger_event */
{
sqlite4IdListDelete(pParse->db, (yypminor->yy160).b);
}
break;
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.
**
** Return the major token number for the symbol popped.
*/
static int yy_pop_parser_stack(yyParser *pParser){
YYCODETYPE yymajor;
yyStackEntry *yytos = &pParser->yystack[pParser->yyidx];
/* There is no mechanism by which the parser stack can be popped below
** empty in SQLite. */
if( NEVER(pParser->yyidx<0) ) return 0;
#ifndef NDEBUG
if( yyTraceFILE && pParser->yyidx>=0 ){
fprintf(yyTraceFILE,"%sPopping %s\n",
yyTracePrompt,
yyTokenName[yytos->major]);
}
#endif
yymajor = yytos->major;
yy_destructor(pParser, yymajor, &yytos->minor);
pParser->yyidx--;
return yymajor;
}
/*
** Deallocate and destroy a parser. Destructors are all called for
** all stack elements before shutting the parser down.
**
** Inputs:
** <ul>
** <li> A pointer to the parser. This should be a pointer
** obtained from sqlite4ParserAlloc.
** <li> A pointer to a function used to reclaim memory obtained
** from malloc.
** </ul>
*/
SQLITE_PRIVATE void sqlite4ParserFree(
void *p, /* The parser to be deleted */
void (*freeProc)(void*,void*) /* Function used to reclaim memory */
){
yyParser *pParser = (yyParser*)p;
/* In SQLite, we never try to destroy a parser that was not successfully
** created in the first place. */
if( NEVER(pParser==0) ) return;
while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser);
#if YYSTACKDEPTH<=0
free(pParser->yystack);
#endif
(*freeProc)(pParser->pEnv, (void*)pParser);
}
/*
** Return the peak depth of the stack for a parser.
*/
#ifdef YYTRACKMAXSTACKDEPTH
SQLITE_PRIVATE int sqlite4ParserStackPeak(void *p){
yyParser *pParser = (yyParser*)p;
return pParser->yyidxMax;
}
#endif
/*
** Find the appropriate action for a parser given the terminal
** look-ahead token iLookAhead.
**
** If the look-ahead token is YYNOCODE, then check to see if the action is
** independent of the look-ahead. If it is, return the action, otherwise
** return YY_NO_ACTION.
*/
static int yy_find_shift_action(
yyParser *pParser, /* The parser */
YYCODETYPE iLookAhead /* The look-ahead token */
){
int i;
int stateno = pParser->yystack[pParser->yyidx].stateno;
if( stateno>YY_SHIFT_COUNT
|| (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){
return yy_default[stateno];
}
assert( iLookAhead!=YYNOCODE );
i += iLookAhead;
if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
if( iLookAhead>0 ){
#ifdef YYFALLBACK
YYCODETYPE iFallback; /* Fallback token */
if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
&& (iFallback = yyFallback[iLookAhead])!=0 ){
#ifndef NDEBUG
if( yyTraceFILE ){
fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n",
yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
}
#endif
return yy_find_shift_action(pParser, iFallback);
}
#endif
#ifdef YYWILDCARD
{
int j = i - iLookAhead + YYWILDCARD;
if(
#if YY_SHIFT_MIN+YYWILDCARD<0
j>=0 &&
#endif
#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT
j<YY_ACTTAB_COUNT &&
#endif
yy_lookahead[j]==YYWILDCARD
){
#ifndef NDEBUG
if( yyTraceFILE ){
fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n",
yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]);
}
#endif /* NDEBUG */
return yy_action[j];
}
}
#endif /* YYWILDCARD */
}
return yy_default[stateno];
}else{
return yy_action[i];
}
}
/*
** Find the appropriate action for a parser given the non-terminal
** look-ahead token iLookAhead.
**
** If the look-ahead token is YYNOCODE, then check to see if the action is
** independent of the look-ahead. If it is, return the action, otherwise
** return YY_NO_ACTION.
*/
static int yy_find_reduce_action(
int stateno, /* Current state number */
YYCODETYPE iLookAhead /* The look-ahead token */
){
int i;
#ifdef YYERRORSYMBOL
if( stateno>YY_REDUCE_COUNT ){
return yy_default[stateno];
}
#else
assert( stateno<=YY_REDUCE_COUNT );
#endif
i = yy_reduce_ofst[stateno];
assert( i!=YY_REDUCE_USE_DFLT );
assert( iLookAhead!=YYNOCODE );
i += iLookAhead;
#ifdef YYERRORSYMBOL
if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
return yy_default[stateno];
}
#else
assert( i>=0 && i<YY_ACTTAB_COUNT );
assert( yy_lookahead[i]==iLookAhead );
#endif
return yy_action[i];
}
/*
** The following routine is called if the stack overflows.
*/
static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){
sqlite4ParserARG_FETCH;
yypParser->yyidx--;
#ifndef NDEBUG
if( yyTraceFILE ){
fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
}
#endif
while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
/* Here code is inserted which will execute if the parser
** stack every overflows */
UNUSED_PARAMETER(yypMinor); /* Silence some compiler warnings */
sqlite4ErrorMsg(pParse, "parser stack overflow");
sqlite4ParserARG_STORE; /* Suppress warning about unused %extra_argument var */
}
/*
** Perform a shift action.
*/
static void yy_shift(
yyParser *yypParser, /* The parser to be shifted */
int yyNewState, /* The new state to shift in */
int yyMajor, /* The major token to shift in */
YYMINORTYPE *yypMinor /* Pointer to the minor token to shift in */
){
yyStackEntry *yytos;
yypParser->yyidx++;
#ifdef YYTRACKMAXSTACKDEPTH
if( yypParser->yyidx>yypParser->yyidxMax ){
yypParser->yyidxMax = yypParser->yyidx;
}
#endif
#if YYSTACKDEPTH>0
if( yypParser->yyidx>=YYSTACKDEPTH ){
yyStackOverflow(yypParser, yypMinor);
return;
}
#else
if( yypParser->yyidx>=yypParser->yystksz ){
yyGrowStack(yypParser);
if( yypParser->yyidx>=yypParser->yystksz ){
yyStackOverflow(yypParser, yypMinor);
return;
}
}
#endif
yytos = &yypParser->yystack[yypParser->yyidx];
yytos->stateno = (YYACTIONTYPE)yyNewState;
yytos->major = (YYCODETYPE)yyMajor;
yytos->minor = *yypMinor;
#ifndef NDEBUG
if( yyTraceFILE && yypParser->yyidx>0 ){
int i;
fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState);
fprintf(yyTraceFILE,"%sStack:",yyTracePrompt);
for(i=1; i<=yypParser->yyidx; i++)
fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]);
fprintf(yyTraceFILE,"\n");
}
#endif
}
/* The following table contains information about every rule that
** is used during the reduce.
*/
static const struct {
YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
unsigned char nrhs; /* Number of right-hand side symbols in the rule */
} yyRuleInfo[] = {
{ 141, 1 },
{ 142, 2 },
{ 142, 1 },
{ 143, 1 },
{ 143, 3 },
{ 144, 0 },
{ 144, 1 },
{ 144, 3 },
{ 145, 1 },
{ 146, 3 },
{ 148, 0 },
{ 148, 1 },
{ 148, 2 },
{ 147, 0 },
{ 147, 1 },
{ 147, 1 },
{ 147, 1 },
{ 146, 2 },
{ 146, 2 },
{ 146, 2 },
{ 150, 1 },
{ 150, 0 },
{ 146, 2 },
{ 146, 3 },
{ 146, 5 },
{ 146, 2 },
{ 151, 6 },
{ 153, 1 },
{ 155, 0 },
{ 155, 3 },
{ 154, 1 },
{ 154, 0 },
{ 152, 4 },
{ 152, 2 },
{ 157, 3 },
{ 157, 1 },
{ 160, 3 },
{ 161, 1 },
{ 164, 1 },
{ 164, 1 },
{ 165, 1 },
{ 149, 1 },
{ 149, 1 },
{ 149, 1 },
{ 162, 0 },
{ 162, 1 },
{ 166, 1 },
{ 166, 4 },
{ 166, 6 },
{ 167, 1 },
{ 167, 2 },
{ 168, 1 },
{ 168, 1 },
{ 163, 2 },
{ 163, 0 },
{ 171, 3 },
{ 171, 1 },
{ 172, 2 },
{ 172, 4 },
{ 172, 3 },
{ 172, 3 },
{ 172, 2 },
{ 172, 2 },
{ 172, 3 },
{ 172, 5 },
{ 172, 2 },
{ 172, 4 },
{ 172, 4 },
{ 172, 1 },
{ 172, 2 },
{ 177, 0 },
{ 177, 1 },
{ 179, 0 },
{ 179, 2 },
{ 181, 2 },
{ 181, 3 },
{ 181, 3 },
{ 181, 3 },
{ 182, 2 },
{ 182, 2 },
{ 182, 1 },
{ 182, 1 },
{ 182, 2 },
{ 180, 3 },
{ 180, 2 },
{ 183, 0 },
{ 183, 2 },
{ 183, 2 },
{ 158, 0 },
{ 158, 2 },
{ 184, 3 },
{ 184, 2 },
{ 184, 1 },
{ 185, 2 },
{ 185, 7 },
{ 185, 5 },
{ 185, 5 },
{ 185, 10 },
{ 187, 0 },
{ 187, 1 },
{ 175, 0 },
{ 175, 3 },
{ 188, 0 },
{ 188, 2 },
{ 189, 1 },
{ 189, 1 },
{ 189, 1 },
{ 146, 4 },
{ 191, 2 },
{ 191, 0 },
{ 146, 8 },
{ 146, 4 },
{ 146, 1 },
{ 159, 1 },
{ 159, 3 },
{ 194, 1 },
{ 194, 2 },
{ 194, 1 },
{ 193, 9 },
{ 195, 1 },
{ 195, 1 },
{ 195, 0 },
{ 203, 2 },
{ 203, 0 },
{ 196, 3 },
{ 196, 2 },
{ 196, 4 },
{ 204, 2 },
{ 204, 1 },
{ 204, 0 },
{ 197, 0 },
{ 197, 2 },
{ 206, 2 },
{ 206, 0 },
{ 205, 7 },
{ 205, 7 },
{ 205, 7 },
{ 156, 0 },
{ 156, 2 },
{ 192, 2 },
{ 207, 1 },
{ 207, 2 },
{ 207, 3 },
{ 207, 4 },
{ 209, 2 },
{ 209, 0 },
{ 208, 0 },
{ 208, 3 },
{ 208, 2 },
{ 210, 4 },
{ 210, 0 },
{ 201, 0 },
{ 201, 3 },
{ 213, 4 },
{ 213, 2 },
{ 214, 1 },
{ 176, 1 },
{ 176, 1 },
{ 176, 0 },
{ 199, 0 },
{ 199, 3 },
{ 200, 0 },
{ 200, 2 },
{ 202, 0 },
{ 202, 2 },
{ 202, 4 },
{ 202, 4 },
{ 146, 5 },
{ 198, 0 },
{ 198, 2 },
{ 146, 7 },
{ 216, 5 },
{ 216, 3 },
{ 146, 8 },
{ 146, 5 },
{ 146, 6 },
{ 217, 2 },
{ 217, 1 },
{ 219, 3 },
{ 219, 1 },
{ 218, 0 },
{ 218, 3 },
{ 212, 3 },
{ 212, 1 },
{ 174, 1 },
{ 174, 3 },
{ 173, 1 },
{ 174, 1 },
{ 174, 1 },
{ 174, 3 },
{ 174, 5 },
{ 173, 1 },
{ 173, 1 },
{ 174, 1 },
{ 174, 1 },
{ 174, 3 },
{ 174, 6 },
{ 174, 5 },
{ 174, 4 },
{ 173, 1 },
{ 174, 3 },
{ 174, 3 },
{ 174, 3 },
{ 174, 3 },
{ 174, 3 },
{ 174, 3 },
{ 174, 3 },
{ 174, 3 },
{ 221, 1 },
{ 221, 2 },
{ 221, 1 },
{ 221, 2 },
{ 174, 3 },
{ 174, 5 },
{ 174, 2 },
{ 174, 3 },
{ 174, 3 },
{ 174, 4 },
{ 174, 2 },
{ 174, 2 },
{ 174, 2 },
{ 174, 2 },
{ 222, 1 },
{ 222, 2 },
{ 174, 5 },
{ 223, 1 },
{ 223, 2 },
{ 174, 5 },
{ 174, 3 },
{ 174, 5 },
{ 174, 4 },
{ 174, 4 },
{ 174, 5 },
{ 225, 5 },
{ 225, 4 },
{ 226, 2 },
{ 226, 0 },
{ 224, 1 },
{ 224, 0 },
{ 220, 1 },
{ 220, 0 },
{ 215, 3 },
{ 215, 1 },
{ 146, 11 },
{ 227, 1 },
{ 227, 0 },
{ 178, 0 },
{ 178, 3 },
{ 186, 5 },
{ 186, 3 },
{ 228, 0 },
{ 228, 2 },
{ 146, 4 },
{ 146, 3 },
{ 146, 5 },
{ 146, 6 },
{ 146, 5 },
{ 146, 6 },
{ 229, 1 },
{ 229, 1 },
{ 229, 1 },
{ 229, 1 },
{ 229, 1 },
{ 169, 2 },
{ 170, 2 },
{ 231, 1 },
{ 230, 1 },
{ 230, 0 },
{ 146, 5 },
{ 232, 11 },
{ 234, 1 },
{ 234, 1 },
{ 234, 2 },
{ 234, 0 },
{ 235, 1 },
{ 235, 1 },
{ 235, 3 },
{ 236, 0 },
{ 236, 3 },
{ 237, 0 },
{ 237, 2 },
{ 233, 3 },
{ 233, 2 },
{ 239, 1 },
{ 239, 3 },
{ 240, 0 },
{ 240, 3 },
{ 240, 2 },
{ 238, 7 },
{ 238, 8 },
{ 238, 5 },
{ 238, 5 },
{ 238, 1 },
{ 174, 4 },
{ 174, 6 },
{ 190, 1 },
{ 190, 1 },
{ 190, 1 },
{ 146, 4 },
{ 146, 6 },
{ 146, 3 },
{ 242, 0 },
{ 242, 2 },
{ 241, 1 },
{ 241, 0 },
{ 146, 1 },
{ 146, 3 },
{ 146, 6 },
{ 146, 6 },
{ 243, 1 },
{ 244, 0 },
{ 244, 1 },
};
static void yy_accept(yyParser*); /* Forward Declaration */
/*
** Perform a reduce action and the shift that must immediately
** follow the reduce.
*/
static void yy_reduce(
yyParser *yypParser, /* The parser */
int yyruleno /* Number of the rule by which to reduce */
){
int yygoto; /* The next state */
int yyact; /* The next action */
YYMINORTYPE yygotominor; /* The LHS of the rule reduced */
yyStackEntry *yymsp; /* The top of the parser's stack */
int yysize; /* Amount to pop the stack */
sqlite4ParserARG_FETCH;
yymsp = &yypParser->yystack[yypParser->yyidx];
#ifndef NDEBUG
if( yyTraceFILE && yyruleno>=0
&& yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
yyRuleName[yyruleno]);
}
#endif /* NDEBUG */
/* Silence complaints from purify about yygotominor being uninitialized
** in some cases when it is copied into the stack after the following
** switch. yygotominor is uninitialized when a rule reduces that does
** not set the value of its left-hand side nonterminal. Leaving the
** value of the nonterminal uninitialized is utterly harmless as long
** as the value is never used. So really the only thing this code
** accomplishes is to quieten purify.
**
** 2007-01-16: The wireshark project (www.wireshark.org) reports that
** without this code, their parser segfaults. I'm not sure what there
** parser is doing to make this happen. This is the second bug report
** from wireshark this week. Clearly they are stressing Lemon in ways
** that it has not been previously stressed... (SQLite ticket #2172)
*/
/*memset(&yygotominor, 0, sizeof(yygotominor));*/
yygotominor = yyzerominor;
switch( yyruleno ){
/* Beginning here are the reduction cases. A typical example
** follows:
** case 0:
** #line <lineno> <grammarfile>
** { ... } // User supplied code
** #line <lineno> <thisfile>
** break;
*/
case 5: /* explain ::= */
{ sqlite4BeginParse(pParse, 0); }
break;
case 6: /* explain ::= EXPLAIN */
{ sqlite4BeginParse(pParse, 1); }
break;
case 7: /* explain ::= EXPLAIN QUERY PLAN */
{ sqlite4BeginParse(pParse, 2); }
break;
case 8: /* cmdx ::= cmd */
{ sqlite4FinishCoding(pParse); }
break;
case 9: /* cmd ::= BEGIN transtype trans_opt */
{sqlite4BeginTransaction(pParse, yymsp[-1].minor.yy32);}
break;
case 13: /* transtype ::= */
{yygotominor.yy32 = TK_DEFERRED;}
break;
case 14: /* transtype ::= DEFERRED */
case 15: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==15);
case 16: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==16);
case 115: /* multiselect_op ::= UNION */ yytestcase(yyruleno==115);
case 117: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==117);
{yygotominor.yy32 = yymsp[0].major;}
break;
case 17: /* cmd ::= COMMIT trans_opt */
case 18: /* cmd ::= END trans_opt */ yytestcase(yyruleno==18);
{sqlite4EndTransaction(pParse, SAVEPOINT_RELEASE);}
break;
case 19: /* cmd ::= ROLLBACK trans_opt */
{sqlite4EndTransaction(pParse, SAVEPOINT_ROLLBACK);}
break;
case 22: /* cmd ::= SAVEPOINT nm */
{
sqlite4Savepoint(pParse, SAVEPOINT_BEGIN, &yymsp[0].minor.yy0);
}
break;
case 23: /* cmd ::= RELEASE savepoint_opt nm */
{
sqlite4Savepoint(pParse, SAVEPOINT_RELEASE, &yymsp[0].minor.yy0);
}
break;
case 24: /* cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
{
sqlite4Savepoint(pParse, SAVEPOINT_ROLLBACK, &yymsp[0].minor.yy0);
}
break;
case 26: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
{
sqlite4StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy32,0,0,yymsp[-2].minor.yy32);
}
break;
case 27: /* createkw ::= CREATE */
{
pParse->db->lookaside.bEnabled = 0;
yygotominor.yy0 = yymsp[0].minor.yy0;
}
break;
case 28: /* ifnotexists ::= */
case 31: /* temp ::= */ yytestcase(yyruleno==31);
case 70: /* autoinc ::= */ yytestcase(yyruleno==70);
case 83: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==83);
case 85: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==85);
case 87: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==87);
case 98: /* defer_subclause_opt ::= */ yytestcase(yyruleno==98);
case 109: /* ifexists ::= */ yytestcase(yyruleno==109);
case 120: /* distinct ::= ALL */ yytestcase(yyruleno==120);
case 121: /* distinct ::= */ yytestcase(yyruleno==121);
case 222: /* between_op ::= BETWEEN */ yytestcase(yyruleno==222);
case 225: /* in_op ::= IN */ yytestcase(yyruleno==225);
{yygotominor.yy32 = 0;}
break;
case 29: /* ifnotexists ::= IF NOT EXISTS */
case 30: /* temp ::= TEMP */ yytestcase(yyruleno==30);
case 71: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==71);
case 86: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==86);
case 108: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==108);
case 119: /* distinct ::= DISTINCT */ yytestcase(yyruleno==119);
case 223: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==223);
case 226: /* in_op ::= NOT IN */ yytestcase(yyruleno==226);
{yygotominor.yy32 = 1;}
break;
case 32: /* create_table_args ::= LP columnlist conslist_opt RP */
{
sqlite4EndTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0);
}
break;
case 33: /* create_table_args ::= AS select */
{
sqlite4EndTable(pParse,0,0,yymsp[0].minor.yy149);
sqlite4SelectDelete(pParse->db, yymsp[0].minor.yy149);
}
break;
case 36: /* column ::= columnid type carglist */
{
yygotominor.yy0.z = yymsp[-2].minor.yy0.z;
yygotominor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-2].minor.yy0.z) + pParse->sLastToken.n;
}
break;
case 37: /* columnid ::= nm */
{
sqlite4AddColumn(pParse,&yymsp[0].minor.yy0);
yygotominor.yy0 = yymsp[0].minor.yy0;
}
break;
case 38: /* id ::= ID */
case 39: /* id ::= INDEXED */ yytestcase(yyruleno==39);
case 40: /* ids ::= ID|STRING */ yytestcase(yyruleno==40);
case 41: /* nm ::= id */ yytestcase(yyruleno==41);
case 42: /* nm ::= STRING */ yytestcase(yyruleno==42);
case 43: /* nm ::= JOIN_KW */ yytestcase(yyruleno==43);
case 46: /* typetoken ::= typename */ yytestcase(yyruleno==46);
case 49: /* typename ::= ids */ yytestcase(yyruleno==49);
case 127: /* as ::= AS nm */ yytestcase(yyruleno==127);
case 128: /* as ::= ids */ yytestcase(yyruleno==128);
case 138: /* dbnm ::= DOT nm */ yytestcase(yyruleno==138);
case 147: /* indexed_opt ::= INDEXED BY nm */ yytestcase(yyruleno==147);
case 251: /* collate ::= COLLATE ids */ yytestcase(yyruleno==251);
case 258: /* nmnum ::= plus_num */ yytestcase(yyruleno==258);
case 259: /* nmnum ::= nm */ yytestcase(yyruleno==259);
case 260: /* nmnum ::= ON */ yytestcase(yyruleno==260);
case 261: /* nmnum ::= DELETE */ yytestcase(yyruleno==261);
case 262: /* nmnum ::= DEFAULT */ yytestcase(yyruleno==262);
case 263: /* plus_num ::= plus_opt number */ yytestcase(yyruleno==263);
case 264: /* minus_num ::= MINUS number */ yytestcase(yyruleno==264);
case 265: /* number ::= INTEGER|FLOAT */ yytestcase(yyruleno==265);
case 283: /* trnm ::= nm */ yytestcase(yyruleno==283);
{yygotominor.yy0 = yymsp[0].minor.yy0;}
break;
case 45: /* type ::= typetoken */
{sqlite4AddColumnType(pParse,&yymsp[0].minor.yy0);}
break;
case 47: /* typetoken ::= typename LP signed RP */
{
yygotominor.yy0.z = yymsp[-3].minor.yy0.z;
yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z);
}
break;
case 48: /* typetoken ::= typename LP signed COMMA signed RP */
{
yygotominor.yy0.z = yymsp[-5].minor.yy0.z;
yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z);
}
break;
case 50: /* typename ::= typename ids */
{yygotominor.yy0.z=yymsp[-1].minor.yy0.z; yygotominor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);}
break;
case 57: /* ccons ::= DEFAULT term */
case 59: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==59);
{sqlite4AddDefaultValue(pParse,&yymsp[0].minor.yy132);}
break;
case 58: /* ccons ::= DEFAULT LP expr RP */
{sqlite4AddDefaultValue(pParse,&yymsp[-1].minor.yy132);}
break;
case 60: /* ccons ::= DEFAULT MINUS term */
{
ExprSpan v;
v.pExpr = sqlite4PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy132.pExpr, 0, 0);
v.zStart = yymsp[-1].minor.yy0.z;
v.zEnd = yymsp[0].minor.yy132.zEnd;
sqlite4AddDefaultValue(pParse,&v);
}
break;
case 61: /* ccons ::= DEFAULT id */
{
ExprSpan v;
spanExpr(&v, pParse, TK_STRING, &yymsp[0].minor.yy0);
sqlite4AddDefaultValue(pParse,&v);
}
break;
case 63: /* ccons ::= NOT NULL onconf */
{sqlite4AddNotNull(pParse, yymsp[0].minor.yy32);}
break;
case 64: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
{sqlite4AddPrimaryKey(pParse,0,yymsp[-1].minor.yy32,yymsp[0].minor.yy32,yymsp[-2].minor.yy32);}
break;
case 65: /* ccons ::= UNIQUE onconf */
{sqlite4CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy32,0,0,0,0,0);}
break;
case 66: /* ccons ::= CHECK LP expr RP */
{sqlite4AddCheckConstraint(pParse,yymsp[-1].minor.yy132.pExpr);}
break;
case 67: /* ccons ::= REFERENCES nm idxlist_opt refargs */
{sqlite4CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy462,yymsp[0].minor.yy32);}
break;
case 68: /* ccons ::= defer_subclause */
{sqlite4DeferForeignKey(pParse,yymsp[0].minor.yy32);}
break;
case 69: /* ccons ::= COLLATE ids */
{sqlite4AddCollateType(pParse, &yymsp[0].minor.yy0);}
break;
case 72: /* refargs ::= */
{ yygotominor.yy32 = OE_None*0x0101; /* EV: R-19803-45884 */}
break;
case 73: /* refargs ::= refargs refarg */
{ yygotominor.yy32 = (yymsp[-1].minor.yy32 & ~yymsp[0].minor.yy47.mask) | yymsp[0].minor.yy47.value; }
break;
case 74: /* refarg ::= MATCH nm */
case 75: /* refarg ::= ON INSERT refact */ yytestcase(yyruleno==75);
{ yygotominor.yy47.value = 0; yygotominor.yy47.mask = 0x000000; }
break;
case 76: /* refarg ::= ON DELETE refact */
{ yygotominor.yy47.value = yymsp[0].minor.yy32; yygotominor.yy47.mask = 0x0000ff; }
break;
case 77: /* refarg ::= ON UPDATE refact */
{ yygotominor.yy47.value = yymsp[0].minor.yy32<<8; yygotominor.yy47.mask = 0x00ff00; }
break;
case 78: /* refact ::= SET NULL */
{ yygotominor.yy32 = OE_SetNull; /* EV: R-33326-45252 */}
break;
case 79: /* refact ::= SET DEFAULT */
{ yygotominor.yy32 = OE_SetDflt; /* EV: R-33326-45252 */}
break;
case 80: /* refact ::= CASCADE */
{ yygotominor.yy32 = OE_Cascade; /* EV: R-33326-45252 */}
break;
case 81: /* refact ::= RESTRICT */
{ yygotominor.yy32 = OE_Restrict; /* EV: R-33326-45252 */}
break;
case 82: /* refact ::= NO ACTION */
{ yygotominor.yy32 = OE_None; /* EV: R-33326-45252 */}
break;
case 84: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
case 99: /* defer_subclause_opt ::= defer_subclause */ yytestcase(yyruleno==99);
case 101: /* onconf ::= ON CONFLICT resolvetype */ yytestcase(yyruleno==101);
case 104: /* resolvetype ::= raisetype */ yytestcase(yyruleno==104);
{yygotominor.yy32 = yymsp[0].minor.yy32;}
break;
case 88: /* conslist_opt ::= */
{yygotominor.yy0.n = 0; yygotominor.yy0.z = 0;}
break;
case 89: /* conslist_opt ::= COMMA conslist */
{yygotominor.yy0 = yymsp[-1].minor.yy0;}
break;
case 94: /* tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf */
{sqlite4AddPrimaryKey(pParse,yymsp[-3].minor.yy462,yymsp[0].minor.yy32,yymsp[-2].minor.yy32,0);}
break;
case 95: /* tcons ::= UNIQUE LP idxlist RP onconf */
{sqlite4CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy462,yymsp[0].minor.yy32,0,0,0,0,0);}
break;
case 96: /* tcons ::= CHECK LP expr RP onconf */
{sqlite4AddCheckConstraint(pParse,yymsp[-2].minor.yy132.pExpr);}
break;
case 97: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt */
{
sqlite4CreateForeignKey(pParse, yymsp[-6].minor.yy462, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy462, yymsp[-1].minor.yy32);
sqlite4DeferForeignKey(pParse, yymsp[0].minor.yy32);
}
break;
case 100: /* onconf ::= */
{yygotominor.yy32 = OE_Default;}
break;
case 102: /* orconf ::= */
{yygotominor.yy378 = OE_Default;}
break;
case 103: /* orconf ::= OR resolvetype */
{yygotominor.yy378 = (u8)yymsp[0].minor.yy32;}
break;
case 105: /* resolvetype ::= IGNORE */
{yygotominor.yy32 = OE_Ignore;}
break;
case 106: /* resolvetype ::= REPLACE */
{yygotominor.yy32 = OE_Replace;}
break;
case 107: /* cmd ::= DROP TABLE ifexists fullname */
{
sqlite4DropTable(pParse, yymsp[0].minor.yy287, 0, yymsp[-1].minor.yy32);
}
break;
case 110: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select */
{
sqlite4CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy149, yymsp[-6].minor.yy32, yymsp[-4].minor.yy32);
}
break;
case 111: /* cmd ::= DROP VIEW ifexists fullname */
{
sqlite4DropTable(pParse, yymsp[0].minor.yy287, 1, yymsp[-1].minor.yy32);
}
break;
case 112: /* cmd ::= select */
{
SelectDest dest = {SRT_Output, 0, 0, 0, 0};
sqlite4Select(pParse, yymsp[0].minor.yy149, &dest);
sqlite4ExplainBegin(pParse->pVdbe);
sqlite4ExplainSelect(pParse->pVdbe, yymsp[0].minor.yy149);
sqlite4ExplainFinish(pParse->pVdbe);
sqlite4SelectDelete(pParse->db, yymsp[0].minor.yy149);
}
break;
case 113: /* select ::= oneselect */
{yygotominor.yy149 = yymsp[0].minor.yy149;}
break;
case 114: /* select ::= select multiselect_op oneselect */
{
if( yymsp[0].minor.yy149 ){
yymsp[0].minor.yy149->op = (u8)yymsp[-1].minor.yy32;
yymsp[0].minor.yy149->pPrior = yymsp[-2].minor.yy149;
}else{
sqlite4SelectDelete(pParse->db, yymsp[-2].minor.yy149);
}
yygotominor.yy149 = yymsp[0].minor.yy149;
}
break;
case 116: /* multiselect_op ::= UNION ALL */
{yygotominor.yy32 = TK_ALL;}
break;
case 118: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
{
yygotominor.yy149 = sqlite4SelectNew(pParse,yymsp[-6].minor.yy462,yymsp[-5].minor.yy287,yymsp[-4].minor.yy342,yymsp[-3].minor.yy462,yymsp[-2].minor.yy342,yymsp[-1].minor.yy462,yymsp[-7].minor.yy32,yymsp[0].minor.yy474.pLimit,yymsp[0].minor.yy474.pOffset);
}
break;
case 122: /* sclp ::= selcollist COMMA */
case 247: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==247);
{yygotominor.yy462 = yymsp[-1].minor.yy462;}
break;
case 123: /* sclp ::= */
case 151: /* orderby_opt ::= */ yytestcase(yyruleno==151);
case 159: /* groupby_opt ::= */ yytestcase(yyruleno==159);
case 240: /* exprlist ::= */ yytestcase(yyruleno==240);
case 246: /* idxlist_opt ::= */ yytestcase(yyruleno==246);
{yygotominor.yy462 = 0;}
break;
case 124: /* selcollist ::= sclp expr as */
{
yygotominor.yy462 = sqlite4ExprListAppend(pParse, yymsp[-2].minor.yy462, yymsp[-1].minor.yy132.pExpr);
if( yymsp[0].minor.yy0.n>0 ) sqlite4ExprListSetName(pParse, yygotominor.yy462, &yymsp[0].minor.yy0, 1);
sqlite4ExprListSetSpan(pParse,yygotominor.yy462,&yymsp[-1].minor.yy132);
}
break;
case 125: /* selcollist ::= sclp STAR */
{
Expr *p = sqlite4Expr(pParse->db, TK_ALL, 0);
yygotominor.yy462 = sqlite4ExprListAppend(pParse, yymsp[-1].minor.yy462, p);
}
break;
case 126: /* selcollist ::= sclp nm DOT STAR */
{
Expr *pRight = sqlite4PExpr(pParse, TK_ALL, 0, 0, &yymsp[0].minor.yy0);
Expr *pLeft = sqlite4PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *pDot = sqlite4PExpr(pParse, TK_DOT, pLeft, pRight, 0);
yygotominor.yy462 = sqlite4ExprListAppend(pParse,yymsp[-3].minor.yy462, pDot);
}
break;
case 129: /* as ::= */
{yygotominor.yy0.n = 0;}
break;
case 130: /* from ::= */
{yygotominor.yy287 = sqlite4DbMallocZero(pParse->db, sizeof(*yygotominor.yy287));}
break;
case 131: /* from ::= FROM seltablist */
{
yygotominor.yy287 = yymsp[0].minor.yy287;
sqlite4SrcListShiftJoinType(yygotominor.yy287);
}
break;
case 132: /* stl_prefix ::= seltablist joinop */
{
yygotominor.yy287 = yymsp[-1].minor.yy287;
if( ALWAYS(yygotominor.yy287 && yygotominor.yy287->nSrc>0) ) yygotominor.yy287->a[yygotominor.yy287->nSrc-1].jointype = (u8)yymsp[0].minor.yy32;
}
break;
case 133: /* stl_prefix ::= */
{yygotominor.yy287 = 0;}
break;
case 134: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
{
yygotominor.yy287 = sqlite4SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy287,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy342,yymsp[0].minor.yy440);
sqlite4SrcListIndexedBy(pParse, yygotominor.yy287, &yymsp[-2].minor.yy0);
}
break;
case 135: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
{
yygotominor.yy287 = sqlite4SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy287,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy149,yymsp[-1].minor.yy342,yymsp[0].minor.yy440);
}
break;
case 136: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
{
if( yymsp[-6].minor.yy287==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy342==0 && yymsp[0].minor.yy440==0 ){
yygotominor.yy287 = yymsp[-4].minor.yy287;
}else{
Select *pSubquery;
sqlite4SrcListShiftJoinType(yymsp[-4].minor.yy287);
pSubquery = sqlite4SelectNew(pParse,0,yymsp[-4].minor.yy287,0,0,0,0,0,0,0);
yygotominor.yy287 = sqlite4SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy287,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy342,yymsp[0].minor.yy440);
}
}
break;
case 137: /* dbnm ::= */
case 146: /* indexed_opt ::= */ yytestcase(yyruleno==146);
{yygotominor.yy0.z=0; yygotominor.yy0.n=0;}
break;
case 139: /* fullname ::= nm dbnm */
{yygotominor.yy287 = sqlite4SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
break;
case 140: /* joinop ::= COMMA|JOIN */
{ yygotominor.yy32 = JT_INNER; }
break;
case 141: /* joinop ::= JOIN_KW JOIN */
{ yygotominor.yy32 = sqlite4JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
break;
case 142: /* joinop ::= JOIN_KW nm JOIN */
{ yygotominor.yy32 = sqlite4JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); }
break;
case 143: /* joinop ::= JOIN_KW nm nm JOIN */
{ yygotominor.yy32 = sqlite4JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); }
break;
case 144: /* on_opt ::= ON expr */
case 155: /* sortitem ::= expr */ yytestcase(yyruleno==155);
case 162: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==162);
case 169: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==169);
case 235: /* case_else ::= ELSE expr */ yytestcase(yyruleno==235);
case 237: /* case_operand ::= expr */ yytestcase(yyruleno==237);
{yygotominor.yy342 = yymsp[0].minor.yy132.pExpr;}
break;
case 145: /* on_opt ::= */
case 161: /* having_opt ::= */ yytestcase(yyruleno==161);
case 168: /* where_opt ::= */ yytestcase(yyruleno==168);
case 236: /* case_else ::= */ yytestcase(yyruleno==236);
case 238: /* case_operand ::= */ yytestcase(yyruleno==238);
{yygotominor.yy342 = 0;}
break;
case 148: /* indexed_opt ::= NOT INDEXED */
{yygotominor.yy0.z=0; yygotominor.yy0.n=1;}
break;
case 149: /* using_opt ::= USING LP inscollist RP */
case 181: /* inscollist_opt ::= LP inscollist RP */ yytestcase(yyruleno==181);
{yygotominor.yy440 = yymsp[-1].minor.yy440;}
break;
case 150: /* using_opt ::= */
case 180: /* inscollist_opt ::= */ yytestcase(yyruleno==180);
{yygotominor.yy440 = 0;}
break;
case 152: /* orderby_opt ::= ORDER BY sortlist */
case 160: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==160);
case 239: /* exprlist ::= nexprlist */ yytestcase(yyruleno==239);
{yygotominor.yy462 = yymsp[0].minor.yy462;}
break;
case 153: /* sortlist ::= sortlist COMMA sortitem sortorder */
{
yygotominor.yy462 = sqlite4ExprListAppend(pParse,yymsp[-3].minor.yy462,yymsp[-1].minor.yy342);
if( yygotominor.yy462 ) yygotominor.yy462->a[yygotominor.yy462->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy32;
}
break;
case 154: /* sortlist ::= sortitem sortorder */
{
yygotominor.yy462 = sqlite4ExprListAppend(pParse,0,yymsp[-1].minor.yy342);
if( yygotominor.yy462 && ALWAYS(yygotominor.yy462->a) ) yygotominor.yy462->a[0].sortOrder = (u8)yymsp[0].minor.yy32;
}
break;
case 156: /* sortorder ::= ASC */
case 158: /* sortorder ::= */ yytestcase(yyruleno==158);
{yygotominor.yy32 = SQLITE_SO_ASC;}
break;
case 157: /* sortorder ::= DESC */
{yygotominor.yy32 = SQLITE_SO_DESC;}
break;
case 163: /* limit_opt ::= */
{yygotominor.yy474.pLimit = 0; yygotominor.yy474.pOffset = 0;}
break;
case 164: /* limit_opt ::= LIMIT expr */
{yygotominor.yy474.pLimit = yymsp[0].minor.yy132.pExpr; yygotominor.yy474.pOffset = 0;}
break;
case 165: /* limit_opt ::= LIMIT expr OFFSET expr */
{yygotominor.yy474.pLimit = yymsp[-2].minor.yy132.pExpr; yygotominor.yy474.pOffset = yymsp[0].minor.yy132.pExpr;}
break;
case 166: /* limit_opt ::= LIMIT expr COMMA expr */
{yygotominor.yy474.pOffset = yymsp[-2].minor.yy132.pExpr; yygotominor.yy474.pLimit = yymsp[0].minor.yy132.pExpr;}
break;
case 167: /* cmd ::= DELETE FROM fullname indexed_opt where_opt */
{
sqlite4SrcListIndexedBy(pParse, yymsp[-2].minor.yy287, &yymsp[-1].minor.yy0);
sqlite4DeleteFrom(pParse,yymsp[-2].minor.yy287,yymsp[0].minor.yy342);
}
break;
case 170: /* cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt */
{
sqlite4SrcListIndexedBy(pParse, yymsp[-4].minor.yy287, &yymsp[-3].minor.yy0);
sqlite4ExprListCheckLength(pParse,yymsp[-1].minor.yy462,"set list");
sqlite4Update(pParse,yymsp[-4].minor.yy287,yymsp[-1].minor.yy462,yymsp[0].minor.yy342,yymsp[-5].minor.yy378);
}
break;
case 171: /* setlist ::= setlist COMMA nm EQ expr */
{
yygotominor.yy462 = sqlite4ExprListAppend(pParse, yymsp[-4].minor.yy462, yymsp[0].minor.yy132.pExpr);
sqlite4ExprListSetName(pParse, yygotominor.yy462, &yymsp[-2].minor.yy0, 1);
}
break;
case 172: /* setlist ::= nm EQ expr */
{
yygotominor.yy462 = sqlite4ExprListAppend(pParse, 0, yymsp[0].minor.yy132.pExpr);
sqlite4ExprListSetName(pParse, yygotominor.yy462, &yymsp[-2].minor.yy0, 1);
}
break;
case 173: /* cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP */
{sqlite4Insert(pParse, yymsp[-5].minor.yy287, yymsp[-1].minor.yy462, 0, yymsp[-4].minor.yy440, yymsp[-7].minor.yy378);}
break;
case 174: /* cmd ::= insert_cmd INTO fullname inscollist_opt select */
{sqlite4Insert(pParse, yymsp[-2].minor.yy287, 0, yymsp[0].minor.yy149, yymsp[-1].minor.yy440, yymsp[-4].minor.yy378);}
break;
case 175: /* cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES */
{sqlite4Insert(pParse, yymsp[-3].minor.yy287, 0, 0, yymsp[-2].minor.yy440, yymsp[-5].minor.yy378);}
break;
case 176: /* insert_cmd ::= INSERT orconf */
{yygotominor.yy378 = yymsp[0].minor.yy378;}
break;
case 177: /* insert_cmd ::= REPLACE */
{yygotominor.yy378 = OE_Replace;}
break;
case 178: /* itemlist ::= itemlist COMMA expr */
case 241: /* nexprlist ::= nexprlist COMMA expr */ yytestcase(yyruleno==241);
{yygotominor.yy462 = sqlite4ExprListAppend(pParse,yymsp[-2].minor.yy462,yymsp[0].minor.yy132.pExpr);}
break;
case 179: /* itemlist ::= expr */
case 242: /* nexprlist ::= expr */ yytestcase(yyruleno==242);
{yygotominor.yy462 = sqlite4ExprListAppend(pParse,0,yymsp[0].minor.yy132.pExpr);}
break;
case 182: /* inscollist ::= inscollist COMMA nm */
{yygotominor.yy440 = sqlite4IdListAppend(pParse->db,yymsp[-2].minor.yy440,&yymsp[0].minor.yy0);}
break;
case 183: /* inscollist ::= nm */
{yygotominor.yy440 = sqlite4IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);}
break;
case 184: /* expr ::= term */
{yygotominor.yy132 = yymsp[0].minor.yy132;}
break;
case 185: /* expr ::= LP expr RP */
{yygotominor.yy132.pExpr = yymsp[-1].minor.yy132.pExpr; spanSet(&yygotominor.yy132,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);}
break;
case 186: /* term ::= NULL */
case 191: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==191);
case 192: /* term ::= STRING */ yytestcase(yyruleno==192);
{spanExpr(&yygotominor.yy132, pParse, yymsp[0].major, &yymsp[0].minor.yy0);}
break;
case 187: /* expr ::= id */
case 188: /* expr ::= JOIN_KW */ yytestcase(yyruleno==188);
{spanExpr(&yygotominor.yy132, pParse, TK_ID, &yymsp[0].minor.yy0);}
break;
case 189: /* expr ::= nm DOT nm */
{
Expr *temp1 = sqlite4PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *temp2 = sqlite4PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
yygotominor.yy132.pExpr = sqlite4PExpr(pParse, TK_DOT, temp1, temp2, 0);
spanSet(&yygotominor.yy132,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
}
break;
case 190: /* expr ::= nm DOT nm DOT nm */
{
Expr *temp1 = sqlite4PExpr(pParse, TK_ID, 0, 0, &yymsp[-4].minor.yy0);
Expr *temp2 = sqlite4PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *temp3 = sqlite4PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
Expr *temp4 = sqlite4PExpr(pParse, TK_DOT, temp2, temp3, 0);
yygotominor.yy132.pExpr = sqlite4PExpr(pParse, TK_DOT, temp1, temp4, 0);
spanSet(&yygotominor.yy132,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
}
break;
case 193: /* expr ::= REGISTER */
{
/* 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. */
if( pParse->nested==0 ){
sqlite4ErrorMsg(pParse, "near \"%T\": syntax error", &yymsp[0].minor.yy0);
yygotominor.yy132.pExpr = 0;
}else{
yygotominor.yy132.pExpr = sqlite4PExpr(pParse, TK_REGISTER, 0, 0, &yymsp[0].minor.yy0);
if( yygotominor.yy132.pExpr ) sqlite4GetInt32(&yymsp[0].minor.yy0.z[1], &yygotominor.yy132.pExpr->iTable);
}
spanSet(&yygotominor.yy132, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
}
break;
case 194: /* expr ::= VARIABLE */
{
spanExpr(&yygotominor.yy132, pParse, TK_VARIABLE, &yymsp[0].minor.yy0);
sqlite4ExprAssignVarNumber(pParse, yygotominor.yy132.pExpr);
spanSet(&yygotominor.yy132, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
}
break;
case 195: /* expr ::= expr COLLATE ids */
{
yygotominor.yy132.pExpr = sqlite4ExprSetCollByToken(pParse, yymsp[-2].minor.yy132.pExpr, &yymsp[0].minor.yy0);
yygotominor.yy132.zStart = yymsp[-2].minor.yy132.zStart;
yygotominor.yy132.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 196: /* expr ::= CAST LP expr AS typetoken RP */
{
yygotominor.yy132.pExpr = sqlite4PExpr(pParse, TK_CAST, yymsp[-3].minor.yy132.pExpr, 0, &yymsp[-1].minor.yy0);
spanSet(&yygotominor.yy132,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
}
break;
case 197: /* expr ::= ID LP distinct exprlist RP */
{
if( yymsp[-1].minor.yy462 && yymsp[-1].minor.yy462->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
sqlite4ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
}
yygotominor.yy132.pExpr = sqlite4ExprFunction(pParse, yymsp[-1].minor.yy462, &yymsp[-4].minor.yy0);
spanSet(&yygotominor.yy132,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
if( yymsp[-2].minor.yy32 && yygotominor.yy132.pExpr ){
yygotominor.yy132.pExpr->flags |= EP_Distinct;
}
}
break;
case 198: /* expr ::= ID LP STAR RP */
{
yygotominor.yy132.pExpr = sqlite4ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
spanSet(&yygotominor.yy132,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
}
break;
case 199: /* term ::= CTIME_KW */
{
/* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are
** treated as functions that return constants */
yygotominor.yy132.pExpr = sqlite4ExprFunction(pParse, 0,&yymsp[0].minor.yy0);
if( yygotominor.yy132.pExpr ){
yygotominor.yy132.pExpr->op = TK_CONST_FUNC;
}
spanSet(&yygotominor.yy132, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
}
break;
case 200: /* expr ::= expr AND expr */
case 201: /* expr ::= expr OR expr */ yytestcase(yyruleno==201);
case 202: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==202);
case 203: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==203);
case 204: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==204);
case 205: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==205);
case 206: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==206);
case 207: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==207);
{spanBinaryExpr(&yygotominor.yy132,pParse,yymsp[-1].major,&yymsp[-2].minor.yy132,&yymsp[0].minor.yy132);}
break;
case 208: /* likeop ::= LIKE_KW */
case 210: /* likeop ::= MATCH */ yytestcase(yyruleno==210);
{yygotominor.yy118.eOperator = yymsp[0].minor.yy0; yygotominor.yy118.not = 0;}
break;
case 209: /* likeop ::= NOT LIKE_KW */
case 211: /* likeop ::= NOT MATCH */ yytestcase(yyruleno==211);
{yygotominor.yy118.eOperator = yymsp[0].minor.yy0; yygotominor.yy118.not = 1;}
break;
case 212: /* expr ::= expr likeop expr */
{
ExprList *pList;
pList = sqlite4ExprListAppend(pParse,0, yymsp[0].minor.yy132.pExpr);
pList = sqlite4ExprListAppend(pParse,pList, yymsp[-2].minor.yy132.pExpr);
yygotominor.yy132.pExpr = sqlite4ExprFunction(pParse, pList, &yymsp[-1].minor.yy118.eOperator);
if( yymsp[-1].minor.yy118.not ) yygotominor.yy132.pExpr = sqlite4PExpr(pParse, TK_NOT, yygotominor.yy132.pExpr, 0, 0);
yygotominor.yy132.zStart = yymsp[-2].minor.yy132.zStart;
yygotominor.yy132.zEnd = yymsp[0].minor.yy132.zEnd;
if( yygotominor.yy132.pExpr ) yygotominor.yy132.pExpr->flags |= EP_InfixFunc;
}
break;
case 213: /* expr ::= expr likeop expr ESCAPE expr */
{
ExprList *pList;
pList = sqlite4ExprListAppend(pParse,0, yymsp[-2].minor.yy132.pExpr);
pList = sqlite4ExprListAppend(pParse,pList, yymsp[-4].minor.yy132.pExpr);
pList = sqlite4ExprListAppend(pParse,pList, yymsp[0].minor.yy132.pExpr);
yygotominor.yy132.pExpr = sqlite4ExprFunction(pParse, pList, &yymsp[-3].minor.yy118.eOperator);
if( yymsp[-3].minor.yy118.not ) yygotominor.yy132.pExpr = sqlite4PExpr(pParse, TK_NOT, yygotominor.yy132.pExpr, 0, 0);
yygotominor.yy132.zStart = yymsp[-4].minor.yy132.zStart;
yygotominor.yy132.zEnd = yymsp[0].minor.yy132.zEnd;
if( yygotominor.yy132.pExpr ) yygotominor.yy132.pExpr->flags |= EP_InfixFunc;
}
break;
case 214: /* expr ::= expr ISNULL|NOTNULL */
{spanUnaryPostfix(&yygotominor.yy132,pParse,yymsp[0].major,&yymsp[-1].minor.yy132,&yymsp[0].minor.yy0);}
break;
case 215: /* expr ::= expr NOT NULL */
{spanUnaryPostfix(&yygotominor.yy132,pParse,TK_NOTNULL,&yymsp[-2].minor.yy132,&yymsp[0].minor.yy0);}
break;
case 216: /* expr ::= expr IS expr */
{
spanBinaryExpr(&yygotominor.yy132,pParse,TK_IS,&yymsp[-2].minor.yy132,&yymsp[0].minor.yy132);
binaryToUnaryIfNull(pParse, yymsp[0].minor.yy132.pExpr, yygotominor.yy132.pExpr, TK_ISNULL);
}
break;
case 217: /* expr ::= expr IS NOT expr */
{
spanBinaryExpr(&yygotominor.yy132,pParse,TK_ISNOT,&yymsp[-3].minor.yy132,&yymsp[0].minor.yy132);
binaryToUnaryIfNull(pParse, yymsp[0].minor.yy132.pExpr, yygotominor.yy132.pExpr, TK_NOTNULL);
}
break;
case 218: /* expr ::= NOT expr */
case 219: /* expr ::= BITNOT expr */ yytestcase(yyruleno==219);
{spanUnaryPrefix(&yygotominor.yy132,pParse,yymsp[-1].major,&yymsp[0].minor.yy132,&yymsp[-1].minor.yy0);}
break;
case 220: /* expr ::= MINUS expr */
{spanUnaryPrefix(&yygotominor.yy132,pParse,TK_UMINUS,&yymsp[0].minor.yy132,&yymsp[-1].minor.yy0);}
break;
case 221: /* expr ::= PLUS expr */
{spanUnaryPrefix(&yygotominor.yy132,pParse,TK_UPLUS,&yymsp[0].minor.yy132,&yymsp[-1].minor.yy0);}
break;
case 224: /* expr ::= expr between_op expr AND expr */
{
ExprList *pList = sqlite4ExprListAppend(pParse,0, yymsp[-2].minor.yy132.pExpr);
pList = sqlite4ExprListAppend(pParse,pList, yymsp[0].minor.yy132.pExpr);
yygotominor.yy132.pExpr = sqlite4PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy132.pExpr, 0, 0);
if( yygotominor.yy132.pExpr ){
yygotominor.yy132.pExpr->x.pList = pList;
}else{
sqlite4ExprListDelete(pParse->db, pList);
}
if( yymsp[-3].minor.yy32 ) yygotominor.yy132.pExpr = sqlite4PExpr(pParse, TK_NOT, yygotominor.yy132.pExpr, 0, 0);
yygotominor.yy132.zStart = yymsp[-4].minor.yy132.zStart;
yygotominor.yy132.zEnd = yymsp[0].minor.yy132.zEnd;
}
break;
case 227: /* expr ::= expr in_op LP exprlist RP */
{
if( yymsp[-1].minor.yy462==0 ){
/* Expressions of the form
**
** expr1 IN ()
** expr1 NOT IN ()
**
** simplify to constants 0 (false) and 1 (true), respectively,
** regardless of the value of expr1.
*/
yygotominor.yy132.pExpr = sqlite4PExpr(pParse, TK_INTEGER, 0, 0, &sqlite4IntTokens[yymsp[-3].minor.yy32]);
sqlite4ExprDelete(pParse->db, yymsp[-4].minor.yy132.pExpr);
}else{
yygotominor.yy132.pExpr = sqlite4PExpr(pParse, TK_IN, yymsp[-4].minor.yy132.pExpr, 0, 0);
if( yygotominor.yy132.pExpr ){
yygotominor.yy132.pExpr->x.pList = yymsp[-1].minor.yy462;
sqlite4ExprSetHeight(pParse, yygotominor.yy132.pExpr);
}else{
sqlite4ExprListDelete(pParse->db, yymsp[-1].minor.yy462);
}
if( yymsp[-3].minor.yy32 ) yygotominor.yy132.pExpr = sqlite4PExpr(pParse, TK_NOT, yygotominor.yy132.pExpr, 0, 0);
}
yygotominor.yy132.zStart = yymsp[-4].minor.yy132.zStart;
yygotominor.yy132.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 228: /* expr ::= LP select RP */
{
yygotominor.yy132.pExpr = sqlite4PExpr(pParse, TK_SELECT, 0, 0, 0);
if( yygotominor.yy132.pExpr ){
yygotominor.yy132.pExpr->x.pSelect = yymsp[-1].minor.yy149;
ExprSetProperty(yygotominor.yy132.pExpr, EP_xIsSelect);
sqlite4ExprSetHeight(pParse, yygotominor.yy132.pExpr);
}else{
sqlite4SelectDelete(pParse->db, yymsp[-1].minor.yy149);
}
yygotominor.yy132.zStart = yymsp[-2].minor.yy0.z;
yygotominor.yy132.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 229: /* expr ::= expr in_op LP select RP */
{
yygotominor.yy132.pExpr = sqlite4PExpr(pParse, TK_IN, yymsp[-4].minor.yy132.pExpr, 0, 0);
if( yygotominor.yy132.pExpr ){
yygotominor.yy132.pExpr->x.pSelect = yymsp[-1].minor.yy149;
ExprSetProperty(yygotominor.yy132.pExpr, EP_xIsSelect);
sqlite4ExprSetHeight(pParse, yygotominor.yy132.pExpr);
}else{
sqlite4SelectDelete(pParse->db, yymsp[-1].minor.yy149);
}
if( yymsp[-3].minor.yy32 ) yygotominor.yy132.pExpr = sqlite4PExpr(pParse, TK_NOT, yygotominor.yy132.pExpr, 0, 0);
yygotominor.yy132.zStart = yymsp[-4].minor.yy132.zStart;
yygotominor.yy132.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 230: /* expr ::= expr in_op nm dbnm */
{
SrcList *pSrc = sqlite4SrcListAppend(pParse->db, 0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);
yygotominor.yy132.pExpr = sqlite4PExpr(pParse, TK_IN, yymsp[-3].minor.yy132.pExpr, 0, 0);
if( yygotominor.yy132.pExpr ){
yygotominor.yy132.pExpr->x.pSelect = sqlite4SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
ExprSetProperty(yygotominor.yy132.pExpr, EP_xIsSelect);
sqlite4ExprSetHeight(pParse, yygotominor.yy132.pExpr);
}else{
sqlite4SrcListDelete(pParse->db, pSrc);
}
if( yymsp[-2].minor.yy32 ) yygotominor.yy132.pExpr = sqlite4PExpr(pParse, TK_NOT, yygotominor.yy132.pExpr, 0, 0);
yygotominor.yy132.zStart = yymsp[-3].minor.yy132.zStart;
yygotominor.yy132.zEnd = yymsp[0].minor.yy0.z ? &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] : &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n];
}
break;
case 231: /* expr ::= EXISTS LP select RP */
{
Expr *p = yygotominor.yy132.pExpr = sqlite4PExpr(pParse, TK_EXISTS, 0, 0, 0);
if( p ){
p->x.pSelect = yymsp[-1].minor.yy149;
ExprSetProperty(p, EP_xIsSelect);
sqlite4ExprSetHeight(pParse, p);
}else{
sqlite4SelectDelete(pParse->db, yymsp[-1].minor.yy149);
}
yygotominor.yy132.zStart = yymsp[-3].minor.yy0.z;
yygotominor.yy132.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 232: /* expr ::= CASE case_operand case_exprlist case_else END */
{
yygotominor.yy132.pExpr = sqlite4PExpr(pParse, TK_CASE, yymsp[-3].minor.yy342, yymsp[-1].minor.yy342, 0);
if( yygotominor.yy132.pExpr ){
yygotominor.yy132.pExpr->x.pList = yymsp[-2].minor.yy462;
sqlite4ExprSetHeight(pParse, yygotominor.yy132.pExpr);
}else{
sqlite4ExprListDelete(pParse->db, yymsp[-2].minor.yy462);
}
yygotominor.yy132.zStart = yymsp[-4].minor.yy0.z;
yygotominor.yy132.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 233: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
{
yygotominor.yy462 = sqlite4ExprListAppend(pParse,yymsp[-4].minor.yy462, yymsp[-2].minor.yy132.pExpr);
yygotominor.yy462 = sqlite4ExprListAppend(pParse,yygotominor.yy462, yymsp[0].minor.yy132.pExpr);
}
break;
case 234: /* case_exprlist ::= WHEN expr THEN expr */
{
yygotominor.yy462 = sqlite4ExprListAppend(pParse,0, yymsp[-2].minor.yy132.pExpr);
yygotominor.yy462 = sqlite4ExprListAppend(pParse,yygotominor.yy462, yymsp[0].minor.yy132.pExpr);
}
break;
case 243: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP */
{
sqlite4CreateIndex(pParse, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0,
sqlite4SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy0,0), yymsp[-1].minor.yy462, yymsp[-9].minor.yy32,
&yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy32, 0);
}
break;
case 244: /* uniqueflag ::= UNIQUE */
case 296: /* raisetype ::= ABORT */ yytestcase(yyruleno==296);
{yygotominor.yy32 = OE_Abort;}
break;
case 245: /* uniqueflag ::= */
{yygotominor.yy32 = OE_None;}
break;
case 248: /* idxlist ::= idxlist COMMA nm collate sortorder */
{
Expr *p = 0;
if( yymsp[-1].minor.yy0.n>0 ){
p = sqlite4Expr(pParse->db, TK_COLUMN, 0);
sqlite4ExprSetCollByToken(pParse, p, &yymsp[-1].minor.yy0);
}
yygotominor.yy462 = sqlite4ExprListAppend(pParse,yymsp[-4].minor.yy462, p);
sqlite4ExprListSetName(pParse,yygotominor.yy462,&yymsp[-2].minor.yy0,1);
sqlite4ExprListCheckLength(pParse, yygotominor.yy462, "index");
if( yygotominor.yy462 ) yygotominor.yy462->a[yygotominor.yy462->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy32;
}
break;
case 249: /* idxlist ::= nm collate sortorder */
{
Expr *p = 0;
if( yymsp[-1].minor.yy0.n>0 ){
p = sqlite4PExpr(pParse, TK_COLUMN, 0, 0, 0);
sqlite4ExprSetCollByToken(pParse, p, &yymsp[-1].minor.yy0);
}
yygotominor.yy462 = sqlite4ExprListAppend(pParse,0, p);
sqlite4ExprListSetName(pParse, yygotominor.yy462, &yymsp[-2].minor.yy0, 1);
sqlite4ExprListCheckLength(pParse, yygotominor.yy462, "index");
if( yygotominor.yy462 ) yygotominor.yy462->a[yygotominor.yy462->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy32;
}
break;
case 250: /* collate ::= */
{yygotominor.yy0.z = 0; yygotominor.yy0.n = 0;}
break;
case 252: /* cmd ::= DROP INDEX ifexists fullname */
{sqlite4DropIndex(pParse, yymsp[0].minor.yy287, yymsp[-1].minor.yy32);}
break;
case 253: /* cmd ::= PRAGMA nm dbnm */
{sqlite4Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
break;
case 254: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
{sqlite4Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
break;
case 255: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
{sqlite4Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
break;
case 256: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
{sqlite4Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
break;
case 257: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
{sqlite4Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
break;
case 268: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
{
Token all;
all.z = yymsp[-3].minor.yy0.z;
all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
sqlite4FinishTrigger(pParse, yymsp[-1].minor.yy7, &all);
}
break;
case 269: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
{
sqlite4BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy32, yymsp[-4].minor.yy160.a, yymsp[-4].minor.yy160.b, yymsp[-2].minor.yy287, yymsp[0].minor.yy342, yymsp[-10].minor.yy32, yymsp[-8].minor.yy32);
yygotominor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0);
}
break;
case 270: /* trigger_time ::= BEFORE */
case 273: /* trigger_time ::= */ yytestcase(yyruleno==273);
{ yygotominor.yy32 = TK_BEFORE; }
break;
case 271: /* trigger_time ::= AFTER */
{ yygotominor.yy32 = TK_AFTER; }
break;
case 272: /* trigger_time ::= INSTEAD OF */
{ yygotominor.yy32 = TK_INSTEAD;}
break;
case 274: /* trigger_event ::= DELETE|INSERT */
case 275: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==275);
{yygotominor.yy160.a = yymsp[0].major; yygotominor.yy160.b = 0;}
break;
case 276: /* trigger_event ::= UPDATE OF inscollist */
{yygotominor.yy160.a = TK_UPDATE; yygotominor.yy160.b = yymsp[0].minor.yy440;}
break;
case 279: /* when_clause ::= */
case 301: /* key_opt ::= */ yytestcase(yyruleno==301);
{ yygotominor.yy342 = 0; }
break;
case 280: /* when_clause ::= WHEN expr */
case 302: /* key_opt ::= KEY expr */ yytestcase(yyruleno==302);
{ yygotominor.yy342 = yymsp[0].minor.yy132.pExpr; }
break;
case 281: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
{
assert( yymsp[-2].minor.yy7!=0 );
yymsp[-2].minor.yy7->pLast->pNext = yymsp[-1].minor.yy7;
yymsp[-2].minor.yy7->pLast = yymsp[-1].minor.yy7;
yygotominor.yy7 = yymsp[-2].minor.yy7;
}
break;
case 282: /* trigger_cmd_list ::= trigger_cmd SEMI */
{
assert( yymsp[-1].minor.yy7!=0 );
yymsp[-1].minor.yy7->pLast = yymsp[-1].minor.yy7;
yygotominor.yy7 = yymsp[-1].minor.yy7;
}
break;
case 284: /* trnm ::= nm DOT nm */
{
yygotominor.yy0 = yymsp[0].minor.yy0;
sqlite4ErrorMsg(pParse,
"qualified table names are not allowed on INSERT, UPDATE, and DELETE "
"statements within triggers");
}
break;
case 286: /* tridxby ::= INDEXED BY nm */
{
sqlite4ErrorMsg(pParse,
"the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
case 287: /* tridxby ::= NOT INDEXED */
{
sqlite4ErrorMsg(pParse,
"the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
case 288: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
{ yygotominor.yy7 = sqlite4TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy462, yymsp[0].minor.yy342, yymsp[-5].minor.yy378); }
break;
case 289: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt VALUES LP itemlist RP */
{yygotominor.yy7 = sqlite4TriggerInsertStep(pParse->db, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy440, yymsp[-1].minor.yy462, 0, yymsp[-7].minor.yy378);}
break;
case 290: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select */
{yygotominor.yy7 = sqlite4TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy440, 0, yymsp[0].minor.yy149, yymsp[-4].minor.yy378);}
break;
case 291: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
{yygotominor.yy7 = sqlite4TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy342);}
break;
case 292: /* trigger_cmd ::= select */
{yygotominor.yy7 = sqlite4TriggerSelectStep(pParse->db, yymsp[0].minor.yy149); }
break;
case 293: /* expr ::= RAISE LP IGNORE RP */
{
yygotominor.yy132.pExpr = sqlite4PExpr(pParse, TK_RAISE, 0, 0, 0);
if( yygotominor.yy132.pExpr ){
yygotominor.yy132.pExpr->affinity = OE_Ignore;
}
yygotominor.yy132.zStart = yymsp[-3].minor.yy0.z;
yygotominor.yy132.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 294: /* expr ::= RAISE LP raisetype COMMA nm RP */
{
yygotominor.yy132.pExpr = sqlite4PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0);
if( yygotominor.yy132.pExpr ) {
yygotominor.yy132.pExpr->affinity = (char)yymsp[-3].minor.yy32;
}
yygotominor.yy132.zStart = yymsp[-5].minor.yy0.z;
yygotominor.yy132.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 295: /* raisetype ::= ROLLBACK */
{yygotominor.yy32 = OE_Rollback;}
break;
case 297: /* raisetype ::= FAIL */
{yygotominor.yy32 = OE_Fail;}
break;
case 298: /* cmd ::= DROP TRIGGER ifexists fullname */
{
sqlite4DropTrigger(pParse,yymsp[0].minor.yy287,yymsp[-1].minor.yy32);
}
break;
case 299: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
{
sqlite4Attach(pParse, yymsp[-3].minor.yy132.pExpr, yymsp[-1].minor.yy132.pExpr, yymsp[0].minor.yy342);
}
break;
case 300: /* cmd ::= DETACH database_kw_opt expr */
{
sqlite4Detach(pParse, yymsp[0].minor.yy132.pExpr);
}
break;
case 305: /* cmd ::= REINDEX */
{sqlite4Reindex(pParse, 0, 0);}
break;
case 306: /* cmd ::= REINDEX nm dbnm */
{sqlite4Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
case 307: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
{
sqlite4AlterRenameTable(pParse,yymsp[-3].minor.yy287,&yymsp[0].minor.yy0);
}
break;
case 308: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */
{
sqlite4AlterFinishAddColumn(pParse, &yymsp[0].minor.yy0);
}
break;
case 309: /* add_column_fullname ::= fullname */
{
pParse->db->lookaside.bEnabled = 0;
sqlite4AlterBeginAddColumn(pParse, yymsp[0].minor.yy287);
}
break;
default:
/* (0) input ::= cmdlist */ yytestcase(yyruleno==0);
/* (1) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==1);
/* (2) cmdlist ::= ecmd */ yytestcase(yyruleno==2);
/* (3) ecmd ::= SEMI */ yytestcase(yyruleno==3);
/* (4) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==4);
/* (10) trans_opt ::= */ yytestcase(yyruleno==10);
/* (11) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==11);
/* (12) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==12);
/* (20) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==20);
/* (21) savepoint_opt ::= */ yytestcase(yyruleno==21);
/* (25) cmd ::= create_table create_table_args */ yytestcase(yyruleno==25);
/* (34) columnlist ::= columnlist COMMA column */ yytestcase(yyruleno==34);
/* (35) columnlist ::= column */ yytestcase(yyruleno==35);
/* (44) type ::= */ yytestcase(yyruleno==44);
/* (51) signed ::= plus_num */ yytestcase(yyruleno==51);
/* (52) signed ::= minus_num */ yytestcase(yyruleno==52);
/* (53) carglist ::= carglist carg */ yytestcase(yyruleno==53);
/* (54) carglist ::= */ yytestcase(yyruleno==54);
/* (55) carg ::= CONSTRAINT nm ccons */ yytestcase(yyruleno==55);
/* (56) carg ::= ccons */ yytestcase(yyruleno==56);
/* (62) ccons ::= NULL onconf */ yytestcase(yyruleno==62);
/* (90) conslist ::= conslist COMMA tcons */ yytestcase(yyruleno==90);
/* (91) conslist ::= conslist tcons */ yytestcase(yyruleno==91);
/* (92) conslist ::= tcons */ yytestcase(yyruleno==92);
/* (93) tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==93);
/* (266) plus_opt ::= PLUS */ yytestcase(yyruleno==266);
/* (267) plus_opt ::= */ yytestcase(yyruleno==267);
/* (277) foreach_clause ::= */ yytestcase(yyruleno==277);
/* (278) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==278);
/* (285) tridxby ::= */ yytestcase(yyruleno==285);
/* (303) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==303);
/* (304) database_kw_opt ::= */ yytestcase(yyruleno==304);
/* (310) kwcolumn_opt ::= */ yytestcase(yyruleno==310);
/* (311) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==311);
break;
};
yygoto = yyRuleInfo[yyruleno].lhs;
yysize = yyRuleInfo[yyruleno].nrhs;
yypParser->yyidx -= yysize;
yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto);
if( yyact < YYNSTATE ){
#ifdef NDEBUG
/* If we are not debugging and the reduce action popped at least
** one element off the stack, then we can push the new element back
** onto the stack here, and skip the stack overflow test in yy_shift().
** That gives a significant speed improvement. */
if( yysize ){
yypParser->yyidx++;
yymsp -= yysize-1;
yymsp->stateno = (YYACTIONTYPE)yyact;
yymsp->major = (YYCODETYPE)yygoto;
yymsp->minor = yygotominor;
}else
#endif
{
yy_shift(yypParser,yyact,yygoto,&yygotominor);
}
}else{
assert( yyact == YYNSTATE + YYNRULE + 1 );
yy_accept(yypParser);
}
}
/*
** The following code executes when the parse fails
*/
#ifndef YYNOERRORRECOVERY
static void yy_parse_failed(
yyParser *yypParser /* The parser */
){
sqlite4ParserARG_FETCH;
#ifndef NDEBUG
if( yyTraceFILE ){
fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt);
}
#endif
while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
/* Here code is inserted which will be executed whenever the
** parser fails */
sqlite4ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
}
#endif /* YYNOERRORRECOVERY */
/*
** The following code executes when a syntax error first occurs.
*/
static void yy_syntax_error(
yyParser *yypParser, /* The parser */
int yymajor, /* The major type of the error token */
YYMINORTYPE yyminor /* The minor type of the error token */
){
sqlite4ParserARG_FETCH;
#define TOKEN (yyminor.yy0)
UNUSED_PARAMETER(yymajor); /* Silence some compiler warnings */
assert( TOKEN.z[0] ); /* The tokenizer always gives us a token */
sqlite4ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
sqlite4ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
}
/*
** The following is executed when the parser accepts
*/
static void yy_accept(
yyParser *yypParser /* The parser */
){
sqlite4ParserARG_FETCH;
#ifndef NDEBUG
if( yyTraceFILE ){
fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt);
}
#endif
while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
/* Here code is inserted which will be executed whenever the
** parser accepts */
sqlite4ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
}
/* The main parser program.
** The first argument is a pointer to a structure obtained from
** "sqlite4ParserAlloc" 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.
*/
SQLITE_PRIVATE void sqlite4Parser(
void *yyp, /* The parser */
int yymajor, /* The major token code number */
sqlite4ParserTOKENTYPE yyminor /* The value for the token */
sqlite4ParserARG_PDECL /* Optional %extra_argument parameter */
){
YYMINORTYPE yyminorunion;
int yyact; /* The parser action. */
#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
int yyendofinput; /* True if we are at the end of input */
#endif
#ifdef YYERRORSYMBOL
int yyerrorhit = 0; /* True if yymajor has invoked an error */
#endif
yyParser *yypParser; /* The parser */
/* (re)initialize the parser, if necessary */
yypParser = (yyParser*)yyp;
if( yypParser->yyidx<0 ){
#if YYSTACKDEPTH<=0
if( yypParser->yystksz <=0 ){
/*memset(&yyminorunion, 0, sizeof(yyminorunion));*/
yyminorunion = yyzerominor;
yyStackOverflow(yypParser, &yyminorunion);
return;
}
#endif
yypParser->yyidx = 0;
yypParser->yyerrcnt = -1;
yypParser->yystack[0].stateno = 0;
yypParser->yystack[0].major = 0;
}
yyminorunion.yy0 = yyminor;
#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
yyendofinput = (yymajor==0);
#endif
sqlite4ParserARG_STORE;
#ifndef NDEBUG
if( yyTraceFILE ){
fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]);
}
#endif
do{
yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
if( yyact<YYNSTATE ){
yy_shift(yypParser,yyact,yymajor,&yyminorunion);
yypParser->yyerrcnt--;
yymajor = YYNOCODE;
}else if( yyact < YYNSTATE + YYNRULE ){
yy_reduce(yypParser,yyact-YYNSTATE);
}else{
assert( yyact == YY_ERROR_ACTION );
#ifdef YYERRORSYMBOL
int yymx;
#endif
#ifndef NDEBUG
if( yyTraceFILE ){
fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt);
}
#endif
#ifdef YYERRORSYMBOL
/* 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( yypParser->yyerrcnt<0 ){
yy_syntax_error(yypParser,yymajor,yyminorunion);
}
yymx = yypParser->yystack[yypParser->yyidx].major;
if( yymx==YYERRORSYMBOL || yyerrorhit ){
#ifndef NDEBUG
if( yyTraceFILE ){
fprintf(yyTraceFILE,"%sDiscard input token %s\n",
yyTracePrompt,yyTokenName[yymajor]);
}
#endif
yy_destructor(yypParser, (YYCODETYPE)yymajor,&yyminorunion);
yymajor = YYNOCODE;
}else{
while(
yypParser->yyidx >= 0 &&
yymx != YYERRORSYMBOL &&
(yyact = yy_find_reduce_action(
yypParser->yystack[yypParser->yyidx].stateno,
YYERRORSYMBOL)) >= YYNSTATE
){
yy_pop_parser_stack(yypParser);
}
if( yypParser->yyidx < 0 || yymajor==0 ){
yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
yy_parse_failed(yypParser);
yymajor = YYNOCODE;
}else if( yymx!=YYERRORSYMBOL ){
YYMINORTYPE u2;
u2.YYERRSYMDT = 0;
yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2);
}
}
yypParser->yyerrcnt = 3;
yyerrorhit = 1;
#elif defined(YYNOERRORRECOVERY)
/* If the YYNOERRORRECOVERY 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.
*/
yy_syntax_error(yypParser,yymajor,yyminorunion);
yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
yymajor = YYNOCODE;
#else /* YYERRORSYMBOL 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( yypParser->yyerrcnt<=0 ){
yy_syntax_error(yypParser,yymajor,yyminorunion);
}
yypParser->yyerrcnt = 3;
yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
if( yyendofinput ){
yy_parse_failed(yypParser);
}
yymajor = YYNOCODE;
#endif
}
}while( yymajor!=YYNOCODE && yypParser->yyidx>=0 );
return;
}
/************** End of parse.c ***********************************************/
/************** Begin file tokenize.c ****************************************/
/*
** 2001 September 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.
**
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
*/
/* #include <stdlib.h> */
/*
** The charMap() macro maps alphabetic characters 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. Only alphabetic characters and underscores
** need to be translated.
*/
#ifdef SQLITE_ASCII
# define charMap(X) sqlite4UpperToLower[(unsigned char)X]
#endif
#ifdef SQLITE_EBCDIC
# define charMap(X) ebcdicToAscii[(unsigned char)X]
const unsigned char ebcdicToAscii[] = {
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3x */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4x */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5x */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, /* 6x */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7x */
0, 97, 98, 99,100,101,102,103,104,105, 0, 0, 0, 0, 0, 0, /* 8x */
0,106,107,108,109,110,111,112,113,114, 0, 0, 0, 0, 0, 0, /* 9x */
0, 0,115,116,117,118,119,120,121,122, 0, 0, 0, 0, 0, 0, /* Ax */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Bx */
0, 97, 98, 99,100,101,102,103,104,105, 0, 0, 0, 0, 0, 0, /* Cx */
0,106,107,108,109,110,111,112,113,114, 0, 0, 0, 0, 0, 0, /* Dx */
0, 0,115,116,117,118,119,120,121,122, 0, 0, 0, 0, 0, 0, /* Ex */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Fx */
};
#endif
/*
** The sqlite4KeywordCode function looks up an identifier to determine if
** it is a keyword. If it is a keyword, the token code of that keyword is
** returned. If the input is not a keyword, TK_ID is returned.
**
** The implementation of this routine was generated by a program,
** mkkeywordhash.h, 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.
*/
/************** Include keywordhash.h in the middle of tokenize.c ************/
/************** Begin file keywordhash.h *************************************/
/***** This file contains automatically generated code ******
**
** The code in this file has been automatically generated by
**
** sqlite/tool/mkkeywordhash.c
**
** The code in this file implements a function that determines whether
** or not a given identifier is really an SQL keyword. The same thing
** might be implemented more directly using a hand-written hash table.
** But by using this automatically generated code, the size of the code
** is substantially reduced. This is important for embedded applications
** on platforms with limited memory.
*/
/* Hash score: 163 */
static int keywordCode(const char *z, int n){
/* zText[] encodes 788 bytes of keywords in 521 bytes */
/* REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT */
/* ABLEFTHENDEFERRABLELSEXCEPTRANSACTIONATURALTERAISEXCLUSIVE */
/* XISTSAVEPOINTERSECTRIGGEREFERENCESCONSTRAINTOFFSETEMPORARY */
/* UNIQUERYATTACHAVINGROUPDATEBEGINNERELEASEBETWEENOTNULLIKE */
/* CASCADELETECASECOLLATECREATECURRENT_DATEDETACHIMMEDIATEJOIN */
/* SERTMATCHPLANDEFAULTPRAGMABORTVALUESWHENWHERENAMEAFTEREPLACE */
/* AUTOINCREMENTCASTCOLUMNCOMMITCONFLICTCROSSCURRENT_TIMESTAMP */
/* RIMARYDEFERREDISTINCTDROPFAILIMITFROMFULLGLOBYIFISNULLORDER */
/* ESTRICTOUTERIGHTROLLBACKROWUNIONUSINGVIEWINITIALLY */
static const char zText[520] = {
'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','E','P','T','R','A','N',
'S','A','C','T','I','O','N','A','T','U','R','A','L','T','E','R','A','I',
'S','E','X','C','L','U','S','I','V','E','X','I','S','T','S','A','V','E',
'P','O','I','N','T','E','R','S','E','C','T','R','I','G','G','E','R','E',
'F','E','R','E','N','C','E','S','C','O','N','S','T','R','A','I','N','T',
'O','F','F','S','E','T','E','M','P','O','R','A','R','Y','U','N','I','Q',
'U','E','R','Y','A','T','T','A','C','H','A','V','I','N','G','R','O','U',
'P','D','A','T','E','B','E','G','I','N','N','E','R','E','L','E','A','S',
'E','B','E','T','W','E','E','N','O','T','N','U','L','L','I','K','E','C',
'A','S','C','A','D','E','L','E','T','E','C','A','S','E','C','O','L','L',
'A','T','E','C','R','E','A','T','E','C','U','R','R','E','N','T','_','D',
'A','T','E','D','E','T','A','C','H','I','M','M','E','D','I','A','T','E',
'J','O','I','N','S','E','R','T','M','A','T','C','H','P','L','A','N','D',
'E','F','A','U','L','T','P','R','A','G','M','A','B','O','R','T','V','A',
'L','U','E','S','W','H','E','N','W','H','E','R','E','N','A','M','E','A',
'F','T','E','R','E','P','L','A','C','E','A','U','T','O','I','N','C','R',
'E','M','E','N','T','C','A','S','T','C','O','L','U','M','N','C','O','M',
'M','I','T','C','O','N','F','L','I','C','T','C','R','O','S','S','C','U',
'R','R','E','N','T','_','T','I','M','E','S','T','A','M','P','R','I','M',
'A','R','Y','D','E','F','E','R','R','E','D','I','S','T','I','N','C','T',
'D','R','O','P','F','A','I','L','I','M','I','T','F','R','O','M','F','U',
'L','L','G','L','O','B','Y','I','F','I','S','N','U','L','L','O','R','D',
'E','R','E','S','T','R','I','C','T','O','U','T','E','R','I','G','H','T',
'R','O','L','L','B','A','C','K','R','O','W','U','N','I','O','N','U','S',
'I','N','G','V','I','E','W','I','N','I','T','I','A','L','L','Y',
};
static const unsigned char aHash[127] = {
72, 98, 112, 70, 0, 45, 0, 0, 79, 0, 73, 0, 0,
42, 12, 74, 15, 0, 111, 80, 50, 106, 0, 19, 0, 0,
35, 0, 114, 109, 0, 22, 86, 0, 9, 0, 0, 66, 67,
0, 65, 6, 0, 48, 75, 95, 0, 113, 94, 0, 0, 44,
0, 96, 24, 0, 17, 0, 116, 49, 23, 0, 5, 104, 25,
89, 0, 0, 118, 99, 56, 117, 53, 28, 51, 0, 76, 0,
93, 26, 0, 92, 0, 0, 0, 88, 85, 90, 83, 103, 14,
39, 102, 0, 78, 0, 18, 84, 105, 32, 0, 115, 77, 107,
58, 46, 101, 0, 0, 87, 40, 0, 110, 0, 36, 0, 0,
29, 0, 81, 59, 60, 0, 20, 57, 0, 52,
};
static const unsigned char aNext[118] = {
0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0,
0, 2, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0,
0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 33, 0, 21, 0, 0, 0, 43, 3, 47,
0, 0, 0, 0, 30, 0, 54, 0, 38, 0, 0, 0, 1,
62, 0, 0, 63, 0, 41, 0, 0, 0, 16, 34, 0, 0,
0, 0, 0, 0, 31, 55, 10, 0, 0, 0, 0, 0, 0,
0, 11, 68, 0, 0, 8, 0, 97, 91, 0, 0, 100, 0,
82, 0, 71, 0, 0, 108, 27, 37, 69, 61, 0, 64, 0,
0,
};
static const unsigned char aLen[118] = {
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, 6,
11, 6, 2, 7, 5, 5, 9, 6, 9, 9, 7, 10, 10,
4, 6, 2, 3, 9, 4, 2, 6, 5, 6, 6, 5, 6,
5, 5, 7, 7, 7, 3, 2, 4, 4, 7, 3, 6, 4,
7, 6, 12, 6, 9, 4, 6, 5, 4, 3, 7, 6, 5,
6, 4, 5, 6, 5, 7, 13, 2, 2, 4, 6, 6, 8,
5, 17, 12, 7, 8, 8, 2, 4, 4, 5, 4, 4, 4,
2, 2, 6, 5, 8, 5, 5, 8, 3, 5, 5, 4, 9,
3,
};
static const unsigned short int aOffset[118] = {
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, 91, 95, 96, 101, 105, 109, 117, 122, 128, 136, 142, 152,
159, 162, 162, 165, 167, 167, 171, 176, 179, 184, 189, 194, 197,
203, 206, 210, 217, 223, 223, 223, 226, 229, 233, 234, 238, 244,
248, 255, 261, 273, 279, 288, 290, 296, 301, 303, 305, 312, 317,
322, 328, 332, 335, 341, 345, 352, 354, 356, 365, 369, 375, 381,
389, 394, 394, 410, 417, 424, 425, 432, 436, 439, 444, 448, 452,
455, 457, 459, 465, 469, 477, 481, 486, 494, 497, 502, 507, 511,
516,
};
static const unsigned char aCode[118] = {
TK_REINDEX, TK_INDEXED, TK_INDEX, TK_DESC, TK_ESCAPE,
TK_EACH, TK_CHECK, TK_KEY, TK_BEFORE, TK_FOREIGN,
TK_FOR, TK_IGNORE, TK_LIKE_KW, TK_EXPLAIN, TK_INSTEAD,
TK_ADD, TK_DATABASE, TK_AS, TK_SELECT, TK_TABLE,
TK_JOIN_KW, TK_THEN, TK_END, TK_DEFERRABLE, TK_ELSE,
TK_EXCEPT, TK_TRANSACTION,TK_ACTION, TK_ON, TK_JOIN_KW,
TK_ALTER, TK_RAISE, TK_EXCLUSIVE, TK_EXISTS, TK_SAVEPOINT,
TK_INTERSECT, TK_TRIGGER, TK_REFERENCES, TK_CONSTRAINT, TK_INTO,
TK_OFFSET, TK_OF, TK_SET, TK_TEMP, TK_TEMP,
TK_OR, TK_UNIQUE, TK_QUERY, TK_ATTACH, TK_HAVING,
TK_GROUP, TK_UPDATE, TK_BEGIN, TK_JOIN_KW, TK_RELEASE,
TK_BETWEEN, TK_NOTNULL, TK_NOT, TK_NO, TK_NULL,
TK_LIKE_KW, TK_CASCADE, TK_ASC, TK_DELETE, TK_CASE,
TK_COLLATE, TK_CREATE, TK_CTIME_KW, TK_DETACH, TK_IMMEDIATE,
TK_JOIN, TK_INSERT, TK_MATCH, TK_PLAN, TK_AND,
TK_DEFAULT, TK_PRAGMA, TK_ABORT, TK_VALUES, TK_WHEN,
TK_WHERE, TK_RENAME, TK_AFTER, TK_REPLACE, TK_AUTOINCR,
TK_TO, TK_IN, TK_CAST, TK_COLUMNKW, TK_COMMIT,
TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW, TK_CTIME_KW, TK_PRIMARY,
TK_DEFERRED, TK_DISTINCT, TK_IS, TK_DROP, TK_FAIL,
TK_LIMIT, TK_FROM, TK_JOIN_KW, TK_LIKE_KW, TK_BY,
TK_IF, TK_ISNULL, TK_ORDER, TK_RESTRICT, TK_JOIN_KW,
TK_JOIN_KW, TK_ROLLBACK, TK_ROW, TK_UNION, TK_USING,
TK_VIEW, TK_INITIALLY, TK_ALL,
};
int h, i;
if( n<2 ) return TK_ID;
h = ((charMap(z[0])*4) ^
(charMap(z[n-1])*3) ^
n) % 127;
for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){
if( aLen[i]==n && sqlite4StrNICmp(&zText[aOffset[i]],z,n)==0 ){
testcase( i==0 ); /* REINDEX */
testcase( i==1 ); /* INDEXED */
testcase( i==2 ); /* INDEX */
testcase( i==3 ); /* DESC */
testcase( i==4 ); /* ESCAPE */
testcase( i==5 ); /* EACH */
testcase( i==6 ); /* CHECK */
testcase( i==7 ); /* KEY */
testcase( i==8 ); /* BEFORE */
testcase( i==9 ); /* FOREIGN */
testcase( i==10 ); /* FOR */
testcase( i==11 ); /* IGNORE */
testcase( i==12 ); /* REGEXP */
testcase( i==13 ); /* EXPLAIN */
testcase( i==14 ); /* INSTEAD */
testcase( i==15 ); /* ADD */
testcase( i==16 ); /* DATABASE */
testcase( i==17 ); /* AS */
testcase( i==18 ); /* SELECT */
testcase( i==19 ); /* TABLE */
testcase( i==20 ); /* LEFT */
testcase( i==21 ); /* THEN */
testcase( i==22 ); /* END */
testcase( i==23 ); /* DEFERRABLE */
testcase( i==24 ); /* ELSE */
testcase( i==25 ); /* EXCEPT */
testcase( i==26 ); /* TRANSACTION */
testcase( i==27 ); /* ACTION */
testcase( i==28 ); /* ON */
testcase( i==29 ); /* NATURAL */
testcase( i==30 ); /* ALTER */
testcase( i==31 ); /* RAISE */
testcase( i==32 ); /* EXCLUSIVE */
testcase( i==33 ); /* EXISTS */
testcase( i==34 ); /* SAVEPOINT */
testcase( i==35 ); /* INTERSECT */
testcase( i==36 ); /* TRIGGER */
testcase( i==37 ); /* REFERENCES */
testcase( i==38 ); /* CONSTRAINT */
testcase( i==39 ); /* INTO */
testcase( i==40 ); /* OFFSET */
testcase( i==41 ); /* OF */
testcase( i==42 ); /* SET */
testcase( i==43 ); /* TEMPORARY */
testcase( i==44 ); /* TEMP */
testcase( i==45 ); /* OR */
testcase( i==46 ); /* UNIQUE */
testcase( i==47 ); /* QUERY */
testcase( i==48 ); /* ATTACH */
testcase( i==49 ); /* HAVING */
testcase( i==50 ); /* GROUP */
testcase( i==51 ); /* UPDATE */
testcase( i==52 ); /* BEGIN */
testcase( i==53 ); /* INNER */
testcase( i==54 ); /* RELEASE */
testcase( i==55 ); /* BETWEEN */
testcase( i==56 ); /* NOTNULL */
testcase( i==57 ); /* NOT */
testcase( i==58 ); /* NO */
testcase( i==59 ); /* NULL */
testcase( i==60 ); /* LIKE */
testcase( i==61 ); /* CASCADE */
testcase( i==62 ); /* ASC */
testcase( i==63 ); /* DELETE */
testcase( i==64 ); /* CASE */
testcase( i==65 ); /* COLLATE */
testcase( i==66 ); /* CREATE */
testcase( i==67 ); /* CURRENT_DATE */
testcase( i==68 ); /* DETACH */
testcase( i==69 ); /* IMMEDIATE */
testcase( i==70 ); /* JOIN */
testcase( i==71 ); /* INSERT */
testcase( i==72 ); /* MATCH */
testcase( i==73 ); /* PLAN */
testcase( i==74 ); /* AND */
testcase( i==75 ); /* DEFAULT */
testcase( i==76 ); /* PRAGMA */
testcase( i==77 ); /* ABORT */
testcase( i==78 ); /* VALUES */
testcase( i==79 ); /* WHEN */
testcase( i==80 ); /* WHERE */
testcase( i==81 ); /* RENAME */
testcase( i==82 ); /* AFTER */
testcase( i==83 ); /* REPLACE */
testcase( i==84 ); /* AUTOINCREMENT */
testcase( i==85 ); /* TO */
testcase( i==86 ); /* IN */
testcase( i==87 ); /* CAST */
testcase( i==88 ); /* COLUMN */
testcase( i==89 ); /* COMMIT */
testcase( i==90 ); /* CONFLICT */
testcase( i==91 ); /* CROSS */
testcase( i==92 ); /* CURRENT_TIMESTAMP */
testcase( i==93 ); /* CURRENT_TIME */
testcase( i==94 ); /* PRIMARY */
testcase( i==95 ); /* DEFERRED */
testcase( i==96 ); /* DISTINCT */
testcase( i==97 ); /* IS */
testcase( i==98 ); /* DROP */
testcase( i==99 ); /* FAIL */
testcase( i==100 ); /* LIMIT */
testcase( i==101 ); /* FROM */
testcase( i==102 ); /* FULL */
testcase( i==103 ); /* GLOB */
testcase( i==104 ); /* BY */
testcase( i==105 ); /* IF */
testcase( i==106 ); /* ISNULL */
testcase( i==107 ); /* ORDER */
testcase( i==108 ); /* RESTRICT */
testcase( i==109 ); /* OUTER */
testcase( i==110 ); /* RIGHT */
testcase( i==111 ); /* ROLLBACK */
testcase( i==112 ); /* ROW */
testcase( i==113 ); /* UNION */
testcase( i==114 ); /* USING */
testcase( i==115 ); /* VIEW */
testcase( i==116 ); /* INITIALLY */
testcase( i==117 ); /* ALL */
return aCode[i];
}
}
return TK_ID;
}
SQLITE_PRIVATE int sqlite4KeywordCode(const unsigned char *z, int n){
return keywordCode((char*)z, n);
}
#define SQLITE_N_KEYWORD 118
/************** End of keywordhash.h *****************************************/
/************** Continuing where we left off in tokenize.c *******************/
/*
** If X is a character that can be used in an identifier then
** IdChar(X) will be true. Otherwise it is false.
**
** For ASCII, any character with the high-order bit set is
** allowed in an identifier. For 7-bit characters,
** sqlite4IsIdChar[X] must be 1.
**
** For EBCDIC, the rules are more complex but have the same
** end result.
**
** Ticket #1066. the SQL standard does not allow '$' in the
** middle of identfiers. But many SQL implementations do.
** SQLite will allow '$' in identifiers for compatibility.
** But the feature is undocumented.
*/
#ifdef SQLITE_ASCII
#define IdChar(C) ((sqlite4CtypeMap[(unsigned char)C]&0x46)!=0)
#endif
#ifdef SQLITE_EBCDIC
SQLITE_PRIVATE const char sqlite4IsEbcdicIdChar[] = {
/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 4x */
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, /* 5x */
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, /* 6x */
0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, /* 7x */
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, /* 8x */
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, /* 9x */
1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, /* Ax */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Bx */
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Cx */
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Dx */
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Ex */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, /* Fx */
};
#define IdChar(C) (((c=C)>=0x42 && sqlite4IsEbcdicIdChar[c-0x40]))
#endif
/*
** Return the length of the token that begins at z[0].
** Store the token type in *tokenType before returning.
*/
SQLITE_PRIVATE int sqlite4GetToken(const unsigned char *z, int *tokenType){
int i, c;
switch( *z ){
case ' ': case '\t': case '\n': case '\f': case '\r': {
testcase( z[0]==' ' );
testcase( z[0]=='\t' );
testcase( z[0]=='\n' );
testcase( z[0]=='\f' );
testcase( z[0]=='\r' );
for(i=1; sqlite4Isspace(z[i]); i++){}
*tokenType = TK_SPACE;
return i;
}
case '-': {
if( z[1]=='-' ){
/* IMP: R-50417-27976 -- syntax diagram for comments */
for(i=2; (c=z[i])!=0 && c!='\n'; i++){}
*tokenType = TK_SPACE; /* IMP: R-22934-25134 */
return i;
}
*tokenType = TK_MINUS;
return 1;
}
case '(': {
*tokenType = TK_LP;
return 1;
}
case ')': {
*tokenType = TK_RP;
return 1;
}
case ';': {
*tokenType = TK_SEMI;
return 1;
}
case '+': {
*tokenType = TK_PLUS;
return 1;
}
case '*': {
*tokenType = TK_STAR;
return 1;
}
case '/': {
if( z[1]!='*' || z[2]==0 ){
*tokenType = TK_SLASH;
return 1;
}
/* IMP: R-50417-27976 -- syntax diagram for comments */
for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}
if( c ) i++;
*tokenType = TK_SPACE; /* IMP: R-22934-25134 */
return i;
}
case '%': {
*tokenType = TK_REM;
return 1;
}
case '=': {
*tokenType = TK_EQ;
return 1 + (z[1]=='=');
}
case '<': {
if( (c=z[1])=='=' ){
*tokenType = TK_LE;
return 2;
}else if( c=='>' ){
*tokenType = TK_NE;
return 2;
}else if( c=='<' ){
*tokenType = TK_LSHIFT;
return 2;
}else{
*tokenType = TK_LT;
return 1;
}
}
case '>': {
if( (c=z[1])=='=' ){
*tokenType = TK_GE;
return 2;
}else if( c=='>' ){
*tokenType = TK_RSHIFT;
return 2;
}else{
*tokenType = TK_GT;
return 1;
}
}
case '!': {
if( z[1]!='=' ){
*tokenType = TK_ILLEGAL;
return 2;
}else{
*tokenType = TK_NE;
return 2;
}
}
case '|': {
if( z[1]!='|' ){
*tokenType = TK_BITOR;
return 1;
}else{
*tokenType = TK_CONCAT;
return 2;
}
}
case ',': {
*tokenType = TK_COMMA;
return 1;
}
case '&': {
*tokenType = TK_BITAND;
return 1;
}
case '~': {
*tokenType = TK_BITNOT;
return 1;
}
case '`':
case '\'':
case '"': {
int delim = z[0];
testcase( delim=='`' );
testcase( delim=='\'' );
testcase( delim=='"' );
for(i=1; (c=z[i])!=0; i++){
if( c==delim ){
if( z[i+1]==delim ){
i++;
}else{
break;
}
}
}
if( c=='\'' ){
*tokenType = TK_STRING;
return i+1;
}else if( c!=0 ){
*tokenType = TK_ID;
return i+1;
}else{
*tokenType = TK_ILLEGAL;
return i;
}
}
case '.': {
#ifndef SQLITE_OMIT_FLOATING_POINT
if( !sqlite4Isdigit(z[1]) )
#endif
{
*tokenType = TK_DOT;
return 1;
}
/* If the next character is a digit, this is a floating point
** number that begins with ".". Fall thru into the next case */
}
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': {
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' );
testcase( z[0]=='9' );
*tokenType = TK_INTEGER;
for(i=0; sqlite4Isdigit(z[i]); i++){}
#ifndef SQLITE_OMIT_FLOATING_POINT
if( z[i]=='.' ){
i++;
while( sqlite4Isdigit(z[i]) ){ i++; }
*tokenType = TK_FLOAT;
}
if( (z[i]=='e' || z[i]=='E') &&
( sqlite4Isdigit(z[i+1])
|| ((z[i+1]=='+' || z[i+1]=='-') && sqlite4Isdigit(z[i+2]))
)
){
i += 2;
while( sqlite4Isdigit(z[i]) ){ i++; }
*tokenType = TK_FLOAT;
}
#endif
while( IdChar(z[i]) ){
*tokenType = TK_ILLEGAL;
i++;
}
return i;
}
case '[': {
for(i=1, c=z[0]; c!=']' && (c=z[i])!=0; i++){}
*tokenType = c==']' ? TK_ID : TK_ILLEGAL;
return i;
}
case '?': {
*tokenType = TK_VARIABLE;
for(i=1; sqlite4Isdigit(z[i]); i++){}
return i;
}
case '#': {
for(i=1; sqlite4Isdigit(z[i]); i++){}
if( i>1 ){
/* Parameters of the form #NNN (where NNN is a number) are used
** internally by sqlite4NestedParse. */
*tokenType = TK_REGISTER;
return i;
}
/* Fall through into the next case if the '#' is not followed by
** a digit. Try to match #AAAA where AAAA is a parameter name. */
}
#ifndef SQLITE_OMIT_TCL_VARIABLE
case '$':
#endif
case '@': /* For compatibility with MS SQL Server */
case ':': {
int n = 0;
testcase( z[0]=='$' ); testcase( z[0]=='@' ); testcase( z[0]==':' );
*tokenType = TK_VARIABLE;
for(i=1; (c=z[i])!=0; i++){
if( IdChar(c) ){
n++;
#ifndef SQLITE_OMIT_TCL_VARIABLE
}else if( c=='(' && n>0 ){
do{
i++;
}while( (c=z[i])!=0 && !sqlite4Isspace(c) && c!=')' );
if( c==')' ){
i++;
}else{
*tokenType = TK_ILLEGAL;
}
break;
}else if( c==':' && z[i+1]==':' ){
i++;
#endif
}else{
break;
}
}
if( n==0 ) *tokenType = TK_ILLEGAL;
return i;
}
#ifndef SQLITE_OMIT_BLOB_LITERAL
case 'x': case 'X': {
testcase( z[0]=='x' ); testcase( z[0]=='X' );
if( z[1]=='\'' ){
*tokenType = TK_BLOB;
for(i=2; sqlite4Isxdigit(z[i]); i++){}
if( z[i]!='\'' || i%2 ){
*tokenType = TK_ILLEGAL;
while( z[i] && z[i]!='\'' ){ i++; }
}
if( z[i] ) i++;
return i;
}
/* Otherwise fall through to the next case */
}
#endif
default: {
if( !IdChar(*z) ){
break;
}
for(i=1; IdChar(z[i]); i++){}
*tokenType = keywordCode((char*)z, i);
return i;
}
}
*tokenType = TK_ILLEGAL;
return 1;
}
/*
** Run the parser on the given SQL string. The parser structure is
** passed in. An SQLITE_ status code is returned. If an error occurs
** then an and attempt is made to write an error message into
** memory obtained from sqlite4_malloc() and to make *pzErrMsg point to that
** error message.
*/
SQLITE_PRIVATE int sqlite4RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
int nErr = 0; /* Number of errors encountered */
int i; /* Loop counter */
void *pEngine; /* The LEMON-generated LALR(1) parser */
int tokenType; /* type of the next token */
int lastTokenParsed = -1; /* type of the previous token */
u8 enableLookaside; /* Saved value of db->lookaside.bEnabled */
sqlite4 *db = pParse->db; /* The database connection */
int mxSqlLen; /* Max length of an SQL string */
mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
if( db->activeVdbeCnt==0 ){
db->u1.isInterrupted = 0;
}
pParse->rc = SQLITE_OK;
pParse->zTail = zSql;
i = 0;
assert( pzErrMsg!=0 );
pEngine = sqlite4ParserAlloc((void*(*)(void*,size_t))sqlite4_malloc,db->pEnv);
if( pEngine==0 ){
db->mallocFailed = 1;
return SQLITE_NOMEM;
}
assert( pParse->pNewTable==0 );
assert( pParse->pNewTrigger==0 );
assert( pParse->nVar==0 );
assert( pParse->nzVar==0 );
assert( pParse->azVar==0 );
enableLookaside = db->lookaside.bEnabled;
if( db->lookaside.pStart ) db->lookaside.bEnabled = 1;
while( !db->mallocFailed && zSql[i]!=0 ){
assert( i>=0 );
pParse->sLastToken.z = &zSql[i];
pParse->sLastToken.n = sqlite4GetToken((unsigned char*)&zSql[i],&tokenType);
i += pParse->sLastToken.n;
if( i>mxSqlLen ){
pParse->rc = SQLITE_TOOBIG;
break;
}
switch( tokenType ){
case TK_SPACE: {
if( db->u1.isInterrupted ){
sqlite4ErrorMsg(pParse, "interrupt");
pParse->rc = SQLITE_INTERRUPT;
goto abort_parse;
}
break;
}
case TK_ILLEGAL: {
sqlite4DbFree(db, *pzErrMsg);
*pzErrMsg = sqlite4MPrintf(db, "unrecognized token: \"%T\"",
&pParse->sLastToken);
nErr++;
goto abort_parse;
}
case TK_SEMI: {
pParse->zTail = &zSql[i];
/* Fall thru into the default case */
}
default: {
sqlite4Parser(pEngine, tokenType, pParse->sLastToken, pParse);
lastTokenParsed = tokenType;
if( pParse->rc!=SQLITE_OK ){
goto abort_parse;
}
break;
}
}
}
abort_parse:
if( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ){
if( lastTokenParsed!=TK_SEMI ){
sqlite4Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
pParse->zTail = &zSql[i];
}
sqlite4Parser(pEngine, 0, pParse->sLastToken, pParse);
}
#if YYTRACKMAXSTACKDEPTH
sqlite4StatusSet(SQLITE_STATUS_PARSER_STACK,
sqlite4ParserStackPeak(pEngine)
);
#endif
sqlite4ParserFree(pEngine, (void(*)(void*,void*))sqlite4_free);
db->lookaside.bEnabled = enableLookaside;
if( db->mallocFailed ){
pParse->rc = SQLITE_NOMEM;
}
if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
sqlite4SetString(&pParse->zErrMsg, db, "%s", sqlite4ErrStr(pParse->rc));
}
assert( pzErrMsg!=0 );
if( pParse->zErrMsg ){
*pzErrMsg = pParse->zErrMsg;
sqlite4_log(db->pEnv, pParse->rc, "%s", *pzErrMsg);
pParse->zErrMsg = 0;
nErr++;
}
if( pParse->pVdbe && pParse->nErr>0 && pParse->nested==0 ){
sqlite4VdbeDelete(pParse->pVdbe);
pParse->pVdbe = 0;
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
sqlite4_free(0, pParse->apVtabLock);
#endif
if( !IN_DECLARE_VTAB ){
/* If the pParse->declareVtab flag is set, do not delete any table
** structure built up in pParse->pNewTable. The calling code (see vtab.c)
** will take responsibility for freeing the Table structure.
*/
sqlite4DeleteTable(db, pParse->pNewTable);
}
sqlite4DeleteTrigger(db, pParse->pNewTrigger);
for(i=pParse->nzVar-1; i>=0; i--) sqlite4DbFree(db, pParse->azVar[i]);
sqlite4DbFree(db, pParse->azVar);
sqlite4DbFree(db, pParse->aAlias);
while( pParse->pAinc ){
AutoincInfo *p = pParse->pAinc;
pParse->pAinc = p->pNext;
sqlite4DbFree(db, p);
}
while( pParse->pZombieTab ){
Table *p = pParse->pZombieTab;
pParse->pZombieTab = p->pNextZombie;
sqlite4DeleteTable(db, p);
}
if( nErr>0 && pParse->rc==SQLITE_OK ){
pParse->rc = SQLITE_ERROR;
}
return nErr;
}
/************** End of tokenize.c ********************************************/
/************** Begin file complete.c ****************************************/
/*
** 2001 September 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.
**
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that implements the sqlite4_complete() API.
** This code used to be part of the tokenizer.c source file. But by
** separating it out, the code will be automatically omitted from
** static links that do not use it.
*/
#ifndef SQLITE_OMIT_COMPLETE
/*
** This is defined in tokenize.c. We just have to import the definition.
*/
#ifndef SQLITE_AMALGAMATION
#ifdef SQLITE_ASCII
#define IdChar(C) ((sqlite4CtypeMap[(unsigned char)C]&0x46)!=0)
#endif
#ifdef SQLITE_EBCDIC
SQLITE_PRIVATE const char sqlite4IsEbcdicIdChar[];
#define IdChar(C) (((c=C)>=0x42 && sqlite4IsEbcdicIdChar[c-0x40]))
#endif
#endif /* SQLITE_AMALGAMATION */
/*
** Token types used by the sqlite4_complete() routine. See the header
** comments on that procedure for additional information.
*/
#define tkSEMI 0
#define tkWS 1
#define tkOTHER 2
#ifndef SQLITE_OMIT_TRIGGER
#define tkEXPLAIN 3
#define tkCREATE 4
#define tkTEMP 5
#define tkTRIGGER 6
#define tkEND 7
#endif
/*
** Return TRUE if the given SQL string ends in a semicolon.
**
** Special handling is require for CREATE TRIGGER statements.
** Whenever the CREATE TRIGGER keywords are seen, the statement
** must end with ";END;".
**
** This implementation uses a state machine with 8 states:
**
** (0) INVALID We have not yet seen a non-whitespace character.
**
** (1) START At the beginning or end of an SQL statement. This routine
** returns 1 if it ends in the START state and 0 if it ends
** in any other state.
**
** (2) NORMAL We are in the middle of statement which ends with a single
** semicolon.
**
** (3) EXPLAIN The keyword EXPLAIN has been seen at the beginning of
** a statement.
**
** (4) CREATE The keyword CREATE has been seen at the beginning of a
** statement, possibly preceeded by EXPLAIN and/or followed by
** TEMP or TEMPORARY
**
** (5) TRIGGER We are in the middle of a trigger definition that must be
** ended by a semicolon, the keyword END, and another semicolon.
**
** (6) SEMI We've seen the first semicolon in the ";END;" that occurs at
** the end of a trigger definition.
**
** (7) END We've seen the ";END" of the ";END;" that occurs at the end
** of a trigger difinition.
**
** Transitions between states above are determined by tokens extracted
** from the input. The following tokens are significant:
**
** (0) tkSEMI A semicolon.
** (1) tkWS Whitespace.
** (2) tkOTHER Any other SQL token.
** (3) tkEXPLAIN The "explain" keyword.
** (4) tkCREATE The "create" keyword.
** (5) tkTEMP The "temp" or "temporary" keyword.
** (6) tkTRIGGER The "trigger" keyword.
** (7) tkEND The "end" keyword.
**
** Whitespace never causes a state transition and is always ignored.
** This means that a SQL string of all whitespace is invalid.
**
** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed
** 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 sqlite4_complete(const char *zSql){
u8 state = 0; /* Current state, using numbers defined in header comment */
u8 token; /* Value of the next token */
#ifndef SQLITE_OMIT_TRIGGER
/* A complex statement machine used to detect the end of a CREATE TRIGGER
** statement. This is the normal case.
*/
static const u8 trans[8][8] = {
/* Token: */
/* State: ** SEMI WS OTHER EXPLAIN CREATE TEMP TRIGGER END */
/* 0 INVALID: */ { 1, 0, 2, 3, 4, 2, 2, 2, },
/* 1 START: */ { 1, 1, 2, 3, 4, 2, 2, 2, },
/* 2 NORMAL: */ { 1, 2, 2, 2, 2, 2, 2, 2, },
/* 3 EXPLAIN: */ { 1, 3, 3, 2, 4, 2, 2, 2, },
/* 4 CREATE: */ { 1, 4, 2, 2, 2, 4, 5, 2, },
/* 5 TRIGGER: */ { 6, 5, 5, 5, 5, 5, 5, 5, },
/* 6 SEMI: */ { 6, 6, 5, 5, 5, 5, 5, 7, },
/* 7 END: */ { 1, 7, 5, 5, 5, 5, 5, 5, },
};
#else
/* If triggers are not supported by this compile then the statement machine
** used to detect the end of a statement is much simplier
*/
static const u8 trans[3][3] = {
/* Token: */
/* State: ** SEMI WS OTHER */
/* 0 INVALID: */ { 1, 0, 2, },
/* 1 START: */ { 1, 1, 2, },
/* 2 NORMAL: */ { 1, 2, 2, },
};
#endif /* SQLITE_OMIT_TRIGGER */
while( *zSql ){
switch( *zSql ){
case ';': { /* A semicolon */
token = tkSEMI;
break;
}
case ' ':
case '\r':
case '\t':
case '\n':
case '\f': { /* White space is ignored */
token = tkWS;
break;
}
case '/': { /* C-style comments */
if( zSql[1]!='*' ){
token = tkOTHER;
break;
}
zSql += 2;
while( zSql[0] && (zSql[0]!='*' || zSql[1]!='/') ){ zSql++; }
if( zSql[0]==0 ) return 0;
zSql++;
token = tkWS;
break;
}
case '-': { /* SQL-style comments from "--" to end of line */
if( zSql[1]!='-' ){
token = tkOTHER;
break;
}
while( *zSql && *zSql!='\n' ){ zSql++; }
if( *zSql==0 ) return state==1;
token = tkWS;
break;
}
case '[': { /* Microsoft-style identifiers in [...] */
zSql++;
while( *zSql && *zSql!=']' ){ zSql++; }
if( *zSql==0 ) return 0;
token = tkOTHER;
break;
}
case '`': /* Grave-accent quoted symbols used by MySQL */
case '"': /* single- and double-quoted strings */
case '\'': {
int c = *zSql;
zSql++;
while( *zSql && *zSql!=c ){ zSql++; }
if( *zSql==0 ) return 0;
token = tkOTHER;
break;
}
default: {
#ifdef SQLITE_EBCDIC
unsigned char c;
#endif
if( IdChar((u8)*zSql) ){
/* Keywords and unquoted identifiers */
int nId;
for(nId=1; IdChar(zSql[nId]); nId++){}
#ifdef SQLITE_OMIT_TRIGGER
token = tkOTHER;
#else
switch( *zSql ){
case 'c': case 'C': {
if( nId==6 && sqlite4StrNICmp(zSql, "create", 6)==0 ){
token = tkCREATE;
}else{
token = tkOTHER;
}
break;
}
case 't': case 'T': {
if( nId==7 && sqlite4StrNICmp(zSql, "trigger", 7)==0 ){
token = tkTRIGGER;
}else if( nId==4 && sqlite4StrNICmp(zSql, "temp", 4)==0 ){
token = tkTEMP;
}else if( nId==9 && sqlite4StrNICmp(zSql, "temporary", 9)==0 ){
token = tkTEMP;
}else{
token = tkOTHER;
}
break;
}
case 'e': case 'E': {
if( nId==3 && sqlite4StrNICmp(zSql, "end", 3)==0 ){
token = tkEND;
}else
#ifndef SQLITE_OMIT_EXPLAIN
if( nId==7 && sqlite4StrNICmp(zSql, "explain", 7)==0 ){
token = tkEXPLAIN;
}else
#endif
{
token = tkOTHER;
}
break;
}
default: {
token = tkOTHER;
break;
}
}
#endif /* SQLITE_OMIT_TRIGGER */
zSql += nId-1;
}else{
/* Operators and special symbols */
token = tkOTHER;
}
break;
}
}
state = trans[state][token];
zSql++;
}
return state==1;
}
#ifndef SQLITE_OMIT_UTF16
/*
** This routine is the same as the sqlite4_complete() routine described
** above, except that the parameter is required to be UTF-16 encoded, not
** UTF-8.
*/
SQLITE_API int sqlite4_complete16(const void *zSql){
sqlite4_value *pVal;
char const *zSql8;
int rc = SQLITE_NOMEM;
#ifndef SQLITE_OMIT_AUTOINIT
rc = sqlite4_initialize(0);
if( rc ) return rc;
#endif
pVal = sqlite4ValueNew(0);
sqlite4ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);
zSql8 = sqlite4ValueText(pVal, SQLITE_UTF8);
if( zSql8 ){
rc = sqlite4_complete(zSql8);
}else{
rc = SQLITE_NOMEM;
}
sqlite4ValueFree(pVal);
return sqlite4ApiExit(0, rc);
}
#endif /* SQLITE_OMIT_UTF16 */
#endif /* SQLITE_OMIT_COMPLETE */
/************** End of complete.c ********************************************/
/************** Begin file main.c ********************************************/
/*
** 2001 September 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.
**
*************************************************************************
** Main file for the SQLite library. The routines in this file
** implement the programmer interface to the library. Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
*/
#ifdef SQLITE_ENABLE_FTS3
# include "fts3.h"
#endif
#ifdef SQLITE_ENABLE_RTREE
# include "rtree.h"
#endif
#ifdef SQLITE_ENABLE_ICU
# include "sqliteicu.h"
#endif
/*
** Dummy function used as a unique symbol for SQLITE_DYNAMIC
*/
SQLITE_API void sqlite4_dynamic(void *p){ (void)p; }
#ifndef SQLITE_AMALGAMATION
/* IMPLEMENTATION-OF: R-46656-45156 The sqlite4_version[] string constant
** contains the text of SQLITE_VERSION macro.
*/
SQLITE_API const char sqlite4_version[] = SQLITE_VERSION;
#endif
/* IMPLEMENTATION-OF: R-53536-42575 The sqlite4_libversion() function returns
** a pointer to the to the sqlite4_version[] string constant.
*/
SQLITE_API const char *sqlite4_libversion(void){ return SQLITE_VERSION; }
/* IMPLEMENTATION-OF: R-63124-39300 The sqlite4_sourceid() function returns a
** pointer to a string constant whose value is the same as the
** SQLITE_SOURCE_ID C preprocessor macro.
*/
SQLITE_API const char *sqlite4_sourceid(void){ return SQLITE_SOURCE_ID; }
/* IMPLEMENTATION-OF: R-35210-63508 The sqlite4_libversion_number() function
** returns an integer equal to SQLITE_VERSION_NUMBER.
*/
SQLITE_API int sqlite4_libversion_number(void){ return SQLITE_VERSION_NUMBER; }
/* Return the thread-safety setting.
*/
SQLITE_API int sqlite4_threadsafe(sqlite4_env *pEnv){
if( pEnv==0 ) pEnv = &sqlite4DefaultEnv;
return pEnv->bCoreMutex + pEnv->bFullMutex;
}
#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)
/*
** If the following function pointer is not NULL and if
** SQLITE_ENABLE_IOTRACE is enabled, then messages describing
** I/O active are written using this function. These messages
** are intended for debugging activity only.
*/
SQLITE_PRIVATE void (*sqlite4IoTrace)(const char*, ...) = 0;
#endif
/*
** Initialize SQLite.
**
** This routine must be called to initialize the run-time environment
** As long as you do not compile with SQLITE_OMIT_AUTOINIT
** this routine will be called automatically by key routines such as
** sqlite4_open().
**
** This routine is a no-op except on its very first call for a given
** sqlite4_env object, or for the first call after a call to sqlite4_shutdown.
**
** This routine is not threadsafe. It should be called from a single
** thread to initialized the library in a multi-threaded system. Other
** threads should avoid using the sqlite4_env object until after it has
** completely initialized.
*/
SQLITE_API int sqlite4_initialize(sqlite4_env *pEnv){
MUTEX_LOGIC( sqlite4_mutex *pMaster; ) /* The main static mutex */
int rc; /* Result code */
if( pEnv==0 ) pEnv = &sqlite4DefaultEnv;
/* If SQLite is already completely initialized, then this call
** to sqlite4_initialize() should be a no-op. But the initialization
** must be complete. So isInit must not be set until the very end
** of this routine.
*/
if( pEnv->isInit ) return SQLITE_OK;
/* Initialize the mutex subsystem
*/
rc = sqlite4MutexInit(pEnv);
if( rc ){
sqlite4MallocEnd(pEnv);
return rc;
}
/* Initialize the memory allocation subsystem
*/
rc = sqlite4MallocInit(pEnv);
if( rc ) return rc;
/* Create required mutexes
*/
if( pEnv->bCoreMutex ){
pEnv->pMemMutex = sqlite4MutexAlloc(pEnv, SQLITE_MUTEX_FAST);
pEnv->pPrngMutex = sqlite4MutexAlloc(pEnv, SQLITE_MUTEX_FAST);
pEnv->pFactoryMutex = sqlite4MutexAlloc(pEnv, SQLITE_MUTEX_FAST);
if( pEnv->pMemMutex==0
|| pEnv->pPrngMutex==0
|| pEnv->pFactoryMutex==0
){
rc = SQLITE_NOMEM;
}
}else{
pEnv->pMemMutex = 0;
pEnv->pPrngMutex = 0;
}
pEnv->isInit = 1;
sqlite4OsInit(pEnv);
/* Register global functions */
if( rc==SQLITE_OK ){
sqlite4RegisterGlobalFunctions(pEnv);
}
/* The following is just a sanity check to make sure SQLite has
** been compiled correctly. It is important to run this code, but
** we don't want to run it too often and soak up CPU cycles for no
** reason. So we run it once during initialization.
*/
#ifndef NDEBUG
#ifndef SQLITE_OMIT_FLOATING_POINT
/* This section of code's only "output" is via assert() statements. */
if ( rc==SQLITE_OK ){
u64 x = (((u64)1)<<63)-1;
double y;
assert(sizeof(x)==8);
assert(sizeof(x)==sizeof(y));
memcpy(&y, &x, 8);
assert( sqlite4IsNaN(y) );
}
#endif
#endif
return rc;
}
/*
** Undo the effects of sqlite4_initialize(). Must not be called while
** there are outstanding database connections or memory allocations or
** while any part of SQLite is otherwise in use in any thread. This
** routine is not threadsafe. But it is safe to invoke this routine
** 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 sqlite4_shutdown(sqlite4_env *pEnv){
if( pEnv==0 ) pEnv = &sqlite4DefaultEnv;
if( pEnv->isInit ){
KVFactory *pMkr;
sqlite4_mutex_free(pEnv->pFactoryMutex);
sqlite4_mutex_free(pEnv->pPrngMutex);
sqlite4_mutex_free(pEnv->pMemMutex);
pEnv->pMemMutex = 0;
while( (pMkr = pEnv->pFactory)!=0 && pMkr->isPerm==0 ){
KVFactory *pNext = pMkr->pNext;
sqlite4_free(pEnv, pMkr);
pMkr = pNext;
}
sqlite4MutexEnd(pEnv);
sqlite4MallocEnd(pEnv);
pEnv->isInit = 0;
}
return SQLITE_OK;
}
/*
** Return the size of an sqlite4_env object
*/
SQLITE_API int sqlite4_env_size(void){ return sizeof(sqlite4_env); }
/*
** This API allows applications to modify the configuration described by
** an sqlite4_env object.
*/
SQLITE_API int sqlite4_env_config(sqlite4_env *pEnv, int op, ...){
va_list ap;
int rc = SQLITE_OK;
if( pEnv==0 ) pEnv = sqlite4_env_default();
va_start(ap, op);
switch( op ){
/*
** sqlite4_env_config(pEnv, SQLITE_ENVCONFIG_INIT, template);
**
** Turn bulk memory into a new sqlite4_env object. The template is
** a prior sqlite4_env that is used as a template in initializing the
** new sqlite4_env object. The size of the bulk memory must be at
** least as many bytes as returned from sqlite4_env_size().
*/
case SQLITE_ENVCONFIG_INIT: {
/* Disable all mutexing */
sqlite4_env *pTemplate = va_arg(ap, sqlite4_env*);
int n = pTemplate->nByte;
if( n>sizeof(sqlite4_env) ) n = sizeof(sqlite4_env);
memcpy(pEnv, pTemplate, n);
pEnv->pFactory = &sqlite4BuiltinFactory;
pEnv->isInit = 0;
break;
}
/* Mutex configuration options are only available in a threadsafe
** compile.
*/
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0
/*
** sqlite4_env_config(pEnv, SQLITE_ENVCONFIG_SINGLETHREAD);
**
** Configure this environment for a single-threaded application.
*/
case SQLITE_ENVCONFIG_SINGLETHREAD: {
/* Disable all mutexing */
if( pEnv->isInit ){ rc = SQLITE_MISUSE; break; }
pEnv->bCoreMutex = 0;
pEnv->bFullMutex = 0;
break;
}
/*
** sqlite4_env_config(pEnv, SQLITE_ENVCONFIG_MULTITHREAD);
**
** Configure this environment for a multi-threaded application where
** the same database connection is never used by more than a single
** thread at a time.
*/
case SQLITE_ENVCONFIG_MULTITHREAD: {
/* Disable mutexing of database connections */
/* Enable mutexing of core data structures */
if( pEnv->isInit ){ rc = SQLITE_MISUSE; break; }
pEnv->bCoreMutex = 1;
pEnv->bFullMutex = 0;
break;
}
/*
** sqlite4_env_config(pEnv, SQLITE_ENVCONFIG_MULTITHREAD);
**
** Configure this environment for an unrestricted multi-threaded
** application where any thread can do whatever it wants with any
** database connection at any time.
*/
case SQLITE_ENVCONFIG_SERIALIZED: {
/* Enable all mutexing */
if( pEnv->isInit ){ rc = SQLITE_MISUSE; break; }
pEnv->bCoreMutex = 1;
pEnv->bFullMutex = 1;
break;
}
/*
** sqlite4_env_config(pEnv, SQLITE_ENVCONFIG_MUTEXT, sqlite4_mutex_methods*)
**
** Configure this environment to use the mutex routines specified by the
** argument.
*/
case SQLITE_ENVCONFIG_MUTEX: {
/* Specify an alternative mutex implementation */
if( pEnv->isInit ){ rc = SQLITE_MISUSE; break; }
pEnv->mutex = *va_arg(ap, sqlite4_mutex_methods*);
break;
}
/*
** sqlite4_env_config(p, SQLITE_ENVCONFIG_GETMUTEX, sqlite4_mutex_methods*)
**
** Copy the mutex routines in use by this environment into the structure
** given in the argument.
*/
case SQLITE_ENVCONFIG_GETMUTEX: {
/* Retrieve the current mutex implementation */
*va_arg(ap, sqlite4_mutex_methods*) = pEnv->mutex;
break;
}
#endif
/*
** sqlite4_env_config(p, SQLITE_ENVCONFIG_MALLOC, sqlite4_mem_methods*)
**
** Set the memory allocation routines to be used by this environment.
*/
case SQLITE_ENVCONFIG_MALLOC: {
/* Specify an alternative malloc implementation */
if( pEnv->isInit ) return SQLITE_MISUSE;
pEnv->m = *va_arg(ap, sqlite4_mem_methods*);
break;
}
/*
** sqlite4_env_config(p, SQLITE_ENVCONFIG_GETMALLOC, sqlite4_mem_methods*)
**
** Copy the memory allocation routines in use by this environment
** into the structure given in the argument.
*/
case SQLITE_ENVCONFIG_GETMALLOC: {
/* Retrieve the current malloc() implementation */
if( pEnv->m.xMalloc==0 ) sqlite4MemSetDefault(pEnv);
*va_arg(ap, sqlite4_mem_methods*) = pEnv->m;
break;
}
/* sqlite4_env_config(p, SQLITE_ENVCONFIG_MEMSTAT, int onoff);
**
** Enable or disable collection of memory usage statistics according to
** the onoff parameter.
*/
case SQLITE_ENVCONFIG_MEMSTATUS: {
/* Enable or disable the malloc status collection */
pEnv->bMemstat = va_arg(ap, int);
break;
}
/*
** sqlite4_env_config(p, SQLITE_ENVCONFIG_LOOKASIDE, size, count);
**
** Set the default lookaside memory settings for all subsequent
** database connections constructed in this environment. The size
** parameter is the size of each lookaside memory buffer and the
** count parameter is the number of lookaside buffers. Set both
** to zero to disable lookaside memory.
*/
case SQLITE_ENVCONFIG_LOOKASIDE: {
pEnv->szLookaside = va_arg(ap, int);
pEnv->nLookaside = va_arg(ap, int);
break;
}
/*
** sqlite4_env_config(p, SQLITE_ENVCONFIG_LOG, xOutput, pArg);
**
** Set the log function that is called in response to sqlite4_log()
** calls.
*/
case SQLITE_ENVCONFIG_LOG: {
/* MSVC is picky about pulling func ptrs from va lists.
** http://support.microsoft.com/kb/47961
** pEnv->xLog = va_arg(ap, void(*)(void*,int,const char*));
*/
typedef void(*LOGFUNC_t)(void*,int,const char*);
pEnv->xLog = va_arg(ap, LOGFUNC_t);
pEnv->pLogArg = va_arg(ap, void*);
break;
}
/*
** sqlite4_env_config(pEnv, SQLITE_ENVCONFIG_KVSTORE_PUSH, zName, xFactory);
**
** Push a new KVStore factory onto the factory stack. The new factory
** takes priority over prior factories.
*/
case SQLITE_ENVCONFIG_KVSTORE_PUSH: {
const char *zName = va_arg(ap, const char*);
int nName = sqlite4Strlen30(zName);
KVFactory *pMkr = sqlite4_malloc(pEnv, sizeof(*pMkr)+nName+1);
char *z;
if( pMkr==0 ) return SQLITE_NOMEM;
z = (char*)&pMkr[1];
memcpy(z, zName, nName+1);
memset(pMkr, 0, sizeof(*pMkr));
pMkr->zName = z;
pMkr->xFactory = va_arg(ap,
int(*)(sqlite4_env*, KVStore **, const char *, unsigned int)
);
sqlite4_mutex_enter(pEnv->pFactoryMutex);
pMkr->pNext = pEnv->pFactory;
pEnv->pFactory = pMkr;
sqlite4_mutex_leave(pEnv->pFactoryMutex);
break;
}
/*
** sqlite4_env_config(pEnv, SQLITE_ENVCONFIG_KVSTORE_POP, zName, &pxFact);
**
** Remove a KVStore factory from the stack.
*/
/*
** sqlite4_env_config(pEnv, SQLITE_ENVCONFIG_KVSTORE_GET, zName, &pxFact);
**
** Get the current factory pointer with the given name but leave the
** factory on the stack.
*/
case SQLITE_ENVCONFIG_KVSTORE_POP:
case SQLITE_ENVCONFIG_KVSTORE_GET: {
const char *zName = va_arg(ap, const char*);
KVFactory *pMkr, **ppPrev;
int (**pxFact)(sqlite4_env*,KVStore**,const char*,unsigned);
pxFact = va_arg(ap,int(**)(sqlite4_env*,KVStore*,const char*,unsigned));
*pxFact = 0;
sqlite4_mutex_enter(pEnv->pFactoryMutex);
ppPrev = &pEnv->pFactory;
pMkr = *ppPrev;
while( pMkr && strcmp(zName, pMkr->zName)!=0 ){
ppPrev = &pMkr->pNext;
pMkr = *ppPrev;
}
if( pMkr ){
*pxFact = pMkr->xFactory;
if( op==SQLITE_ENVCONFIG_KVSTORE_POP && pMkr->isPerm==0 ){
*ppPrev = pMkr->pNext;
sqlite4_free(pEnv, pMkr);
}
}
sqlite4_mutex_leave(pEnv->pFactoryMutex);
break;
}
default: {
rc = SQLITE_ERROR;
break;
}
}
va_end(ap);
return rc;
}
/*
** Set up the lookaside buffers for a database connection.
** Return SQLITE_OK on success.
** If lookaside is already active, return SQLITE_BUSY.
**
** The sz parameter is the number of bytes in each lookaside slot.
** The cnt parameter is the number of slots. If pStart is NULL the
** space for the lookaside memory is obtained from sqlite4_malloc().
** If pStart is not NULL then it is sz*cnt bytes of memory to use for
** the lookaside memory.
*/
static int setupLookaside(sqlite4 *db, void *pBuf, int sz, int cnt){
void *pStart;
if( db->lookaside.nOut ){
return SQLITE_BUSY;
}
/* Free any existing lookaside buffer for this handle before
** allocating a new one so we don't have to have space for
** both at the same time.
*/
if( db->lookaside.bMalloced ){
sqlite4_free(db->pEnv, db->lookaside.pStart);
}
/* The size of a lookaside slot after ROUNDDOWN8 needs to be larger
** than a pointer to be useful.
*/
sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */
if( sz<=(int)sizeof(LookasideSlot*) ) sz = 0;
if( cnt<0 ) cnt = 0;
if( sz==0 || cnt==0 ){
sz = 0;
pStart = 0;
}else if( pBuf==0 ){
sqlite4BeginBenignMalloc(db->pEnv);
pStart = sqlite4Malloc(db->pEnv, sz*cnt ); /* IMP: R-61949-35727 */
sqlite4EndBenignMalloc(db->pEnv);
if( pStart ) cnt = sqlite4MallocSize(db->pEnv, pStart)/sz;
}else{
pStart = pBuf;
}
db->lookaside.pStart = pStart;
db->lookaside.pFree = 0;
db->lookaside.sz = (u16)sz;
if( pStart ){
int i;
LookasideSlot *p;
assert( sz > (int)sizeof(LookasideSlot*) );
p = (LookasideSlot*)pStart;
for(i=cnt-1; i>=0; i--){
p->pNext = db->lookaside.pFree;
db->lookaside.pFree = p;
p = (LookasideSlot*)&((u8*)p)[sz];
}
db->lookaside.pEnd = p;
db->lookaside.bEnabled = 1;
db->lookaside.bMalloced = pBuf==0 ?1:0;
}else{
db->lookaside.pEnd = 0;
db->lookaside.bEnabled = 0;
db->lookaside.bMalloced = 0;
}
return SQLITE_OK;
}
/*
** Return the mutex associated with a database connection.
*/
SQLITE_API sqlite4_mutex *sqlite4_db_mutex(sqlite4 *db){
return db->mutex;
}
/*
** Free up as much memory as we can from the given database
** connection.
*/
SQLITE_API int sqlite4_db_release_memory(sqlite4 *db){
sqlite4_mutex_enter(db->mutex);
sqlite4_mutex_leave(db->mutex);
return SQLITE_OK;
}
/*
** Configuration settings for an individual database connection
*/
SQLITE_API int sqlite4_db_config(sqlite4 *db, int op, ...){
va_list ap;
int rc;
va_start(ap, op);
switch( op ){
case SQLITE_DBCONFIG_LOOKASIDE: {
void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */
int sz = va_arg(ap, int); /* IMP: R-47871-25994 */
int cnt = va_arg(ap, int); /* IMP: R-04460-53386 */
rc = setupLookaside(db, pBuf, sz, cnt);
break;
}
default: {
static const struct {
int op; /* The opcode */
u32 mask; /* Mask of the bit in sqlite4.flags to set/clear */
} aFlagOp[] = {
{ SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys },
{ SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger },
};
unsigned int i;
rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
for(i=0; i<ArraySize(aFlagOp); i++){
if( aFlagOp[i].op==op ){
int onoff = va_arg(ap, int);
int *pRes = va_arg(ap, int*);
int oldFlags = db->flags;
if( onoff>0 ){
db->flags |= aFlagOp[i].mask;
}else if( onoff==0 ){
db->flags &= ~aFlagOp[i].mask;
}
if( oldFlags!=db->flags ){
sqlite4ExpirePreparedStatements(db);
}
if( pRes ){
*pRes = (db->flags & aFlagOp[i].mask)!=0;
}
rc = SQLITE_OK;
break;
}
}
break;
}
}
va_end(ap);
return rc;
}
/*
** Return true if the buffer z[0..n-1] contains all spaces.
*/
static int allSpaces(const char *z, int n){
while( n>0 && z[n-1]==' ' ){ n--; }
return n==0;
}
/*
** This is the default collating function named "BINARY" which is always
** available.
**
** If the padFlag argument is not NULL then space padding at the end
** of strings is ignored. This implements the RTRIM collation.
*/
static int binCollFunc(
void *padFlag,
int nKey1, const void *pKey1,
int nKey2, const void *pKey2
){
int rc, n;
n = nKey1<nKey2 ? nKey1 : nKey2;
rc = memcmp(pKey1, pKey2, n);
if( rc==0 ){
if( padFlag
&& allSpaces(((char*)pKey1)+n, nKey1-n)
&& allSpaces(((char*)pKey2)+n, nKey2-n)
){
/* Leave rc unchanged at 0 */
}else{
rc = nKey1 - nKey2;
}
}
return rc;
}
/*
** The xMakeKey callback for the built-in RTRIM collation. The output
** is the same as the input, with any trailing ' ' characters removed.
** (e.g. " abc " -> " abc").
*/
static int collRtrimMkKey(
void *NotUsed, /* Not used */
int nIn, const void *pIn, /* Input text. UTF-8. */
int nOut, void *pOut /* Output buffer */
){
int nCopy = nIn;
while( nCopy>0 && ((const char *)pIn)[nCopy-1]==' ' ) nCopy--;
if( nCopy<=nOut ){
memcpy(pOut, pIn, nCopy);
}
return nCopy;
}
/*
** Another built-in collating sequence: NOCASE.
**
** This collating sequence is intended to be used for "case independant
** comparison". SQLite's knowledge of upper and lower case equivalents
** extends only to the 26 characters used in the English language.
**
** At the moment there is only a UTF-8 implementation.
*/
static int collNocaseCmp(
void *NotUsed,
int nKey1, const void *pKey1,
int nKey2, const void *pKey2
){
int r = sqlite4StrNICmp(
(const char *)pKey1, (const char *)pKey2, (nKey1<nKey2)?nKey1:nKey2);
UNUSED_PARAMETER(NotUsed);
if( 0==r ){
r = nKey1-nKey2;
}
return r;
}
static int collNocaseMkKey(
void *NotUsed,
int nIn, const void *pKey1,
int nOut, void *pKey2
){
if( nOut>=nIn ){
int i;
u8 *aIn = (u8 *)pKey1;
u8 *aOut = (u8 *)pKey2;
for(i=0; i<nIn; i++){
aOut[i] = sqlite4UpperToLower[aIn[i]];
}
}
return nIn;
}
/*
** Return the ROWID of the most recent insert
*/
SQLITE_API sqlite_int64 sqlite4_last_insert_rowid(sqlite4 *db){
return db->lastRowid;
}
/*
** Return the number of changes in the most recent call to sqlite4_exec().
*/
SQLITE_API int sqlite4_changes(sqlite4 *db){
return db->nChange;
}
/*
** Return the number of changes since the database handle was opened.
*/
SQLITE_API int sqlite4_total_changes(sqlite4 *db){
return db->nTotalChange;
}
/*
** Close all open savepoints. This function only manipulates fields of the
** database handle object, it does not close any savepoints that may be open
** at the b-tree/pager level.
*/
SQLITE_PRIVATE void sqlite4CloseSavepoints(sqlite4 *db){
while( db->pSavepoint ){
Savepoint *pTmp = db->pSavepoint;
db->pSavepoint = pTmp->pNext;
sqlite4DbFree(db, pTmp);
}
db->nSavepoint = 0;
db->nStatement = 0;
}
/*
** Invoke the destructor function associated with FuncDef p, if any. Except,
** if this is not the last copy of the function, do not invoke it. Multiple
** copies of a single function are created when create_function() is called
** with SQLITE_ANY as the encoding.
*/
static void functionDestroy(sqlite4 *db, FuncDef *p){
FuncDestructor *pDestructor = p->pDestructor;
if( pDestructor ){
pDestructor->nRef--;
if( pDestructor->nRef==0 ){
pDestructor->xDestroy(pDestructor->pUserData);
sqlite4DbFree(db, pDestructor);
}
}
}
/*
** Close an existing SQLite database
*/
SQLITE_API int sqlite4_close(sqlite4 *db){
HashElem *i; /* Hash table iterator */
int j;
if( !db ){
return SQLITE_OK;
}
if( !sqlite4SafetyCheckSickOrOk(db) ){
return SQLITE_MISUSE_BKPT;
}
sqlite4_mutex_enter(db->mutex);
/* Force xDestroy calls on all virtual tables */
sqlite4ResetInternalSchema(db, -1);
/* If a transaction is open, the ResetInternalSchema() call above
** will not have called the xDisconnect() method on any virtual
** tables in the db->aVTrans[] array. The following sqlite4VtabRollback()
** call will do so. We need to do this before the check for active
** SQL statements below, as the v-table implementation may be storing
** some prepared statements internally.
*/
sqlite4VtabRollback(db);
/* If there are any outstanding VMs, return SQLITE_BUSY. */
if( db->pVdbe ){
sqlite4Error(db, SQLITE_BUSY,
"unable to close due to unfinalised statements");
sqlite4_mutex_leave(db->mutex);
return SQLITE_BUSY;
}
assert( sqlite4SafetyCheckSickOrOk(db) );
/* Free any outstanding Savepoint structures. */
sqlite4CloseSavepoints(db);
for(j=0; j<db->nDb; j++){
struct Db *pDb = &db->aDb[j];
if( pDb->pKV ){
sqlite4KVStoreClose(pDb->pKV);
pDb->pKV = 0;
if( j!=1 ){
pDb->pSchema = 0;
}
}
}
sqlite4ResetInternalSchema(db, -1);
/* Tell the code in notify.c that the connection no longer holds any
** locks and does not require any further unlock-notify callbacks.
*/
sqlite4ConnectionClosed(db);
assert( db->nDb<=2 );
assert( db->aDb==db->aDbStatic );
{
FuncDef *pNext, *pSame, *p;
for(p=db->aFunc.pFirst; p; p=pNext){
pNext = p->pNextName;
while( p ){
functionDestroy(db, p);
pSame = p->pSameName;
sqlite4DbFree(db, p);
p = pSame;
}
}
}
for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){
CollSeq *pColl = (CollSeq *)sqliteHashData(i);
/* Invoke any destructors registered for collation sequence user data. */
for(j=0; j<3; j++){
if( pColl[j].xDel ){
pColl[j].xDel(pColl[j].pUser);
}
}
sqlite4DbFree(db, pColl);
}
sqlite4HashClear(&db->aCollSeq);
#ifndef SQLITE_OMIT_VIRTUALTABLE
for(i=sqliteHashFirst(&db->aModule); i; i=sqliteHashNext(i)){
Module *pMod = (Module *)sqliteHashData(i);
if( pMod->xDestroy ){
pMod->xDestroy(pMod->pAux);
}
sqlite4DbFree(db, pMod);
}
sqlite4HashClear(&db->aModule);
#endif
sqlite4Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */
if( db->pErr ){
sqlite4ValueFree(db->pErr);
}
db->magic = SQLITE_MAGIC_ERROR;
/* The temp-database schema is allocated differently from the other schema
** objects (using sqliteMalloc() directly, instead of sqlite4BTreeSchema()).
** So it needs to be freed here. Todo: Why not roll the temp schema into
** the same sqliteMalloc() as the one that allocates the database
** structure?
*/
sqlite4DbFree(db, db->aDb[1].pSchema);
sqlite4_mutex_leave(db->mutex);
db->magic = SQLITE_MAGIC_CLOSED;
sqlite4_mutex_free(db->mutex);
assert( db->lookaside.nOut==0 ); /* Fails on a lookaside memory leak */
if( db->lookaside.bMalloced ){
sqlite4_free(db->pEnv, db->lookaside.pStart);
}
sqlite4_free(db->pEnv, db);
return SQLITE_OK;
}
/*
** Return a static string that describes the kind of error specified in the
** argument.
*/
SQLITE_PRIVATE const char *sqlite4ErrStr(int rc){
static const char* const aMsg[] = {
/* SQLITE_OK */ "not an error",
/* SQLITE_ERROR */ "SQL logic error or missing database",
/* SQLITE_INTERNAL */ 0,
/* SQLITE_PERM */ "access permission denied",
/* SQLITE_ABORT */ "callback requested query abort",
/* SQLITE_BUSY */ "database is locked",
/* SQLITE_LOCKED */ "database table is locked",
/* SQLITE_NOMEM */ "out of memory",
/* SQLITE_READONLY */ "attempt to write a readonly database",
/* SQLITE_INTERRUPT */ "interrupted",
/* SQLITE_IOERR */ "disk I/O error",
/* SQLITE_CORRUPT */ "database disk image is malformed",
/* SQLITE_NOTFOUND */ "unknown operation",
/* SQLITE_FULL */ "database or disk is full",
/* SQLITE_CANTOPEN */ "unable to open database file",
/* SQLITE_PROTOCOL */ "locking protocol",
/* SQLITE_EMPTY */ "table contains no data",
/* SQLITE_SCHEMA */ "database schema has changed",
/* SQLITE_TOOBIG */ "string or blob too big",
/* SQLITE_CONSTRAINT */ "constraint failed",
/* SQLITE_MISMATCH */ "datatype mismatch",
/* SQLITE_MISUSE */ "library routine called out of sequence",
/* SQLITE_NOLFS */ "large file support is disabled",
/* SQLITE_AUTH */ "authorization denied",
/* SQLITE_FORMAT */ "auxiliary database format error",
/* SQLITE_RANGE */ "bind or column index out of range",
/* SQLITE_NOTADB */ "file is encrypted or is not a database",
};
rc &= 0xff;
if( ALWAYS(rc>=0) && rc<(int)(sizeof(aMsg)/sizeof(aMsg[0])) && aMsg[rc]!=0 ){
return aMsg[rc];
}else{
return "unknown error";
}
}
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
/*
** This routine sets the progress callback for an Sqlite database to the
** given callback function with the given argument. The progress callback will
** be invoked every nOps opcodes.
*/
SQLITE_API void sqlite4_progress_handler(
sqlite4 *db,
int nOps,
int (*xProgress)(void*),
void *pArg
){
sqlite4_mutex_enter(db->mutex);
if( nOps>0 ){
db->xProgress = xProgress;
db->nProgressOps = nOps;
db->pProgressArg = pArg;
}else{
db->xProgress = 0;
db->nProgressOps = 0;
db->pProgressArg = 0;
}
sqlite4_mutex_leave(db->mutex);
}
#endif
/*
** Cause any pending operation to stop at its earliest opportunity.
*/
SQLITE_API void sqlite4_interrupt(sqlite4 *db){
db->u1.isInterrupted = 1;
}
/*
** This function is exactly the same as sqlite4_create_function(), except
** that it is designed to be called by internal code. The difference is
** that if a malloc() fails in sqlite4_create_function(), an error code
** is returned and the mallocFailed flag cleared.
*/
SQLITE_PRIVATE int sqlite4CreateFunc(
sqlite4 *db,
const char *zFunctionName,
int nArg,
int enc,
void *pUserData,
void (*xFunc)(sqlite4_context*,int,sqlite4_value **),
void (*xStep)(sqlite4_context*,int,sqlite4_value **),
void (*xFinal)(sqlite4_context*),
FuncDestructor *pDestructor
){
FuncDef *p;
int nName;
assert( sqlite4_mutex_held(db->mutex) );
if( zFunctionName==0 ||
(xFunc && (xFinal || xStep)) ||
(!xFunc && (xFinal && !xStep)) ||
(!xFunc && (!xFinal && xStep)) ||
(nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) ||
(255<(nName = sqlite4Strlen30( zFunctionName))) ){
return SQLITE_MISUSE_BKPT;
}
#ifndef SQLITE_OMIT_UTF16
/* If SQLITE_UTF16 is specified as the encoding type, transform this
** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the
** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally.
**
** If SQLITE_ANY is specified, add three versions of the function
** to the hash table.
*/
if( enc==SQLITE_UTF16 ){
enc = SQLITE_UTF16NATIVE;
}else if( enc==SQLITE_ANY ){
int rc;
rc = sqlite4CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8,
pUserData, xFunc, xStep, xFinal, pDestructor);
if( rc==SQLITE_OK ){
rc = sqlite4CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE,
pUserData, xFunc, xStep, xFinal, pDestructor);
}
if( rc!=SQLITE_OK ){
return rc;
}
enc = SQLITE_UTF16BE;
}
#else
enc = SQLITE_UTF8;
#endif
/* Check if an existing function is being overridden or deleted. If so,
** and there are active VMs, then return SQLITE_BUSY. If a function
** is being overridden/deleted but there are no active VMs, allow the
** operation to continue but invalidate all precompiled statements.
*/
p = sqlite4FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0);
if( p && p->iPrefEnc==enc && p->nArg==nArg ){
if( db->activeVdbeCnt ){
sqlite4Error(db, SQLITE_BUSY,
"unable to delete/modify user-function due to active statements");
assert( !db->mallocFailed );
return SQLITE_BUSY;
}else{
sqlite4ExpirePreparedStatements(db);
}
}
p = sqlite4FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 1);
assert(p || db->mallocFailed);
if( !p ){
return SQLITE_NOMEM;
}
/* If an older version of the function with a configured destructor is
** being replaced invoke the destructor function here. */
functionDestroy(db, p);
if( pDestructor ){
pDestructor->nRef++;
}
p->pDestructor = pDestructor;
p->flags = 0;
p->xFunc = xFunc;
p->xStep = xStep;
p->xFinalize = xFinal;
p->pUserData = pUserData;
p->nArg = (u16)nArg;
return SQLITE_OK;
}
/*
** Create new user functions.
*/
SQLITE_API int sqlite4_create_function(
sqlite4 *db,
const char *zFunc,
int nArg,
int enc,
void *p,
void (*xFunc)(sqlite4_context*,int,sqlite4_value **),
void (*xStep)(sqlite4_context*,int,sqlite4_value **),
void (*xFinal)(sqlite4_context*)
){
return sqlite4_create_function_v2(db, zFunc, nArg, enc, p, xFunc, xStep,
xFinal, 0);
}
SQLITE_API int sqlite4_create_function_v2(
sqlite4 *db,
const char *zFunc,
int nArg,
int enc,
void *p,
void (*xFunc)(sqlite4_context*,int,sqlite4_value **),
void (*xStep)(sqlite4_context*,int,sqlite4_value **),
void (*xFinal)(sqlite4_context*),
void (*xDestroy)(void *)
){
int rc = SQLITE_ERROR;
FuncDestructor *pArg = 0;
sqlite4_mutex_enter(db->mutex);
if( xDestroy ){
pArg = (FuncDestructor *)sqlite4DbMallocZero(db, sizeof(FuncDestructor));
if( !pArg ){
xDestroy(p);
goto out;
}
pArg->xDestroy = xDestroy;
pArg->pUserData = p;
}
rc = sqlite4CreateFunc(db, zFunc, nArg, enc, p, xFunc, xStep, xFinal, pArg);
if( pArg && pArg->nRef==0 ){
assert( rc!=SQLITE_OK );
xDestroy(p);
sqlite4DbFree(db, pArg);
}
out:
rc = sqlite4ApiExit(db, rc);
sqlite4_mutex_leave(db->mutex);
return rc;
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API int sqlite4_create_function16(
sqlite4 *db,
const void *zFunctionName,
int nArg,
int eTextRep,
void *p,
void (*xFunc)(sqlite4_context*,int,sqlite4_value**),
void (*xStep)(sqlite4_context*,int,sqlite4_value**),
void (*xFinal)(sqlite4_context*)
){
int rc;
char *zFunc8;
sqlite4_mutex_enter(db->mutex);
assert( !db->mallocFailed );
zFunc8 = sqlite4Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE);
rc = sqlite4CreateFunc(db, zFunc8, nArg, eTextRep, p, xFunc, xStep, xFinal,0);
sqlite4DbFree(db, zFunc8);
rc = sqlite4ApiExit(db, rc);
sqlite4_mutex_leave(db->mutex);
return rc;
}
#endif
/*
** Declare that a function has been overloaded by a virtual table.
**
** If the function already exists as a regular global function, then
** this routine is a no-op. If the function does not exist, then create
** a new one that always throws a run-time error.
**
** When virtual tables intend to provide an overloaded function, they
** should call this routine to make sure the global function exists.
** A global function must exist in order for name resolution to work
** properly.
*/
SQLITE_API int sqlite4_overload_function(
sqlite4 *db,
const char *zName,
int nArg
){
int nName = sqlite4Strlen30(zName);
int rc = SQLITE_OK;
sqlite4_mutex_enter(db->mutex);
if( sqlite4FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){
rc = sqlite4CreateFunc(db, zName, nArg, SQLITE_UTF8,
0, sqlite4InvalidFunction, 0, 0, 0);
}
rc = sqlite4ApiExit(db, rc);
sqlite4_mutex_leave(db->mutex);
return rc;
}
#ifndef SQLITE_OMIT_TRACE
/*
** Register a trace function. The pArg from the previously registered trace
** is returned.
**
** A NULL trace function means that no tracing is executes. A non-NULL
** trace is a pointer to a function that is invoked at the start of each
** SQL statement.
*/
SQLITE_API void *sqlite4_trace(sqlite4 *db, void (*xTrace)(void*,const char*), void *pArg){
void *pOld;
sqlite4_mutex_enter(db->mutex);
pOld = db->pTraceArg;
db->xTrace = xTrace;
db->pTraceArg = pArg;
sqlite4_mutex_leave(db->mutex);
return pOld;
}
/*
** Register a profile function. The pArg from the previously registered
** profile function is returned.
**
** A NULL profile function means that no profiling is executes. A non-NULL
** profile is a pointer to a function that is invoked at the conclusion of
** each SQL statement that is run.
*/
SQLITE_API void *sqlite4_profile(
sqlite4 *db,
void (*xProfile)(void*,const char*,sqlite_uint64),
void *pArg
){
void *pOld;
sqlite4_mutex_enter(db->mutex);
pOld = db->pProfileArg;
db->xProfile = xProfile;
db->pProfileArg = pArg;
sqlite4_mutex_leave(db->mutex);
return pOld;
}
#endif /* SQLITE_OMIT_TRACE */
/*
** This function returns true if main-memory should be used instead of
** a temporary file for transient pager files and statement journals.
** The value returned depends on the value of db->temp_store (runtime
** parameter) and the compile time value of SQLITE_TEMP_STORE. The
** following table describes the relationship between these two values
** and this functions return value.
**
** SQLITE_TEMP_STORE db->temp_store Location of temporary database
** ----------------- -------------- ------------------------------
** 0 any file (return 0)
** 1 1 file (return 0)
** 1 2 memory (return 1)
** 1 0 file (return 0)
** 2 1 file (return 0)
** 2 2 memory (return 1)
** 2 0 memory (return 1)
** 3 any memory (return 1)
*/
SQLITE_PRIVATE int sqlite4TempInMemory(const sqlite4 *db){
#if SQLITE_TEMP_STORE==1
return ( db->temp_store==2 );
#endif
#if SQLITE_TEMP_STORE==2
return ( db->temp_store!=1 );
#endif
#if SQLITE_TEMP_STORE==3
return 1;
#endif
#if SQLITE_TEMP_STORE<1 || SQLITE_TEMP_STORE>3
return 0;
#endif
}
/*
** Return UTF-8 encoded English language explanation of the most recent
** error.
*/
SQLITE_API const char *sqlite4_errmsg(sqlite4 *db){
const char *z;
if( !db ){
return sqlite4ErrStr(SQLITE_NOMEM);
}
if( !sqlite4SafetyCheckSickOrOk(db) ){
return sqlite4ErrStr(SQLITE_MISUSE_BKPT);
}
sqlite4_mutex_enter(db->mutex);
if( db->mallocFailed ){
z = sqlite4ErrStr(SQLITE_NOMEM);
}else{
z = (char*)sqlite4_value_text(db->pErr);
assert( !db->mallocFailed );
if( z==0 ){
z = sqlite4ErrStr(db->errCode);
}
}
sqlite4_mutex_leave(db->mutex);
return z;
}
#ifndef SQLITE_OMIT_UTF16
/*
** Return UTF-16 encoded English language explanation of the most recent
** error.
*/
SQLITE_API const void *sqlite4_errmsg16(sqlite4 *db){
static const u16 outOfMem[] = {
'o', 'u', 't', ' ', 'o', 'f', ' ', 'm', 'e', 'm', 'o', 'r', 'y', 0
};
static const u16 misuse[] = {
'l', 'i', 'b', 'r', 'a', 'r', 'y', ' ',
'r', 'o', 'u', 't', 'i', 'n', 'e', ' ',
'c', 'a', 'l', 'l', 'e', 'd', ' ',
'o', 'u', 't', ' ',
'o', 'f', ' ',
's', 'e', 'q', 'u', 'e', 'n', 'c', 'e', 0
};
const void *z;
if( !db ){
return (void *)outOfMem;
}
if( !sqlite4SafetyCheckSickOrOk(db) ){
return (void *)misuse;
}
sqlite4_mutex_enter(db->mutex);
if( db->mallocFailed ){
z = (void *)outOfMem;
}else{
z = sqlite4_value_text16(db->pErr);
if( z==0 ){
sqlite4ValueSetStr(db->pErr, -1, sqlite4ErrStr(db->errCode),
SQLITE_UTF8, SQLITE_STATIC);
z = sqlite4_value_text16(db->pErr);
}
/* A malloc() may have failed within the call to sqlite4_value_text16()
** above. If this is the case, then the db->mallocFailed flag needs to
** be cleared before returning. Do this directly, instead of via
** sqlite4ApiExit(), to avoid setting the database handle error message.
*/
db->mallocFailed = 0;
}
sqlite4_mutex_leave(db->mutex);
return z;
}
#endif /* SQLITE_OMIT_UTF16 */
/*
** Return the most recent error code generated by an SQLite routine. If NULL is
** passed to this function, we assume a malloc() failed during sqlite4_open().
*/
SQLITE_API int sqlite4_errcode(sqlite4 *db){
if( db && !sqlite4SafetyCheckSickOrOk(db) ){
return SQLITE_MISUSE_BKPT;
}
if( !db || db->mallocFailed ){
return SQLITE_NOMEM;
}
return db->errCode;
}
/*
** Create a new collating function for database "db". The name is zName
** and the encoding is enc.
*/
static int createCollation(
sqlite4* db,
const char *zName,
u8 enc,
void* pCtx,
int(*xCompare)(void*,int,const void*,int,const void*),
int(*xMakeKey)(void*,int,const void*,int,void*),
void(*xDel)(void*)
){
CollSeq *pColl;
int enc2;
int nName = sqlite4Strlen30(zName);
assert( sqlite4_mutex_held(db->mutex) );
/* If SQLITE_UTF16 is specified as the encoding type, transform this
** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the
** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally.
*/
enc2 = enc;
testcase( enc2==SQLITE_UTF16 );
testcase( enc2==SQLITE_UTF16_ALIGNED );
if( enc2==SQLITE_UTF16 || enc2==SQLITE_UTF16_ALIGNED ){
enc2 = SQLITE_UTF16NATIVE;
}
if( enc2<SQLITE_UTF8 || enc2>SQLITE_UTF16BE ){
return SQLITE_MISUSE_BKPT;
}
/* Check if this call is removing or replacing an existing collation
** sequence. If so, and there are active VMs, return busy. If there
** are no active VMs, invalidate any pre-compiled statements.
*/
pColl = sqlite4FindCollSeq(db, (u8)enc2, zName, 0);
if( pColl && pColl->xCmp ){
if( db->activeVdbeCnt ){
sqlite4Error(db, SQLITE_BUSY,
"unable to delete/modify collation sequence due to active statements");
return SQLITE_BUSY;
}
sqlite4ExpirePreparedStatements(db);
/* If collation sequence pColl was created directly by a call to
** sqlite4_create_collation, and not generated by synthCollSeq(),
** then any copies made by synthCollSeq() need to be invalidated.
** Also, collation destructor - CollSeq.xDel() - function may need
** to be called.
*/
if( (pColl->enc & ~SQLITE_UTF16_ALIGNED)==enc2 ){
CollSeq *aColl = sqlite4HashFind(&db->aCollSeq, zName, nName);
int j;
for(j=0; j<3; j++){
CollSeq *p = &aColl[j];
if( p->enc==pColl->enc ){
if( p->xDel ){
p->xDel(p->pUser);
}
p->xCmp = 0;
}
}
}
}
pColl = sqlite4FindCollSeq(db, (u8)enc2, zName, 1);
if( pColl==0 ) return SQLITE_NOMEM;
pColl->xCmp = xCompare;
pColl->xMkKey = xMakeKey;
pColl->pUser = pCtx;
pColl->xDel = xDel;
pColl->enc = (u8)(enc2 | (enc & SQLITE_UTF16_ALIGNED));
sqlite4Error(db, SQLITE_OK, 0);
return SQLITE_OK;
}
/*
** This array defines hard upper bounds on limit values. The
** initializer must be kept in sync with the SQLITE_LIMIT_*
** #defines in sqlite4.h.
*/
static const int aHardLimit[] = {
SQLITE_MAX_LENGTH,
SQLITE_MAX_SQL_LENGTH,
SQLITE_MAX_COLUMN,
SQLITE_MAX_EXPR_DEPTH,
SQLITE_MAX_COMPOUND_SELECT,
SQLITE_MAX_VDBE_OP,
SQLITE_MAX_FUNCTION_ARG,
SQLITE_MAX_ATTACHED,
SQLITE_MAX_LIKE_PATTERN_LENGTH,
SQLITE_MAX_VARIABLE_NUMBER,
SQLITE_MAX_TRIGGER_DEPTH,
};
/*
** Make sure the hard limits are set to reasonable values
*/
#if SQLITE_MAX_LENGTH<100
# error SQLITE_MAX_LENGTH must be at least 100
#endif
#if SQLITE_MAX_SQL_LENGTH<100
# error SQLITE_MAX_SQL_LENGTH must be at least 100
#endif
#if SQLITE_MAX_SQL_LENGTH>SQLITE_MAX_LENGTH
# error SQLITE_MAX_SQL_LENGTH must not be greater than SQLITE_MAX_LENGTH
#endif
#if SQLITE_MAX_COMPOUND_SELECT<2
# error SQLITE_MAX_COMPOUND_SELECT must be at least 2
#endif
#if SQLITE_MAX_VDBE_OP<40
# error SQLITE_MAX_VDBE_OP must be at least 40
#endif
#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000
# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000
#endif
#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>62
# error SQLITE_MAX_ATTACHED must be between 0 and 62
#endif
#if SQLITE_MAX_LIKE_PATTERN_LENGTH<1
# error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1
#endif
#if SQLITE_MAX_COLUMN>32767
# error SQLITE_MAX_COLUMN must not exceed 32767
#endif
#if SQLITE_MAX_TRIGGER_DEPTH<1
# error SQLITE_MAX_TRIGGER_DEPTH must be at least 1
#endif
/*
** Change the value of a limit. Report the old value.
** If an invalid limit index is supplied, report -1.
** Make no changes but still report the old value if the
** new limit is negative.
**
** A new lower limit does not shrink existing constructs.
** It merely prevents new constructs that exceed the limit
** from forming.
*/
SQLITE_API int sqlite4_limit(sqlite4 *db, int limitId, int newLimit){
int oldLimit;
/* EVIDENCE-OF: R-30189-54097 For each limit category SQLITE_LIMIT_NAME
** there is a hard upper bound set at compile-time by a C preprocessor
** macro called SQLITE_MAX_NAME. (The "_LIMIT_" in the name is changed to
** "_MAX_".)
*/
assert( aHardLimit[SQLITE_LIMIT_LENGTH]==SQLITE_MAX_LENGTH );
assert( aHardLimit[SQLITE_LIMIT_SQL_LENGTH]==SQLITE_MAX_SQL_LENGTH );
assert( aHardLimit[SQLITE_LIMIT_COLUMN]==SQLITE_MAX_COLUMN );
assert( aHardLimit[SQLITE_LIMIT_EXPR_DEPTH]==SQLITE_MAX_EXPR_DEPTH );
assert( aHardLimit[SQLITE_LIMIT_COMPOUND_SELECT]==SQLITE_MAX_COMPOUND_SELECT);
assert( aHardLimit[SQLITE_LIMIT_VDBE_OP]==SQLITE_MAX_VDBE_OP );
assert( aHardLimit[SQLITE_LIMIT_FUNCTION_ARG]==SQLITE_MAX_FUNCTION_ARG );
assert( aHardLimit[SQLITE_LIMIT_ATTACHED]==SQLITE_MAX_ATTACHED );
assert( aHardLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]==
SQLITE_MAX_LIKE_PATTERN_LENGTH );
assert( aHardLimit[SQLITE_LIMIT_VARIABLE_NUMBER]==SQLITE_MAX_VARIABLE_NUMBER);
assert( aHardLimit[SQLITE_LIMIT_TRIGGER_DEPTH]==SQLITE_MAX_TRIGGER_DEPTH );
assert( SQLITE_LIMIT_TRIGGER_DEPTH==(SQLITE_N_LIMIT-1) );
if( limitId<0 || limitId>=SQLITE_N_LIMIT ){
return -1;
}
oldLimit = db->aLimit[limitId];
if( newLimit>=0 ){ /* IMP: R-52476-28732 */
if( newLimit>aHardLimit[limitId] ){
newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */
}
db->aLimit[limitId] = newLimit;
}
return oldLimit; /* IMP: R-53341-35419 */
}
/*
** This function is used to parse both URIs and non-URI filenames passed by the
** user to API functions sqlite4_open() and for database
** URIs specified as part of ATTACH statements.
**
** The first argument to this function is the name of the VFS to use (or
** a NULL to signify the default VFS) if the URI does not contain a "vfs=xxx"
** query parameter. The second argument contains the URI (or non-URI filename)
** itself. When this function is called the *pFlags variable should contain
** the default flags to open the database handle with. The value stored in
** *pFlags may be updated before returning if the URI filename contains
** "cache=xxx" or "mode=xxx" query parameters.
**
** If successful, SQLITE_OK is returned. In this case *ppVfs is set to point to
** the VFS that should be used to open the database file. *pzFile is set to
** point to a buffer containing the name of the file to open. It is the
** responsibility of the caller to eventually call sqlite4_free() to release
** this buffer.
**
** If an error occurs, then an SQLite error code is returned and *pzErrMsg
** may be set to point to a buffer containing an English language error
** message. It is the responsibility of the caller to eventually release
** this buffer by calling sqlite4_free().
*/
SQLITE_PRIVATE int sqlite4ParseUri(
sqlite4_env *pEnv, /* Run-time environment */
const char *zUri, /* Nul-terminated URI to parse */
unsigned int *pFlags, /* IN/OUT: SQLITE_OPEN_XXX flags */
char **pzFile, /* OUT: Filename component of URI */
char **pzErrMsg /* OUT: Error message (if rc!=SQLITE_OK) */
){
int rc = SQLITE_OK;
unsigned int flags = *pFlags;
char *zFile;
char c;
int nUri = sqlite4Strlen30(zUri);
assert( *pzErrMsg==0 );
if( nUri>=5 && memcmp(zUri, "file:", 5)==0 ){
char *zOpt;
int eState; /* Parser state when parsing URI */
int iIn; /* Input character index */
int iOut = 0; /* Output character index */
int nByte = nUri+2; /* Bytes of space to allocate */
for(iIn=0; iIn<nUri; iIn++) nByte += (zUri[iIn]=='&');
zFile = sqlite4_malloc(pEnv, nByte);
if( !zFile ) return SQLITE_NOMEM;
/* Discard the scheme and authority segments of the URI. */
if( zUri[5]=='/' && zUri[6]=='/' ){
iIn = 7;
while( zUri[iIn] && zUri[iIn]!='/' ) iIn++;
if( iIn!=7 && (iIn!=16 || memcmp("localhost", &zUri[7], 9)) ){
*pzErrMsg = sqlite4_mprintf(pEnv,"invalid uri authority: %.*s",
iIn-7, &zUri[7]);
rc = SQLITE_ERROR;
goto parse_uri_out;
}
}else{
iIn = 5;
}
/* Copy the filename and any query parameters into the zFile buffer.
** Decode %HH escape codes along the way.
**
** Within this loop, variable eState may be set to 0, 1 or 2, depending
** on the parsing context. As follows:
**
** 0: Parsing file-name.
** 1: Parsing name section of a name=value query parameter.
** 2: Parsing value section of a name=value query parameter.
*/
eState = 0;
while( (c = zUri[iIn])!=0 && c!='#' ){
iIn++;
if( c=='%'
&& sqlite4Isxdigit(zUri[iIn])
&& sqlite4Isxdigit(zUri[iIn+1])
){
int octet = (sqlite4HexToInt(zUri[iIn++]) << 4);
octet += sqlite4HexToInt(zUri[iIn++]);
assert( octet>=0 && octet<256 );
if( octet==0 ){
/* 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
** and skip to the next "?", "=" or "&", as appropriate. */
while( (c = zUri[iIn])!=0 && c!='#'
&& (eState!=0 || c!='?')
&& (eState!=1 || (c!='=' && c!='&'))
&& (eState!=2 || c!='&')
){
iIn++;
}
continue;
}
c = octet;
}else if( eState==1 && (c=='&' || c=='=') ){
if( zFile[iOut-1]==0 ){
/* An empty option name. Ignore this option altogether. */
while( zUri[iIn] && zUri[iIn]!='#' && zUri[iIn-1]!='&' ) iIn++;
continue;
}
if( c=='&' ){
zFile[iOut++] = '\0';
}else{
eState = 2;
}
c = 0;
}else if( (eState==0 && c=='?') || (eState==2 && c=='&') ){
c = 0;
eState = 1;
}
zFile[iOut++] = c;
}
if( eState==1 ) zFile[iOut++] = '\0';
zFile[iOut++] = '\0';
zFile[iOut++] = '\0';
/* Check if there were any options specified that should be interpreted
** here. Options that are interpreted here include "vfs" and those that
** correspond to flags that may be passed to the sqlite4_open()
** method. */
zOpt = &zFile[sqlite4Strlen30(zFile)+1];
while( zOpt[0] ){
int nOpt = sqlite4Strlen30(zOpt);
char *zVal = &zOpt[nOpt+1];
int nVal = sqlite4Strlen30(zVal);
struct OpenMode {
const char *z;
int mode;
} *aMode = 0;
char *zModeType = 0;
int mask = 0;
int limit = 0;
if( nOpt==4 && memcmp("mode", zOpt, 4)==0 ){
static struct OpenMode aOpenMode[] = {
{ "ro", SQLITE_OPEN_READONLY },
{ "rw", SQLITE_OPEN_READWRITE },
{ "rwc", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE },
{ 0, 0 }
};
mask = SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
aMode = aOpenMode;
limit = mask & flags;
zModeType = "access";
}
if( aMode ){
int i;
int mode = 0;
for(i=0; aMode[i].z; i++){
const char *z = aMode[i].z;
if( nVal==sqlite4Strlen30(z) && 0==memcmp(zVal, z, nVal) ){
mode = aMode[i].mode;
break;
}
}
if( mode==0 ){
*pzErrMsg = sqlite4_mprintf(pEnv, "no such %s mode: %s",
zModeType, zVal);
rc = SQLITE_ERROR;
goto parse_uri_out;
}
if( mode>limit ){
*pzErrMsg = sqlite4_mprintf(pEnv, "%s mode not allowed: %s",
zModeType, zVal);
rc = SQLITE_PERM;
goto parse_uri_out;
}
flags = (flags & ~mask) | mode;
}
zOpt = &zVal[nVal+1];
}
}else{
zFile = sqlite4_malloc(pEnv, nUri+2);
if( !zFile ) return SQLITE_NOMEM;
memcpy(zFile, zUri, nUri);
zFile[nUri] = '\0';
zFile[nUri+1] = '\0';
}
parse_uri_out:
if( rc!=SQLITE_OK ){
sqlite4_free(pEnv, zFile);
zFile = 0;
}
*pFlags = flags;
*pzFile = zFile;
return rc;
}
/*
** This routine does the work of opening a database on behalf of
** sqlite4_open(). The database filename "zFilename" is UTF-8 encoded.
*/
static int openDatabase(
sqlite4_env *pEnv, /* The run-time environment */
const char *zFilename, /* Database filename UTF-8 encoded */
unsigned int flags, /* Flags influencing the open */
sqlite4 **ppDb, /* OUT: Returned database handle */
va_list ap /* Zero-terminated list of options */
){
sqlite4 *db; /* Store allocated handle here */
int rc; /* Return code */
int isThreadsafe; /* True for threadsafe connections */
char *zOpen = 0; /* Filename passed to StorageOpen() */
char *zErrMsg = 0; /* Error message from sqlite4ParseUri() */
*ppDb = 0;
#ifndef SQLITE_OMIT_AUTOINIT
rc = sqlite4_initialize(pEnv);
if( rc ) return rc;
#endif
if( pEnv->bCoreMutex==0 ){
isThreadsafe = 0;
}else{
isThreadsafe = pEnv->bFullMutex;
}
/* Allocate the sqlite data structure */
db = sqlite4MallocZero(pEnv, sizeof(sqlite4) );
if( db==0 ) goto opendb_out;
db->pEnv = pEnv;
if( isThreadsafe ){
db->mutex = sqlite4MutexAlloc(pEnv, SQLITE_MUTEX_RECURSIVE);
if( db->mutex==0 ){
sqlite4_free(pEnv, db);
db = 0;
goto opendb_out;
}
}
sqlite4_mutex_enter(db->mutex);
db->nDb = 2;
db->magic = SQLITE_MAGIC_BUSY;
db->aDb = db->aDbStatic;
assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
db->nextAutovac = -1;
db->nextPagesize = 0;
db->flags |= SQLITE_AutoIndex
| SQLITE_EnableTrigger
| SQLITE_ForeignKeys
;
sqlite4HashInit(pEnv, &db->aCollSeq);
#ifndef SQLITE_OMIT_VIRTUALTABLE
sqlite4HashInit(pEnv, &db->aModule);
#endif
/* Add the default collation sequence BINARY. BINARY works for both UTF-8
** and UTF-16, so add a version for each to avoid any unnecessary
** conversions. The only error that can occur here is a malloc() failure.
*/
createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc, 0, 0);
createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc, 0, 0);
createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc, 0, 0);
createCollation(
db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, collRtrimMkKey, 0
);
if( db->mallocFailed ){
goto opendb_out;
}
db->pDfltColl = sqlite4FindCollSeq(db, SQLITE_UTF8, "BINARY", 0);
assert( db->pDfltColl!=0 );
/* Also add a UTF-8 case-insensitive collation sequence. */
createCollation(db,
"NOCASE", SQLITE_UTF8, 0, collNocaseCmp, collNocaseMkKey, 0
);
/* Parse the filename/URI argument. */
rc = sqlite4ParseUri(pEnv, zFilename, &flags, &zOpen, &zErrMsg);
if( rc!=SQLITE_OK ){
if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
sqlite4Error(db, rc, zErrMsg ? "%s" : 0, zErrMsg);
sqlite4_free(pEnv, zErrMsg);
goto opendb_out;
}
db->openFlags = flags;
/* Open the backend database driver */
rc = sqlite4KVStoreOpen(db, "main", zOpen, &db->aDb[0].pKV, flags);
if( rc!=SQLITE_OK ){
if( rc==SQLITE_IOERR_NOMEM ){
rc = SQLITE_NOMEM;
}
sqlite4Error(db, rc, 0);
goto opendb_out;
}
db->aDb[0].pSchema = sqlite4SchemaGet(db);
db->aDb[1].pSchema = sqlite4SchemaGet(db);
/* The default safety_level for the main database is 'full'; for the temp
** database it is 'NONE'. This matches the pager layer defaults.
*/
db->aDb[0].zName = "main";
db->aDb[1].zName = "temp";
db->magic = SQLITE_MAGIC_OPEN;
if( db->mallocFailed ){
goto opendb_out;
}
/* Register all built-in functions, but do not attempt to read the
** database schema yet. This is delayed until the first time the database
** is accessed.
*/
sqlite4Error(db, SQLITE_OK, 0);
sqlite4RegisterBuiltinFunctions(db);
/* Load automatic extensions - extensions that have been registered
** using the sqlite4_automatic_extension() API.
*/
rc = sqlite4_errcode(db);
if( rc==SQLITE_OK ){
/* sqlite4AutoLoadExtensions(db); */
rc = sqlite4_errcode(db);
if( rc!=SQLITE_OK ){
goto opendb_out;
}
}
#ifdef SQLITE_ENABLE_FTS3
if( !db->mallocFailed && rc==SQLITE_OK ){
rc = sqlite4Fts3Init(db);
}
#endif
#ifdef SQLITE_ENABLE_ICU
if( !db->mallocFailed && rc==SQLITE_OK ){
rc = sqlite4IcuInit(db);
}
#endif
#ifdef SQLITE_ENABLE_RTREE
if( !db->mallocFailed && rc==SQLITE_OK){
rc = sqlite4RtreeInit(db);
}
#endif
sqlite4Error(db, rc, 0);
/* Enable the lookaside-malloc subsystem */
setupLookaside(db, 0, pEnv->szLookaside,
pEnv->nLookaside);
opendb_out:
sqlite4_free(pEnv, zOpen);
if( db ){
assert( db->mutex!=0 || isThreadsafe==0 || pEnv->bFullMutex==0 );
sqlite4_mutex_leave(db->mutex);
}
rc = sqlite4_errcode(db);
assert( db!=0 || rc==SQLITE_NOMEM );
if( rc==SQLITE_NOMEM ){
sqlite4_close(db);
db = 0;
}else if( rc!=SQLITE_OK ){
db->magic = SQLITE_MAGIC_SICK;
}
*ppDb = db;
return sqlite4ApiExit(0, rc);
}
/*
** Open a new database handle.
*/
SQLITE_API int sqlite4_open(
sqlite4_env *pEnv,
const char *zFilename,
sqlite4 **ppDb,
...
){
va_list ap;
int rc;
if( pEnv==0 ) pEnv = sqlite4_env_default();
va_start(ap, ppDb);
rc = openDatabase(pEnv, zFilename,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, ppDb, ap);
va_end(ap);
return rc;
}
/*
** Return the environment of a database connection
*/
SQLITE_API sqlite4_env *sqlite4_db_env(sqlite4 *db){
return db ? db->pEnv : sqlite4_env_default();
}
/*
** Register a new collation sequence with the database handle db.
*/
SQLITE_API int sqlite4_create_collation(
sqlite4* db,
const char *zName,
int enc,
void* pCtx,
int(*xCompare)(void*,int,const void*,int,const void*),
int(*xMakeKey)(void*,int,const void*,int,void*),
void(*xDel)(void*)
){
int rc;
sqlite4_mutex_enter(db->mutex);
assert( !db->mallocFailed );
rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, xMakeKey, xDel);
rc = sqlite4ApiExit(db, rc);
sqlite4_mutex_leave(db->mutex);
return rc;
}
/*
** Register a collation sequence factory callback with the database handle
** db. Replace any previously installed collation sequence factory.
*/
SQLITE_API int sqlite4_collation_needed(
sqlite4 *db,
void *pCollNeededArg,
void(*xCollNeeded)(void*,sqlite4*,int eTextRep,const char*)
){
sqlite4_mutex_enter(db->mutex);
db->xCollNeeded = xCollNeeded;
db->xCollNeeded16 = 0;
db->pCollNeededArg = pCollNeededArg;
sqlite4_mutex_leave(db->mutex);
return SQLITE_OK;
}
#ifndef SQLITE_OMIT_UTF16
/*
** Register a collation sequence factory callback with the database handle
** db. Replace any previously installed collation sequence factory.
*/
SQLITE_API int sqlite4_collation_needed16(
sqlite4 *db,
void *pCollNeededArg,
void(*xCollNeeded16)(void*,sqlite4*,int eTextRep,const void*)
){
sqlite4_mutex_enter(db->mutex);
db->xCollNeeded = 0;
db->xCollNeeded16 = xCollNeeded16;
db->pCollNeededArg = pCollNeededArg;
sqlite4_mutex_leave(db->mutex);
return SQLITE_OK;
}
#endif /* SQLITE_OMIT_UTF16 */
#ifndef SQLITE_OMIT_DEPRECATED
/*
** 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 sqlite4_global_recover(void){
return SQLITE_OK;
}
#endif
/*
** Test to see whether or not the database connection is in autocommit
** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on
** by default. Autocommit is disabled by a BEGIN statement and reenabled
** by the next COMMIT or ROLLBACK.
**
******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
*/
SQLITE_API int sqlite4_get_autocommit(sqlite4 *db){
return (db->pSavepoint==0);
}
/*
** The following routines are subtitutes for constants SQLITE_CORRUPT,
** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_IOERR and possibly other error
** constants. They server two purposes:
**
** 1. Serve as a convenient place to set a breakpoint in a debugger
** to detect when version error conditions occurs.
**
** 2. Invoke sqlite4_log() to provide the source code location where
** a low-level error is first detected.
*/
SQLITE_PRIVATE int sqlite4CorruptError(int lineno){
testcase( sqlite4DefaultEnv.xLog!=0 );
sqlite4_log(0, SQLITE_CORRUPT,
"database corruption at line %d of [%.10s]",
lineno, 20+sqlite4_sourceid());
return SQLITE_CORRUPT;
}
SQLITE_PRIVATE int sqlite4MisuseError(int lineno){
testcase( sqlite4DefaultEnv.xLog!=0 );
sqlite4_log(0, SQLITE_MISUSE,
"misuse at line %d of [%.10s]",
lineno, 20+sqlite4_sourceid());
return SQLITE_MISUSE;
}
SQLITE_PRIVATE int sqlite4CantopenError(int lineno){
testcase( sqlite4DefaultEnv.xLog!=0 );
sqlite4_log(0, SQLITE_CANTOPEN,
"cannot open file at line %d of [%.10s]",
lineno, 20+sqlite4_sourceid());
return SQLITE_CANTOPEN;
}
/*
** Sleep for a little while. Return the amount of time slept.
*/
SQLITE_API int sqlite4_sleep(int ms){
return SQLITE_MISUSE;
}
/*
** Invoke the xFileControl method on a particular database.
*/
SQLITE_API int sqlite4_kvstore_control(
sqlite4 *db, /* Database handle */
const char *zDbName, /* Name of database backend ("main" etc.) */
int op, /* First argument to pass to xControl() */
void *pArg /* Second argument to pass to xControl() */
){
int rc = SQLITE_ERROR;
KVStore *pKV = 0;
int i;
sqlite4_mutex_enter(db->mutex);
/* Find the named key-value store */
for(i=0; i<db->nDb; i++){
Db *pDb = &db->aDb[i];
if( pDb->pKV && (0==zDbName || 0==sqlite4StrICmp(zDbName, pDb->zName)) ){
pKV = pDb->pKV;
break;
}
}
/* If the named key-value store was located, invoke its xControl() method. */
if( pKV ){
rc = pKV->pStoreVfunc->xControl(pKV, op, pArg);
}
sqlite4_mutex_leave(db->mutex);
return rc;
}
/*
** Interface to the testing logic.
*/
SQLITE_API int sqlite4_test_control(int op, ...){
int rc = 0;
#ifndef SQLITE_OMIT_BUILTIN_TEST
va_list ap;
va_start(ap, op);
switch( op ){
/*
** sqlite4_test_control(SQLITE_TESTCTRL_ASSERT, int X)
**
** This action provides a run-time test to see whether or not
** assert() was enabled at compile-time. If X is true and assert()
** is enabled, then the return value is true. If X is true and
** assert() is disabled, then the return value is zero. If X is
** false and assert() is enabled, then the assertion fires and the
** process aborts. If X is false and assert() is disabled, then the
** return value is zero.
*/
case SQLITE_TESTCTRL_ASSERT: {
volatile int x = 0;
assert( (x = va_arg(ap,int))!=0 );
rc = x;
break;
}
/*
** sqlite4_test_control(SQLITE_TESTCTRL_ALWAYS, int X)
**
** 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).
**
** 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
** default setting. If the return value is 1, then ALWAYS() is either
** hard-coded to true or else it asserts if its argument is false.
** The first behavior (hard-coded to true) is the case if
** SQLITE_TESTCTRL_ASSERT shows that assert() is disabled and the second
** behavior (assert if the argument to ALWAYS() is false) is the case if
** SQLITE_TESTCTRL_ASSERT shows that assert() is enabled.
**
** The run-time test procedure might look something like this:
**
** if( sqlite4_test_control(SQLITE_TESTCTRL_ALWAYS, 2)==2 ){
** // ALWAYS() and NEVER() are no-op pass-through macros
** }else if( sqlite4_test_control(SQLITE_TESTCTRL_ASSERT, 1) ){
** // ALWAYS(x) asserts that x is true. NEVER(x) asserts x is false.
** }else{
** // ALWAYS(x) is a constant 1. NEVER(x) is a constant 0.
** }
*/
case SQLITE_TESTCTRL_ALWAYS: {
int x = va_arg(ap,int);
rc = ALWAYS(x);
break;
}
/* sqlite4_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, sqlite4 *db, int N)
**
** Enable or disable various optimizations for testing purposes. The
** argument N is a bitmask of optimizations to be disabled. For normal
** operation N should be 0. The idea is that a test program (like the
** SQL Logic Test or SLT test module) can run the same SQL multiple times
** with various optimizations disabled to verify that the same answer
** is obtained in every case.
*/
case SQLITE_TESTCTRL_OPTIMIZATIONS: {
sqlite4 *db = va_arg(ap, sqlite4*);
int x = va_arg(ap,int);
db->flags = (x & SQLITE_OptMask) | (db->flags & ~SQLITE_OptMask);
break;
}
#ifdef SQLITE_N_KEYWORD
/* sqlite4_test_control(SQLITE_TESTCTRL_ISKEYWORD, const char *zWord)
**
** If zWord is a keyword recognized by the parser, then return the
** number of keywords. Or if zWord is not a keyword, return 0.
**
** This test feature is only available in the amalgamation since
** the SQLITE_N_KEYWORD macro is not defined in this file if SQLite
** is built using separate source files.
*/
case SQLITE_TESTCTRL_ISKEYWORD: {
const char *zWord = va_arg(ap, const char*);
int n = sqlite4Strlen30(zWord);
rc = (sqlite4KeywordCode((u8*)zWord, n)!=TK_ID) ? SQLITE_N_KEYWORD : 0;
break;
}
#endif
/* sqlite4_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff);
**
** If parameter onoff is non-zero, configure the wrappers so that all
** subsequent calls to localtime() and variants fail. If onoff is zero,
** undo this setting.
*/
case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
sqlite4DefaultEnv.bLocaltimeFault = va_arg(ap, int);
break;
}
#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
/* sqlite4_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT,
** sqlite4_stmt*,const char**);
**
** If compiled with SQLITE_ENABLE_TREE_EXPLAIN, each sqlite4_stmt holds
** a string that describes the optimized parse tree. This test-control
** returns a pointer to that string.
*/
case SQLITE_TESTCTRL_EXPLAIN_STMT: {
sqlite4_stmt *pStmt = va_arg(ap, sqlite4_stmt*);
const char **pzRet = va_arg(ap, const char**);
*pzRet = sqlite4VdbeExplanation((Vdbe*)pStmt);
break;
}
#endif
}
va_end(ap);
#endif /* SQLITE_OMIT_BUILTIN_TEST */
return rc;
}
/*
** This is a utility routine, useful to VFS implementations, that checks
** to see if a database file was a URI that contained a specific query
** parameter, and if so obtains the value of the query parameter.
**
** The zFilename argument is the filename pointer passed into the xOpen()
** method of a VFS implementation. The zParam argument is the name of the
** query parameter we seek. This routine returns the value of the zParam
** parameter if it exists. If the parameter does not exist, this routine
** returns a NULL pointer.
*/
SQLITE_API const char *sqlite4_uri_parameter(const char *zFilename, const char *zParam){
if( zFilename==0 ) return 0;
zFilename += sqlite4Strlen30(zFilename) + 1;
while( zFilename[0] ){
int x = strcmp(zFilename, zParam);
zFilename += sqlite4Strlen30(zFilename) + 1;
if( x==0 ) return zFilename;
zFilename += sqlite4Strlen30(zFilename) + 1;
}
return 0;
}
/*
** Return a boolean value for a query parameter.
*/
SQLITE_API int sqlite4_uri_boolean(const char *zFilename, const char *zParam, int bDflt){
const char *z = sqlite4_uri_parameter(zFilename, zParam);
return z ? sqlite4GetBoolean(z) : (bDflt!=0);
}
/*
** Return a 64-bit integer value for a query parameter.
*/
SQLITE_API sqlite4_int64 sqlite4_uri_int64(
const char *zFilename, /* Filename as passed to xOpen */
const char *zParam, /* URI parameter sought */
sqlite4_int64 bDflt /* return if parameter is missing */
){
const char *z = sqlite4_uri_parameter(zFilename, zParam);
sqlite4_int64 v;
if( z && sqlite4Atoi64(z, &v, sqlite4Strlen30(z), SQLITE_UTF8)==SQLITE_OK ){
bDflt = v;
}
return bDflt;
}
/************** End of main.c ************************************************/