Index: CHANGES.md ================================================================== --- CHANGES.md +++ CHANGES.md @@ -1,10 +1,5 @@ -**fnc 0.15** 2023-04-20 [[history][0.15a] / [diff][0.15b]] - -- update in-tree sqlite to 3.42.0 to fix unused-but-set clang 14.03 build error -- latest upstream libfossil with fixes for clang 14.03 build errors - **fnc 0.14** 2023-04-18 [[history][0.14a] / [diff][0.14b]] - show msg rather than error if timeline C keymap is used outside a work tree - check path is in the requested version if T keymap is used with `fnc tl path` - display the work tree path in checkout diff headlines @@ -320,12 +315,10 @@ - tailor help/usage output to the specified command - fix invalid memory read in diff routine - add support for repository fingerprint version 1 - fix line wrap bug that truncated lines in fullscreen mode -[0.15a]: https://fnc.bsdbox.org/timeline?p=0.15&bt=0.14 -[0.15b]: https://fnc.bsdbox.org/vdiff?from=0.14&to=0.15 [0.14a]: https://fnc.bsdbox.org/timeline?p=0.14&bt=0.13 [0.14b]: https://fnc.bsdbox.org/vdiff?from=0.13&to=0.14 [0.13a]: https://fnc.bsdbox.org/timeline?p=0.13&bt=0.12 [0.13b]: https://fnc.bsdbox.org/vdiff?from=0.12&to=0.13 [0.12a]: https://fnc.bsdbox.org/timeline?p=0.12&bt=0.11 Index: fnc.bld.mk ================================================================== --- fnc.bld.mk +++ fnc.bld.mk @@ -4,11 +4,11 @@ # CONFIGURATION CC ?= cc PREFIX ?= /usr/local MANDIR ?= /share/man -VERSION ?= 0.15 +VERSION ?= 0.14 HASH != cut -f 1 manifest.uuid DATE != sed '2q;d' manifest | cut -d ' ' -f 2 | tr T ' ' # FLAGS NEEDED TO BUILD SQLITE3 SQLITE_CFLAGS = ${CFLAGS} -Wall -Werror -Wno-sign-compare -pedantic -std=c99 \ Index: lib/libfossil-config.h ================================================================== --- lib/libfossil-config.h +++ lib/libfossil-config.h @@ -81,13 +81,13 @@ #endif #endif /* _WIN32 */ -#define FSL_LIB_VERSION_HASH "231fed953330909f8c8db7cf93f31c84b4fc51d5" -#define FSL_LIB_VERSION_TIMESTAMP "2023-04-19 12:46:07.202 UTC" -#define FSL_LIB_CONFIG_TIME "2023-04-20 11:48 GMT" +#define FSL_LIB_VERSION_HASH "9a8269d7377f77c179c4bfb05cda36c9f01976e8" +#define FSL_LIB_VERSION_TIMESTAMP "2023-03-07 14:32:32.997 UTC" +#define FSL_LIB_CONFIG_TIME "2023-04-17 13:37 GMT" #if defined(_MSC_VER) #define FSL_PLATFORM_OS "windows" #define FSL_PLATFORM_IS_WINDOWS 1 #define FSL_PLATFORM_IS_UNIX 0 #define FSL_PLATFORM_PLATFORM "windows" Index: lib/libfossil.c ================================================================== --- lib/libfossil.c +++ lib/libfossil.c @@ -1142,11 +1142,11 @@ #undef STR } return NULL; } -char const * fsl_library_version(void){ +char const * fsl_library_version(){ return FSL_LIBRARY_VERSION; } bool fsl_library_version_matches(char const * yourLibVersion){ return 0 == fsl_strcmp(FSL_LIBRARY_VERSION, yourLibVersion); @@ -1154,11 +1154,11 @@ double fsl_unix_to_julian( fsl_time_t unix_ ){ return (unix_ * 1.0 / 86400.0 ) + 2440587.5; } -double fsl_julian_now(void){ +double fsl_julian_now(){ return fsl_unix_to_julian( time(0) ); } int fsl_strcmp(const char *zA, const char *zB){ @@ -1355,11 +1355,11 @@ return true; } } } -char * fsl_user_name_guess(void){ +char * fsl_user_name_guess(){ char const ** e; static char const * list[] = { "FOSSIL_USER", #if defined(_WIN32) "USERNAME", @@ -1783,11 +1783,11 @@ */ fsl_size_t fsl_simplify_sql_buffer( fsl_buffer * const b ){ return b->used = fsl_simplify_sql( (char *)b->mem, (fsl_int_t)b->used ); } -char const *fsl_preferred_ckout_db_name(void){ +char const *fsl_preferred_ckout_db_name(){ #if FSL_PLATFORM_IS_WINDOWS return "_FOSSIL_"; #else return ".fslckout"; #endif @@ -7006,10 +7006,11 @@ fsl_ckout_changes_f visitor, void * state ){ int rc; fsl_db * db; fsl_stmt st = fsl_stmt_empty; + int count = 0; fsl_ckout_change_e coChange; fsl_fstat fstat; if(!f || !visitor) return FSL_RC_MISUSE; db = fsl_needs_ckout(f); if(!db) return FSL_RC_NOT_A_CKOUT; @@ -7067,10 +7068,11 @@ MARKER(("INTERNAL ERROR: unhandled vfile.chnged " "value %d for file [%s]\n", changed, name)); continue; } + ++count; rc = visitor(state, coChange, name, oname); if(rc){ if(FSL_RC_BREAK==rc){ rc = 0; break; @@ -11370,11 +11372,11 @@ "safe and restore them after re-opening the repository.\n"); } return rc; } -char const * fcli_progname(void){ +char const * fcli_progname(){ if(!fcli.appName || !*fcli.appName) return NULL; char const * z = fcli.appName; char const * zEnd = z + fsl_strlen(z) - 1; for( ; zEnd > z; --zEnd ){ switch((int)*zEnd){ @@ -13895,11 +13897,11 @@ { "web-browser", 0, 32, 0, "" }, { "white-foreground", 0, 0, 0, "off" }, { 0,0,0,0,0 } }; -char *fsl_db_setting_inop_rhs(void){ +char *fsl_db_setting_inop_rhs(){ fsl_buffer x = fsl_buffer_empty; const char *zSep = ""; fsl_config_ctrl const * ct = &fslConfigCtrl[0]; int rc = fsl_buffer_append(&x, "(", 1); for( ; !rc && ct && ct->name; ++ct){ @@ -14482,11 +14484,11 @@ return (f && f->dbMain && f->dbMain->dbh) ? fsl_db_last_insert_id(f->dbMain) : -1; } -fsl_cx * fsl_cx_malloc(void){ +fsl_cx * fsl_cx_malloc(){ fsl_cx * rc = (fsl_cx *)fsl_malloc(sizeof(fsl_cx)); if(rc) { *rc = fsl_cx_empty; rc->allocStamp = &fsl_cx_empty; } @@ -17398,20 +17400,20 @@ break; } return 0; } -fsl_db * fsl_db_malloc(void){ +fsl_db * fsl_db_malloc(){ fsl_db * rc = (fsl_db *)fsl_malloc(sizeof(fsl_db)); if(rc){ *rc = fsl_db_empty; rc->allocStamp = &fsl_db_empty; } return rc; } -fsl_stmt * fsl_stmt_malloc(void){ +fsl_stmt * fsl_stmt_malloc(){ fsl_stmt * rc = (fsl_stmt *)fsl_malloc(sizeof(fsl_stmt)); if(rc){ *rc = fsl_stmt_empty; rc->allocStamp = &fsl_stmt_empty; } @@ -18744,11 +18746,11 @@ static int fsl_list_v_card_J_free(void * obj, void * visitorState __unused){ if(obj) fsl_card_J_free( (fsl_card_J*)obj ); return 0; } -fsl_deck * fsl_deck_malloc(void){ +fsl_deck * fsl_deck_malloc(){ fsl_deck * rc = (fsl_deck *)fsl_malloc(sizeof(fsl_deck)); if(rc){ *rc = fsl_deck_empty; rc->allocStamp = &fsl_deck_empty; } @@ -27961,10 +27963,11 @@ ){ int i, j, k; /* Loop counters */ int *a = 0; /* One row of the Wagner matrix */ int *pToFree = 0; /* Space that needs to be freed */ unsigned char *aM = 0; /* Wagner result matrix */ + int nMatch, iMatch; /* Number of matching lines and match score */ int aBuf[100]; /* Stack space for a[] if nRight not to big */ int rc = 0; if( nLeft==0 ){ aM = fsl_malloc( nRight + 2 ); @@ -28049,16 +28052,19 @@ /* Compute the lowest-cost path back through the matrix */ i = nRight; j = nLeft; k = (nRight+1)*(nLeft+1)-1; + nMatch = iMatch = 0; while( i+j>0 ){ unsigned char c = aM[k]; if( c>=3 ){ assert( i>0 && j>0 ); i--; j--; + nMatch++; + iMatch += (c>>2); aM[k] = 3; }else if( c==2 ){ assert( i>0 ); i--; }else{ @@ -33778,11 +33784,11 @@ }; /** Asserts, the first time it is called, that all mergeMarker entries are of the same length and returns that length. */ -static inline fsl_int_t assert_mema_lengths(void){ +static inline fsl_int_t assert_mema_lengths(){ static bool once = true; if(once){ once = false; assert(sizeof(mergeMarker)/sizeof(mergeMarker[0]) == 4); assert((fsl_int_t)fsl_strlen(mergeMarker[0])==MEMA_LENGTH); @@ -34223,19 +34229,20 @@ return rc; } signal(SIGPIPE,SIG_IGN); if( *pChildPid==0 ){ int fd; + int nErr = 0; /* This is the child process */ close(0); fd = dup(pout[0]); - if( fd!=0 ) { /* nop */ }; + if( fd!=0 ) nErr++; close(pout[0]); close(pout[1]); close(1); fd = dup(pin[1]); - if( fd!=1 ) { /* nop */ }; + if( fd!=1 ) nErr++; close(pin[0]); close(pin[1]); execl("/bin/sh", "/bin/sh", "-c", zCmd, (char*)0) /* doesn't return on success */; return fsl_errno_to_rc(errno, FSL_RC_ERROR); @@ -36917,41 +36924,41 @@ This file implements schema-related parts of the library. */ #include -char const * fsl_schema_ckout(void){ +char const * fsl_schema_ckout(){ extern char const * fsl_schema_ckout_cstr; return fsl_schema_ckout_cstr; } -char const * fsl_schema_repo2(void){ +char const * fsl_schema_repo2(){ extern char const * fsl_schema_repo2_cstr; return fsl_schema_repo2_cstr; } -char const * fsl_schema_repo1(void){ +char const * fsl_schema_repo1(){ extern char const * fsl_schema_repo1_cstr; return fsl_schema_repo1_cstr; } -char const * fsl_schema_config(void){ +char const * fsl_schema_config(){ extern char const * fsl_schema_config_cstr; return fsl_schema_config_cstr; } -char const * fsl_schema_ticket_reports(void){ +char const * fsl_schema_ticket_reports(){ extern char const * fsl_schema_ticket_reports_cstr; return fsl_schema_ticket_reports_cstr; } -char const * fsl_schema_ticket(void){ +char const * fsl_schema_ticket(){ extern char const * fsl_schema_ticket_cstr; return fsl_schema_ticket_cstr; } -char const * fsl_schema_forum(void){ +char const * fsl_schema_forum(){ extern char const * fsl_schema_forum_cstr; return fsl_schema_forum_cstr; } /* end of file ./src/schema.c */ /* start of file ./src/search.c */ Index: lib/libfossil.h ================================================================== --- lib/libfossil.h +++ lib/libfossil.h @@ -1149,11 +1149,11 @@ Returns the current Unix Epoch time converted to its approximate Julian form. Equivalent to fsl_unix_to_julian(time(0)). See fsl_unix_to_julian() for details. Note that the returned time has seconds, not milliseconds, precision. */ -FSL_EXPORT double fsl_julian_now(void); +FSL_EXPORT double fsl_julian_now(); #if 0 /** UNTESTED, possibly broken vis-a-vis timezone conversion. Returns the given Unix Epoch time value formatted as an ISO8601 @@ -3264,11 +3264,11 @@ NULL. @see fsl_cx_user_set() @see fsl_cx_user_get() */ -FSL_EXPORT char * fsl_user_name_guess(void); +FSL_EXPORT char * fsl_user_name_guess(); /** Tries to find the user's home directory. If found, 0 is returned, tgt's memory is _overwritten_ (not appended) with the path, and tgt->used is set to the path's string length. (Design @@ -7037,11 +7037,11 @@ The API does not yet have any mechanism for determining compatibility between library versions and it also currently does no explicit checking to disallow incompatible versions. */ -FSL_EXPORT char const * fsl_library_version(void); +FSL_EXPORT char const * fsl_library_version(); /** Returns true (non-0) if yourLibVersion compares lexically equal to FSL_LIBRARY_VERSION, else it returns false (0). It is intended to be passed the FSL_LIBRARY_VERSION string the client code was built @@ -7158,11 +7158,11 @@ be passed to fsl_cx_finalize() to clean it up. Normally clients do not need this - they can simply pass a pointer to NULL as the first argument to fsl_cx_init() to let it allocate an instance for them. */ -FSL_EXPORT fsl_cx * fsl_cx_malloc(void); +FSL_EXPORT fsl_cx * fsl_cx_malloc(); /** Initializes a fsl_cx instance. tgt must be a pointer to NULL, e.g.: @@ -8861,11 +8861,11 @@ fsl_stmt_finalize() to free it (whether or not it is ever passed to fsl_db_prepare()). Returns NULL on allocation error. */ -FSL_EXPORT fsl_stmt * fsl_stmt_malloc(void); +FSL_EXPORT fsl_stmt * fsl_stmt_malloc(); /** Behaves like fsl_error_get(), using the db's underlying error state. Results are undefined if !db. @@ -10019,19 +10019,19 @@ determining if fsl_db_close() should free the value or not. Thus if clients copy over this value without adjusting allocStamp back to its original value, the library will likely leak the instance. Been there, done that. */ -FSL_EXPORT fsl_db * fsl_db_malloc(void); +FSL_EXPORT fsl_db * fsl_db_malloc(); /** The fsl_stmt counterpart of fsl_db_malloc(). See that function for when you might want to use this and a caveat involving the allocStamp member of the returned value. fsl_stmt_finalize() will free statements created with this function. */ -FSL_EXPORT fsl_stmt * fsl_stmt_malloc(void); +FSL_EXPORT fsl_stmt * fsl_stmt_malloc(); /** ATTACHes the file zDbName to db using the databbase name zLabel. Returns 0 on success. Returns FSL_RC_MISUSE if any argument is NULL or any string argument starts with a NUL byte, @@ -11367,11 +11367,11 @@ fsl_deck_finalize() to free its resources. @see fsl_deck_finalize() @see fsl_deck_clean() */ -FSL_EXPORT fsl_deck * fsl_deck_malloc(void); +FSL_EXPORT fsl_deck * fsl_deck_malloc(); /** Frees all resources belonging to the given deck's members (including its parents, recursively), and wipes deck clean of most state, but does not free() deck. Is a no-op if deck is NULL. As a @@ -13951,56 +13951,56 @@ /** Returns the raw SQL code for a Fossil global config database. TODO: add optional (fsl_size_t*) to return the length. */ -FSL_EXPORT char const * fsl_schema_config(void); +FSL_EXPORT char const * fsl_schema_config(); /** Returns the raw SQL code for the "static" parts of a Fossil repository database. These are the parts which are immutable (for the most part) between Fossil versions. They change _very_ rarely. TODO: add optional (fsl_size_t*) to return the length. */ -FSL_EXPORT char const * fsl_schema_repo1(void); +FSL_EXPORT char const * fsl_schema_repo1(); /** Returns the raw SQL code for the "transient" parts of a Fossil repository database - any parts which can be calculated via data held in the primary "static" schemas. These parts are occassionally recreated, e.g. via a 'rebuild' of a repository. TODO: add optional (fsl_size_t*) to return the length. */ -FSL_EXPORT char const * fsl_schema_repo2(void); +FSL_EXPORT char const * fsl_schema_repo2(); /** Returns the raw SQL code for a Fossil checkout database. TODO: add optional (fsl_size_t*) to return the length. */ -FSL_EXPORT char const * fsl_schema_ckout(void); +FSL_EXPORT char const * fsl_schema_ckout(); /** Returns the raw SQL code for a Fossil checkout db's _default_ core ticket-related tables. TODO: add optional (fsl_size_t*) to return the length. @see fsl_cx_schema_ticket() */ -FSL_EXPORT char const * fsl_schema_ticket(void); +FSL_EXPORT char const * fsl_schema_ticket(); /** Returns the raw SQL code for the "forum" parts of a Fossil repository database. TODO: add optional (fsl_size_t*) to return the length. */ -FSL_EXPORT char const * fsl_schema_forum(void); +FSL_EXPORT char const * fsl_schema_forum(); /** If f's opened repository has a non-empty config entry named 'ticket-table', this returns its text via appending it to pOut. If no entry is found, fsl_schema_ticket() is appended to @@ -14015,11 +14015,11 @@ Returns the raw SQL code for Fossil ticket reports schemas. This gets installed as needed into repository databases. TODO: add optional (fsl_size_t*) to return the length. */ -FSL_EXPORT char const * fsl_schema_ticket_reports(void); +FSL_EXPORT char const * fsl_schema_ticket_reports(); /** This is a wrapper around fsl_cx_hash_buffer() which looks for a matching artifact for the given input blob. It first hashes src using f's "alternate" hash and then, if no match is found, tries @@ -16519,11 +16519,11 @@ file. That is "_FOSSIL_" on Windows and ".fslckout" everywhere else. The returned bytes are static. TODO: an API which takes a dir name and looks for either name */ -FSL_EXPORT char const *fsl_preferred_ckout_db_name(void); +FSL_EXPORT char const *fsl_preferred_ckout_db_name(); /** File-overwrite policy values for use with fsl_ckup_opt and friends. */ enum fsl_file_overwrite_policy_e { @@ -20449,11 +20449,11 @@ fsl_free(). Returns NULL on allocation error. Reminder to self: this is part of the infrastructure for copying config state from an existing repo when creating new repo. */ -char *fsl_db_setting_inop_rhs(void); +char *fsl_db_setting_inop_rhs(); /** @internal Creates the ticket and ticketchng tables in f's repository db, DROPPING them if they already exist. The schema comes from Index: lib/sqlite3.c ================================================================== --- lib/sqlite3.c +++ lib/sqlite3.c @@ -1,8 +1,8 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.42.0. By combining all the individual C code files into this +** version 3.38.5. 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. @@ -450,13 +450,13 @@ ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.42.0" -#define SQLITE_VERSION_NUMBER 3042000 -#define SQLITE_SOURCE_ID "2023-04-18 23:05:34 ba8e4378f21d529a248d2d60b60974fef0d6612dcaaa1f6b7f8a6946fc46b39b" +#define SQLITE_VERSION "3.38.5" +#define SQLITE_VERSION_NUMBER 3038005 +#define SQLITE_SOURCE_ID "2022-05-06 15:25:27 78d9c993d404cdfaa7fdd2973fa1052e3da9f66215cff9c5540ebe55c407d9fe" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version sqlite3_sourceid ** @@ -867,11 +867,10 @@ #define SQLITE_CONSTRAINT_ROWID (SQLITE_CONSTRAINT |(10<<8)) #define SQLITE_CONSTRAINT_PINNED (SQLITE_CONSTRAINT |(11<<8)) #define SQLITE_CONSTRAINT_DATATYPE (SQLITE_CONSTRAINT |(12<<8)) #define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8)) #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8)) -#define SQLITE_NOTICE_RBU (SQLITE_NOTICE | (3<<8)) #define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8)) #define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8)) #define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8)) #define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal use only */ @@ -975,21 +974,17 @@ /* ** CAPI3REF: File Locking Levels ** ** SQLite uses one of these integer values as the second ** argument to calls it makes to the xLock() and xUnlock() methods -** of an [sqlite3_io_methods] object. These values are ordered from -** lest restrictive to most restrictive. -** -** The argument to xLock() is always SHARED or higher. The argument to -** xUnlock is either SHARED or NONE. +** of an [sqlite3_io_methods] object. */ -#define SQLITE_LOCK_NONE 0 /* xUnlock() only */ -#define SQLITE_LOCK_SHARED 1 /* xLock() or xUnlock() */ -#define SQLITE_LOCK_RESERVED 2 /* xLock() only */ -#define SQLITE_LOCK_PENDING 3 /* xLock() only */ -#define SQLITE_LOCK_EXCLUSIVE 4 /* xLock() only */ +#define SQLITE_LOCK_NONE 0 +#define SQLITE_LOCK_SHARED 1 +#define SQLITE_LOCK_RESERVED 2 +#define SQLITE_LOCK_PENDING 3 +#define SQLITE_LOCK_EXCLUSIVE 4 /* ** CAPI3REF: Synchronization Type Flags ** ** When SQLite invokes the xSync() method of an @@ -1063,18 +1058,11 @@ **
  • [SQLITE_LOCK_SHARED], **
  • [SQLITE_LOCK_RESERVED], **
  • [SQLITE_LOCK_PENDING], or **
  • [SQLITE_LOCK_EXCLUSIVE]. ** -** xLock() upgrades the database file lock. In other words, xLock() moves the -** database file lock in the direction NONE toward EXCLUSIVE. The argument to -** xLock() is always on of SHARED, RESERVED, PENDING, or EXCLUSIVE, never -** SQLITE_LOCK_NONE. If the database file lock is already at or above the -** requested lock, then the call to xLock() is a no-op. -** xUnlock() downgrades the database file lock to either SHARED or NONE. -* If the lock is already at or below the requested lock state, then the call -** to xUnlock() is a no-op. +** xLock() increases the lock. xUnlock() decreases the lock. ** The xCheckReservedLock() method checks whether any database connection, ** either in this process or in some other process, is holding a RESERVED, ** PENDING, or EXCLUSIVE lock on the file. It returns true ** if such a lock exists and false otherwise. ** @@ -1175,12 +1163,13 @@ **
  • [[SQLITE_FCNTL_LOCKSTATE]] ** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This ** opcode causes the xFileControl method to write the current state of ** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], ** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) -** into an integer that the pArg argument points to. -** This capability is only available if SQLite is compiled with [SQLITE_DEBUG]. +** into an integer that the pArg argument points to. This capability +** is used during testing and is only available when the SQLITE_TEST +** compile-time option is used. ** **
  • [[SQLITE_FCNTL_SIZE_HINT]] ** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS ** layer a hint of how large the database file will grow to be during the ** current transaction. This hint is not guaranteed to be accurate but it @@ -1480,10 +1469,11 @@ **
  • [[SQLITE_FCNTL_CKPT_DONE]] ** The [SQLITE_FCNTL_CKPT_DONE] opcode is invoked from within a checkpoint ** in wal mode after the client has finished copying pages from the wal ** file to the database file, but before the *-shm file is updated to ** record the fact that the pages have been checkpointed. +** ** **
  • [[SQLITE_FCNTL_EXTERNAL_READER]] ** The EXPERIMENTAL [SQLITE_FCNTL_EXTERNAL_READER] opcode is used to detect ** whether or not there is a database client in another process with a wal-mode ** transaction open on the database or not. It is only available on unix.The @@ -1492,20 +1482,14 @@ ** mode database and there exists at least one client in another process that ** currently has an SQL transaction open on the database. It is set to 0 if ** the database is not a wal-mode db, or if there is no such connection in any ** other process. This opcode cannot be used to detect transactions opened ** by clients within the current process, only within other processes. +** ** **
  • [[SQLITE_FCNTL_CKSM_FILE]] -** The [SQLITE_FCNTL_CKSM_FILE] opcode is for use interally by the -** [checksum VFS shim] only. -** -**
  • [[SQLITE_FCNTL_RESET_CACHE]] -** If there is currently no transaction open on the database, and the -** database is not a temp db, then the [SQLITE_FCNTL_RESET_CACHE] file-control -** purges the contents of the in-memory page cache. If there is an open -** transaction, or if the db is a temp-db, this opcode is a no-op, not an error. +** Used by the cksmvfs VFS module only. ** */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_FCNTL_GET_LOCKPROXYFILE 2 #define SQLITE_FCNTL_SET_LOCKPROXYFILE 3 @@ -1544,11 +1528,10 @@ #define SQLITE_FCNTL_CKPT_DONE 37 #define SQLITE_FCNTL_RESERVE_BYTES 38 #define SQLITE_FCNTL_CKPT_START 39 #define SQLITE_FCNTL_EXTERNAL_READER 40 #define SQLITE_FCNTL_CKSM_FILE 41 -#define SQLITE_FCNTL_RESET_CACHE 42 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO @@ -1574,30 +1557,10 @@ ** structure must be typedefed in order to work around compiler warnings ** on some platforms. */ typedef struct sqlite3_api_routines sqlite3_api_routines; -/* -** CAPI3REF: File Name -** -** Type [sqlite3_filename] is used by SQLite to pass filenames to the -** xOpen method of a [VFS]. It may be cast to (const char*) and treated -** as a normal, nul-terminated, UTF-8 buffer containing the filename, but -** may also be passed to special APIs such as: -** -** -*/ -typedef const char *sqlite3_filename; - /* ** CAPI3REF: OS Interface Object ** ** An instance of the sqlite3_vfs object defines the interface between ** the SQLite core and the underlying operating system. The "vfs" @@ -1772,11 +1735,11 @@ int szOsFile; /* Size of subclassed sqlite3_file */ int mxPathname; /* Maximum file pathname length */ sqlite3_vfs *pNext; /* Next registered VFS */ const char *zName; /* Name of this virtual file system */ void *pAppData; /* Pointer to application-specific data */ - int (*xOpen)(sqlite3_vfs*, sqlite3_filename zName, sqlite3_file*, + int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, int flags, int *pOutFlags); int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut); int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); @@ -1959,27 +1922,24 @@ ** ** The sqlite3_config() interface is not threadsafe. The application ** must ensure that no other SQLite interfaces are invoked by other ** threads while sqlite3_config() is running. ** +** The sqlite3_config() interface +** may only be invoked prior to library initialization using +** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()]. +** ^If sqlite3_config() is called after [sqlite3_initialize()] and before +** [sqlite3_shutdown()] then it will return SQLITE_MISUSE. +** Note, however, that ^sqlite3_config() can be called as part of the +** implementation of an application-defined [sqlite3_os_init()]. +** ** The first argument to sqlite3_config() is an integer ** [configuration option] that determines ** what property of SQLite is to be configured. Subsequent arguments ** vary depending on the [configuration option] ** in the first argument. ** -** For most configuration options, the sqlite3_config() interface -** may only be invoked prior to library initialization using -** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()]. -** The exceptional configuration options that may be invoked at any time -** are called "anytime configuration options". -** ^If sqlite3_config() is called after [sqlite3_initialize()] and before -** [sqlite3_shutdown()] with a first argument that is not an anytime -** configuration option, then the sqlite3_config() call will return SQLITE_MISUSE. -** Note, however, that ^sqlite3_config() can be called as part of the -** implementation of an application-defined [sqlite3_os_init()]. -** ** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK]. ** ^If the option is unknown or SQLite is unable to set the option ** then this routine returns a non-zero [error code]. */ SQLITE_API int sqlite3_config(int, ...); @@ -2083,27 +2043,10 @@ ** KEYWORDS: {configuration option} ** ** These constants are the available integer configuration options that ** can be passed as the first argument to the [sqlite3_config()] interface. ** -** Most of the configuration options for sqlite3_config() -** will only work if invoked prior to [sqlite3_initialize()] or after -** [sqlite3_shutdown()]. The few exceptions to this rule are called -** "anytime configuration options". -** ^Calling [sqlite3_config()] with a first argument that is not an -** anytime configuration option in between calls to [sqlite3_initialize()] and -** [sqlite3_shutdown()] is a no-op that returns SQLITE_MISUSE. -** -** The set of anytime configuration options can change (by insertions -** and/or deletions) from one release of SQLite to the next. -** As of SQLite version 3.42.0, the complete set of anytime configuration -** options is: -** -** ** New configuration options may be added in future releases of SQLite. ** Existing configuration options might be discontinued. Applications ** should check the return code from [sqlite3_config()] to make sure that ** the call worked. The [sqlite3_config()] interface will return a ** non-zero [error code] if a discontinued or unsupported configuration option @@ -2508,11 +2451,11 @@ ** 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 -** [sqlite3_db_status](D,[SQLITE_DBSTATUS_LOOKASIDE_USED],...) is zero. +** [sqlite3_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].)^ ** ** [[SQLITE_DBCONFIG_ENABLE_FKEY]] @@ -2658,16 +2601,12 @@ **
  • sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0); **
  • [sqlite3_exec](db, "[VACUUM]", 0, 0, 0); **
  • sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0); ** ** Because resetting a database is destructive and irreversible, the -** process requires the use of this obscure API and multiple steps to -** help ensure that it does not happen by accident. Because this -** feature must be capable of resetting corrupt databases, and -** shutting down virtual tables may require access to that corrupt -** storage, the library must abandon any installed virtual tables -** without calling their xDestroy() methods. +** process requires the use of this obscure API and multiple steps to help +** ensure that it does not happen by accident. ** ** [[SQLITE_DBCONFIG_DEFENSIVE]]
    SQLITE_DBCONFIG_DEFENSIVE
    **
    The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the ** "defensive" flag for a database connection. When the defensive ** flag is enabled, language features that allow ordinary SQL to @@ -2674,11 +2613,10 @@ ** deliberately corrupt the database file are disabled. The disabled ** features include but are not limited to the following: **
      **
    • The [PRAGMA writable_schema=ON] statement. **
    • The [PRAGMA journal_mode=OFF] statement. -**
    • The [PRAGMA schema_version=N] statement. **
    • Writes to the [sqlite_dbpage] virtual table. **
    • Direct writes to [shadow tables]. **
    **
    ** @@ -2760,30 +2698,10 @@ ** the [VACUUM] command will fail with an obscure error when attempting to ** process a table with generated columns and a descending index. This is ** not considered a bug since SQLite versions 3.3.0 and earlier do not support ** either generated columns or decending indexes. ** -** -** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]] -**
    SQLITE_DBCONFIG_STMT_SCANSTATUS -**
    The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in -** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears -** a flag that enables collection of the sqlite3_stmt_scanstatus_v2() -** statistics. For statistics to be collected, the flag must be set on -** the database handle both when the SQL statement is prepared and when it -** is stepped. The flag is set (collection of statistics is enabled) -** by default.
    -** -** [[SQLITE_DBCONFIG_REVERSE_SCANORDER]] -**
    SQLITE_DBCONFIG_REVERSE_SCANORDER -**
    The SQLITE_DBCONFIG_REVERSE_SCANORDER option change the default order -** in which tables and indexes are scanned so that the scans start at the end -** and work toward the beginning rather than starting at the beginning and -** working toward the end. Setting SQLITE_DBCONFIG_REVERSE_SCANORDER is the -** same as setting [PRAGMA reverse_unordered_selects]. This configuration option -** is useful for application testing.
    -** ** */ #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ #define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ @@ -2800,13 +2718,11 @@ #define SQLITE_DBCONFIG_DQS_DML 1013 /* int int* */ #define SQLITE_DBCONFIG_DQS_DDL 1014 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */ #define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 1016 /* int int* */ #define SQLITE_DBCONFIG_TRUSTED_SCHEMA 1017 /* int int* */ -#define SQLITE_DBCONFIG_STMT_SCANSTATUS 1018 /* int int* */ -#define SQLITE_DBCONFIG_REVERSE_SCANORDER 1019 /* int int* */ -#define SQLITE_DBCONFIG_MAX 1019 /* Largest DBCONFIG */ +#define SQLITE_DBCONFIG_MAX 1017 /* Largest DBCONFIG */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes ** METHOD: sqlite3 ** @@ -3024,16 +2940,12 @@ ** that are started after the running statement count reaches zero are ** not effected by the sqlite3_interrupt(). ** ^A call to sqlite3_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 sqlite3_interrupt() call returns. -** -** ^The [sqlite3_is_interrupted(D)] interface can be used to determine whether -** or not an interrupt is currently in effect for [database connection] D. */ SQLITE_API void sqlite3_interrupt(sqlite3*); -SQLITE_API int sqlite3_is_interrupted(sqlite3*); /* ** CAPI3REF: Determine If An SQL Statement Is Complete ** ** These routines are useful during command-line input to determine if the @@ -3647,12 +3559,12 @@ ** ** [[SQLITE_TRACE_PROFILE]]
    SQLITE_TRACE_PROFILE
    **
    ^An SQLITE_TRACE_PROFILE callback provides approximately the same ** information as is provided by the [sqlite3_profile()] callback. ** ^The P argument is a pointer to the [prepared statement] and the -** X argument points to a 64-bit integer which is approximately -** the number of nanoseconds that the prepared statement took to run. +** X argument points to a 64-bit integer which is the estimated of +** the number of nanosecond that the prepared statement took to run. ** ^The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes. ** ** [[SQLITE_TRACE_ROW]]
    SQLITE_TRACE_ROW
    **
    ^An SQLITE_TRACE_ROW callback is invoked whenever a prepared ** statement generates a single row of result. @@ -3711,11 +3623,11 @@ ** CAPI3REF: Query Progress Callbacks ** METHOD: sqlite3 ** ** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback ** function X to be invoked periodically during long running calls to -** [sqlite3_step()] and [sqlite3_prepare()] and similar for +** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] 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 approximate number of @@ -3736,17 +3648,10 @@ ** The progress handler callback must not do anything that will modify ** the database connection that invoked the progress handler. ** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their ** database connections for the meaning of "modify" in this paragraph. ** -** The progress handler callback would originally only be invoked from the -** bytecode engine. It still might be invoked during [sqlite3_prepare()] -** and similar because those routines might force a reparse of the schema -** which involves running the bytecode engine. However, beginning with -** SQLite version 3.41.0, the progress handler callback might also be -** invoked directly from [sqlite3_prepare()] while analyzing and generating -** code for complex queries. */ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); /* ** CAPI3REF: Opening A New Database Connection @@ -3779,22 +3684,17 @@ ** sqlite3_open_v2() must include, at a minimum, one of the following ** three flag combinations:)^ ** **
    ** ^(
    [SQLITE_OPEN_READONLY]
    -**
    The database is opened in read-only mode. If the database does -** not already exist, an error is returned.
    )^ +**
    The database is opened in read-only mode. If the database does not +** already exist, an error is returned.
    )^ ** ** ^(
    [SQLITE_OPEN_READWRITE]
    -**
    The database is opened for reading and writing if possible, or -** reading only if the file is write protected by the operating -** system. In either case the database must already exist, otherwise -** an error is returned. For historical reasons, if opening in -** read-write mode fails due to OS-level permissions, an attempt is -** made to open it in read-only mode. [sqlite3_db_readonly()] can be -** used to determine whether the database is actually -** read-write.
    )^ +**
    The database is opened for reading and writing if possible, or reading +** only if the file is write protected by the operating system. In either +** case the database must already exist, otherwise an error is returned.
    )^ ** ** ^(
    [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]
    **
    The database is opened for reading and writing, and is created if ** it does not already exist. This is the behavior that is always used for ** sqlite3_open() and sqlite3_open16().
    )^ @@ -3828,13 +3728,10 @@ ** ** ^(
    [SQLITE_OPEN_SHAREDCACHE]
    **
    The database is opened [shared cache] enabled, overriding ** the default shared cache setting provided by ** [sqlite3_enable_shared_cache()].)^ -** The [use of shared cache mode is discouraged] and hence shared cache -** capabilities may be omitted from many builds of SQLite. In such cases, -** this option is a no-op. ** ** ^(
    [SQLITE_OPEN_PRIVATECACHE]
    **
    The database is opened [shared cache] disabled, overriding ** the default shared cache setting provided by ** [sqlite3_enable_shared_cache()].)^ @@ -3846,11 +3743,11 @@ ** connection as soon as the connection is created. In addition to setting ** the extended result code mode, this flag also causes [sqlite3_open_v2()] ** to return an extended result code.
    ** ** [[OPEN_NOFOLLOW]] ^(
    [SQLITE_OPEN_NOFOLLOW]
    -**
    The database filename is not allowed to contain a symbolic link
    +**
    The database filename is not allowed to be a symbolic link
    **
    )^ ** ** If the 3rd parameter to sqlite3_open_v2() is not one of the ** required combinations shown above optionally combined with other ** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits] @@ -4105,14 +4002,14 @@ ** it has access to all the same query parameters as were found on the ** main database file. ** ** See the [URI filename] documentation for additional information. */ -SQLITE_API const char *sqlite3_uri_parameter(sqlite3_filename z, const char *zParam); -SQLITE_API int sqlite3_uri_boolean(sqlite3_filename z, const char *zParam, int bDefault); -SQLITE_API sqlite3_int64 sqlite3_uri_int64(sqlite3_filename, const char*, sqlite3_int64); -SQLITE_API const char *sqlite3_uri_key(sqlite3_filename z, int N); +SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam); +SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); +SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64); +SQLITE_API const char *sqlite3_uri_key(const char *zFilename, int N); /* ** CAPI3REF: Translate filenames ** ** These routines are available to [VFS|custom VFS implementations] for @@ -4137,13 +4034,13 @@ ** In all of the above, if F is not the name of a database, journal or WAL ** filename passed into the VFS from the SQLite core and F is not the ** return value from [sqlite3_db_filename()], then the result is ** undefined and is likely a memory access violation. */ -SQLITE_API const char *sqlite3_filename_database(sqlite3_filename); -SQLITE_API const char *sqlite3_filename_journal(sqlite3_filename); -SQLITE_API const char *sqlite3_filename_wal(sqlite3_filename); +SQLITE_API const char *sqlite3_filename_database(const char*); +SQLITE_API const char *sqlite3_filename_journal(const char*); +SQLITE_API const char *sqlite3_filename_wal(const char*); /* ** CAPI3REF: Database File Corresponding To A Journal ** ** ^If X is the name of a rollback or WAL-mode journal file that is @@ -4205,18 +4102,18 @@ ** used again after sqlite3_free_filename(Y) has been called. This means ** that if the [sqlite3_vfs.xOpen()] method of a VFS has been called using Y, ** then the corresponding [sqlite3_module.xClose() method should also be ** invoked prior to calling sqlite3_free_filename(Y). */ -SQLITE_API sqlite3_filename sqlite3_create_filename( +SQLITE_API char *sqlite3_create_filename( const char *zDatabase, const char *zJournal, const char *zWal, int nParam, const char **azParam ); -SQLITE_API void sqlite3_free_filename(sqlite3_filename); +SQLITE_API void sqlite3_free_filename(char*); /* ** CAPI3REF: Error Codes And Messages ** METHOD: sqlite3 ** @@ -5771,25 +5668,14 @@ ** [[SQLITE_DIRECTONLY]]
    SQLITE_DIRECTONLY
    ** The SQLITE_DIRECTONLY flag means that the function may only be invoked ** from top-level SQL, and cannot be used in VIEWs or TRIGGERs nor in ** schema structures such as [CHECK constraints], [DEFAULT clauses], ** [expression indexes], [partial indexes], or [generated columns]. -**

    -** The SQLITE_DIRECTONLY flag is recommended for any -** [application-defined SQL function] -** that has side-effects or that could potentially leak sensitive information. -** This will prevent attacks in which an application is tricked -** into using a database file that has had its schema surreptiously -** modified to invoke the application-defined function in ways that are -** harmful. -**

    -** Some people say it is good practice to set SQLITE_DIRECTONLY on all -** [application-defined SQL functions], regardless of whether or not they -** are security sensitive, as doing so prevents those functions from being used -** inside of the database schema, and thus ensures that the database -** can be inspected and modified using generic tools (such as the [CLI]) -** that do not have access to the application-defined functions. +** The SQLITE_DIRECTONLY flags is a security feature which is recommended +** for all [application-defined SQL functions], and especially for functions +** that have side-effects or that could potentially leak sensitive +** information. **

    ** ** [[SQLITE_INNOCUOUS]]
    SQLITE_INNOCUOUS
    ** The SQLITE_INNOCUOUS flag means that the function is unlikely ** to cause problems even if misused. An innocuous function should have @@ -5991,32 +5877,10 @@ SQLITE_API int sqlite3_value_type(sqlite3_value*); SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); SQLITE_API int sqlite3_value_nochange(sqlite3_value*); SQLITE_API int sqlite3_value_frombind(sqlite3_value*); -/* -** CAPI3REF: Report the internal text encoding state of an sqlite3_value object -** METHOD: sqlite3_value -** -** ^(The sqlite3_value_encoding(X) interface returns one of [SQLITE_UTF8], -** [SQLITE_UTF16BE], or [SQLITE_UTF16LE] according to the current text encoding -** of the value X, assuming that X has type TEXT.)^ If sqlite3_value_type(X) -** returns something other than SQLITE_TEXT, then the return value from -** sqlite3_value_encoding(X) is meaningless. ^Calls to -** [sqlite3_value_text(X)], [sqlite3_value_text16(X)], [sqlite3_value_text16be(X)], -** [sqlite3_value_text16le(X)], [sqlite3_value_bytes(X)], or -** [sqlite3_value_bytes16(X)] might change the encoding of the value X and -** thus change the return from subsequent calls to sqlite3_value_encoding(X). -** -** This routine is intended for used by applications that test and validate -** the SQLite implementation. This routine is inquiring about the opaque -** internal state of an [sqlite3_value] object. Ordinary applications should -** not need to know what the internal state of an sqlite3_value object is and -** hence should not need to use this interface. -*/ -SQLITE_API int sqlite3_value_encoding(sqlite3_value*); - /* ** CAPI3REF: Finding The Subtype Of SQL Values ** METHOD: sqlite3_value ** ** The sqlite3_value_subtype(V) function returns the subtype for @@ -6033,12 +5897,11 @@ ** ** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value] ** object D and returns a pointer to that copy. ^The [sqlite3_value] returned ** is a [protected sqlite3_value] object even if the input is not. ** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a -** memory allocation fails. ^If V is a [pointer value], then the result -** of sqlite3_value_dup(V) is a NULL value. +** memory allocation fails. ** ** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object ** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer ** then sqlite3_value_free(V) is a harmless no-op. */ @@ -6065,11 +5928,11 @@ ** In those cases, sqlite3_aggregate_context() might be called for the ** first time from within xFinal().)^ ** ** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer ** when first called if N is less than or equal to zero or if a memory -** allocation error occurs. +** allocate error occurs. ** ** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is ** determined by the N parameter on first successful call. Changing the ** value of N in any subsequent call to sqlite3_aggregate_context() within ** the same aggregate function instance will not resize the memory @@ -6270,14 +6133,13 @@ ** application-defined function to be a text string in an encoding ** specified by the fifth (and last) parameter, which must be one ** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]. ** ^SQLite takes the text result from the application from ** the 2nd parameter of the sqlite3_result_text* interfaces. -** ^If the 3rd parameter to any of the sqlite3_result_text* interfaces -** other than sqlite3_result_text64() is negative, then SQLite computes -** the string length itself by searching the 2nd parameter for the first -** zero character. +** ^If the 3rd parameter to the sqlite3_result_text* interfaces +** is negative, then SQLite takes result text from the 2nd parameter +** through the first zero character. ** ^If the 3rd parameter to the sqlite3_result_text* interfaces ** is non-negative, then as many bytes (not characters) of the text ** pointed to by the 2nd parameter are taken as the application-defined ** function result. If the 3rd parameter is non-negative, then it ** must be the byte offset into the string where the NUL terminator would @@ -6717,32 +6579,10 @@ ** to the [sqlite3_prepare_v2()] call (or its variants) that was used to ** create the statement in the first place. */ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); -/* -** CAPI3REF: Return The Schema Name For A Database Connection -** METHOD: sqlite3 -** -** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name -** for the N-th database on database connection D, or a NULL pointer of N is -** out of range. An N value of 0 means the main database file. An N of 1 is -** the "temp" schema. Larger values of N correspond to various ATTACH-ed -** databases. -** -** Space to hold the string that is returned by sqlite3_db_name() is managed -** by SQLite itself. The string might be deallocated by any operation that -** changes the schema, including [ATTACH] or [DETACH] or calls to -** [sqlite3_serialize()] or [sqlite3_deserialize()], even operations that -** occur on a different thread. Applications that need to -** remember the string long-term should make their own copy. Applications that -** are accessing the same database connection simultaneously on multiple -** threads should mutex-protect calls to this API and should make their own -** private copy of the result prior to releasing the mutex. -*/ -SQLITE_API const char *sqlite3_db_name(sqlite3 *db, int N); - /* ** CAPI3REF: Return The Filename For A Database Connection ** METHOD: sqlite3 ** ** ^The sqlite3_db_filename(D,N) interface returns a pointer to the filename @@ -6769,11 +6609,11 @@ **
  • [sqlite3_filename_database()] **
  • [sqlite3_filename_journal()] **
  • [sqlite3_filename_wal()] ** */ -SQLITE_API sqlite3_filename sqlite3_db_filename(sqlite3 *db, const char *zDbName); +SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); /* ** CAPI3REF: Determine if a database is read-only ** METHOD: sqlite3 ** @@ -6906,11 +6746,11 @@ ** ** ^The sqlite3_autovacuum_pages(D,C,P,X) interface registers a callback ** function C that is invoked prior to each autovacuum of the database ** file. ^The callback is passed a copy of the generic data pointer (P), ** the schema-name of the attached database that is being autovacuumed, -** the size of the database file in pages, the number of free pages, +** the the size of the database file in pages, the number of free pages, ** and the number of bytes per page, respectively. The callback should ** return the number of free pages that should be removed by the ** autovacuum. ^If the callback returns zero, then no autovacuum happens. ** ^If the value returned is greater than or equal to the number of ** free pages, then a complete autovacuum happens. @@ -7027,15 +6867,10 @@ ** ^(This routine enables or disables the sharing of the database cache ** and schema data structures between [database connection | connections] ** to the same database. Sharing is enabled if the argument is true ** and disabled if the argument is false.)^ ** -** This interface is omitted if SQLite is compiled with -** [-DSQLITE_OMIT_SHARED_CACHE]. The [-DSQLITE_OMIT_SHARED_CACHE] -** compile-time option is recommended because the -** [use of shared cache mode is discouraged]. -** ** ^Cache sharing is enabled and disabled for an entire process. ** This is a change as of SQLite [version 3.5.0] ([dateof:3.5.0]). ** In prior versions of SQLite, ** sharing was enabled or disabled for each thread separately. ** @@ -7130,11 +6965,11 @@ ** ^Setting the heap limits to zero disables the heap limiter mechanism. ** ** ^The soft heap limit may not be greater than the hard heap limit. ** ^If the hard heap limit is enabled and if sqlite3_soft_heap_limit(N) ** is invoked with a value of N that is greater than the hard heap limit, -** the soft heap limit is set to the value of the hard heap limit. +** the the soft heap limit is set to the value of the hard heap limit. ** ^The soft heap limit is automatically enabled whenever the hard heap ** limit is enabled. ^When sqlite3_hard_heap_limit64(N) is invoked and ** the soft heap limit is outside the range of 1..N, then the soft heap ** limit is set to N. ^Invoking sqlite3_soft_heap_limit64(0) when the ** hard heap limit is enabled makes the soft heap limit equal to the @@ -7391,10 +7226,19 @@ ** ^This interface disables all automatic extensions previously ** registered using [sqlite3_auto_extension()]. */ SQLITE_API void sqlite3_reset_auto_extension(void); +/* +** 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 sqlite3_vtab sqlite3_vtab; typedef struct sqlite3_index_info sqlite3_index_info; @@ -7509,14 +7353,14 @@ ** checked separately in byte code. If the omit flag is change to true, then ** the constraint may or may not be checked in byte code. In other words, ** when the omit flag is true there is no guarantee that the constraint will ** not be checked again using byte code.)^ ** -** ^The idxNum and idxStr values are recorded and passed into the +** ^The idxNum and idxPtr values are recorded and passed into the ** [xFilter] method. -** ^[sqlite3_free()] is used to free idxStr if and only if -** needToFreeIdxStr is true. +** ^[sqlite3_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. ** @@ -7632,11 +7476,11 @@ ** ** The collating sequence to be used for comparison can be found using ** the [sqlite3_vtab_collation()] interface. For most real-world virtual ** tables, the collating sequence of constraints does not matter (for example ** because the constraints are numeric) and so the sqlite3_vtab_collation() -** interface is not commonly needed. +** interface is no commonly needed. */ #define SQLITE_INDEX_CONSTRAINT_EQ 2 #define SQLITE_INDEX_CONSTRAINT_GT 4 #define SQLITE_INDEX_CONSTRAINT_LE 8 #define SQLITE_INDEX_CONSTRAINT_LT 16 @@ -7790,10 +7634,20 @@ ** 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 sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); + +/* +** The interface to the virtual-table mechanism defined above (back up +** to a comment remarkably similar to this one) 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. +*/ /* ** CAPI3REF: A Handle To An Open BLOB ** KEYWORDS: {BLOB handle} {BLOB handles} ** @@ -9406,11 +9260,11 @@ ** sqlite3_backup_init() is called and before the corresponding call to ** sqlite3_backup_finish(). SQLite does not currently check to see ** if the application incorrectly accesses the destination [database connection] ** and so no error code is reported, but the operations may malfunction ** nevertheless. Use of the destination database connection while a -** backup is in progress might also cause a mutex deadlock. +** backup is in progress might also also cause a mutex deadlock. ** ** If running in [shared cache mode], the application must ** guarantee that the shared cache used by the destination database ** is not accessed while the backup is running. In practice this means ** that the application must guarantee that the disk file being @@ -9834,11 +9688,11 @@ ** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the ** meaning of each of these checkpoint modes. */ #define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */ #define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */ -#define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for readers */ +#define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for for readers */ #define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */ /* ** CAPI3REF: Virtual Table Interface Configuration ** @@ -9910,32 +9764,22 @@ **
  • ** ** [[SQLITE_VTAB_INNOCUOUS]]
    SQLITE_VTAB_INNOCUOUS
    **
    Calls of the form ** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the -** the [xConnect] or [xCreate] methods of a [virtual table] implementation +** the [xConnect] or [xCreate] methods of a [virtual table] implmentation ** identify that virtual table as being safe to use from within triggers ** and views. Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the ** virtual table can do no serious harm even if it is controlled by a ** malicious hacker. Developers should avoid setting the SQLITE_VTAB_INNOCUOUS ** flag unless absolutely necessary. **
    -** -** [[SQLITE_VTAB_USES_ALL_SCHEMAS]]
    SQLITE_VTAB_USES_ALL_SCHEMAS
    -**
    Calls of the form -** [sqlite3_vtab_config](db,SQLITE_VTAB_USES_ALL_SCHEMA) from within the -** the [xConnect] or [xCreate] methods of a [virtual table] implementation -** instruct the query planner to begin at least a read transaction on -** all schemas ("main", "temp", and any ATTACH-ed databases) whenever the -** virtual table is used. -**
    ** */ #define SQLITE_VTAB_CONSTRAINT_SUPPORT 1 #define SQLITE_VTAB_INNOCUOUS 2 #define SQLITE_VTAB_DIRECTONLY 3 -#define SQLITE_VTAB_USES_ALL_SCHEMAS 4 /* ** CAPI3REF: Determine The Virtual Table Conflict Policy ** ** This function may only be called from within a call to the [xUpdate] method @@ -10004,22 +9848,22 @@ ** statement that was passed into [sqlite3_declare_vtab()], then the ** name of that alternative collating sequence is returned. **
  • Otherwise, "BINARY" is returned. ** */ -SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int); +SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int); /* ** CAPI3REF: Determine if a virtual table query is DISTINCT ** METHOD: sqlite3_index_info ** ** This API may only be used from within an [xBestIndex|xBestIndex method] ** of a [virtual table] implementation. The result of calling this ** interface from outside of xBestIndex() is undefined and probably harmful. ** -** ^The sqlite3_vtab_distinct() interface returns an integer between 0 and -** 3. The integer returned by sqlite3_vtab_distinct() +** ^The sqlite3_vtab_distinct() interface returns an integer that is +** either 0, 1, or 2. The integer returned by sqlite3_vtab_distinct() ** gives the virtual table additional information about how the query ** planner wants the output to be ordered. As long as the virtual table ** can meet the ordering requirements of the query planner, it may set ** the "orderByConsumed" flag. ** @@ -10047,17 +9891,10 @@ ** values in all "aOrderBy" columns to be returned, as long as all such rows ** are adjacent. ^The virtual table may, if it chooses, omit extra rows ** that have the same value for all columns identified by "aOrderBy". ** ^However omitting the extra rows is optional. ** This mode is used for a DISTINCT query. -**

  • -** ^(If the sqlite3_vtab_distinct() interface returns 3, that means -** that the query planner needs only distinct rows but it does need the -** rows to be sorted.)^ ^The virtual table implementation is free to omit -** rows that are identical in all aOrderBy columns, if it wants to, but -** it is not required to omit any rows. This mode is used for queries -** that have both DISTINCT and ORDER BY clauses. ** ** ** ^For the purposes of comparing virtual table output values to see if the ** values are same value for sorting purposes, two NULL values are considered ** to be the same. In other words, the comparison operator is "IS" @@ -10161,24 +9998,25 @@ ** [xFilter|xFilter() method] of a [virtual table] implementation. ** The result of invoking these interfaces from any other context ** is undefined and probably harmful. ** ** The X parameter in a call to sqlite3_vtab_in_first(X,P) or -** sqlite3_vtab_in_next(X,P) should be one of the parameters to the +** sqlite3_vtab_in_next(X,P) must be one of the parameters to the ** xFilter method which invokes these routines, and specifically ** a parameter that was previously selected for all-at-once IN constraint ** processing use the [sqlite3_vtab_in()] interface in the ** [xBestIndex|xBestIndex method]. ^(If the X parameter is not ** an xFilter argument that was selected for all-at-once IN constraint -** processing, then these routines return [SQLITE_ERROR].)^ +** processing, then these routines return [SQLITE_MISUSE])^ or perhaps +** exhibit some other undefined or harmful behavior. ** ** ^(Use these routines to access all values on the right-hand side ** of the IN constraint using code like the following: ** **

     **    for(rc=sqlite3_vtab_in_first(pList, &pVal);
    -**        rc==SQLITE_OK && pVal;
    +**        rc==SQLITE_OK && pVal
     **        rc=sqlite3_vtab_in_next(pList, &pVal)
     **    ){
     **      // do something with pVal
     **    }
     **    if( rc!=SQLITE_OK ){
    @@ -10272,14 +10110,10 @@
     **
     ** When the value returned to V is a string, space to hold that string is
     ** managed by the prepared statement S and will be automatically freed when
     ** S is finalized.
     **
    -** Not all values are available for all query elements. When a value is
    -** not available, the output variable is set to -1 if the value is numeric,
    -** or to NULL if it is a string (SQLITE_SCANSTAT_NAME).
    -**
     ** 
    ** [[SQLITE_SCANSTAT_NLOOP]]
    SQLITE_SCANSTAT_NLOOP
    **
    ^The [sqlite3_int64] variable pointed to by the V parameter will be ** set to the total number of times that the X-th loop has run.
    ** @@ -10303,44 +10137,30 @@ ** [[SQLITE_SCANSTAT_EXPLAIN]]
    SQLITE_SCANSTAT_EXPLAIN
    **
    ^The "const char *" variable pointed to by the V parameter will be set ** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] ** description for the X-th loop. ** -** [[SQLITE_SCANSTAT_SELECTID]]
    SQLITE_SCANSTAT_SELECTID
    +** [[SQLITE_SCANSTAT_SELECTID]]
    SQLITE_SCANSTAT_SELECT
    **
    ^The "int" variable pointed to by the V parameter will be set to the -** id for the X-th query plan element. The id value is unique within the -** statement. The select-id is the same value as is output in the first -** column of an [EXPLAIN QUERY PLAN] query. -** -** [[SQLITE_SCANSTAT_PARENTID]]
    SQLITE_SCANSTAT_PARENTID
    -**
    The "int" variable pointed to by the V parameter will be set to the -** the id of the parent of the current query element, if applicable, or -** to zero if the query element has no parent. This is the same value as -** returned in the second column of an [EXPLAIN QUERY PLAN] query. -** -** [[SQLITE_SCANSTAT_NCYCLE]]
    SQLITE_SCANSTAT_NCYCLE
    -**
    The sqlite3_int64 output value is set to the number of cycles, -** according to the processor time-stamp counter, that elapsed while the -** query element was being processed. This value is not available for -** all query elements - if it is unavailable the output variable is -** set to -1. +** "select-id" for the X-th loop. The select-id identifies which query or +** subquery the loop is part of. The main query has a select-id of zero. +** The select-id is the same value as is output in the first column +** of an [EXPLAIN QUERY PLAN] query. **
    */ #define SQLITE_SCANSTAT_NLOOP 0 #define SQLITE_SCANSTAT_NVISIT 1 #define SQLITE_SCANSTAT_EST 2 #define SQLITE_SCANSTAT_NAME 3 #define SQLITE_SCANSTAT_EXPLAIN 4 #define SQLITE_SCANSTAT_SELECTID 5 -#define SQLITE_SCANSTAT_PARENTID 6 -#define SQLITE_SCANSTAT_NCYCLE 7 /* ** CAPI3REF: Prepared Statement Scan Status ** METHOD: sqlite3_stmt ** -** These interfaces return information about the predicted and measured +** This interface returns information about the predicted and measured ** performance for pStmt. Advanced applications can use this ** interface to compare the predicted and the measured performance and ** issue warnings and/or rerun [ANALYZE] if discrepancies are found. ** ** Since this interface is expected to be rarely used, it is only @@ -10347,51 +10167,32 @@ ** available if SQLite is compiled using the [SQLITE_ENABLE_STMT_SCANSTATUS] ** compile-time option. ** ** The "iScanStatusOp" parameter determines which status information to return. ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior -** of this interface is undefined. ^The requested measurement is written into -** a variable pointed to by the "pOut" parameter. -** -** The "flags" parameter must be passed a mask of flags. At present only -** one flag is defined - SQLITE_SCANSTAT_COMPLEX. If SQLITE_SCANSTAT_COMPLEX -** is specified, then status information is available for all elements -** of a query plan that are reported by "EXPLAIN QUERY PLAN" output. If -** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements -** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of -** the EXPLAIN QUERY PLAN output) are available. Invoking API -** sqlite3_stmt_scanstatus() is equivalent to calling -** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter. -** -** Parameter "idx" identifies the specific query element to retrieve statistics -** for. Query elements are numbered starting from zero. A value of -1 may be -** to query for statistics regarding the entire query. ^If idx is out of range -** - less than -1 or greater than or equal to the total number of query -** elements used to implement the statement - a non-zero value is returned and -** the variable that pOut points to is unchanged. +** of this interface is undefined. +** ^The requested measurement is written into a variable pointed to by +** the "pOut" parameter. +** Parameter "idx" identifies the specific loop to retrieve statistics for. +** Loops are numbered starting from zero. ^If idx is out of range - less than +** zero or greater than or equal to the total number of loops used to implement +** the statement - a non-zero value is returned and the variable that pOut +** points to is unchanged. +** +** ^Statistics might not be available for all loops in all statements. ^In cases +** where there exist loops with no available statistics, this function behaves +** as if the loop did not exist - it returns non-zero and leave the variable +** that pOut points to unchanged. ** ** See also: [sqlite3_stmt_scanstatus_reset()] */ SQLITE_API int sqlite3_stmt_scanstatus( sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ int idx, /* Index of loop to report on */ int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ void *pOut /* Result written here */ ); -SQLITE_API int sqlite3_stmt_scanstatus_v2( - sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ - int idx, /* Index of loop to report on */ - int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ - int flags, /* Mask of flags defined below */ - void *pOut /* Result written here */ -); - -/* -** CAPI3REF: Prepared Statement Scan Status -** KEYWORDS: {scan status flags} -*/ -#define SQLITE_SCANSTAT_COMPLEX 0x0001 /* ** CAPI3REF: Zero Scan-Status Counters ** METHOD: sqlite3_stmt ** @@ -10478,14 +10279,10 @@ ** seventh parameter is the final rowid value of the row being inserted ** or updated. The value of the seventh parameter passed to the callback ** function is not defined for operations on WITHOUT ROWID tables, or for ** DELETE operations on rowid tables. ** -** ^The sqlite3_preupdate_hook(D,C,P) function returns the P argument from -** the previous call on the same [database connection] D, or NULL for -** the first call on D. -** ** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()], ** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces ** provide additional information about a preupdate event. These routines ** may only be called from within a preupdate callback. Invoking any of ** these routines from outside of a preupdate callback or with a @@ -10887,23 +10684,10 @@ */ #ifdef SQLITE_OMIT_FLOATING_POINT # undef double #endif -#if defined(__wasi__) -# undef SQLITE_WASI -# define SQLITE_WASI 1 -# undef SQLITE_OMIT_WAL -# define SQLITE_OMIT_WAL 1/* because it requires shared memory APIs */ -# ifndef SQLITE_OMIT_LOAD_EXTENSION -# define SQLITE_OMIT_LOAD_EXTENSION -# endif -# ifndef SQLITE_THREADSAFE -# define SQLITE_THREADSAFE 0 -# endif -#endif - #if 0 } /* End of the 'extern "C"' block */ #endif #endif /* SQLITE3_H */ @@ -12269,27 +12053,13 @@ ** **
    SQLITE_CHANGESETAPPLY_INVERT
    ** Invert the changeset before applying it. This is equivalent to inverting ** a changeset using sqlite3changeset_invert() before applying it. It is ** an error to specify this flag with a patchset. -** -**
    SQLITE_CHANGESETAPPLY_IGNORENOOP
    -** Do not invoke the conflict handler callback for any changes that -** would not actually modify the database even if they were applied. -** Specifically, this means that the conflict handler is not invoked -** for: -**
      -**
    • a delete change if the row being deleted cannot be found, -**
    • an update change if the modified fields are already set to -** their new values in the conflicting row, or -**
    • an insert change if all fields of the conflicting row match -** the row being inserted. -**
    */ #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001 #define SQLITE_CHANGESETAPPLY_INVERT 0x0002 -#define SQLITE_CHANGESETAPPLY_IGNORENOOP 0x0004 /* ** CAPI3REF: Constants Passed To The Conflict Handler ** ** Values that may be passed as the second argument to a conflict-handler. @@ -13342,21 +13112,16 @@ /******** End of fts5.h *********/ /************** End of sqlite3.h *********************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ -/* -** Reuse the STATIC_LRU for mutex access to sqlite3_temp_directory. -*/ -#define SQLITE_MUTEX_STATIC_TEMPDIR SQLITE_MUTEX_STATIC_VFS1 - /* ** Include the configuration header output by 'configure' if we're using the ** autoconf-based build */ #if defined(_HAVE_SQLITE_CONFIG_H) && !defined(SQLITECONFIG_H) -#include "sqlite_cfg.h" +#include "config.h" #define SQLITECONFIG_H 1 #endif /************** Include sqliteLimit.h in the middle of sqliteInt.h ***********/ /************** Begin file sqliteLimit.h *************************************/ @@ -13582,12 +13347,12 @@ #pragma warn -csu /* Comparing signed and unsigned */ #pragma warn -spa /* Suspicious pointer arithmetic */ #endif /* -** A few places in the code require atomic load/store of aligned -** integer values. +** WAL mode depends on atomic aligned 32-bit loads and stores in a few +** places. The following macros try to make this explicit. */ #ifndef __has_extension # define __has_extension(x) 0 /* compatibility with non-clang compilers */ #endif #if GCC_VERSION>=4007000 || __has_extension(c_atomic) @@ -13639,26 +13404,19 @@ # define SQLITE_INT_TO_PTR(X) ((void*)(X)) # define SQLITE_PTR_TO_INT(X) ((int)(X)) #endif /* -** Macros to hint to the compiler that a function should or should not be +** A macro to hint to the compiler that a function should not be ** inlined. */ #if defined(__GNUC__) # define SQLITE_NOINLINE __attribute__((noinline)) -# define SQLITE_INLINE __attribute__((always_inline)) inline #elif defined(_MSC_VER) && _MSC_VER>=1310 # define SQLITE_NOINLINE __declspec(noinline) -# define SQLITE_INLINE __forceinline #else # define SQLITE_NOINLINE -# define SQLITE_INLINE -#endif -#if defined(SQLITE_COVERAGE_TEST) -# undef SQLITE_INLINE -# define SQLITE_INLINE #endif /* ** Make sure that the compiler intrinsics we desire are enabled when ** compiling with an appropriate version of MSVC unless prevented by @@ -14472,13 +14230,19 @@ */ #define SQLITE_MAX_U32 ((((u64)1)<<32)-1) /* ** The datatype used to store estimates of the number of rows in a -** table or index. +** 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. */ -typedef u64 tRowcnt; +#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 /* ** Estimated quantities used for query planning are stored as 16-bit ** logarithms. For quantity X, the value stored is 10*log2(X). This ** gives a possible range of values of approximately 1.0e986 to 1e-986. @@ -14591,23 +14355,12 @@ #define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) /* ** Round up a number to the next larger multiple of 8. This is used ** to force 8-byte alignment on 64-bit architectures. -** -** ROUND8() always does the rounding, for any argument. -** -** ROUND8P() assumes that the argument is already an integer number of -** pointers in size, and so it is a no-op on systems where the pointer -** size is 8. */ #define ROUND8(x) (((x)+7)&~7) -#if SQLITE_PTRSIZE==8 -# define ROUND8P(x) (x) -#else -# define ROUND8P(x) (((x)+7)&~7) -#endif /* ** Round down to the nearest multiple of 8 */ #define ROUNDDOWN8(x) ((x)&~7) @@ -14620,13 +14373,13 @@ ** Except, if SQLITE_4_BYTE_ALIGNED_MALLOC is defined, then the ** underlying malloc() implementation 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) ((((uptr)(X) - (uptr)0)&3)==0) +# define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&3)==0) #else -# define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&7)==0) +# define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&7)==0) #endif /* ** Disable MMAP on platforms where it is known to not work */ @@ -14666,52 +14419,28 @@ # undef SQLITE_DEFAULT_MMAP_SIZE # define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE #endif /* -** TREETRACE_ENABLED will be either 1 or 0 depending on whether or not -** the Abstract Syntax Tree tracing logic is turned on. +** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not +** the Select query generator tracing logic is turned on. */ #if !defined(SQLITE_AMALGAMATION) -SQLITE_PRIVATE u32 sqlite3TreeTrace; +SQLITE_PRIVATE u32 sqlite3SelectTrace; #endif #if defined(SQLITE_DEBUG) \ - && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_SELECTTRACE) \ - || defined(SQLITE_ENABLE_TREETRACE)) -# define TREETRACE_ENABLED 1 -# define TREETRACE(K,P,S,X) \ - if(sqlite3TreeTrace&(K)) \ + && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_SELECTTRACE)) +# define SELECTTRACE_ENABLED 1 +# define SELECTTRACE(K,P,S,X) \ + if(sqlite3SelectTrace&(K)) \ sqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\ sqlite3DebugPrintf X #else -# define TREETRACE(K,P,S,X) -# define TREETRACE_ENABLED 0 +# define SELECTTRACE(K,P,S,X) +# define SELECTTRACE_ENABLED 0 #endif -/* TREETRACE flag meanings: -** -** 0x00000001 Beginning and end of SELECT processing -** 0x00000002 WHERE clause processing -** 0x00000004 Query flattener -** 0x00000008 Result-set wildcard expansion -** 0x00000010 Query name resolution -** 0x00000020 Aggregate analysis -** 0x00000040 Window functions -** 0x00000080 Generated column names -** 0x00000100 Move HAVING terms into WHERE -** 0x00000200 Count-of-view optimization -** 0x00000400 Compound SELECT processing -** 0x00000800 Drop superfluous ORDER BY -** 0x00001000 LEFT JOIN simplifies to JOIN -** 0x00002000 Constant propagation -** 0x00004000 Push-down optimization -** 0x00008000 After all FROM-clause analysis -** 0x00010000 Beginning of DELETE/INSERT/UPDATE processing -** 0x00020000 Transform DISTINCT into GROUP BY -** 0x00040000 SELECT tree dump after all code has been generated -*/ - /* ** Macros for "wheretrace" */ SQLITE_PRIVATE u32 sqlite3WhereTrace; #if defined(SQLITE_DEBUG) \ @@ -14720,40 +14449,10 @@ # define WHERETRACE_ENABLED 1 #else # define WHERETRACE(K,X) #endif -/* -** Bits for the sqlite3WhereTrace mask: -** -** (---any--) Top-level block structure -** 0x-------F High-level debug messages -** 0x----FFF- More detail -** 0xFFFF---- Low-level debug messages -** -** 0x00000001 Code generation -** 0x00000002 Solver -** 0x00000004 Solver costs -** 0x00000008 WhereLoop inserts -** -** 0x00000010 Display sqlite3_index_info xBestIndex calls -** 0x00000020 Range an equality scan metrics -** 0x00000040 IN operator decisions -** 0x00000080 WhereLoop cost adjustements -** 0x00000100 -** 0x00000200 Covering index decisions -** 0x00000400 OR optimization -** 0x00000800 Index scanner -** 0x00001000 More details associated with code generation -** 0x00002000 -** 0x00004000 Show all WHERE terms at key points -** 0x00008000 Show the full SELECT statement at key places -** -** 0x00010000 Show more detail when printing WHERE terms -** 0x00020000 Show WHERE terms returned from whereScanNext() -*/ - /* ** An instance of the following structure is used to store the busy-handler ** callback for a given sqlite handle. ** @@ -14820,11 +14519,11 @@ ** one parameter that destructors normally want. So we have to introduce ** this magic value that the code knows to handle differently. Any ** pointer will work here as long as it is distinct from SQLITE_STATIC ** and SQLITE_TRANSIENT. */ -#define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3OomClear) +#define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3OomFault) /* ** When SQLITE_OMIT_WSD is defined, it means that the target platform does ** not support Writable Static Data (WSD) such as global and static variables. ** All variables must either be on the stack or dynamically allocated from @@ -14889,19 +14588,17 @@ typedef struct FuncDestructor FuncDestructor; typedef struct FuncDef FuncDef; typedef struct FuncDefHash FuncDefHash; typedef struct IdList IdList; typedef struct Index Index; -typedef struct IndexedExpr IndexedExpr; 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 OnOrUsing OnOrUsing; typedef struct Parse Parse; typedef struct ParseCleanup ParseCleanup; typedef struct PreUpdate PreUpdate; typedef struct PrintfArguments PrintfArguments; typedef struct RenameToken RenameToken; @@ -14955,11 +14652,10 @@ #define MASKBIT(n) (((Bitmask)1)<<(n)) #define MASKBIT64(n) (((u64)1)<<(n)) #define MASKBIT32(n) (((unsigned int)1)<<(n)) #define SMASKBIT32(n) ((n)<=31?((unsigned int)1)<<(n):0) #define ALLBITS ((Bitmask)-1) -#define TOPBIT (((Bitmask)1)<<(BMS-1)) /* A VList object records a mapping between parameters/variables/wildcards ** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer ** variable number associated with that parameter. See the format description ** on the sqlite3VListAdd() routine for more information. A VList is really @@ -14970,335 +14666,10 @@ /* ** Defer sourcing vdbe.h and btree.h until after the "u8" and ** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque ** pointer types (i.e. FuncDef) defined above. */ -/************** 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_ - -/* -** Attempt to automatically detect the operating system and setup the -** necessary pre-processor macros for it. -*/ -/************** Include os_setup.h in the middle of os.h *********************/ -/************** Begin file os_setup.h ****************************************/ -/* -** 2013 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 pre-processor directives related to operating system -** detection and/or setup. -*/ -#ifndef SQLITE_OS_SETUP_H -#define SQLITE_OS_SETUP_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_KV -** SQLITE_OS_OTHER -** SQLITE_OS_UNIX -** SQLITE_OS_WIN -** -** will defined to either 1 or 0. One of them will be 1. The others will be 0. -** If none of the macros are initially defined, then select either -** SQLITE_OS_UNIX or SQLITE_OS_WIN depending on the target platform. -** -** If SQLITE_OS_OTHER=1 is specified at compile-time, then the application -** must provide its own VFS implementation together with sqlite3_os_init() -** and sqlite3_os_end() routines. -*/ -#if !defined(SQLITE_OS_KV) && !defined(SQLITE_OS_OTHER) && \ - !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_WIN) -# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || \ - defined(__MINGW32__) || defined(__BORLANDC__) -# define SQLITE_OS_WIN 1 -# define SQLITE_OS_UNIX 0 -# else -# define SQLITE_OS_WIN 0 -# define SQLITE_OS_UNIX 1 -# endif -#endif -#if SQLITE_OS_OTHER+1>1 -# undef SQLITE_OS_KV -# define SQLITE_OS_KV 0 -# undef SQLITE_OS_UNIX -# define SQLITE_OS_UNIX 0 -# undef SQLITE_OS_WIN -# define SQLITE_OS_WIN 0 -#endif -#if SQLITE_OS_KV+1>1 -# undef SQLITE_OS_OTHER -# define SQLITE_OS_OTHER 0 -# undef SQLITE_OS_UNIX -# define SQLITE_OS_UNIX 0 -# undef SQLITE_OS_WIN -# define SQLITE_OS_WIN 0 -# define SQLITE_OMIT_LOAD_EXTENSION 1 -# define SQLITE_OMIT_WAL 1 -# define SQLITE_OMIT_DEPRECATED 1 -# undef SQLITE_TEMP_STORE -# define SQLITE_TEMP_STORE 3 /* Always use memory for temporary storage */ -# define SQLITE_DQS 0 -# define SQLITE_OMIT_SHARED_CACHE 1 -# define SQLITE_OMIT_AUTOINIT 1 -#endif -#if SQLITE_OS_UNIX+1>1 -# undef SQLITE_OS_KV -# define SQLITE_OS_KV 0 -# undef SQLITE_OS_OTHER -# define SQLITE_OS_OTHER 0 -# undef SQLITE_OS_WIN -# define SQLITE_OS_WIN 0 -#endif -#if SQLITE_OS_WIN+1>1 -# undef SQLITE_OS_KV -# define SQLITE_OS_KV 0 -# undef SQLITE_OS_OTHER -# define SQLITE_OS_OTHER 0 -# undef SQLITE_OS_UNIX -# define SQLITE_OS_UNIX 0 -#endif - - -#endif /* SQLITE_OS_SETUP_H */ - -/************** End of os_setup.h ********************************************/ -/************** Continuing where we left off in os.h *************************/ - -/* If the SET_FULLSYNC macro is not defined above, then make it -** a no-op -*/ -#ifndef SET_FULLSYNC -# define SET_FULLSYNC(x,y) -#endif - -/* Maximum pathname length. Note: FILENAME_MAX defined by stdio.h -*/ -#ifndef SQLITE_MAX_PATHLEN -# define SQLITE_MAX_PATHLEN FILENAME_MAX -#endif - -/* Maximum number of symlinks that will be resolved while trying to -** expand a filename in xFullPathname() in the VFS. -*/ -#ifndef SQLITE_MAX_SYMLINK -# define SQLITE_MAX_SYMLINK 200 -#endif - -/* -** The default size of a disk sector -*/ -#ifndef SQLITE_DEFAULT_SECTOR_SIZE -# define SQLITE_DEFAULT_SECTOR_SIZE 4096 -#endif - -/* -** Temporary files are named starting with this prefix followed by 16 random -** alphanumeric characters, and no file extension. They are stored in the -** OS's standard temporary file directory, and are deleted prior to exit. -** If sqlite is being embedded in another program, you may wish to change the -** prefix to reflect your program's name, so that if your program exits -** prematurely, old temporary files can be easily identified. This can be done -** using -DSQLITE_TEMP_FILE_PREFIX=myprefix_ on the compiler command line. -** -** 2006-10-31: The default prefix used to be "sqlite_". But then -** Mcafee started using SQLite in their anti-virus product and it -** started putting files with the "sqlite" name in the c:/temp folder. -** This annoyed many windows users. Those users would then do a -** Google search for "sqlite", find the telephone numbers of the -** developers and call to wake them up at night and complain. -** For this reason, the default name prefix is changed to be "sqlite" -** spelled backwards. So the temp files are still identified, but -** anybody smart enough to figure out the code is also likely smart -** enough to know that calling the developer will not help get rid -** of the file. -*/ -#ifndef SQLITE_TEMP_FILE_PREFIX -# define SQLITE_TEMP_FILE_PREFIX "etilqs_" -#endif - -/* -** The following values may be passed as the second argument to -** sqlite3OsLock(). The various locks exhibit the following semantics: -** -** SHARED: Any number of processes may hold a SHARED lock simultaneously. -** RESERVED: A single process may hold a RESERVED lock on a file at -** any time. Other processes may hold and obtain new SHARED locks. -** PENDING: A single process may hold a PENDING lock on a file at -** any one time. Existing SHARED locks may persist, but no new -** SHARED locks may be obtained by other processes. -** EXCLUSIVE: An EXCLUSIVE lock precludes all other locks. -** -** PENDING_LOCK may not be passed directly to sqlite3OsLock(). Instead, a -** process that requests an EXCLUSIVE lock may actually obtain a PENDING -** lock. This can be upgraded to an EXCLUSIVE lock by a subsequent call to -** sqlite3OsLock(). -*/ -#define NO_LOCK 0 -#define SHARED_LOCK 1 -#define RESERVED_LOCK 2 -#define PENDING_LOCK 3 -#define EXCLUSIVE_LOCK 4 - -/* -** File Locking Notes: (Mostly about windows but also some info for Unix) -** -** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because -** those functions are not available. So we use only LockFile() and -** UnlockFile(). -** -** LockFile() prevents not just writing but also reading by other processes. -** A SHARED_LOCK is obtained by locking a single randomly-chosen -** byte out of a specific range of bytes. The lock byte is obtained at -** random so two separate readers can probably access the file at the -** same time, unless they are unlucky and choose the same lock byte. -** An EXCLUSIVE_LOCK is obtained by locking all bytes in the range. -** There can only be one writer. A RESERVED_LOCK is obtained by locking -** a single byte of the file that is designated as the reserved lock byte. -** A PENDING_LOCK is obtained by locking a designated byte different from -** the RESERVED_LOCK byte. -** -** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available, -** which means we can use reader/writer locks. When reader/writer locks -** are used, the lock is placed on the same range of bytes that is used -** for probabilistic locking in Win95/98/ME. Hence, the locking scheme -** will support two or more Win95 readers or two or more WinNT readers. -** But a single Win95 reader will lock out all WinNT readers and a single -** WinNT reader will lock out all other Win95 readers. -** -** The following #defines specify the range of bytes used for locking. -** SHARED_SIZE is the number of bytes available in the pool from which -** a random byte is selected for a shared lock. The pool of bytes for -** shared locks begins at SHARED_FIRST. -** -** The same locking strategy and -** byte ranges are used for Unix. This leaves open the possibility of having -** clients on win95, winNT, and unix all talking to the same shared file -** and all locking correctly. To do so would require that samba (or whatever -** tool is being used for file sharing) implements locks correctly between -** windows and unix. I'm guessing that isn't likely to happen, but by -** using the same locking range we are at least open to the possibility. -** -** Locking in windows is manditory. For this reason, we cannot store -** actual data in the bytes used for locking. The pager never allocates -** the pages involved in locking therefore. SHARED_SIZE is selected so -** that all locks will fit on a single page even at the minimum page size. -** PENDING_BYTE defines the beginning of the locks. By default PENDING_BYTE -** is set high so that we don't have to allocate an unused page except -** for very large databases. But one should test the page skipping logic -** by setting PENDING_BYTE low and running the entire regression suite. -** -** Changing the value of PENDING_BYTE results in a subtly incompatible -** file format. Depending on how it is changed, you might not notice -** the incompatibility right away, even running a full regression test. -** The default location of PENDING_BYTE is the first byte past the -** 1GB boundary. -** -*/ -#ifdef SQLITE_OMIT_WSD -# define PENDING_BYTE (0x40000000) -#else -# define PENDING_BYTE sqlite3PendingByte -#endif -#define RESERVED_BYTE (PENDING_BYTE+1) -#define SHARED_FIRST (PENDING_BYTE+2) -#define SHARED_SIZE 510 - -/* -** Wrapper around OS specific sqlite3_os_init() function. -*/ -SQLITE_PRIVATE int sqlite3OsInit(void); - -/* -** Functions for accessing sqlite3_file methods -*/ -SQLITE_PRIVATE void sqlite3OsClose(sqlite3_file*); -SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset); -SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset); -SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file*, i64 size); -SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file*, int); -SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file*, i64 *pSize); -SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file*, int); -SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file*, int); -SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut); -SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file*,int,void*); -SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file*,int,void*); -#define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0 -SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id); -SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id); -#ifndef SQLITE_OMIT_WAL -SQLITE_PRIVATE int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **); -SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int, int, int); -SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id); -SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int); -#endif /* SQLITE_OMIT_WAL */ -SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64, int, void **); -SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *, i64, void *); - - -/* -** Functions for accessing sqlite3_vfs methods -*/ -SQLITE_PRIVATE int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *); -SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *, const char *, int); -SQLITE_PRIVATE int sqlite3OsAccess(sqlite3_vfs *, const char *, int, int *pResOut); -SQLITE_PRIVATE int sqlite3OsFullPathname(sqlite3_vfs *, const char *, int, char *); -#ifndef SQLITE_OMIT_LOAD_EXTENSION -SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *, const char *); -SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *, int, char *); -SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *, void *, const char *))(void); -SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *, void *); -#endif /* SQLITE_OMIT_LOAD_EXTENSION */ -SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *, int, char *); -SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *, int); -SQLITE_PRIVATE int sqlite3OsGetLastError(sqlite3_vfs*); -SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*); - -/* -** Convenience functions for opening and closing files using -** sqlite3_malloc() to obtain space for the file-handle structure. -*/ -SQLITE_PRIVATE int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int,int*); -SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *); - -#endif /* _SQLITE_OS_H_ */ - -/************** End of os.h **************************************************/ -/************** Continuing where we left off in sqliteInt.h ******************/ /************** Include pager.h in the middle of sqliteInt.h *****************/ /************** Begin file pager.h *******************************************/ /* ** 2001 September 15 ** @@ -15342,19 +14713,18 @@ ** Handle type for pages. */ typedef struct PgHdr DbPage; /* -** Page number PAGER_SJ_PGNO is never used in an SQLite database (it is +** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is ** reserved for working around a windows/posix incompatibility). It is ** used in the journal to signify that the remainder of the journal file ** is devoted to storing a super-journal name - there are no more pages to ** roll back. See comments for function writeSuperJournal() in pager.c ** for details. */ -#define PAGER_SJ_PGNO_COMPUTED(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1)) -#define PAGER_SJ_PGNO(x) ((x)->lckPgno) +#define PAGER_MJ_PGNO(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1)) /* ** Allowed values for the flags parameter to sqlite3PagerOpen(). ** ** NOTE: These values must match the corresponding BTREE_ values in btree.h. @@ -15730,11 +15100,11 @@ ** to prefetch content from remote machines - to provide those ** implementations with limits on what needs to be prefetched and thereby ** reduce network bandwidth. ** ** Note that BTREE_HINT_FLAGS with BTREE_BULKLOAD is the only hint used by -** standard SQLite. The other hints are provided for extensions that use +** standard SQLite. The other hints are provided for extentions that use ** the SQLite parser and code generator but substitute their own storage ** engine. */ #define BTREE_HINT_RANGE 0 /* Range constraints on queries */ @@ -15876,19 +15246,11 @@ SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*); SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt); SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor*); SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor*); -SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( - sqlite3 *db, /* Database connection that is running the check */ - Btree *p, /* The btree to be checked */ - Pgno *aRoot, /* An array of root pages numbers for individual trees */ - int nRoot, /* Number of entries in aRoot[] */ - int mxErr, /* Stop reporting errors after this many */ - int *pnErr, /* OUT: Write number of errors seen to this variable */ - char **pzOut /* OUT: Write the error message string here */ -); +SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(sqlite3*,Btree*,Pgno*aRoot,int nRoot,int,int*); SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*); SQLITE_PRIVATE i64 sqlite3BtreeRowCountEst(BtCursor*); #ifndef SQLITE_OMIT_INCRBLOB SQLITE_PRIVATE int sqlite3BtreePayloadChecked(BtCursor*, u32 offset, u32 amt, void*); @@ -15923,12 +15285,10 @@ SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree*, int, int *, int *); #endif SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor*, BtCursor*, i64); -SQLITE_PRIVATE void sqlite3BtreeClearCache(Btree*); - /* ** If we are not using shared cache, then there is no need to ** use mutexes to access the BtShared structures. So make the ** Enter and Leave procedures no-ops. */ @@ -16037,22 +15397,23 @@ SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */ Table *pTab; /* Used when p4type is P4_TABLE */ #ifdef SQLITE_ENABLE_CURSOR_HINTS Expr *pExpr; /* Used when p4type is P4_EXPR */ #endif + int (*xAdvance)(BtCursor *, int); } p4; #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS char *zComment; /* Comment to improve readability */ #endif +#ifdef VDBE_PROFILE + u32 cnt; /* Number of times this instruction was executed */ + u64 cycles; /* Total time spent executing this instruction */ +#endif #ifdef SQLITE_VDBE_COVERAGE u32 iSrcLine; /* Source-code line that generated this opcode ** with flags in the upper 8 bits */ #endif -#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) - u64 nExec; - u64 nCycle; -#endif }; typedef struct VdbeOp VdbeOp; /* @@ -16087,23 +15448,25 @@ #define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */ #define P4_STATIC (-1) /* Pointer to a static string */ #define P4_COLLSEQ (-2) /* P4 is a pointer to a CollSeq structure */ #define P4_INT32 (-3) /* P4 is a 32-bit signed integer */ #define P4_SUBPROGRAM (-4) /* P4 is a pointer to a SubProgram structure */ -#define P4_TABLE (-5) /* P4 is a pointer to a Table structure */ +#define P4_ADVANCE (-5) /* P4 is a pointer to BtreeNext() or BtreePrev() */ +#define P4_TABLE (-6) /* P4 is a pointer to a Table structure */ /* Above do not own any resources. Must free those below */ -#define P4_FREE_IF_LE (-6) -#define P4_DYNAMIC (-6) /* Pointer to memory from sqliteMalloc() */ -#define P4_FUNCDEF (-7) /* P4 is a pointer to a FuncDef structure */ -#define P4_KEYINFO (-8) /* P4 is a pointer to a KeyInfo structure */ -#define P4_EXPR (-9) /* P4 is a pointer to an Expr tree */ -#define P4_MEM (-10) /* P4 is a pointer to a Mem* structure */ -#define P4_VTAB (-11) /* P4 is a pointer to an sqlite3_vtab structure */ -#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_INTARRAY (-14) /* P4 is a vector of 32-bit integers */ -#define P4_FUNCCTX (-15) /* P4 is a pointer to an sqlite3_context object */ +#define P4_FREE_IF_LE (-7) +#define P4_DYNAMIC (-7) /* Pointer to memory from sqliteMalloc() */ +#define P4_FUNCDEF (-8) /* P4 is a pointer to a FuncDef structure */ +#define P4_KEYINFO (-9) /* P4 is a pointer to a KeyInfo structure */ +#define P4_EXPR (-10) /* P4 is a pointer to an Expr tree */ +#define P4_MEM (-11) /* P4 is a pointer to a Mem* structure */ +#define P4_VTAB (-12) /* P4 is a pointer to an sqlite3_vtab structure */ +#define P4_REAL (-13) /* P4 is a 64-bit floating point value */ +#define P4_INT64 (-14) /* P4 is a 64-bit signed integer */ +#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */ +#define P4_FUNCCTX (-16) /* P4 is a pointer to an sqlite3_context object */ +#define P4_DYNBLOB (-17) /* Pointer to memory from sqliteMalloc() */ /* Error message codes for OP_Halt */ #define P5_ConstraintNotNull 1 #define P5_ConstraintUnique 2 #define P5_ConstraintCheck 3 @@ -16144,109 +15507,109 @@ /* Automatically generated. Do not edit */ /* See the tool/mkopcodeh.tcl script for details */ #define OP_Savepoint 0 #define OP_AutoCommit 1 #define OP_Transaction 2 -#define OP_Checkpoint 3 -#define OP_JournalMode 4 -#define OP_Vacuum 5 -#define OP_VFilter 6 /* jump, synopsis: iplan=r[P3] zplan='P4' */ -#define OP_VUpdate 7 /* synopsis: data=r[P3@P2] */ -#define OP_Init 8 /* jump, synopsis: Start at P2 */ -#define OP_Goto 9 /* jump */ -#define OP_Gosub 10 /* jump */ -#define OP_InitCoroutine 11 /* jump */ -#define OP_Yield 12 /* jump */ -#define OP_MustBeInt 13 /* jump */ -#define OP_Jump 14 /* jump */ -#define OP_Once 15 /* jump */ -#define OP_If 16 /* jump */ -#define OP_IfNot 17 /* jump */ -#define OP_IsType 18 /* jump, synopsis: if typeof(P1.P3) in P5 goto P2 */ +#define OP_SorterNext 3 /* jump */ +#define OP_Prev 4 /* jump */ +#define OP_Next 5 /* jump */ +#define OP_Checkpoint 6 +#define OP_JournalMode 7 +#define OP_Vacuum 8 +#define OP_VFilter 9 /* jump, synopsis: iplan=r[P3] zplan='P4' */ +#define OP_VUpdate 10 /* synopsis: data=r[P3@P2] */ +#define OP_Goto 11 /* jump */ +#define OP_Gosub 12 /* jump */ +#define OP_InitCoroutine 13 /* jump */ +#define OP_Yield 14 /* jump */ +#define OP_MustBeInt 15 /* jump */ +#define OP_Jump 16 /* jump */ +#define OP_Once 17 /* jump */ +#define OP_If 18 /* jump */ #define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */ -#define OP_IfNullRow 20 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */ -#define OP_SeekLT 21 /* jump, synopsis: key=r[P3@P4] */ -#define OP_SeekLE 22 /* jump, synopsis: key=r[P3@P4] */ -#define OP_SeekGE 23 /* jump, synopsis: key=r[P3@P4] */ -#define OP_SeekGT 24 /* jump, synopsis: key=r[P3@P4] */ -#define OP_IfNotOpen 25 /* jump, synopsis: if( !csr[P1] ) goto P2 */ -#define OP_IfNoHope 26 /* jump, synopsis: key=r[P3@P4] */ -#define OP_NoConflict 27 /* jump, synopsis: key=r[P3@P4] */ -#define OP_NotFound 28 /* jump, synopsis: key=r[P3@P4] */ -#define OP_Found 29 /* jump, synopsis: key=r[P3@P4] */ -#define OP_SeekRowid 30 /* jump, synopsis: intkey=r[P3] */ -#define OP_NotExists 31 /* jump, synopsis: intkey=r[P3] */ -#define OP_Last 32 /* jump */ -#define OP_IfSmaller 33 /* jump */ -#define OP_SorterSort 34 /* jump */ -#define OP_Sort 35 /* jump */ -#define OP_Rewind 36 /* jump */ -#define OP_SorterNext 37 /* jump */ -#define OP_Prev 38 /* jump */ -#define OP_Next 39 /* jump */ -#define OP_IdxLE 40 /* jump, synopsis: key=r[P3@P4] */ -#define OP_IdxGT 41 /* jump, synopsis: key=r[P3@P4] */ -#define OP_IdxLT 42 /* jump, synopsis: key=r[P3@P4] */ +#define OP_IfNot 20 /* jump */ +#define OP_IsNullOrType 21 /* jump, synopsis: if typeof(r[P1]) IN (P3,5) goto P2 */ +#define OP_IfNullRow 22 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */ +#define OP_SeekLT 23 /* jump, synopsis: key=r[P3@P4] */ +#define OP_SeekLE 24 /* jump, synopsis: key=r[P3@P4] */ +#define OP_SeekGE 25 /* jump, synopsis: key=r[P3@P4] */ +#define OP_SeekGT 26 /* jump, synopsis: key=r[P3@P4] */ +#define OP_IfNotOpen 27 /* jump, synopsis: if( !csr[P1] ) goto P2 */ +#define OP_IfNoHope 28 /* jump, synopsis: key=r[P3@P4] */ +#define OP_NoConflict 29 /* jump, synopsis: key=r[P3@P4] */ +#define OP_NotFound 30 /* jump, synopsis: key=r[P3@P4] */ +#define OP_Found 31 /* jump, synopsis: key=r[P3@P4] */ +#define OP_SeekRowid 32 /* jump, synopsis: intkey=r[P3] */ +#define OP_NotExists 33 /* jump, synopsis: intkey=r[P3] */ +#define OP_Last 34 /* jump */ +#define OP_IfSmaller 35 /* jump */ +#define OP_SorterSort 36 /* jump */ +#define OP_Sort 37 /* jump */ +#define OP_Rewind 38 /* jump */ +#define OP_IdxLE 39 /* jump, synopsis: key=r[P3@P4] */ +#define OP_IdxGT 40 /* jump, synopsis: key=r[P3@P4] */ +#define OP_IdxLT 41 /* jump, synopsis: key=r[P3@P4] */ +#define OP_IdxGE 42 /* jump, synopsis: key=r[P3@P4] */ #define OP_Or 43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ #define OP_And 44 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ -#define OP_IdxGE 45 /* jump, synopsis: key=r[P3@P4] */ -#define OP_RowSetRead 46 /* jump, synopsis: r[P3]=rowset(P1) */ -#define OP_RowSetTest 47 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ -#define OP_Program 48 /* jump */ -#define OP_FkIfZero 49 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ +#define OP_RowSetRead 45 /* jump, synopsis: r[P3]=rowset(P1) */ +#define OP_RowSetTest 46 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ +#define OP_Program 47 /* jump */ +#define OP_FkIfZero 48 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ +#define OP_IfPos 49 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ #define OP_IsNull 50 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ #define OP_NotNull 51 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ #define OP_Ne 52 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */ #define OP_Eq 53 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */ #define OP_Gt 54 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */ #define OP_Le 55 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */ #define OP_Lt 56 /* jump, same as TK_LT, synopsis: IF r[P3]=r[P1] */ #define OP_ElseEq 58 /* jump, same as TK_ESCAPE */ -#define OP_IfPos 59 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ -#define OP_IfNotZero 60 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ -#define OP_DecrJumpZero 61 /* jump, synopsis: if (--r[P1])==0 goto P2 */ -#define OP_IncrVacuum 62 /* jump */ -#define OP_VNext 63 /* jump */ -#define OP_Filter 64 /* jump, synopsis: if key(P3@P4) not in filter(P1) goto P2 */ +#define OP_IfNotZero 59 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ +#define OP_DecrJumpZero 60 /* jump, synopsis: if (--r[P1])==0 goto P2 */ +#define OP_IncrVacuum 61 /* jump */ +#define OP_VNext 62 /* jump */ +#define OP_Filter 63 /* jump, synopsis: if key(P3@P4) not in filter(P1) goto P2 */ +#define OP_Init 64 /* jump, synopsis: Start at P2 */ #define OP_PureFunc 65 /* synopsis: r[P3]=func(r[P2@NP]) */ #define OP_Function 66 /* synopsis: r[P3]=func(r[P2@NP]) */ #define OP_Return 67 #define OP_EndCoroutine 68 #define OP_HaltIfNull 69 /* synopsis: if r[P3]=null halt */ #define OP_Halt 70 #define OP_Integer 71 /* synopsis: r[P2]=P1 */ #define OP_Int64 72 /* synopsis: r[P2]=P4 */ #define OP_String 73 /* synopsis: r[P2]='P4' (len=P1) */ -#define OP_BeginSubrtn 74 /* synopsis: r[P2]=NULL */ -#define OP_Null 75 /* synopsis: r[P2..P3]=NULL */ -#define OP_SoftNull 76 /* synopsis: r[P1]=NULL */ -#define OP_Blob 77 /* synopsis: r[P2]=P4 (len=P1) */ -#define OP_Variable 78 /* synopsis: r[P2]=parameter(P1,P4) */ -#define OP_Move 79 /* synopsis: r[P2@P3]=r[P1@P3] */ -#define OP_Copy 80 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ -#define OP_SCopy 81 /* synopsis: r[P2]=r[P1] */ -#define OP_IntCopy 82 /* synopsis: r[P2]=r[P1] */ -#define OP_FkCheck 83 -#define OP_ResultRow 84 /* synopsis: output=r[P1@P2] */ -#define OP_CollSeq 85 -#define OP_AddImm 86 /* synopsis: r[P1]=r[P1]+P2 */ -#define OP_RealAffinity 87 -#define OP_Cast 88 /* synopsis: affinity(r[P1]) */ -#define OP_Permutation 89 -#define OP_Compare 90 /* synopsis: r[P1@P3] <-> r[P2@P3] */ -#define OP_IsTrue 91 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */ -#define OP_ZeroOrNull 92 /* synopsis: r[P2] = 0 OR NULL */ -#define OP_Offset 93 /* synopsis: r[P3] = sqlite_offset(P1) */ -#define OP_Column 94 /* synopsis: r[P3]=PX cursor P1 column P2 */ -#define OP_TypeCheck 95 /* synopsis: typecheck(r[P1@P2]) */ -#define OP_Affinity 96 /* synopsis: affinity(r[P1@P2]) */ -#define OP_MakeRecord 97 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ -#define OP_Count 98 /* synopsis: r[P2]=count() */ -#define OP_ReadCookie 99 -#define OP_SetCookie 100 -#define OP_ReopenIdx 101 /* synopsis: root=P2 iDb=P3 */ +#define OP_Null 74 /* synopsis: r[P2..P3]=NULL */ +#define OP_SoftNull 75 /* synopsis: r[P1]=NULL */ +#define OP_Blob 76 /* synopsis: r[P2]=P4 (len=P1) */ +#define OP_Variable 77 /* synopsis: r[P2]=parameter(P1,P4) */ +#define OP_Move 78 /* synopsis: r[P2@P3]=r[P1@P3] */ +#define OP_Copy 79 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ +#define OP_SCopy 80 /* synopsis: r[P2]=r[P1] */ +#define OP_IntCopy 81 /* synopsis: r[P2]=r[P1] */ +#define OP_FkCheck 82 +#define OP_ResultRow 83 /* synopsis: output=r[P1@P2] */ +#define OP_CollSeq 84 +#define OP_AddImm 85 /* synopsis: r[P1]=r[P1]+P2 */ +#define OP_RealAffinity 86 +#define OP_Cast 87 /* synopsis: affinity(r[P1]) */ +#define OP_Permutation 88 +#define OP_Compare 89 /* synopsis: r[P1@P3] <-> r[P2@P3] */ +#define OP_IsTrue 90 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */ +#define OP_ZeroOrNull 91 /* synopsis: r[P2] = 0 OR NULL */ +#define OP_Offset 92 /* synopsis: r[P3] = sqlite_offset(P1) */ +#define OP_Column 93 /* synopsis: r[P3]=PX */ +#define OP_TypeCheck 94 /* synopsis: typecheck(r[P1@P2]) */ +#define OP_Affinity 95 /* synopsis: affinity(r[P1@P2]) */ +#define OP_MakeRecord 96 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ +#define OP_Count 97 /* synopsis: r[P2]=count() */ +#define OP_ReadCookie 98 +#define OP_SetCookie 99 +#define OP_ReopenIdx 100 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenRead 101 /* synopsis: root=P2 iDb=P3 */ #define OP_BitAnd 102 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ #define OP_BitOr 103 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ #define OP_ShiftLeft 104 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */ #define OP_Add 106 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ @@ -16253,85 +15616,83 @@ #define OP_Subtract 107 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ #define OP_Multiply 108 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ #define OP_Divide 109 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ #define OP_Remainder 110 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ #define OP_Concat 111 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ -#define OP_OpenRead 112 /* synopsis: root=P2 iDb=P3 */ -#define OP_OpenWrite 113 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenWrite 112 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenDup 113 #define OP_BitNot 114 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */ -#define OP_OpenDup 115 -#define OP_OpenAutoindex 116 /* synopsis: nColumn=P2 */ +#define OP_OpenAutoindex 115 /* synopsis: nColumn=P2 */ +#define OP_OpenEphemeral 116 /* synopsis: nColumn=P2 */ #define OP_String8 117 /* same as TK_STRING, synopsis: r[P2]='P4' */ -#define OP_OpenEphemeral 118 /* synopsis: nColumn=P2 */ -#define OP_SorterOpen 119 -#define OP_SequenceTest 120 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ -#define OP_OpenPseudo 121 /* synopsis: P3 columns in r[P2] */ -#define OP_Close 122 -#define OP_ColumnsUsed 123 -#define OP_SeekScan 124 /* synopsis: Scan-ahead up to P1 rows */ -#define OP_SeekHit 125 /* synopsis: set P2<=seekHit<=P3 */ -#define OP_Sequence 126 /* synopsis: r[P2]=cursor[P1].ctr++ */ -#define OP_NewRowid 127 /* synopsis: r[P2]=rowid */ -#define OP_Insert 128 /* synopsis: intkey=r[P3] data=r[P2] */ -#define OP_RowCell 129 -#define OP_Delete 130 -#define OP_ResetCount 131 -#define OP_SorterCompare 132 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ -#define OP_SorterData 133 /* synopsis: r[P2]=data */ -#define OP_RowData 134 /* synopsis: r[P2]=data */ -#define OP_Rowid 135 /* synopsis: r[P2]=PX rowid of P1 */ -#define OP_NullRow 136 -#define OP_SeekEnd 137 -#define OP_IdxInsert 138 /* synopsis: key=r[P2] */ -#define OP_SorterInsert 139 /* synopsis: key=r[P2] */ -#define OP_IdxDelete 140 /* synopsis: key=r[P2@P3] */ -#define OP_DeferredSeek 141 /* synopsis: Move P3 to P1.rowid if needed */ -#define OP_IdxRowid 142 /* synopsis: r[P2]=rowid */ -#define OP_FinishSeek 143 -#define OP_Destroy 144 -#define OP_Clear 145 -#define OP_ResetSorter 146 -#define OP_CreateBtree 147 /* synopsis: r[P2]=root iDb=P1 flags=P3 */ -#define OP_SqlExec 148 -#define OP_ParseSchema 149 -#define OP_LoadAnalysis 150 -#define OP_DropTable 151 -#define OP_DropIndex 152 +#define OP_SorterOpen 118 +#define OP_SequenceTest 119 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ +#define OP_OpenPseudo 120 /* synopsis: P3 columns in r[P2] */ +#define OP_Close 121 +#define OP_ColumnsUsed 122 +#define OP_SeekScan 123 /* synopsis: Scan-ahead up to P1 rows */ +#define OP_SeekHit 124 /* synopsis: set P2<=seekHit<=P3 */ +#define OP_Sequence 125 /* synopsis: r[P2]=cursor[P1].ctr++ */ +#define OP_NewRowid 126 /* synopsis: r[P2]=rowid */ +#define OP_Insert 127 /* synopsis: intkey=r[P3] data=r[P2] */ +#define OP_RowCell 128 +#define OP_Delete 129 +#define OP_ResetCount 130 +#define OP_SorterCompare 131 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ +#define OP_SorterData 132 /* synopsis: r[P2]=data */ +#define OP_RowData 133 /* synopsis: r[P2]=data */ +#define OP_Rowid 134 /* synopsis: r[P2]=rowid */ +#define OP_NullRow 135 +#define OP_SeekEnd 136 +#define OP_IdxInsert 137 /* synopsis: key=r[P2] */ +#define OP_SorterInsert 138 /* synopsis: key=r[P2] */ +#define OP_IdxDelete 139 /* synopsis: key=r[P2@P3] */ +#define OP_DeferredSeek 140 /* synopsis: Move P3 to P1.rowid if needed */ +#define OP_IdxRowid 141 /* synopsis: r[P2]=rowid */ +#define OP_FinishSeek 142 +#define OP_Destroy 143 +#define OP_Clear 144 +#define OP_ResetSorter 145 +#define OP_CreateBtree 146 /* synopsis: r[P2]=root iDb=P1 flags=P3 */ +#define OP_SqlExec 147 +#define OP_ParseSchema 148 +#define OP_LoadAnalysis 149 +#define OP_DropTable 150 +#define OP_DropIndex 151 +#define OP_DropTrigger 152 #define OP_Real 153 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ -#define OP_DropTrigger 154 -#define OP_IntegrityCk 155 -#define OP_RowSetAdd 156 /* synopsis: rowset(P1)=r[P2] */ -#define OP_Param 157 -#define OP_FkCounter 158 /* synopsis: fkctr[P1]+=P2 */ -#define OP_MemMax 159 /* synopsis: r[P1]=max(r[P1],r[P2]) */ -#define OP_OffsetLimit 160 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ -#define OP_AggInverse 161 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */ -#define OP_AggStep 162 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -#define OP_AggStep1 163 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -#define OP_AggValue 164 /* synopsis: r[P3]=value N=P2 */ -#define OP_AggFinal 165 /* synopsis: accum=r[P1] N=P2 */ -#define OP_Expire 166 -#define OP_CursorLock 167 -#define OP_CursorUnlock 168 -#define OP_TableLock 169 /* synopsis: iDb=P1 root=P2 write=P3 */ -#define OP_VBegin 170 -#define OP_VCreate 171 -#define OP_VDestroy 172 -#define OP_VOpen 173 -#define OP_VInitIn 174 /* synopsis: r[P2]=ValueList(P1,P3) */ -#define OP_VColumn 175 /* synopsis: r[P3]=vcolumn(P2) */ -#define OP_VRename 176 -#define OP_Pagecount 177 -#define OP_MaxPgcnt 178 -#define OP_ClrSubtype 179 /* synopsis: r[P1].subtype = 0 */ -#define OP_FilterAdd 180 /* synopsis: filter(P1) += key(P3@P4) */ -#define OP_Trace 181 -#define OP_CursorHint 182 -#define OP_ReleaseReg 183 /* synopsis: release r[P1@P2] mask P3 */ -#define OP_Noop 184 -#define OP_Explain 185 -#define OP_Abortable 186 +#define OP_IntegrityCk 154 +#define OP_RowSetAdd 155 /* synopsis: rowset(P1)=r[P2] */ +#define OP_Param 156 +#define OP_FkCounter 157 /* synopsis: fkctr[P1]+=P2 */ +#define OP_MemMax 158 /* synopsis: r[P1]=max(r[P1],r[P2]) */ +#define OP_OffsetLimit 159 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ +#define OP_AggInverse 160 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */ +#define OP_AggStep 161 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +#define OP_AggStep1 162 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +#define OP_AggValue 163 /* synopsis: r[P3]=value N=P2 */ +#define OP_AggFinal 164 /* synopsis: accum=r[P1] N=P2 */ +#define OP_Expire 165 +#define OP_CursorLock 166 +#define OP_CursorUnlock 167 +#define OP_TableLock 168 /* synopsis: iDb=P1 root=P2 write=P3 */ +#define OP_VBegin 169 +#define OP_VCreate 170 +#define OP_VDestroy 171 +#define OP_VOpen 172 +#define OP_VInitIn 173 /* synopsis: r[P2]=ValueList(P1,P3) */ +#define OP_VColumn 174 /* synopsis: r[P3]=vcolumn(P2) */ +#define OP_VRename 175 +#define OP_Pagecount 176 +#define OP_MaxPgcnt 177 +#define OP_FilterAdd 178 /* synopsis: filter(P1) += key(P3@P4) */ +#define OP_Trace 179 +#define OP_CursorHint 180 +#define OP_ReleaseReg 181 /* synopsis: release r[P1@P2] mask P3 */ +#define OP_Noop 182 +#define OP_Explain 183 +#define OP_Abortable 184 /* 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: */ @@ -16339,36 +15700,35 @@ #define OPFLG_IN1 0x02 /* in1: P1 is an input */ #define OPFLG_IN2 0x04 /* in2: P2 is an input */ #define OPFLG_IN3 0x08 /* in3: P3 is an input */ #define OPFLG_OUT2 0x10 /* out2: P2 is an output */ #define OPFLG_OUT3 0x20 /* out3: P3 is an output */ -#define OPFLG_NCYCLE 0x40 /* ncycle:Cycles count against P1 */ #define OPFLG_INITIALIZER {\ -/* 0 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x41, 0x00,\ -/* 8 */ 0x01, 0x01, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01,\ -/* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0x49, 0x49, 0x49,\ -/* 24 */ 0x49, 0x01, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49,\ -/* 32 */ 0x41, 0x01, 0x01, 0x01, 0x41, 0x01, 0x41, 0x41,\ -/* 40 */ 0x41, 0x41, 0x41, 0x26, 0x26, 0x41, 0x23, 0x0b,\ -/* 48 */ 0x01, 0x01, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\ -/* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x03, 0x01, 0x41,\ +/* 0 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x10,\ +/* 8 */ 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03,\ +/* 16 */ 0x01, 0x01, 0x03, 0x12, 0x03, 0x03, 0x01, 0x09,\ +/* 24 */ 0x09, 0x09, 0x09, 0x01, 0x09, 0x09, 0x09, 0x09,\ +/* 32 */ 0x09, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\ +/* 40 */ 0x01, 0x01, 0x01, 0x26, 0x26, 0x23, 0x0b, 0x01,\ +/* 48 */ 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\ +/* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x01, 0x01,\ /* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\ -/* 72 */ 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10, 0x00,\ -/* 80 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02,\ -/* 88 */ 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x40, 0x00,\ -/* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x40, 0x26, 0x26,\ +/* 72 */ 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00,\ +/* 80 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02,\ +/* 88 */ 0x00, 0x00, 0x12, 0x1e, 0x20, 0x00, 0x00, 0x00,\ +/* 96 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x26, 0x26,\ /* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\ -/* 112 */ 0x40, 0x00, 0x12, 0x40, 0x40, 0x10, 0x40, 0x00,\ -/* 120 */ 0x00, 0x00, 0x40, 0x00, 0x40, 0x40, 0x10, 0x10,\ -/* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,\ -/* 136 */ 0x00, 0x40, 0x04, 0x04, 0x00, 0x40, 0x50, 0x40,\ -/* 144 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\ -/* 152 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\ -/* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x50, 0x40,\ -/* 176 */ 0x00, 0x10, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00,\ -/* 184 */ 0x00, 0x00, 0x00,} +/* 112 */ 0x00, 0x00, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00,\ +/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00,\ +/* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,\ +/* 136 */ 0x00, 0x04, 0x04, 0x00, 0x00, 0x10, 0x00, 0x10,\ +/* 144 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 152 */ 0x00, 0x10, 0x00, 0x06, 0x10, 0x00, 0x04, 0x1a,\ +/* 160 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\ +/* 176 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 184 */ 0x00,} /* The resolve3P2Values() routine is able to run faster if it knows ** the value of the largest JUMP opcode. The smaller the maximum ** JUMP opcode the better, so the mkopcodeh.tcl script that ** generated this include file strives to group all JUMP opcodes @@ -16410,31 +15770,23 @@ # define sqlite3VdbeVerifyNoMallocRequired(A,B) # define sqlite3VdbeVerifyNoResultRow(A) #endif #if defined(SQLITE_DEBUG) SQLITE_PRIVATE void sqlite3VdbeVerifyAbortable(Vdbe *p, int); -SQLITE_PRIVATE void sqlite3VdbeNoJumpsOutsideSubrtn(Vdbe*,int,int,int); #else # define sqlite3VdbeVerifyAbortable(A,B) -# define sqlite3VdbeNoJumpsOutsideSubrtn(A,B,C,D) #endif SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp,int iLineno); #ifndef SQLITE_OMIT_EXPLAIN -SQLITE_PRIVATE int sqlite3VdbeExplain(Parse*,u8,const char*,...); +SQLITE_PRIVATE void sqlite3VdbeExplain(Parse*,u8,const char*,...); SQLITE_PRIVATE void sqlite3VdbeExplainPop(Parse*); SQLITE_PRIVATE int sqlite3VdbeExplainParent(Parse*); # define ExplainQueryPlan(P) sqlite3VdbeExplain P -# ifdef SQLITE_ENABLE_STMT_SCANSTATUS -# define ExplainQueryPlan2(V,P) (V = sqlite3VdbeExplain P) -# else -# define ExplainQueryPlan2(V,P) ExplainQueryPlan(P) -# endif # define ExplainQueryPlanPop(P) sqlite3VdbeExplainPop(P) # define ExplainQueryPlanParent(P) sqlite3VdbeExplainParent(P) #else # define ExplainQueryPlan(P) -# define ExplainQueryPlan2(V,P) # define ExplainQueryPlanPop(P) # define ExplainQueryPlanParent(P) 0 # define sqlite3ExplainBreakpoint(A,B) /*no-op*/ #endif #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_EXPLAIN) @@ -16446,11 +15798,10 @@ SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe*, int addr, u8); SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1); SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2); SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe*, int addr, int P3); SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u16 P5); -SQLITE_PRIVATE void sqlite3VdbeTypeofColumn(Vdbe*, int); SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe*, int addr); SQLITE_PRIVATE void sqlite3VdbeJumpHereOrPopInst(Vdbe*, int addr); SQLITE_PRIVATE int sqlite3VdbeChangeToNoop(Vdbe*, int addr); SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op); #ifdef SQLITE_DEBUG @@ -16461,15 +15812,15 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N); SQLITE_PRIVATE void sqlite3VdbeAppendP4(Vdbe*, void *pP4, int p4type); SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse*, Index*); SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int); SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); -SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetLastOp(Vdbe*); SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Parse*); SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3*,Vdbe*); SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,Parse*); SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int); SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*); #ifdef SQLITE_DEBUG @@ -16603,26 +15954,18 @@ # define VDBE_OFFSET_LINENO(x) 0 #endif #ifdef SQLITE_ENABLE_STMT_SCANSTATUS SQLITE_PRIVATE void sqlite3VdbeScanStatus(Vdbe*, int, int, int, LogEst, const char*); -SQLITE_PRIVATE void sqlite3VdbeScanStatusRange(Vdbe*, int, int, int); -SQLITE_PRIVATE void sqlite3VdbeScanStatusCounters(Vdbe*, int, int, int); #else -# define sqlite3VdbeScanStatus(a,b,c,d,e,f) -# define sqlite3VdbeScanStatusRange(a,b,c,d) -# define sqlite3VdbeScanStatusCounters(a,b,c,d) +# define sqlite3VdbeScanStatus(a,b,c,d,e) #endif #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, VdbeOp*); #endif -#if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG) -SQLITE_PRIVATE int sqlite3CursorRangeHintExprCheck(Walker *pWalker, Expr *pExpr); -#endif - #endif /* SQLITE_VDBE_H */ /************** End of vdbe.h ************************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ /************** Include pcache.h in the middle of sqliteInt.h ****************/ @@ -16667,11 +16010,11 @@ /********************************************************************** ** Elements above, except pCache, are public. All that follow are ** private to pcache.c and should not be accessed by other modules. ** pCache is grouped with the public elements for efficiency. */ - i64 nRef; /* Number of users of this page */ + i16 nRef; /* Number of users of this page */ PgHdr *pDirtyNext; /* Next element in list of dirty pages */ PgHdr *pDirtyPrev; /* Previous element in list of dirty pages */ /* NB: pDirtyNext and pDirtyPrev are undefined if the ** PgHdr object is not dirty */ }; @@ -16748,16 +16091,16 @@ /* Discard the contents of the cache */ SQLITE_PRIVATE void sqlite3PcacheClear(PCache*); /* Return the total number of outstanding page references */ -SQLITE_PRIVATE i64 sqlite3PcacheRefCount(PCache*); +SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache*); /* Increment the reference count of an existing page */ SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr*); -SQLITE_PRIVATE i64 sqlite3PcachePageRefcount(PgHdr*); +SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr*); /* Return the total number of pages stored in the cache */ SQLITE_PRIVATE int sqlite3PcachePagecount(PCache*); #if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG) @@ -16817,10 +16160,294 @@ #endif #endif /* _PCACHE_H_ */ /************** End of pcache.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_ + +/* +** Attempt to automatically detect the operating system and setup the +** necessary pre-processor macros for it. +*/ +/************** Include os_setup.h in the middle of os.h *********************/ +/************** Begin file os_setup.h ****************************************/ +/* +** 2013 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 pre-processor directives related to operating system +** detection and/or setup. +*/ +#ifndef SQLITE_OS_SETUP_H +#define SQLITE_OS_SETUP_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, and SQLITE_OS_OTHER will defined to either 1 or 0. One of +** the three will be 1. The other two 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 +# 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 +# else +# define SQLITE_OS_WIN 0 +# define SQLITE_OS_UNIX 1 +# endif +# else +# define SQLITE_OS_UNIX 0 +# endif +#else +# ifndef SQLITE_OS_WIN +# define SQLITE_OS_WIN 0 +# endif +#endif + +#endif /* SQLITE_OS_SETUP_H */ + +/************** End of os_setup.h ********************************************/ +/************** Continuing where we left off in os.h *************************/ + +/* If the SET_FULLSYNC macro is not defined above, then make it +** a no-op +*/ +#ifndef SET_FULLSYNC +# define SET_FULLSYNC(x,y) +#endif + +/* Maximum pathname length. Note: FILENAME_MAX defined by stdio.h +*/ +#ifndef SQLITE_MAX_PATHLEN +# define SQLITE_MAX_PATHLEN FILENAME_MAX +#endif + +/* +** The default size of a disk sector +*/ +#ifndef SQLITE_DEFAULT_SECTOR_SIZE +# define SQLITE_DEFAULT_SECTOR_SIZE 4096 +#endif + +/* +** Temporary files are named starting with this prefix followed by 16 random +** alphanumeric characters, and no file extension. They are stored in the +** OS's standard temporary file directory, and are deleted prior to exit. +** If sqlite is being embedded in another program, you may wish to change the +** prefix to reflect your program's name, so that if your program exits +** prematurely, old temporary files can be easily identified. This can be done +** using -DSQLITE_TEMP_FILE_PREFIX=myprefix_ on the compiler command line. +** +** 2006-10-31: The default prefix used to be "sqlite_". But then +** Mcafee started using SQLite in their anti-virus product and it +** started putting files with the "sqlite" name in the c:/temp folder. +** This annoyed many windows users. Those users would then do a +** Google search for "sqlite", find the telephone numbers of the +** developers and call to wake them up at night and complain. +** For this reason, the default name prefix is changed to be "sqlite" +** spelled backwards. So the temp files are still identified, but +** anybody smart enough to figure out the code is also likely smart +** enough to know that calling the developer will not help get rid +** of the file. +*/ +#ifndef SQLITE_TEMP_FILE_PREFIX +# define SQLITE_TEMP_FILE_PREFIX "etilqs_" +#endif + +/* +** The following values may be passed as the second argument to +** sqlite3OsLock(). The various locks exhibit the following semantics: +** +** SHARED: Any number of processes may hold a SHARED lock simultaneously. +** RESERVED: A single process may hold a RESERVED lock on a file at +** any time. Other processes may hold and obtain new SHARED locks. +** PENDING: A single process may hold a PENDING lock on a file at +** any one time. Existing SHARED locks may persist, but no new +** SHARED locks may be obtained by other processes. +** EXCLUSIVE: An EXCLUSIVE lock precludes all other locks. +** +** PENDING_LOCK may not be passed directly to sqlite3OsLock(). Instead, a +** process that requests an EXCLUSIVE lock may actually obtain a PENDING +** lock. This can be upgraded to an EXCLUSIVE lock by a subsequent call to +** sqlite3OsLock(). +*/ +#define NO_LOCK 0 +#define SHARED_LOCK 1 +#define RESERVED_LOCK 2 +#define PENDING_LOCK 3 +#define EXCLUSIVE_LOCK 4 + +/* +** File Locking Notes: (Mostly about windows but also some info for Unix) +** +** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because +** those functions are not available. So we use only LockFile() and +** UnlockFile(). +** +** LockFile() prevents not just writing but also reading by other processes. +** A SHARED_LOCK is obtained by locking a single randomly-chosen +** byte out of a specific range of bytes. The lock byte is obtained at +** random so two separate readers can probably access the file at the +** same time, unless they are unlucky and choose the same lock byte. +** An EXCLUSIVE_LOCK is obtained by locking all bytes in the range. +** There can only be one writer. A RESERVED_LOCK is obtained by locking +** a single byte of the file that is designated as the reserved lock byte. +** A PENDING_LOCK is obtained by locking a designated byte different from +** the RESERVED_LOCK byte. +** +** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available, +** which means we can use reader/writer locks. When reader/writer locks +** are used, the lock is placed on the same range of bytes that is used +** for probabilistic locking in Win95/98/ME. Hence, the locking scheme +** will support two or more Win95 readers or two or more WinNT readers. +** But a single Win95 reader will lock out all WinNT readers and a single +** WinNT reader will lock out all other Win95 readers. +** +** The following #defines specify the range of bytes used for locking. +** SHARED_SIZE is the number of bytes available in the pool from which +** a random byte is selected for a shared lock. The pool of bytes for +** shared locks begins at SHARED_FIRST. +** +** The same locking strategy and +** byte ranges are used for Unix. This leaves open the possibility of having +** clients on win95, winNT, and unix all talking to the same shared file +** and all locking correctly. To do so would require that samba (or whatever +** tool is being used for file sharing) implements locks correctly between +** windows and unix. I'm guessing that isn't likely to happen, but by +** using the same locking range we are at least open to the possibility. +** +** Locking in windows is manditory. For this reason, we cannot store +** actual data in the bytes used for locking. The pager never allocates +** the pages involved in locking therefore. SHARED_SIZE is selected so +** that all locks will fit on a single page even at the minimum page size. +** PENDING_BYTE defines the beginning of the locks. By default PENDING_BYTE +** is set high so that we don't have to allocate an unused page except +** for very large databases. But one should test the page skipping logic +** by setting PENDING_BYTE low and running the entire regression suite. +** +** Changing the value of PENDING_BYTE results in a subtly incompatible +** file format. Depending on how it is changed, you might not notice +** the incompatibility right away, even running a full regression test. +** The default location of PENDING_BYTE is the first byte past the +** 1GB boundary. +** +*/ +#ifdef SQLITE_OMIT_WSD +# define PENDING_BYTE (0x40000000) +#else +# define PENDING_BYTE sqlite3PendingByte +#endif +#define RESERVED_BYTE (PENDING_BYTE+1) +#define SHARED_FIRST (PENDING_BYTE+2) +#define SHARED_SIZE 510 + +/* +** Wrapper around OS specific sqlite3_os_init() function. +*/ +SQLITE_PRIVATE int sqlite3OsInit(void); + +/* +** Functions for accessing sqlite3_file methods +*/ +SQLITE_PRIVATE void sqlite3OsClose(sqlite3_file*); +SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset); +SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset); +SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file*, i64 size); +SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file*, int); +SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file*, i64 *pSize); +SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file*, int); +SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file*, int); +SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut); +SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file*,int,void*); +SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file*,int,void*); +#define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0 +SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id); +SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id); +#ifndef SQLITE_OMIT_WAL +SQLITE_PRIVATE int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **); +SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int, int, int); +SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id); +SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int); +#endif /* SQLITE_OMIT_WAL */ +SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64, int, void **); +SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *, i64, void *); + + +/* +** Functions for accessing sqlite3_vfs methods +*/ +SQLITE_PRIVATE int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *); +SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *, const char *, int); +SQLITE_PRIVATE int sqlite3OsAccess(sqlite3_vfs *, const char *, int, int *pResOut); +SQLITE_PRIVATE int sqlite3OsFullPathname(sqlite3_vfs *, const char *, int, char *); +#ifndef SQLITE_OMIT_LOAD_EXTENSION +SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *, const char *); +SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *, int, char *); +SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *, void *, const char *))(void); +SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *, void *); +#endif /* SQLITE_OMIT_LOAD_EXTENSION */ +SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *, int, char *); +SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *, int); +SQLITE_PRIVATE int sqlite3OsGetLastError(sqlite3_vfs*); +SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*); + +/* +** Convenience functions for opening and closing files using +** sqlite3_malloc() to obtain space for the file-handle structure. +*/ +SQLITE_PRIVATE int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int,int*); +SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *); + +#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 @@ -17063,11 +16690,10 @@ void *pMiddle; /* First byte past end of full-size buffers and ** the first byte of LOOKASIDE_SMALL buffers */ #endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ void *pStart; /* First byte of available memory space */ void *pEnd; /* First byte past end of available space */ - void *pTrueEnd; /* True value of pEnd, when db->pnBytesFreed!=0 */ }; struct LookasideSlot { LookasideSlot *pNext; /* Next buffer in the list of free buffers */ }; @@ -17328,11 +16954,11 @@ #define SQLITE_TrustedSchema 0x00000080 /* Allow unsafe functions and ** vtabs in the schema definition */ #define SQLITE_NullCallback 0x00000100 /* Invoke the callback once if the */ /* result set is empty */ #define SQLITE_IgnoreChecks 0x00000200 /* Do not enforce check constraints */ -#define SQLITE_StmtScanStatus 0x00000400 /* Enable stmt_scanstats() counters */ +#define SQLITE_ReadUncommit 0x00000400 /* READ UNCOMMITTED in shared-cache */ #define SQLITE_NoCkptOnClose 0x00000800 /* No checkpoint on close()/DETACH */ #define SQLITE_ReverseOrder 0x00001000 /* Reverse unordered SELECTs */ #define SQLITE_RecTriggers 0x00002000 /* Enable recursive triggers */ #define SQLITE_ForeignKeys 0x00004000 /* Enforce foreign key constraints */ #define SQLITE_AutoIndex 0x00008000 /* Enable automatic indexes */ @@ -17354,11 +16980,10 @@ #define SQLITE_EnableView 0x80000000 /* Enable the use of views */ #define SQLITE_CountRows HI(0x00001) /* Count rows changed by INSERT, */ /* DELETE, or UPDATE and return */ /* the count using a callback. */ #define SQLITE_CorruptRdOnly HI(0x00002) /* Prohibit writes due to error */ -#define SQLITE_ReadUncommit HI(0x00004) /* READ UNCOMMITTED in shared-cache */ /* Flags used only if debugging */ #ifdef SQLITE_DEBUG #define SQLITE_SqlTrace HI(0x0100000) /* Debug print SQL as it executes */ #define SQLITE_VdbeListing HI(0x0200000) /* Debug listings of VDBE progs */ @@ -17406,16 +17031,10 @@ #define SQLITE_OmitOrderBy 0x00040000 /* Omit pointless ORDER BY */ /* TH3 expects this value ^^^^^^^^^^ to be 0x40000. Coordinate any change */ #define SQLITE_BloomFilter 0x00080000 /* Use a Bloom filter on searches */ #define SQLITE_BloomPulldown 0x00100000 /* Run Bloom filters early */ #define SQLITE_BalancedMerge 0x00200000 /* Balance multi-way merges */ -#define SQLITE_ReleaseReg 0x00400000 /* Use OP_ReleaseReg for testing */ -#define SQLITE_FlttnUnionAll 0x00800000 /* Disable the UNION ALL flattener */ - /* TH3 expects this value ^^^^^^^^^^ See flatten04.test */ -#define SQLITE_IndexedExpr 0x01000000 /* Pull exprs from index when able */ -#define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */ -#define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* ** Macros for testing whether or not optimizations are enabled or disabled. */ @@ -17496,18 +17115,12 @@ ** SQLITE_FUNC_ANYORDER == NC_OrderAgg == SF_OrderByReqd ** SQLITE_FUNC_LENGTH == OPFLAG_LENGTHARG ** SQLITE_FUNC_TYPEOF == OPFLAG_TYPEOFARG ** SQLITE_FUNC_CONSTANT == SQLITE_DETERMINISTIC from the API ** SQLITE_FUNC_DIRECT == SQLITE_DIRECTONLY from the API -** SQLITE_FUNC_UNSAFE == SQLITE_INNOCUOUS -- opposite meanings!!! +** SQLITE_FUNC_UNSAFE == SQLITE_INNOCUOUS ** SQLITE_FUNC_ENCMASK depends on SQLITE_UTF* macros in the API -** -** Note that even though SQLITE_FUNC_UNSAFE and SQLITE_INNOCUOUS have the -** same bit value, their meanings are inverted. SQLITE_FUNC_UNSAFE is -** used internally and if set means tha the function has side effects. -** SQLITE_INNOCUOUS is used by application code and means "not unsafe". -** See multiple instances of tag-20230109-1. */ #define SQLITE_FUNC_ENCMASK 0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */ #define SQLITE_FUNC_LIKE 0x0004 /* Candidate for the LIKE optimization */ #define SQLITE_FUNC_CASE 0x0008 /* Case-sensitive LIKE-type function */ #define SQLITE_FUNC_EPHEM 0x0010 /* Ephemeral. Delete with VDBE */ @@ -17520,11 +17133,11 @@ #define SQLITE_FUNC_CONSTANT 0x0800 /* Constant inputs give a constant output */ #define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */ #define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a ** single query - might change over time */ #define SQLITE_FUNC_TEST 0x4000 /* Built-in testing functions */ -/* 0x8000 -- available for reuse */ +#define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */ #define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */ #define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */ #define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */ #define SQLITE_FUNC_SUBTYPE 0x00100000 /* Result likely to have sub-type */ #define SQLITE_FUNC_UNSAFE 0x00200000 /* Function has side effects */ @@ -17537,11 +17150,10 @@ #define INLINEFUNC_implies_nonnull_row 1 #define INLINEFUNC_expr_implies_expr 2 #define INLINEFUNC_expr_compare 3 #define INLINEFUNC_affinity 4 #define INLINEFUNC_iif 5 -#define INLINEFUNC_sqlite_offset 6 #define INLINEFUNC_unlikely 99 /* Default case */ /* ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are ** used to create the initializers for the FuncDef structures. @@ -17620,11 +17232,11 @@ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } #define MFUNCTION(zName, nArg, xPtr, xFunc) \ {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ xPtr, 0, xFunc, 0, 0, 0, #zName, {0} } #define JFUNCTION(zName, nArg, iArg, xFunc) \ - {nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|\ + {nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS|\ SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } #define INLINE_FUNC(zName, nArg, iArg, mFlags) \ {nArg, SQLITE_FUNC_BUILTIN|\ SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \ @@ -17764,11 +17376,10 @@ #define COLFLAG_VIRTUAL 0x0020 /* GENERATED ALWAYS AS ... VIRTUAL */ #define COLFLAG_STORED 0x0040 /* GENERATED ALWAYS AS ... STORED */ #define COLFLAG_NOTAVAIL 0x0080 /* STORED column not yet calculated */ #define COLFLAG_BUSY 0x0100 /* Blocks recursion on GENERATED columns */ #define COLFLAG_HASCOLL 0x0200 /* Has collating sequence name in zCnName */ -#define COLFLAG_NOEXPAND 0x0400 /* Omit this column when expanding "*" */ #define COLFLAG_GENERATED 0x0060 /* Combo: _STORED, _VIRTUAL */ #define COLFLAG_NOINSERT 0x0062 /* Combo: _HIDDEN, _STORED, _VIRTUAL */ /* ** A "Collating Sequence" is defined by an instance of the following @@ -17812,11 +17423,10 @@ #define SQLITE_AFF_BLOB 0x41 /* 'A' */ #define SQLITE_AFF_TEXT 0x42 /* 'B' */ #define SQLITE_AFF_NUMERIC 0x43 /* 'C' */ #define SQLITE_AFF_INTEGER 0x44 /* 'D' */ #define SQLITE_AFF_REAL 0x45 /* 'E' */ -#define SQLITE_AFF_FLEXNUM 0x46 /* 'F' */ #define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) /* ** The SQLITE_AFF_MASK values masks off the significant bits of an @@ -17883,11 +17493,10 @@ sqlite3 *db; /* Database connection associated with this table */ Module *pMod; /* Pointer to module implementation */ sqlite3_vtab *pVtab; /* Pointer to vtab instance */ int nRef; /* Number of pointers to this structure */ u8 bConstraint; /* True if constraints are supported */ - u8 bAllSchemas; /* True if might use any attached schema */ u8 eVtabRisk; /* Riskiness of allowing hacker access */ int iSavepoint; /* Depth of the SAVEPOINT stack */ VTable *pNext; /* Next in linked list (see above) */ }; @@ -17992,11 +17601,11 @@ ** table support is omitted from the build. */ #ifndef SQLITE_OMIT_VIRTUALTABLE # define IsVirtual(X) ((X)->eTabType==TABTYP_VTAB) # define ExprIsVtab(X) \ - ((X)->op==TK_COLUMN && (X)->y.pTab->eTabType==TABTYP_VTAB) + ((X)->op==TK_COLUMN && (X)->y.pTab!=0 && (X)->y.pTab->eTabType==TABTYP_VTAB) #else # define IsVirtual(X) 0 # define ExprIsVtab(X) 0 #endif @@ -18173,15 +17782,10 @@ ** b-tree. */ struct UnpackedRecord { KeyInfo *pKeyInfo; /* Collation and sort-order information */ Mem *aMem; /* Values */ - union { - char *z; /* Cache of aMem[0].z for vdbeRecordCompareString() */ - i64 i; /* Cache of aMem[0].u.i for vdbeRecordCompareInt() */ - } u; - int n; /* Cache of aMem[0].n used by vdbeRecordCompareString() */ u16 nField; /* Number of entries in apMem[] */ i8 default_rc; /* Comparison result if keys are equal */ u8 errCode; /* Error detected by xRecordCompare (CORRUPT or NOMEM) */ i8 r1; /* Value to return if (lhs < rhs) */ i8 r2; /* Value to return if (lhs > rhs) */ @@ -18209,26 +17813,14 @@ ** 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 indicates which conflict resolution -** algorithm to employ when an attempt is made to insert a non-unique +** 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. ** -** The colNotIdxed bitmask is used in combination with SrcItem.colUsed -** for a fast test to see if an index can serve as a covering index. -** colNotIdxed has a 1 bit for every column of the original table that -** is *not* available in the index. Thus the expression -** "colUsed & colNotIdxed" will be non-zero if the index is not a -** covering index. The most significant bit of of colNotIdxed will always -** be true (note-20221022-a). If a column beyond the 63rd column of the -** table is used, the "colUsed & colNotIdxed" test will always be non-zero -** and we have to assume either that the index is not covering, or use -** an alternative (slower) algorithm to determine whether or not -** the index is covering. -** ** While parsing a CREATE TABLE or CREATE INDEX statement in order to ** generate VDBE code (as opposed to parsing one read from an sqlite_schema ** table as part of parsing an existing database schema), transient instances ** of this structure may be created. In this case the Index.tnum variable is ** used to store the address of a VDBE instruction, not a database page @@ -18260,21 +17852,19 @@ unsigned noSkipScan:1; /* Do not try to use skip-scan if true */ unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */ unsigned bNoQuery:1; /* Do not use this index to optimize queries */ unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */ unsigned bHasVCol:1; /* Index references one or more VIRTUAL columns */ - unsigned bHasExpr:1; /* Index contains an expression, either a literal - ** expression, or a reference to a VIRTUAL column */ #ifdef SQLITE_ENABLE_STAT4 int nSample; /* Number of elements in aSample[] */ int nSampleCol; /* Size of IndexSample.anEq[] and so on */ tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */ IndexSample *aSample; /* Samples of the left-most key */ tRowcnt *aiRowEst; /* Non-logarithmic stat1 data for this index */ tRowcnt nRowEst0; /* Non-logarithmic number of rows in the index */ #endif - Bitmask colNotIdxed; /* Unindexed columns in pTab */ + Bitmask colNotIdxed; /* 0 for unindexed columns in pTab */ }; /* ** Allowed values for Index.idxType */ @@ -18345,19 +17935,20 @@ 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 */ - u16 nSortingColumn; /* Number of columns in the sorting index */ int sortingIdx; /* Cursor number of the sorting index */ int sortingIdxPTab; /* Cursor number of pseudo-table */ - int iFirstReg; /* First register in range for aCol[] and aFunc[] */ + int nSortingColumn; /* Number of columns in the sorting index */ + int mnReg, mxReg; /* Range of registers allocated for aCol and aFunc */ ExprList *pGroupBy; /* The group by clause */ struct AggInfo_col { /* For each column used in source tables */ Table *pTab; /* Source table */ Expr *pCExpr; /* The original expression */ int iTable; /* Cursor number of the source table */ + int iMem; /* Memory location that acts as accumulator */ i16 iColumn; /* Column number within the source table */ i16 iSorterColumn; /* Column number in the sorting index */ } *aCol; int nColumn; /* Number of used entries in aCol[] */ int nAccumulator; /* Number of columns that show through to the output. @@ -18364,31 +17955,18 @@ ** Additional columns are used only as parameters to ** aggregate functions */ struct AggInfo_func { /* For each aggregate function */ Expr *pFExpr; /* 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 */ int iDistAddr; /* Address of OP_OpenEphemeral */ } *aFunc; int nFunc; /* Number of entries in aFunc[] */ u32 selId; /* Select to which this AggInfo belongs */ -#ifdef SQLITE_DEBUG - Select *pSelect; /* SELECT statement that this AggInfo supports */ -#endif }; -/* -** Macros to compute aCol[] and aFunc[] register numbers. -** -** These macros should not be used prior to the call to -** assignAggregateRegisters() that computes the value of pAggInfo->iFirstReg. -** The assert()s that are part of this macro verify that constraint. -*/ -#define AggInfoColumnReg(A,I) (assert((A)->iFirstReg),(A)->iFirstReg+(I)) -#define AggInfoFuncReg(A,I) \ - (assert((A)->iFirstReg),(A)->iFirstReg+(A)->nColumn+(I)) - /* ** 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 @@ -18512,11 +18090,11 @@ ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid. ** TK_VARIABLE: variable number (always >= 1). ** TK_SELECT_COLUMN: column of the result vector */ i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */ union { - int iJoin; /* If EP_OuterON or EP_InnerON, the right table */ + int iRightJoinTable; /* If EP_FromJoin, the right table of the join */ int iOfst; /* else: start of token from start of statement */ } w; AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ union { Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL @@ -18533,33 +18111,33 @@ ** Value restrictions: ** ** EP_Agg == NC_HasAgg == SF_HasAgg ** EP_Win == NC_HasWin */ -#define EP_OuterON 0x000001 /* Originates in ON/USING clause of outer join */ -#define EP_InnerON 0x000002 /* Originates in ON/USING of an inner join */ -#define EP_Distinct 0x000004 /* Aggregate function with DISTINCT keyword */ -#define EP_HasFunc 0x000008 /* Contains one or more functions of any kind */ +#define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */ +#define EP_Distinct 0x000002 /* Aggregate function with DISTINCT keyword */ +#define EP_HasFunc 0x000004 /* Contains one or more functions of any kind */ +#define EP_FixedCol 0x000008 /* TK_Column with a known fixed value */ #define EP_Agg 0x000010 /* Contains one or more aggregate functions */ -#define EP_FixedCol 0x000020 /* TK_Column with a known fixed value */ -#define EP_VarSelect 0x000040 /* pSelect is correlated, not constant */ -#define EP_DblQuoted 0x000080 /* token.z was originally in "..." */ -#define EP_InfixFunc 0x000100 /* True for an infix function: LIKE, GLOB, etc */ -#define EP_Collate 0x000200 /* Tree contains a TK_COLLATE operator */ -#define EP_Commuted 0x000400 /* Comparison operator has been commuted */ -#define EP_IntValue 0x000800 /* Integer value contained in u.iValue */ -#define EP_xIsSelect 0x001000 /* x.pSelect is valid (otherwise x.pList is) */ -#define EP_Skip 0x002000 /* Operator does not contribute to affinity */ -#define EP_Reduced 0x004000 /* Expr struct EXPR_REDUCEDSIZE bytes only */ +#define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */ +#define EP_DblQuoted 0x000040 /* token.z was originally in "..." */ +#define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */ +#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE operator */ +#define EP_Commuted 0x000200 /* Comparison operator has been commuted */ +#define EP_IntValue 0x000400 /* Integer value contained in u.iValue */ +#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */ +#define EP_Skip 0x001000 /* Operator does not contribute to affinity */ +#define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */ +#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */ #define EP_Win 0x008000 /* Contains window functions */ -#define EP_TokenOnly 0x010000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */ - /* 0x020000 // Available for reuse */ -#define EP_IfNullRow 0x040000 /* The TK_IF_NULL_ROW opcode */ -#define EP_Unlikely 0x080000 /* unlikely() or likelihood() function */ -#define EP_ConstFunc 0x100000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */ -#define EP_CanBeNull 0x200000 /* Can be null despite NOT NULL constraint */ -#define EP_Subquery 0x400000 /* Tree contains a TK_SELECT operator */ +#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */ +#define EP_IfNullRow 0x020000 /* The TK_IF_NULL_ROW opcode */ +#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */ +#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */ +#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */ +#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */ + /* 0x400000 // Available */ #define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */ #define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */ #define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */ #define EP_Quoted 0x4000000 /* TK_ID was originally quoted */ #define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */ @@ -18578,12 +18156,12 @@ */ #define ExprHasProperty(E,P) (((E)->flags&(P))!=0) #define ExprHasAllProperty(E,P) (((E)->flags&(P))==(P)) #define ExprSetProperty(E,P) (E)->flags|=(P) #define ExprClearProperty(E,P) (E)->flags&=~(P) -#define ExprAlwaysTrue(E) (((E)->flags&(EP_OuterON|EP_IsTrue))==EP_IsTrue) -#define ExprAlwaysFalse(E) (((E)->flags&(EP_OuterON|EP_IsFalse))==EP_IsFalse) +#define ExprAlwaysTrue(E) (((E)->flags&(EP_FromJoin|EP_IsTrue))==EP_IsTrue) +#define ExprAlwaysFalse(E) (((E)->flags&(EP_FromJoin|EP_IsFalse))==EP_IsFalse) /* Macros used to ensure that the correct members of unions are accessed ** in Expr. */ #define ExprUseUToken(E) (((E)->flags&EP_IntValue)==0) @@ -18666,22 +18244,16 @@ int nExpr; /* Number of expressions on the list */ int nAlloc; /* Number of a[] slots allocated */ struct ExprList_item { /* For each expression in the list */ Expr *pExpr; /* The parse tree for this expression */ char *zEName; /* Token associated with this expression */ - struct { - u8 sortFlags; /* Mask of KEYINFO_ORDER_* flags */ - unsigned eEName :2; /* Meaning of zEName */ - unsigned done :1; /* Indicates when processing is finished */ - unsigned reusable :1; /* Constant expression is reusable */ - unsigned bSorterRef :1; /* Defer evaluation until after sorting */ - unsigned bNulls :1; /* True if explicit "NULLS FIRST/LAST" */ - unsigned bUsed :1; /* This column used in a SF_NestedFrom subquery */ - unsigned bUsingTerm:1; /* Term from the USING clause of a NestedFrom */ - unsigned bNoExpand: 1; /* Term is an auxiliary in NestedFrom and should - ** not be expanded by "*" in parent queries */ - } fg; + u8 sortFlags; /* Mask of KEYINFO_ORDER_* flags */ + unsigned eEName :2; /* Meaning of zEName */ + unsigned done :1; /* A flag to indicate when processing is finished */ + unsigned reusable :1; /* Constant expression is reusable */ + unsigned bSorterRef :1; /* Defer evaluation until after sorting */ + unsigned bNulls: 1; /* True if explicit "NULLS FIRST/LAST" */ union { struct { /* Used by any ExprList other than Parse.pConsExpr */ u16 iOrderByCol; /* For ORDER BY, column number in result set */ u16 iAlias; /* Index into Parse.aAlias[] for zName */ } x; @@ -18712,41 +18284,21 @@ ** INSERT INTO t(a,b,c) ... ** ** If "a" is the k-th column of table "t", then IdList.a[0].idx==k. */ struct IdList { - int nId; /* Number of identifiers on the list */ - u8 eU4; /* Which element of a.u4 is valid */ struct IdList_item { char *zName; /* Name of the identifier */ - union { - int idx; /* Index in some Table.aCol[] of a column named zName */ - Expr *pExpr; /* Expr to implement a USING variable -- NOT USED */ - } u4; - } a[1]; + int idx; /* Index in some Table.aCol[] of a column named zName */ + } *a; + int nId; /* Number of identifiers on the list */ }; -/* -** Allowed values for IdList.eType, which determines which value of the a.u4 -** is valid. -*/ -#define EU4_NONE 0 /* Does not use IdList.a.u4 */ -#define EU4_IDX 1 /* Uses IdList.a.u4.idx */ -#define EU4_EXPR 2 /* Uses IdList.a.u4.pExpr -- NOT CURRENTLY USED */ - /* ** The SrcItem object represents a single term in the FROM clause of a query. ** The SrcList object is mostly an array of SrcItems. ** -** 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 sqlite3SrcListShiftJoinType() 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. -** ** Union member validity: ** ** u1.zIndexedBy fg.isIndexedBy && !fg.isTabFunc ** u1.pFuncArg fg.isTabFunc && !fg.isIndexedBy ** u2.pIBIndex fg.isIndexedBy && !fg.isCte @@ -18766,52 +18318,48 @@ u8 jointype; /* Type of join between this table and the previous */ unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */ unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */ unsigned isTabFunc :1; /* True if table-valued-function syntax */ unsigned isCorrelated :1; /* True if sub-query is correlated */ - unsigned isMaterialized:1; /* This is a materialized view */ unsigned viaCoroutine :1; /* Implemented as a co-routine */ unsigned isRecursive :1; /* True for recursive reference in WITH */ unsigned fromDDL :1; /* Comes from sqlite_schema */ unsigned isCte :1; /* This is a CTE */ unsigned notCte :1; /* This item may not match a CTE */ - unsigned isUsing :1; /* u3.pUsing is valid */ - unsigned isOn :1; /* u3.pOn was once valid and non-NULL */ - unsigned isSynthUsing :1; /* u3.pUsing is synthensized from NATURAL */ - unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */ } fg; int iCursor; /* The VDBE cursor number used to access this table */ - union { - Expr *pOn; /* fg.isUsing==0 => The ON clause of a join */ - IdList *pUsing; /* fg.isUsing==1 => The USING clause of a join */ - } u3; - Bitmask colUsed; /* Bit N set if column N used. Details above for N>62 */ + Expr *pOn; /* The ON clause of a join */ + IdList *pUsing; /* The USING clause of a join */ + Bitmask colUsed; /* Bit N (1<" clause */ ExprList *pFuncArg; /* Arguments to table-valued-function */ } u1; union { Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */ - CteUse *pCteUse; /* CTE Usage info when fg.isCte is true */ + CteUse *pCteUse; /* CTE Usage info info fg.isCte is true */ } u2; }; /* -** The OnOrUsing object represents either an ON clause or a USING clause. -** It can never be both at the same time, but it can be neither. -*/ -struct OnOrUsing { - Expr *pOn; /* The ON clause of a join */ - IdList *pUsing; /* The USING clause of a join */ -}; - -/* -** This object represents one or more tables that are the source of -** content for an SQL statement. For example, a single SrcList object -** is used to hold the FROM clause of a SELECT statement. SrcList also -** represents the target tables for DELETE, INSERT, and UPDATE statements. +** 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 sqlite3SrcListShiftJoinType() 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 { int nSrc; /* Number of tables or subqueries in the FROM clause */ u32 nAlloc; /* Number of entries allocated in a[] below */ SrcItem a[1]; /* One entry for each identifier on the list */ @@ -18818,19 +18366,18 @@ }; /* ** Permitted values of the SrcList.a.jointype field */ -#define JT_INNER 0x01 /* Any kind of inner or cross join */ -#define JT_CROSS 0x02 /* Explicit use of the CROSS keyword */ -#define JT_NATURAL 0x04 /* True for a "natural" join */ -#define JT_LEFT 0x08 /* Left outer join */ -#define JT_RIGHT 0x10 /* Right outer join */ -#define JT_OUTER 0x20 /* The "OUTER" keyword is present */ -#define JT_LTORJ 0x40 /* One of the LEFT operands of a RIGHT JOIN - ** Mnemonic: Left Table Of Right Join */ -#define JT_ERROR 0x80 /* unknown or unsupported join type */ +#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 */ + /* ** Flags appropriate for the wctrlFlags parameter of sqlite3WhereBegin() ** and the WhereInfo.wctrlFlags member. ** @@ -18849,11 +18396,11 @@ #define WHERE_DISTINCTBY 0x0080 /* pOrderby is really a DISTINCT clause */ #define WHERE_WANT_DISTINCT 0x0100 /* All output needs to be distinct */ #define WHERE_SORTBYGROUP 0x0200 /* Support sqlite3WhereIsSorted() */ #define WHERE_AGG_DISTINCT 0x0400 /* Query is "SELECT agg(DISTINCT ...)" */ #define WHERE_ORDERBY_LIMIT 0x0800 /* ORDERBY+LIMIT on the inner loop */ -#define WHERE_RIGHT_JOIN 0x1000 /* Processing a RIGHT JOIN */ + /* 0x1000 not currently used */ /* 0x2000 not currently used */ #define WHERE_USE_LIMIT 0x4000 /* Use the LIMIT in cost estimates */ /* 0x8000 not currently used */ /* Allowed return values from sqlite3WhereIsDistinct() @@ -18915,11 +18462,11 @@ #define NC_IsCheck 0x000004 /* True if resolving a CHECK constraint */ #define NC_GenCol 0x000008 /* True for a GENERATED ALWAYS AS clause */ #define NC_HasAgg 0x000010 /* One or more aggregate functions seen */ #define NC_IdxExpr 0x000020 /* True if resolving columns of CREATE INDEX */ #define NC_SelfRef 0x00002e /* Combo: PartIdx, isCheck, GenCol, and IdxExpr */ -#define NC_Subquery 0x000040 /* A subquery has been seen */ +#define NC_VarSelect 0x000040 /* A correlated subquery has been seen */ #define NC_UEList 0x000080 /* True if uNC.pEList is used */ #define NC_UAggInfo 0x000100 /* True if uNC.pAggInfo is used */ #define NC_UUpsert 0x000200 /* True if uNC.pUpsert is used */ #define NC_UBaseReg 0x000400 /* True if uNC.iBaseReg is used */ #define NC_MinMaxAgg 0x001000 /* min/max aggregates seen. See note above */ @@ -19044,14 +18591,10 @@ #define SF_UFSrcCheck 0x0800000 /* Check pSrc as required by UPDATE...FROM */ #define SF_PushDown 0x1000000 /* SELECT has be modified by push-down opt */ #define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */ #define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */ #define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */ -#define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */ - -/* True if S exists and has SF_NestedFrom */ -#define IsNestedFrom(S) ((S)!=0 && ((S)->selFlags&SF_NestedFrom)!=0) /* ** The results of a SELECT can be distributed in several ways, as defined ** by one of the following macros. The "SRT" prefix means "SELECT Result ** Type". @@ -19153,11 +18696,11 @@ u8 eDest; /* How to dispose of the results. One of SRT_* above. */ int iSDParm; /* A parameter used by the eDest disposal method */ int iSDParm2; /* A second parameter for the eDest disposal method */ int iSdst; /* Base register where results are written */ int nSdst; /* Number of registers allocated */ - char *zAffSdst; /* Affinity used for SRT_Set */ + char *zAffSdst; /* Affinity used when eDest==SRT_Set */ ExprList *pOrderBy; /* Key columns for SRT_Queue and SRT_DistQueue */ }; /* ** During code generation of statements that do inserts into AUTOINCREMENT @@ -19212,38 +18755,15 @@ # define DbMaskAllZero(M) sqlite3DbMaskAllZero(M) # define DbMaskNonZero(M) (sqlite3DbMaskAllZero(M)==0) #else typedef unsigned int yDbMask; # define DbMaskTest(M,I) (((M)&(((yDbMask)1)<<(I)))!=0) -# define DbMaskZero(M) ((M)=0) -# define DbMaskSet(M,I) ((M)|=(((yDbMask)1)<<(I))) -# define DbMaskAllZero(M) ((M)==0) -# define DbMaskNonZero(M) ((M)!=0) -#endif - -/* -** For each index X that has as one of its arguments either an expression -** or the name of a virtual generated column, and if X is in scope such that -** the value of the expression can simply be read from the index, then -** there is an instance of this object on the Parse.pIdxExpr list. -** -** During code generation, while generating code to evaluate expressions, -** this list is consulted and if a matching expression is found, the value -** is read from the index rather than being recomputed. -*/ -struct IndexedExpr { - Expr *pExpr; /* The expression contained in the index */ - int iDataCur; /* The data cursor associated with the index */ - int iIdxCur; /* The index cursor */ - int iIdxCol; /* The index column that contains value of pExpr */ - u8 bMaybeNullRow; /* True if we need an OP_IfNullRow check */ - u8 aff; /* Affinity of the pExpr expression */ - IndexedExpr *pIENext; /* Next in a list of all indexed expressions */ -#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS - const char *zIdxName; /* Name of index, used only for bytecode comments */ -#endif -}; +# define DbMaskZero(M) (M)=0 +# define DbMaskSet(M,I) (M)|=(((yDbMask)1)<<(I)) +# define DbMaskAllZero(M) (M)==0 +# define DbMaskNonZero(M) (M)!=0 +#endif /* ** An instance of the ParseCleanup object specifies an operation that ** should be performed after parsing to deallocation resources obtained ** during the parse and which are no longer needed. @@ -19282,18 +18802,14 @@ u8 isMultiWrite; /* True if statement may modify/insert multiple rows */ u8 mayAbort; /* True if statement may throw an ABORT exception */ u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */ u8 okConstFactor; /* OK to factor out constants */ u8 disableLookaside; /* Number of times lookaside has been disabled */ - u8 prepFlags; /* SQLITE_PREPARE_* flags */ - u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */ + u8 disableVtab; /* Disable all virtual tables for this parse */ #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */ #endif -#ifdef SQLITE_DEBUG - u8 ifNotExists; /* Might be true if IF NOT EXISTS. Assert()s only */ -#endif 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 */ @@ -19302,11 +18818,10 @@ ** of the base register during check-constraint eval */ int nLabel; /* The *negative* of the number of labels used */ int nLabelAlloc; /* Number of slots in aLabel */ int *aLabel; /* Space to hold the labels */ ExprList *pConstExpr;/* Constant expressions */ - IndexedExpr *pIdxEpr;/* List of expressions used by active indexes */ Token constraintName;/* Name of the constraint currently being parsed */ yDbMask writeMask; /* Start a write transaction on these databases */ yDbMask cookieMask; /* Bitmask of schema verified databases */ int regRowid; /* Register holding rowid of CREATE TABLE entry */ int regRoot; /* Register holding root page number for new objects */ @@ -19326,13 +18841,10 @@ Returning *pReturning; /* The RETURNING clause */ } u1; u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */ u32 oldmask; /* Mask of old.* columns referenced */ u32 newmask; /* Mask of new.* columns referenced */ -#ifndef SQLITE_OMIT_PROGRESS_CALLBACK - u32 nProgressSteps; /* xProgress steps taken during sqlite3_prepare() */ -#endif u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */ u8 bReturning; /* Coding a RETURNING trigger */ u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ u8 disableTriggers; /* True to disable triggers */ @@ -19463,24 +18975,24 @@ #define OPFLAG_AUXDELETE 0x04 /* OP_Delete: index in a DELETE op */ #define OPFLAG_NOCHNG_MAGIC 0x6d /* OP_MakeRecord: serialtype 10 is ok */ #define OPFLAG_PREFORMAT 0x80 /* OP_Insert uses preformatted cell */ /* -** Each trigger present in the database schema is stored as an instance of -** struct Trigger. -** -** Pointers to instances of struct Trigger are stored in two ways. -** 1. In the "trigHash" hash table (part of the sqlite3* that represents the -** database). This allows Trigger structures to be retrieved by name. -** 2. All triggers associated with a single table form a linked list, using the -** pNext member of struct Trigger. A pointer to the first element of the -** 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. -*/ + * 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 sqlite3* that represents the + * database). This allows Trigger structures to be retrieved by name. + * 2. All triggers associated with a single table form a linked list, using the + * pNext member of struct Trigger. A pointer to the first element of the + * 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 */ @@ -19503,52 +19015,47 @@ */ #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 -> The content to be inserted - either a SELECT statement or -** a VALUES clause. -** zTarget -> Dequoted name of the table to insert into. -** pIdList -> If this is an INSERT INTO ... () VALUES ... -** statement, then this stores the column-names to be -** inserted into. -** pUpsert -> The ON CONFLICT clauses for an Upsert -** -** (op == TK_DELETE) -** zTarget -> Dequoted name of the table to delete from. -** pWhere -> The WHERE clause of the DELETE statement if one is specified. -** Otherwise NULL. -** -** (op == TK_UPDATE) -** zTarget -> Dequoted name of the table to update. -** pWhere -> The WHERE clause of the UPDATE statement if one is specified. -** Otherwise NULL. -** pExprList -> A list of the columns to update and the expressions to update -** them to. See sqlite3Update() documentation of "pChanges" -** argument. -** -** (op == TK_SELECT) -** pSelect -> The SELECT statement -** -** (op == TK_RETURNING) -** pExprList -> The list of expressions that follow the RETURNING keyword. -** -*/ + * 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. + * zTarget -> Dequoted name of the table to insert into. + * pExprList -> If this is an INSERT INTO ... VALUES ... statement, then + * this stores values to be inserted. Otherwise NULL. + * pIdList -> If this is an INSERT INTO ... () VALUES ... + * statement, then this stores the column-names to be + * inserted into. + * + * (op == TK_DELETE) + * zTarget -> Dequoted name of the table to delete from. + * pWhere -> The WHERE clause of the DELETE statement if one is specified. + * Otherwise NULL. + * + * (op == TK_UPDATE) + * zTarget -> Dequoted name of the table to update. + * pWhere -> The WHERE clause of the UPDATE statement if one is specified. + * Otherwise NULL. + * pExprList -> A list of the columns to update and the expressions to update + * them to. See sqlite3Update() documentation of "pChanges" + * argument. + * + */ struct TriggerStep { u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT, ** or TK_RETURNING */ u8 orconf; /* OE_Rollback etc. */ Trigger *pTrig; /* The trigger that this step is a part of */ @@ -19741,20 +19248,19 @@ SrcList *pSrcList; /* FROM clause */ struct CCurHint *pCCurHint; /* Used by codeCursorHint() */ struct RefSrcList *pRefSrcList; /* sqlite3ReferencesSrcList() */ int *aiCol; /* array of column indexes */ struct IdxCover *pIdxCover; /* Check for index coverage */ + struct IdxExprTrans *pIdxTrans; /* Convert idxed expr to column */ ExprList *pGroupBy; /* GROUP BY clause */ Select *pSelect; /* HAVING to WHERE clause ctx */ struct WindowRewrite *pRewrite; /* Window rewrite context */ struct WhereConst *pConst; /* WHERE clause constants */ struct RenameCtx *pRename; /* RENAME COLUMN context */ struct Table *pTab; /* Table of generated column */ - struct CoveringIndexCheck *pCovIdxCk; /* Check for covering index */ SrcItem *pSrcItem; /* A single FROM clause item */ - DbFixer *pFix; /* See sqlite3FixSelect() */ - Mem *aMem; /* See sqlite3BtreeCursorHint() */ + DbFixer *pFix; } u; }; /* ** The following structure contains information used by the sqliteFix... @@ -19900,11 +19406,11 @@ Expr *pStart; /* Expression for " PRECEDING" */ Expr *pEnd; /* Expression for " FOLLOWING" */ Window **ppThis; /* Pointer to this object in Select.pWin list */ Window *pNextWin; /* Next window function belonging to this SELECT */ Expr *pFilter; /* The FILTER expression */ - FuncDef *pWFunc; /* The function */ + FuncDef *pFunc; /* The function */ int iEphCsr; /* Partition buffer or Peer buffer */ int regAccum; /* Accumulator */ int regResult; /* Interim result */ int csrApp; /* Function cursor (used by min/max) */ int regApp; /* Function register (also used by min/max) */ @@ -20056,11 +19562,10 @@ SQLITE_PRIVATE void *sqlite3Realloc(void*, u64); SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64); SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, u64); SQLITE_PRIVATE void sqlite3DbFree(sqlite3*, void*); SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3*, void*); -SQLITE_PRIVATE void sqlite3DbNNFreeNN(sqlite3*, void*); SQLITE_PRIVATE int sqlite3MallocSize(const void*); SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3*, const void*); SQLITE_PRIVATE void *sqlite3PageMalloc(int); SQLITE_PRIVATE void sqlite3PageFree(void*); SQLITE_PRIVATE void sqlite3MemSetDefault(void); @@ -20077,18 +19582,16 @@ ** The alloca() routine never returns NULL. This will cause code paths ** that deal with sqlite3StackAlloc() failures to be unreachable. */ #ifdef SQLITE_USE_ALLOCA # define sqlite3StackAllocRaw(D,N) alloca(N) -# define sqlite3StackAllocRawNN(D,N) alloca(N) +# define sqlite3StackAllocZero(D,N) memset(alloca(N), 0, N) # define sqlite3StackFree(D,P) -# define sqlite3StackFreeNN(D,P) #else # define sqlite3StackAllocRaw(D,N) sqlite3DbMallocRaw(D,N) -# define sqlite3StackAllocRawNN(D,N) sqlite3DbMallocRawNN(D,N) +# define sqlite3StackAllocZero(D,N) sqlite3DbMallocZero(D,N) # define sqlite3StackFree(D,P) sqlite3DbFree(D,P) -# define sqlite3StackFreeNN(D,P) sqlite3DbFreeNN(D,P) #endif /* Do not allow both MEMSYS5 and MEMSYS3 to be defined together. If they ** are, disable MEMSYS3 */ @@ -20158,60 +19661,24 @@ #if defined(SQLITE_TEST) SQLITE_PRIVATE void *sqlite3TestTextToPtr(const char*); #endif #if defined(SQLITE_DEBUG) -SQLITE_PRIVATE void sqlite3TreeViewLine(TreeView*, const char *zFormat, ...); SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView*, const Expr*, u8); SQLITE_PRIVATE void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*); SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*); -SQLITE_PRIVATE void sqlite3TreeViewBareIdList(TreeView*, const IdList*, const char*); -SQLITE_PRIVATE void sqlite3TreeViewIdList(TreeView*, const IdList*, u8, const char*); -SQLITE_PRIVATE void sqlite3TreeViewColumnList(TreeView*, const Column*, int, u8); SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView*, const SrcList*); SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8); SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8); -SQLITE_PRIVATE void sqlite3TreeViewUpsert(TreeView*, const Upsert*, u8); -#if TREETRACE_ENABLED -SQLITE_PRIVATE void sqlite3TreeViewDelete(const With*, const SrcList*, const Expr*, - const ExprList*,const Expr*, const Trigger*); -SQLITE_PRIVATE void sqlite3TreeViewInsert(const With*, const SrcList*, - const IdList*, const Select*, const ExprList*, - int, const Upsert*, const Trigger*); -SQLITE_PRIVATE void sqlite3TreeViewUpdate(const With*, const SrcList*, const ExprList*, - const Expr*, int, const ExprList*, const Expr*, - const Upsert*, const Trigger*); -#endif -#ifndef SQLITE_OMIT_TRIGGER -SQLITE_PRIVATE void sqlite3TreeViewTriggerStep(TreeView*, const TriggerStep*, u8, u8); -SQLITE_PRIVATE void sqlite3TreeViewTrigger(TreeView*, const Trigger*, u8, u8); -#endif #ifndef SQLITE_OMIT_WINDOWFUNC SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView*, const Window*, u8); SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8); #endif -SQLITE_PRIVATE void sqlite3ShowExpr(const Expr*); -SQLITE_PRIVATE void sqlite3ShowExprList(const ExprList*); -SQLITE_PRIVATE void sqlite3ShowIdList(const IdList*); -SQLITE_PRIVATE void sqlite3ShowSrcList(const SrcList*); -SQLITE_PRIVATE void sqlite3ShowSelect(const Select*); -SQLITE_PRIVATE void sqlite3ShowWith(const With*); -SQLITE_PRIVATE void sqlite3ShowUpsert(const Upsert*); -#ifndef SQLITE_OMIT_TRIGGER -SQLITE_PRIVATE void sqlite3ShowTriggerStep(const TriggerStep*); -SQLITE_PRIVATE void sqlite3ShowTriggerStepList(const TriggerStep*); -SQLITE_PRIVATE void sqlite3ShowTrigger(const Trigger*); -SQLITE_PRIVATE void sqlite3ShowTriggerList(const Trigger*); -#endif -#ifndef SQLITE_OMIT_WINDOWFUNC -SQLITE_PRIVATE void sqlite3ShowWindow(const Window*); -SQLITE_PRIVATE void sqlite3ShowWinFunc(const Window*); -#endif -#endif - -SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*); -SQLITE_PRIVATE void sqlite3ProgressCheck(Parse*); +#endif + + +SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*); SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...); SQLITE_PRIVATE int sqlite3ErrorToParser(sqlite3*,int); SQLITE_PRIVATE void sqlite3Dequote(char*); SQLITE_PRIVATE void sqlite3DequoteExpr(Expr*); SQLITE_PRIVATE void sqlite3DequoteToken(Token*); @@ -20222,14 +19689,10 @@ SQLITE_PRIVATE int sqlite3GetTempReg(Parse*); SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse*,int); SQLITE_PRIVATE int sqlite3GetTempRange(Parse*,int); SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse*,int,int); SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse*); -SQLITE_PRIVATE void sqlite3TouchRegister(Parse*,int); -#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_DEBUG) -SQLITE_PRIVATE int sqlite3FirstAvailableRegister(Parse*,int); -#endif #ifdef SQLITE_DEBUG SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse*,int,int); #endif SQLITE_PRIVATE Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int); SQLITE_PRIVATE Expr *sqlite3Expr(sqlite3*,int,const char*); @@ -20269,11 +19732,11 @@ SQLITE_PRIVATE void sqlite3ColumnSetColl(sqlite3*,Column*,const char*zColl); SQLITE_PRIVATE const char *sqlite3ColumnColl(Column*); SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3*,Table*); SQLITE_PRIVATE void sqlite3GenerateColumnNames(Parse *pParse, Select *pSelect); SQLITE_PRIVATE int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**); -SQLITE_PRIVATE void sqlite3SubqueryColumnTypes(Parse*,Table*,Select*,char); +SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*,char); SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*,char); SQLITE_PRIVATE void sqlite3OpenSchemaTable(Parse *, int); SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table*); SQLITE_PRIVATE i16 sqlite3TableColumnToIndex(Index*, i16); #ifdef SQLITE_OMIT_GENERATED_COLUMNS @@ -20358,18 +19821,17 @@ SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*); SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int); SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2); SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*); SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*, - Token*, Select*, OnOrUsing*); + Token*, Select*, Expr*, IdList*); SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *); SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*); SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, SrcItem *); -SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(Parse*,SrcList*); +SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList*); SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*); SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*); -SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3*, OnOrUsing*); SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*); SQLITE_PRIVATE Index *sqlite3AllocateIndexObject(sqlite3*,i16,int,char**); SQLITE_PRIVATE void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, Expr*, int, int, u8); SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int); @@ -20376,11 +19838,11 @@ SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*); SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*, Expr*,ExprList*,u32,Expr*); SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*); SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*); -SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, Trigger*); +SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int); SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*); #endif SQLITE_PRIVATE void sqlite3CodeChangeCount(Vdbe*,int,const char*); @@ -20563,12 +20025,11 @@ # define sqlite3TriggerStepSrc(A,B) 0 #endif SQLITE_PRIVATE int sqlite3JoinType(Parse*, Token*, Token*, Token*); SQLITE_PRIVATE int sqlite3ColumnIndex(Table *pTab, const char *zCol); -SQLITE_PRIVATE void sqlite3SrcItemColumnUsed(SrcItem*,int); -SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr*,int,u32); +SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr*,int); SQLITE_PRIVATE void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int); SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse*, int); #ifndef SQLITE_OMIT_AUTHORIZATION SQLITE_PRIVATE void sqlite3AuthRead(Parse*,Expr*,Schema*,SrcList*); SQLITE_PRIVATE int sqlite3AuthCheck(Parse*,int, const char*, const char*, const char*); @@ -20588,12 +20049,11 @@ SQLITE_PRIVATE int sqlite3FixSrcList(DbFixer*, SrcList*); SQLITE_PRIVATE int sqlite3FixSelect(DbFixer*, Select*); SQLITE_PRIVATE int sqlite3FixExpr(DbFixer*, Expr*); SQLITE_PRIVATE int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); SQLITE_PRIVATE int sqlite3RealSameAsInt(double,sqlite3_int64); -SQLITE_PRIVATE i64 sqlite3RealToI64(double); -SQLITE_PRIVATE int sqlite3Int64ToText(i64,char*); +SQLITE_PRIVATE void sqlite3Int64ToText(i64,char*); SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*, int, u8); SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*); SQLITE_PRIVATE int sqlite3GetUInt32(const char*, u32*); SQLITE_PRIVATE int sqlite3Atoi(const char*); #ifndef SQLITE_OMIT_UTF16 @@ -20634,17 +20094,15 @@ #define getVarint sqlite3GetVarint #define putVarint sqlite3PutVarint SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3*, Index*); -SQLITE_PRIVATE char *sqlite3TableAffinityStr(sqlite3*,const Table*); SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe*, Table*, int); SQLITE_PRIVATE char sqlite3CompareAffinity(const Expr *pExpr, char aff2); SQLITE_PRIVATE int sqlite3IndexAffinityOk(const Expr *pExpr, char idx_affinity); SQLITE_PRIVATE char sqlite3TableColumnAffinity(const Table*,int); SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr); -SQLITE_PRIVATE int sqlite3ExprDataType(const Expr *pExpr); SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8); SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*); SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...); SQLITE_PRIVATE void sqlite3Error(sqlite3*,int); SQLITE_PRIVATE void sqlite3ErrorClear(sqlite3*); @@ -20657,13 +20115,10 @@ SQLITE_PRIVATE const char *sqlite3ErrName(int); #endif #ifndef SQLITE_OMIT_DESERIALIZE SQLITE_PRIVATE int sqlite3MemdbInit(void); -SQLITE_PRIVATE int sqlite3IsMemdb(const sqlite3_vfs*); -#else -# define sqlite3IsMemdb(X) 0 #endif SQLITE_PRIVATE const char *sqlite3ErrStr(int); SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse); SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); @@ -20710,10 +20165,11 @@ #ifndef SQLITE_AMALGAMATION SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[]; SQLITE_PRIVATE const char sqlite3StrBINARY[]; SQLITE_PRIVATE const unsigned char sqlite3StdTypeLen[]; SQLITE_PRIVATE const char sqlite3StdTypeAffinity[]; +SQLITE_PRIVATE const char sqlite3StdTypeMap[]; SQLITE_PRIVATE const char *sqlite3StdType[]; SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[]; SQLITE_PRIVATE const unsigned char *sqlite3aLTb; SQLITE_PRIVATE const unsigned char *sqlite3aEQb; SQLITE_PRIVATE const unsigned char *sqlite3aGTb; @@ -20799,11 +20255,11 @@ SQLITE_PRIVATE void sqlite3OomClear(sqlite3*); SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int); SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *); SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int); -SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum*, i64); +SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum*, int); SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*); SQLITE_PRIVATE void sqlite3StrAccumSetError(StrAccum*, u8); SQLITE_PRIVATE void sqlite3ResultStrAccum(sqlite3_context*,StrAccum*); SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int); SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int); @@ -20913,11 +20369,14 @@ SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse*, Table*); SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *); SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *); SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*); -SQLITE_PRIVATE void sqlite3VtabUsesAllSchemas(Parse*); +#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \ + && !defined(SQLITE_OMIT_VIRTUALTABLE) +SQLITE_PRIVATE void sqlite3VtabWriteAll(sqlite3_index_info*); +#endif SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*); SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); SQLITE_PRIVATE void sqlite3ParseObjectInit(Parse*,sqlite3*); SQLITE_PRIVATE void sqlite3ParseObjectReset(Parse*); @@ -21150,26 +20609,10 @@ #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt); #endif -#if SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL) -SQLITE_PRIVATE int sqlite3KvvfsInit(void); -#endif - -#if defined(VDBE_PROFILE) \ - || defined(SQLITE_PERFORMANCE_TRACE) \ - || defined(SQLITE_ENABLE_STMT_SCANSTATUS) -SQLITE_PRIVATE sqlite3_uint64 sqlite3Hwtime(void); -#endif - -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS -# define IS_STMT_SCANSTATUS(db) (db->flags & SQLITE_StmtScanStatus) -#else -# define IS_STMT_SCANSTATUS(db) 0 -#endif - #endif /* SQLITEINT_H */ /************** End of sqliteInt.h *******************************************/ /************** Begin file os_common.h ***************************************/ /* @@ -21207,10 +20650,105 @@ ** Macros for performance tracing. Normally turned off. Only works ** on i486 hardware. */ #ifdef SQLITE_PERFORMANCE_TRACE +/* +** hwtime.h contains inline assembler code for implementing +** high-performance timing routines. +*/ +/************** Include hwtime.h in the middle of os_common.h ****************/ +/************** 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 and x86_64 class CPUs. +*/ +#ifndef SQLITE_HWTIME_H +#define SQLITE_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(__STRICT_ANSI__) && \ + (defined(__GNUC__) || defined(_MSC_VER)) && \ + (defined(i386) || defined(__i386__) || defined(_M_IX86)) + + #if defined(__GNUC__) + + __inline__ sqlite_uint64 sqlite3Hwtime(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 sqlite3Hwtime(void){ + __asm { + rdtsc + ret ; return value at EDX:EAX + } + } + + #endif + +#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned long val; + __asm__ __volatile__ ("rdtsc" : "=A" (val)); + return val; + } + +#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__)) + + __inline__ sqlite_uint64 sqlite3Hwtime(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 + + /* + ** asm() is needed for hardware timing support. Without asm(), + ** disable the sqlite3Hwtime() routine. + ** + ** sqlite3Hwtime() is only used for some obscure debugging + ** and analysis configurations, not in any deliverable, so this + ** should not be a great loss. + */ +SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } + +#endif + +#endif /* !defined(SQLITE_HWTIME_H) */ + +/************** End of hwtime.h **********************************************/ +/************** Continuing where we left off in os_common.h ******************/ + static sqlite_uint64 g_start; static sqlite_uint64 g_elapsed; #define TIMER_START g_start=sqlite3Hwtime() #define TIMER_END g_elapsed=sqlite3Hwtime()-g_start #define TIMER_ELAPSED g_elapsed @@ -21302,11 +20840,11 @@ /* ** Include the configuration header output by 'configure' if we're using the ** autoconf-based build */ #if defined(_HAVE_SQLITE_CONFIG_H) && !defined(SQLITECONFIG_H) -/* #include "sqlite_cfg.h" */ +/* #include "config.h" */ #define SQLITECONFIG_H 1 #endif /* These macros are provided to "stringify" the value of the define ** for those options in which the value is meaningful. */ @@ -21467,13 +21005,10 @@ "DISABLE_PAGECACHE_OVERFLOW_STATS", #endif #ifdef SQLITE_DISABLE_SKIPAHEAD_DISTINCT "DISABLE_SKIPAHEAD_DISTINCT", #endif -#ifdef SQLITE_DQS - "DQS=" CTIMEOPT_VAL(SQLITE_DQS), -#endif #ifdef SQLITE_ENABLE_8_3_NAMES "ENABLE_8_3_NAMES=" CTIMEOPT_VAL(SQLITE_ENABLE_8_3_NAMES), #endif #ifdef SQLITE_ENABLE_API_ARMOR "ENABLE_API_ARMOR", @@ -21583,10 +21118,13 @@ #ifdef SQLITE_ENABLE_RBU "ENABLE_RBU", #endif #ifdef SQLITE_ENABLE_RTREE "ENABLE_RTREE", +#endif +#ifdef SQLITE_ENABLE_SELECTTRACE + "ENABLE_SELECTTRACE", #endif #ifdef SQLITE_ENABLE_SESSION "ENABLE_SESSION", #endif #ifdef SQLITE_ENABLE_SNAPSHOT @@ -21605,13 +21143,10 @@ "ENABLE_STMTVTAB", #endif #ifdef SQLITE_ENABLE_STMT_SCANSTATUS "ENABLE_STMT_SCANSTATUS", #endif -#ifdef SQLITE_ENABLE_TREETRACE - "ENABLE_TREETRACE", -#endif #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION "ENABLE_UNKNOWN_SQL_FUNCTION", #endif #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY "ENABLE_UNLOCK_NOTIFY", @@ -21959,10 +21494,13 @@ #ifdef SQLITE_OMIT_WSD "OMIT_WSD", #endif #ifdef SQLITE_OMIT_XFER_OPT "OMIT_XFER_OPT", +#endif +#ifdef SQLITE_PCACHE_SEPARATE_HEADER + "PCACHE_SEPARATE_HEADER", #endif #ifdef SQLITE_PERFORMANCE_TRACE "PERFORMANCE_TRACE", #endif #ifdef SQLITE_POWERSAFE_OVERWRITE @@ -22354,13 +21892,10 @@ 0, /* bLocaltimeFault */ 0, /* xAltLocaltime */ 0x7ffffffe, /* iOnceResetThreshold */ SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */ 0, /* iPrngSeed */ -#ifdef SQLITE_DEBUG - {0,0,0,0,0,0}, /* aTune */ -#endif }; /* ** Hash table for global functions - functions common to all ** database connections. After initialization, this table is @@ -22411,11 +21946,11 @@ #endif /* ** Tracing flags set by SQLITE_TESTCTRL_TRACEFLAGS. */ -SQLITE_PRIVATE u32 sqlite3TreeTrace = 0; +SQLITE_PRIVATE u32 sqlite3SelectTrace = 0; SQLITE_PRIVATE u32 sqlite3WhereTrace = 0; /* #include "opcodes.h" */ /* ** Properties of opcodes. The OPFLG_INITIALIZER macro is @@ -22439,19 +21974,31 @@ ** sqlite3StdTypeLen[] The length (in bytes) of each entry ** in sqlite3StdType[]. ** ** sqlite3StdTypeAffinity[] The affinity associated with each entry ** in sqlite3StdType[]. +** +** sqlite3StdTypeMap[] The type value (as returned from +** sqlite3_column_type() or sqlite3_value_type()) +** for each entry in sqlite3StdType[]. */ SQLITE_PRIVATE const unsigned char sqlite3StdTypeLen[] = { 3, 4, 3, 7, 4, 4 }; SQLITE_PRIVATE const char sqlite3StdTypeAffinity[] = { SQLITE_AFF_NUMERIC, SQLITE_AFF_BLOB, SQLITE_AFF_INTEGER, SQLITE_AFF_INTEGER, SQLITE_AFF_REAL, SQLITE_AFF_TEXT +}; +SQLITE_PRIVATE const char sqlite3StdTypeMap[] = { + 0, + SQLITE_BLOB, + SQLITE_INTEGER, + SQLITE_INTEGER, + SQLITE_FLOAT, + SQLITE_TEXT }; SQLITE_PRIVATE const char *sqlite3StdType[] = { "ANY", "BLOB", "INT", @@ -22566,11 +22113,11 @@ u8 wrFlag; /* The wrFlag argument to sqlite3BtreeCursor() */ #endif Bool isEphemeral:1; /* True for an ephemeral table */ Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */ Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */ - Bool noReuse:1; /* OpenEphemeral may not reuse this cursor */ + Bool hasBeenDuped:1; /* This cursor was source or target of OP_OpenDup */ u16 seekHit; /* See the OP_SeekHit and OP_IfNoHope opcodes */ union { /* pBtx for isEphermeral. pAltMap otherwise */ Btree *pBtx; /* Separate file holding temporary table */ u32 *aAltMap; /* Mapping from table to index column numbers */ } ub; @@ -22614,15 +22161,10 @@ ** static element declared in the structure. nField total array slots for ** aType[] and nField+1 array slots for aOffset[] */ u32 aType[1]; /* Type values record decode. MUST BE LAST */ }; -/* Return true if P is a null-only cursor -*/ -#define IsNullCursor(P) \ - ((P)->eCurType==CURTYPE_PSEUDO && (P)->nullRow && (P)->seekResult==0) - /* ** A value for VdbeCursor.cacheStatus that means the cache is always invalid. */ #define CACHE_STALE 0 @@ -22651,10 +22193,11 @@ typedef struct VdbeFrame VdbeFrame; struct VdbeFrame { Vdbe *v; /* VM this frame belongs to */ VdbeFrame *pParent; /* Parent of this frame, or NULL if parent is main */ Op *aOp; /* Program instructions for parent frame */ + i64 *anExec; /* Event counters from parent frame */ Mem *aMem; /* Array of memory cells for parent frame */ VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */ u8 *aOnce; /* Bitmask used by OP_Once */ void *token; /* Copy of SubProgram.token */ i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */ @@ -22692,20 +22235,20 @@ i64 i; /* Integer value used when MEM_Int is set in flags */ int nZero; /* Extra zero bytes when MEM_Zero and MEM_Blob set */ const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */ FuncDef *pDef; /* Used only when flags==MEM_Agg */ } u; - char *z; /* String or BLOB value */ - int n; /* Number of characters in string value, excluding '\0' */ u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */ u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */ u8 eSubtype; /* Subtype for this value */ + int n; /* Number of characters in string value, excluding '\0' */ + char *z; /* String or BLOB value */ /* ShallowCopy only needs to copy the information above */ - sqlite3 *db; /* The associated database connection */ + char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */ int szMalloc; /* Size of the zMalloc allocation */ u32 uTemp; /* Transient storage for serial_type in OP_MakeRecord */ - char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */ + sqlite3 *db; /* The associated database connection */ void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */ #ifdef SQLITE_DEBUG Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */ u16 mScopyFlags; /* flags value immediately after the shallow copy */ #endif @@ -22713,46 +22256,14 @@ /* ** Size of struct Mem not including the Mem.zMalloc member or anything that ** follows. */ -#define MEMCELLSIZE offsetof(Mem,db) - -/* One or more of the following flags are set to indicate the -** representations of the value stored in the Mem struct. -** -** * MEM_Null An SQL NULL value -** -** * MEM_Null|MEM_Zero An SQL NULL with the virtual table -** UPDATE no-change flag set -** -** * MEM_Null|MEM_Term| An SQL NULL, but also contains a -** MEM_Subtype pointer accessible using -** sqlite3_value_pointer(). -** -** * MEM_Null|MEM_Cleared Special SQL NULL that compares non-equal -** to other NULLs even using the IS operator. -** -** * MEM_Str A string, stored in Mem.z with -** length Mem.n. Zero-terminated if -** MEM_Term is set. This flag is -** incompatible with MEM_Blob and -** MEM_Null, but can appear with MEM_Int, -** MEM_Real, and MEM_IntReal. -** -** * MEM_Blob A blob, stored in Mem.z length Mem.n. -** Incompatible with MEM_Str, MEM_Null, -** MEM_Int, MEM_Real, and MEM_IntReal. -** -** * MEM_Blob|MEM_Zero A blob in Mem.z of length Mem.n plus -** MEM.u.i extra 0x00 bytes at the end. -** -** * MEM_Int Integer stored in Mem.u.i. -** -** * MEM_Real Real stored in Mem.u.r. -** -** * MEM_IntReal Real stored as an integer in Mem.u.i. +#define MEMCELLSIZE offsetof(Mem,zMalloc) + +/* 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. ** For a pointer type created using sqlite3_bind_pointer() or ** sqlite3_result_pointer() the MEM_Term and MEM_Subtype flags are also set. ** @@ -22760,36 +22271,39 @@ ** 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_Undefined 0x0000 /* Value is undefined */ #define MEM_Null 0x0001 /* Value is NULL (or a pointer) */ #define MEM_Str 0x0002 /* Value is a string */ #define MEM_Int 0x0004 /* Value is an integer */ #define MEM_Real 0x0008 /* Value is a real number */ #define MEM_Blob 0x0010 /* Value is a BLOB */ #define MEM_IntReal 0x0020 /* MEM_Int that stringifies like MEM_Real */ #define MEM_AffMask 0x003f /* Mask of affinity bits */ - -/* Extra bits that modify the meanings of the core datatypes above -*/ #define MEM_FromBind 0x0040 /* Value originates from sqlite3_bind() */ - /* 0x0080 // Available */ +#define MEM_Undefined 0x0080 /* Value is undefined */ #define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */ +#define MEM_TypeMask 0xc1bf /* 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 in Mem.z is zero terminated */ -#define MEM_Zero 0x0400 /* Mem.i contains count of 0s appended to blob */ -#define MEM_Subtype 0x0800 /* Mem.eSubtype is valid */ -#define MEM_TypeMask 0x0dbf /* Mask of type bits */ - -/* Bits that determine the storage for Mem.z for a string or blob or -** aggregate accumulator. -*/ -#define MEM_Dyn 0x1000 /* Need to call Mem.xDel() on Mem.z */ -#define MEM_Static 0x2000 /* Mem.z points to a static string */ -#define MEM_Ephem 0x4000 /* Mem.z points to an ephemeral string */ -#define MEM_Agg 0x8000 /* Mem.z points to an agg function context */ +#define MEM_Dyn 0x0400 /* Need to call Mem.xDel() on Mem.z */ +#define MEM_Static 0x0800 /* Mem.z points to a static string */ +#define MEM_Ephem 0x1000 /* Mem.z points to an ephemeral string */ +#define MEM_Agg 0x2000 /* Mem.z points to an agg function context */ +#define MEM_Zero 0x4000 /* Mem.i contains count of 0s appended to blob */ +#define MEM_Subtype 0x8000 /* Mem.eSubtype is valid */ +#ifdef SQLITE_OMIT_INCRBLOB + #undef MEM_Zero + #define MEM_Zero 0x0000 +#endif /* Return TRUE if Mem X contains dynamically allocated content - anything ** that needs to be deallocated to avoid a leak. */ #define VdbeMemDynamic(X) \ @@ -22807,19 +22321,15 @@ #define MemNullNochng(X) \ (((X)->flags&MEM_TypeMask)==(MEM_Null|MEM_Zero) \ && (X)->n==0 && (X)->u.nZero==0) /* -** Return true if a memory cell has been initialized and is valid. +** Return true if a memory cell is not marked as invalid. This macro ** is for use inside assert() statements only. -** -** A Memory cell is initialized if at least one of the -** MEM_Null, MEM_Str, MEM_Int, MEM_Real, MEM_Blob, or MEM_IntReal bits -** is set. It is "undefined" if all those bits are zero. */ #ifdef SQLITE_DEBUG -#define memIsValid(M) ((M)->flags & MEM_AffMask)!=0 +#define memIsValid(M) ((M)->flags & MEM_Undefined)==0 #endif /* ** Each auxiliary data pointer stored by a user defined function ** implementation calling sqlite3_set_auxdata() is stored in an instance @@ -22853,11 +22363,10 @@ FuncDef *pFunc; /* Pointer to function information */ Mem *pMem; /* Memory cell used to store aggregate context */ Vdbe *pVdbe; /* The VM that owns this context */ int iOp; /* Instruction number of OP_Function */ int isError; /* Error code returned by the function. */ - u8 enc; /* Encoding to use for results */ u8 skipFlag; /* Skip accumulator loading if true */ u8 argc; /* Number of arguments */ sqlite3_value *argv[1]; /* Argument set */ }; @@ -22866,23 +22375,14 @@ */ typedef unsigned bft; /* Bit Field Type */ /* The ScanStatus object holds a single value for the ** sqlite3_stmt_scanstatus() interface. -** -** aAddrRange[]: -** This array is used by ScanStatus elements associated with EQP -** notes that make an SQLITE_SCANSTAT_NCYCLE value available. It is -** an array of up to 3 ranges of VM addresses for which the Vdbe.anCycle[] -** values should be summed to calculate the NCYCLE value. Each pair of -** integer addresses is a start and end address (both inclusive) for a range -** instructions. A start value of 0 indicates an empty range. */ typedef struct ScanStatus ScanStatus; struct ScanStatus { int addrExplain; /* OP_Explain for loop */ - int aAddrRange[6]; int addrLoop; /* Address of "loops" counter */ int addrVisit; /* Address of "rows visited" counter */ int iSelectID; /* The "Select-ID" for this loop */ LogEst nEst; /* Estimated output rows per loop */ char *zName; /* Name of table or index */ @@ -22908,13 +22408,14 @@ ** The "sqlite3_stmt" structure pointer that is returned by sqlite3_prepare() ** is really a pointer to an instance of this structure. */ struct Vdbe { sqlite3 *db; /* The database connection that owns this statement */ - Vdbe **ppVPrev,*pVNext; /* Linked list of VDBEs with the same Vdbe.db */ + Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ Parse *pParse; /* Parsing context used to create this Vdbe */ ynVar nVar; /* Number of entries in aVar[] */ + u32 iVdbeMagic; /* Magic number defining state of the SQL statement */ int nMem; /* Number of memory locations currently allocated */ int nCursor; /* Number of slots in apCsr[] */ u32 cacheCtr; /* VdbeCursor row cache generation counter */ int pc; /* The program counter */ int rc; /* Value to return */ @@ -22934,11 +22435,11 @@ Op *aOp; /* Space to hold the virtual machine's program */ int nOp; /* Number of instructions in the program */ int nOpAlloc; /* Slots allocated for aOp[] */ Mem *aColName; /* Column names to return */ - Mem *pResultRow; /* Current output row */ + Mem *pResultSet; /* Pointer to an array of results */ char *zErrMsg; /* Error message written here */ VList *pVList; /* Name of variables */ #ifndef SQLITE_OMIT_TRACE i64 startTime; /* Time when query started - used for profiling */ #endif @@ -22948,14 +22449,15 @@ #endif u16 nResColumn; /* Number of columns in one row of the result set */ u8 errorAction; /* Recovery action to do in case of an error */ u8 minWriteFileFormat; /* Minimum file format for writable database files */ u8 prepFlags; /* SQLITE_PREPARE_* flags */ - u8 eVdbeState; /* On of the VDBE_*_STATE values */ + u8 doingRerun; /* True if rerunning after an auto-reprepare */ bft expired:2; /* 1: recompile VM immediately 2: when convenient */ bft explain:2; /* True if EXPLAIN present on SQL command */ bft changeCntOn:1; /* True to update the change-counter */ + bft runOnlyOnce:1; /* Automatically expire on reset */ bft usesStmtJournal:1; /* True if uses a statement journal */ bft readOnly:1; /* True for statements that do not write */ bft bIsReader:1; /* True for statements that read */ yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */ yDbMask lockMask; /* Subset of btreeMask that requires a lock */ @@ -22971,22 +22473,24 @@ 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 */ AuxData *pAuxData; /* Linked list of auxdata allocations */ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS + i64 *anExec; /* Number of times each op has been executed */ int nScan; /* Entries in aScan[] */ ScanStatus *aScan; /* Scan definitions for sqlite3_stmt_scanstatus() */ #endif }; /* -** The following are allowed values for Vdbe.eVdbeState +** The following are allowed values for Vdbe.magic */ -#define VDBE_INIT_STATE 0 /* Prepared statement under construction */ -#define VDBE_READY_STATE 1 /* Ready to run but not yet started */ -#define VDBE_RUN_STATE 2 /* Run in progress */ -#define VDBE_HALT_STATE 3 /* Finished. Need reset() or finalize() */ +#define VDBE_MAGIC_INIT 0x16bceaa5 /* Building a VDBE program */ +#define VDBE_MAGIC_RUN 0x2df20da3 /* VDBE is ready to execute */ +#define VDBE_MAGIC_HALT 0x319c2973 /* VDBE has completed execution */ +#define VDBE_MAGIC_RESET 0x48fa9f76 /* Reset and ready to run again */ +#define VDBE_MAGIC_DEAD 0x5606c3c8 /* The VDBE has been deallocated */ /* ** Structure used to store the context required by the ** sqlite3_preupdate_*() API functions. */ @@ -23023,35 +22527,22 @@ struct ValueList { BtCursor *pCsr; /* An ephemeral table holding all values */ sqlite3_value *pOut; /* Register to hold each decoded output value */ }; -/* Size of content associated with serial types that fit into a -** single-byte varint. -*/ -#ifndef SQLITE_AMALGAMATION -SQLITE_PRIVATE const u8 sqlite3SmallTypeSizes[]; -#endif - /* ** Function prototypes */ SQLITE_PRIVATE void sqlite3VdbeError(Vdbe*, const char *, ...); SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*); -SQLITE_PRIVATE void sqlite3VdbeFreeCursorNN(Vdbe*,VdbeCursor*); void sqliteVdbePopStack(Vdbe*,int); -SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeHandleMovedCursor(VdbeCursor *p); SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor*); +SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor**, u32*); SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*); SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32); SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8); -#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT -SQLITE_PRIVATE u64 sqlite3FloatSwap(u64 in); -# define swapMixedEndianFloat(X) X = sqlite3FloatSwap(X) -#else -# define swapMixedEndianFloat(X) -#endif +SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32); SQLITE_PRIVATE void sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int); int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*); @@ -23105,11 +22596,10 @@ SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemCast(Mem*,u8,u8); SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*); SQLITE_PRIVATE int sqlite3VdbeMemFromBtreeZeroOffset(BtCursor*,u32,Mem*); SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p); -SQLITE_PRIVATE void sqlite3VdbeMemReleaseMalloc(Mem*p); SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*); #ifndef SQLITE_OMIT_WINDOWFUNC SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*); #endif #if !defined(SQLITE_OMIT_EXPLAIN) || defined(SQLITE_ENABLE_BYTECODE_VTAB) @@ -23137,12 +22627,10 @@ SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *); SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *, int *); SQLITE_PRIVATE int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *); SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *); -SQLITE_PRIVATE void sqlite3VdbeValueListFree(void*); - #ifdef SQLITE_DEBUG SQLITE_PRIVATE void sqlite3VdbeIncrWriteCounter(Vdbe*, VdbeCursor*); SQLITE_PRIVATE void sqlite3VdbeAssertAbortable(Vdbe*); #else # define sqlite3VdbeIncrWriteCounter(V,C) @@ -23467,12 +22955,10 @@ int i; /* Used to iterate through schemas */ int nByte = 0; /* Used to accumulate return value */ sqlite3BtreeEnterAll(db); db->pnBytesFreed = &nByte; - assert( db->lookaside.pEnd==db->lookaside.pTrueEnd ); - db->lookaside.pEnd = db->lookaside.pStart; for(i=0; inDb; i++){ Schema *pSchema = db->aDb[i].pSchema; if( ALWAYS(pSchema!=0) ){ HashElem *p; @@ -23494,11 +22980,10 @@ sqlite3DeleteTable(db, (Table *)sqliteHashData(p)); } } } db->pnBytesFreed = 0; - db->lookaside.pEnd = db->lookaside.pTrueEnd; sqlite3BtreeLeaveAll(db); *pHighwater = 0; *pCurrent = nByte; break; @@ -23512,16 +22997,14 @@ case SQLITE_DBSTATUS_STMT_USED: { struct Vdbe *pVdbe; /* Used to iterate through VMs */ int nByte = 0; /* Used to accumulate return value */ db->pnBytesFreed = &nByte; - assert( db->lookaside.pEnd==db->lookaside.pTrueEnd ); - db->lookaside.pEnd = db->lookaside.pStart; - for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pVNext){ - sqlite3VdbeDelete(pVdbe); + for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){ + sqlite3VdbeClearObject(db, pVdbe); + sqlite3DbFree(db, pVdbe); } - db->lookaside.pEnd = db->lookaside.pTrueEnd; db->pnBytesFreed = 0; *pHighwater = 0; /* IMP: R-64479-57858 */ *pCurrent = nByte; @@ -23853,11 +23336,11 @@ X1 = 36525*(Y+4716)/100; X2 = 306001*(M+1)/10000; p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000); p->validJD = 1; if( p->validHMS ){ - p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000 + 0.5); + p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000); if( p->validTZ ){ p->iJD -= p->tz*60000; p->validYMD = 0; p->validHMS = 0; p->validTZ = 0; @@ -24326,11 +23809,11 @@ else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){ if( p->tzSet==0 ){ i64 iOrigJD; /* Original localtime */ i64 iGuess; /* Guess at the corresponding utc time */ int cnt = 0; /* Safety to prevent infinite loop */ - i64 iErr; /* Guess is off by this much */ + int iErr; /* Guess is off by this much */ computeJD(p); iGuess = iOrigJD = p->iJD; iErr = 0; do{ @@ -24362,11 +23845,11 @@ ** weekday N where 0==Sunday, 1==Monday, and so forth. If the ** date is already on the appropriate weekday, this is a no-op. */ if( sqlite3_strnicmp(z, "weekday ", 8)==0 && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)>0 - && r>=0.0 && r<7.0 && (n=(int)r)==r ){ + && (n=(int)r)==r && n>=0 && r<7 ){ sqlite3_int64 Z; computeYMD_HMS(p); p->validTZ = 0; p->validJD = 0; computeJD(p); @@ -25043,15 +24526,13 @@ DO_OS_MALLOC_TEST(id); return id->pMethods->xFileSize(id, pSize); } SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file *id, int lockType){ DO_OS_MALLOC_TEST(id); - assert( lockType>=SQLITE_LOCK_SHARED && lockType<=SQLITE_LOCK_EXCLUSIVE ); return id->pMethods->xLock(id, lockType); } SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file *id, int lockType){ - assert( lockType==SQLITE_LOCK_NONE || lockType==SQLITE_LOCK_SHARED ); return id->pMethods->xUnlock(id, lockType); } SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){ DO_OS_MALLOC_TEST(id); return id->pMethods->xCheckReservedLock(id, pResOut); @@ -25162,11 +24643,10 @@ DO_OS_MALLOC_TEST(0); /* 0x87f7f is a mask of SQLITE_OPEN_ flags that are valid to be passed ** down into the VFS layer. Some SQLITE_OPEN_ flags (for example, ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before ** reaching the VFS. */ - assert( zPath || (flags & SQLITE_OPEN_EXCLUSIVE) ); rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x1087f7f, pFlagsOut); assert( rc==SQLITE_OK || pFile->pMethods==0 ); return rc; } SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ @@ -27474,21 +26954,12 @@ ** 32-bit signed integer. Hence the largest allocation is 0x40000000 ** or 1073741824 bytes. */ static int memsys5Roundup(int n){ int iFullSz; - if( n<=mem5.szAtom*2 ){ - if( n<=mem5.szAtom ) return mem5.szAtom; - return mem5.szAtom*2; - } - if( n>0x10000000 ){ - if( n>0x40000000 ) return 0; - if( n>0x20000000 ) return 0x40000000; - return 0x20000000; - } - for(iFullSz=mem5.szAtom*8; iFullSz=(i64)n ) return iFullSz/2; + if( n > 0x40000000 ) return 0; + for(iFullSz=mem5.szAtom; iFullSz2147483391 -# error Maximum size for SQLITE_MAX_ALLOCATION_SIZE is 2147483391 -#endif - /* ** Allocate memory. This routine is like sqlite3_malloc() except that it ** assumes the memory subsystem has already been initialized. */ SQLITE_PRIVATE void *sqlite3Malloc(u64 n){ void *p; - if( n==0 || n>SQLITE_MAX_ALLOCATION_SIZE ){ + if( n==0 || 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 sqlite3_malloc() */ p = 0; }else if( sqlite3GlobalConfig.bMemstat ){ sqlite3_mutex_enter(mem0.mutex); mallocWithAlarm((int)n, &p); sqlite3_mutex_leave(mem0.mutex); @@ -29448,11 +28903,11 @@ /* ** TRUE if p is a lookaside memory allocation from db */ #ifndef SQLITE_OMIT_LOOKASIDE static int isLookaside(sqlite3 *db, const void *p){ - return SQLITE_WITHIN(p, db->lookaside.pStart, db->lookaside.pTrueEnd); + return SQLITE_WITHIN(p, db->lookaside.pStart, db->lookaside.pEnd); } #else #define isLookaside(A,B) 0 #endif @@ -29472,20 +28927,22 @@ #endif } SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, const void *p){ assert( p!=0 ); #ifdef SQLITE_DEBUG - if( db==0 ){ - assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); - assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); - }else if( !isLookaside(db,p) ){ - assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); - assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + if( db==0 || !isLookaside(db,p) ){ + if( db==0 ){ + assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); + assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); + }else{ + assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + } } #endif if( db ){ - if( ((uptr)p)<(uptr)(db->lookaside.pTrueEnd) ){ + if( ((uptr)p)<(uptr)(db->lookaside.pEnd) ){ #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){ assert( sqlite3_mutex_held(db->mutex) ); return LOOKASIDE_SMALL; } @@ -29537,15 +28994,18 @@ */ SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3 *db, void *p){ assert( db==0 || sqlite3_mutex_held(db->mutex) ); assert( p!=0 ); if( db ){ + if( db->pnBytesFreed ){ + measureAllocationSize(db, p); + return; + } if( ((uptr)p)<(uptr)(db->lookaside.pEnd) ){ #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){ LookasideSlot *pBuf = (LookasideSlot*)p; - assert( db->pnBytesFreed==0 ); #ifdef SQLITE_DEBUG memset(p, 0xaa, LOOKASIDE_SMALL); /* Trash freed content */ #endif pBuf->pNext = db->lookaside.pSmallFree; db->lookaside.pSmallFree = pBuf; @@ -29552,67 +29012,25 @@ return; } #endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ if( ((uptr)p)>=(uptr)(db->lookaside.pStart) ){ LookasideSlot *pBuf = (LookasideSlot*)p; - assert( db->pnBytesFreed==0 ); #ifdef SQLITE_DEBUG memset(p, 0xaa, db->lookaside.szTrue); /* Trash freed content */ #endif pBuf->pNext = db->lookaside.pFree; db->lookaside.pFree = pBuf; return; } } - if( db->pnBytesFreed ){ - measureAllocationSize(db, p); - return; - } } assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); sqlite3MemdebugSetType(p, MEMTYPE_HEAP); sqlite3_free(p); } -SQLITE_PRIVATE void sqlite3DbNNFreeNN(sqlite3 *db, void *p){ - assert( db!=0 ); - assert( sqlite3_mutex_held(db->mutex) ); - assert( p!=0 ); - if( ((uptr)p)<(uptr)(db->lookaside.pEnd) ){ -#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE - if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){ - LookasideSlot *pBuf = (LookasideSlot*)p; - assert( db->pnBytesFreed==0 ); -#ifdef SQLITE_DEBUG - memset(p, 0xaa, LOOKASIDE_SMALL); /* Trash freed content */ -#endif - pBuf->pNext = db->lookaside.pSmallFree; - db->lookaside.pSmallFree = pBuf; - return; - } -#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ - if( ((uptr)p)>=(uptr)(db->lookaside.pStart) ){ - LookasideSlot *pBuf = (LookasideSlot*)p; - assert( db->pnBytesFreed==0 ); -#ifdef SQLITE_DEBUG - memset(p, 0xaa, db->lookaside.szTrue); /* Trash freed content */ -#endif - pBuf->pNext = db->lookaside.pFree; - db->lookaside.pFree = pBuf; - return; - } - } - if( db->pnBytesFreed ){ - measureAllocationSize(db, p); - return; - } - assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); - assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); - sqlite3MemdebugSetType(p, MEMTYPE_HEAP); - sqlite3_free(p); -} SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){ assert( db==0 || sqlite3_mutex_held(db->mutex) ); if( p ) sqlite3DbFreeNN(db, p); } @@ -29908,18 +29326,13 @@ ** SQL statement. Make a copy of this phrase in space obtained form ** sqlite3DbMalloc(). Omit leading and trailing whitespace. */ SQLITE_PRIVATE char *sqlite3DbSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){ int n; -#ifdef SQLITE_DEBUG - /* Because of the way the parser works, the span is guaranteed to contain - ** at least one non-space character */ - for(n=0; sqlite3Isspace(zStart[n]); n++){ assert( &zStart[n]0) && sqlite3Isspace(zStart[n-1]) ) n--; return sqlite3DbStrNDup(db, zStart, n); } /* ** Free any prior content in *pz and replace it with a copy of zNew. @@ -29949,17 +29362,12 @@ if( db->nVdbeExec>0 ){ AtomicStore(&db->u1.isInterrupted, 1); } DisableLookaside; if( db->pParse ){ - Parse *pParse; sqlite3ErrorMsg(db->pParse, "out of memory"); db->pParse->rc = SQLITE_NOMEM_BKPT; - for(pParse=db->pParse->pOuterParse; pParse; pParse = pParse->pOuterParse){ - pParse->nErr++; - pParse->rc = SQLITE_NOMEM; - } } } return 0; } @@ -30160,24 +29568,10 @@ *val = (*val - d)*10.0; return (char)digit; } #endif /* SQLITE_OMIT_FLOATING_POINT */ -#ifndef SQLITE_OMIT_FLOATING_POINT -/* -** "*val" is a u64. *msd is a divisor used to extract the -** most significant digit of *val. Extract that most significant -** digit and return it. -*/ -static char et_getdigit_int(u64 *val, u64 *msd){ - u64 x = (*val)/(*msd); - *val -= x*(*msd); - if( *msd>=10 ) *msd /= 10; - return '0' + (char)(x & 15); -} -#endif /* SQLITE_OMIT_FLOATING_POINT */ - /* ** Set the StrAccum object to an error mode. */ SQLITE_PRIVATE void sqlite3StrAccumSetError(StrAccum *p, u8 eError){ assert( eError==SQLITE_NOMEM || eError==SQLITE_TOOBIG ); @@ -30266,12 +29660,10 @@ etByte xtype = etINVALID; /* Conversion paradigm */ u8 bArgList; /* True for SQLITE_PRINTF_SQLFUNC */ char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ sqlite_uint64 longvalue; /* Value for integer types */ LONGDOUBLE_TYPE realvalue; /* Value for real types */ - sqlite_uint64 msd; /* Divisor to get most-significant-digit - ** of longvalue */ const et_info *infop; /* Pointer to the appropriate info structure */ char *zOut; /* Rendering buffer */ int nOut; /* Size of the rendering buffer */ char *zExtra = 0; /* Malloced memory used by some conversion */ #ifndef SQLITE_OMIT_FLOATING_POINT @@ -30574,82 +29966,56 @@ realvalue = -realvalue; prefix = '-'; }else{ prefix = flag_prefix; } - exp = 0; if( xtype==etGENERIC && precision>0 ) precision--; testcase( precision>0xfff ); - if( realvalue<1.0e+16 - && realvalue==(LONGDOUBLE_TYPE)(longvalue = (u64)realvalue) - ){ - /* Number is a pure integer that can be represented as u64 */ - for(msd=1; msd*10<=longvalue; msd *= 10, exp++){} - if( exp>precision && xtype!=etFLOAT ){ - u64 rnd = msd/2; - int kk = precision; - while( kk-- > 0 ){ rnd /= 10; } - longvalue += rnd; - } - }else{ - msd = 0; - longvalue = 0; /* To prevent a compiler warning */ - idx = precision & 0xfff; - rounder = arRound[idx%10]; - while( idx>=10 ){ rounder *= 1.0e-10; idx -= 10; } - if( xtype==etFLOAT ){ - double rx = (double)realvalue; - sqlite3_uint64 u; - int ex; - memcpy(&u, &rx, sizeof(u)); - ex = -1023 + (int)((u>>52)&0x7ff); - if( precision+(ex/3) < 15 ) rounder += realvalue*3e-16; - realvalue += rounder; - } - if( sqlite3IsNaN((double)realvalue) ){ - if( flag_zeropad ){ - bufpt = "null"; - length = 4; - }else{ - bufpt = "NaN"; - length = 3; - } - break; - } - - /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */ - if( ALWAYS(realvalue>0.0) ){ - LONGDOUBLE_TYPE scale = 1.0; - while( realvalue>=1e100*scale && exp<=350){ scale*=1e100;exp+=100;} - while( realvalue>=1e10*scale && exp<=350 ){ scale*=1e10; exp+=10; } - while( realvalue>=10.0*scale && exp<=350 ){ scale *= 10.0; exp++; } - realvalue /= scale; - while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; } - while( realvalue<1.0 ){ realvalue *= 10.0; exp--; } - if( exp>350 ){ - if( flag_zeropad ){ - realvalue = 9.0; - exp = 999; - }else{ - bufpt = buf; - buf[0] = prefix; - memcpy(buf+(prefix!=0),"Inf",4); - length = 3+(prefix!=0); - break; - } - } - if( xtype!=etFLOAT ){ - realvalue += rounder; - if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; } - } - } - } - + idx = precision & 0xfff; + rounder = arRound[idx%10]; + while( idx>=10 ){ rounder *= 1.0e-10; idx -= 10; } + if( xtype==etFLOAT ){ + double rx = (double)realvalue; + sqlite3_uint64 u; + int ex; + memcpy(&u, &rx, sizeof(u)); + ex = -1023 + (int)((u>>52)&0x7ff); + if( precision+(ex/3) < 15 ) rounder += realvalue*3e-16; + realvalue += rounder; + } + /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */ + exp = 0; + if( sqlite3IsNaN((double)realvalue) ){ + bufpt = "NaN"; + length = 3; + break; + } + if( realvalue>0.0 ){ + LONGDOUBLE_TYPE scale = 1.0; + while( realvalue>=1e100*scale && exp<=350 ){ scale *= 1e100;exp+=100;} + while( realvalue>=1e10*scale && exp<=350 ){ scale *= 1e10; exp+=10; } + while( realvalue>=10.0*scale && exp<=350 ){ scale *= 10.0; exp++; } + realvalue /= scale; + while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; } + while( realvalue<1.0 ){ realvalue *= 10.0; exp--; } + if( exp>350 ){ + bufpt = buf; + buf[0] = prefix; + memcpy(buf+(prefix!=0),"Inf",4); + length = 3+(prefix!=0); + 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{ @@ -30662,33 +30028,28 @@ if( xtype==etEXP ){ e2 = 0; }else{ e2 = exp; } - nsd = 16 + flag_altform2*10; - bufpt = buf; { i64 szBufNeeded; /* Size of a temporary buffer needed */ szBufNeeded = MAX(e2,0)+(i64)precision+(i64)width+15; if( szBufNeeded > etBUFSIZE ){ bufpt = zExtra = printfTempBuf(pAccum, szBufNeeded); if( bufpt==0 ) return; } } zOut = bufpt; + nsd = 16 + flag_altform2*10; 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 if( msd>0 ){ - for(; e2>=0; e2--){ - *(bufpt++) = et_getdigit_int(&longvalue,&msd); - } }else{ for(; e2>=0; e2--){ *(bufpt++) = et_getdigit(&realvalue,&nsd); } } @@ -30701,18 +30062,12 @@ for(e2++; e2<0; precision--, e2++){ assert( precision>0 ); *(bufpt++) = '0'; } /* Significant digits after the decimal point */ - if( msd>0 ){ - while( (precision--)>0 ){ - *(bufpt++) = et_getdigit_int(&longvalue,&msd); - } - }else{ - while( (precision--)>0 ){ - *(bufpt++) = et_getdigit(&realvalue,&nsd); - } + 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 ); @@ -30807,30 +30162,17 @@ buf[3] = 0x80 + (u8)(ch & 0x3f); length = 4; } } if( precision>1 ){ - i64 nPrior = 1; width -= precision-1; if( width>1 && !flag_leftjustify ){ sqlite3_str_appendchar(pAccum, width-1, ' '); width = 0; } - sqlite3_str_append(pAccum, buf, length); - precision--; - while( precision > 1 ){ - i64 nCopyBytes; - if( nPrior > precision-1 ) nPrior = precision - 1; - nCopyBytes = length*nPrior; - if( nCopyBytes + pAccum->nChar >= pAccum->nAlloc ){ - sqlite3StrAccumEnlarge(pAccum, nCopyBytes); - } - if( pAccum->accError ) break; - sqlite3_str_append(pAccum, - &pAccum->zText[pAccum->nChar-nCopyBytes], nCopyBytes); - precision -= nPrior; - nPrior *= 2; + while( precision-- > 1 ){ + sqlite3_str_append(pAccum, buf, length); } } bufpt = buf; flag_altform2 = 1; goto adjust_width_for_utf8; @@ -30887,12 +30229,12 @@ } break; case etSQLESCAPE: /* %q: Escape ' characters */ case etSQLESCAPE2: /* %Q: Escape ' and enclose in '...' */ case etSQLESCAPE3: { /* %w: Escape " characters */ - i64 i, j, k, n; - int needQuote, isnull; + int i, j, k, n, isnull; + int needQuote; char ch; char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote character */ char *escarg; if( bArgList ){ @@ -30968,18 +30310,12 @@ sqlite3_str_append(pAccum, ".", 1); } sqlite3_str_appendall(pAccum, pItem->zName); }else if( pItem->zAlias ){ sqlite3_str_appendall(pAccum, pItem->zAlias); - }else{ - Select *pSel = pItem->pSelect; - assert( pSel!=0 ); - if( pSel->selFlags & SF_NestedFrom ){ - sqlite3_str_appendf(pAccum, "(join-%u)", pSel->selId); - }else{ - sqlite3_str_appendf(pAccum, "(subquery-%u)", pSel->selId); - } + }else if( ALWAYS(pItem->pSelect) ){ + sqlite3_str_appendf(pAccum, "SUBQUERY %u", pItem->pSelect->selId); } length = width = 0; break; } default: { @@ -31038,13 +30374,11 @@ /* ** If pExpr has a byte offset for the start of a token, record that as ** as the error offset. */ SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3 *db, const Expr *pExpr){ - while( pExpr - && (ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) || pExpr->w.iOfst<=0) - ){ + while( pExpr && (ExprHasProperty(pExpr,EP_FromJoin) || pExpr->w.iOfst<=0) ){ pExpr = pExpr->pLeft; } if( pExpr==0 ) return; db->errByteOffset = pExpr->w.iOfst; } @@ -31054,13 +30388,13 @@ ** able to accept at least N more bytes of text. ** ** Return the number of bytes of text that StrAccum is able to accept ** after the attempted enlargement. The value returned might be zero. */ -SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum *p, i64 N){ +SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum *p, int N){ char *zNew; - assert( p->nChar+N >= p->nAlloc ); /* Only called if really needed */ + assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */ if( p->accError ){ testcase(p->accError==SQLITE_TOOBIG); testcase(p->accError==SQLITE_NOMEM); return 0; } @@ -31067,11 +30401,12 @@ if( p->mxAlloc==0 ){ sqlite3StrAccumSetError(p, SQLITE_TOOBIG); return p->nAlloc - p->nChar - 1; }else{ char *zOld = isMalloced(p) ? p->zText : 0; - i64 szNew = p->nChar + N + 1; + i64 szNew = p->nChar; + szNew += (sqlite3_int64)N + 1; if( szNew+p->nChar<=p->mxAlloc ){ /* Force exponential buffer size growth as long as it does not overflow, ** to avoid having to call this routine too often */ szNew += p->nChar; } @@ -31097,12 +30432,11 @@ sqlite3_str_reset(p); sqlite3StrAccumSetError(p, SQLITE_NOMEM); return 0; } } - assert( N>=0 && N<=0x7fffffff ); - return (int)N; + return N; } /* ** Append N copies of character c to the given string buffer. */ @@ -31389,26 +30723,16 @@ sqlite3_str_vappendf(&acc, zFormat, ap); zBuf[acc.nChar] = 0; return zBuf; } SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ - StrAccum acc; + char *z; va_list ap; - if( n<=0 ) return zBuf; -#ifdef SQLITE_ENABLE_API_ARMOR - if( zBuf==0 || zFormat==0 ) { - (void)SQLITE_MISUSE_BKPT; - if( zBuf ) zBuf[0] = 0; - return zBuf; - } -#endif - sqlite3StrAccumInit(&acc, 0, zBuf, n, 0); va_start(ap,zFormat); - sqlite3_str_vappendf(&acc, zFormat, ap); + z = sqlite3_vsnprintf(n, zBuf, zFormat, ap); va_end(ap); - zBuf[acc.nChar] = 0; - return zBuf; + return z; } /* ** This is the routine that actually formats the sqlite3_log() message. ** We house it in a separate routine from sqlite3_log() to avoid using @@ -31510,48 +30834,44 @@ /* ** Add a new subitem to the tree. The moreToFollow flag indicates that this ** is not the last item in the tree. */ -static void sqlite3TreeViewPush(TreeView **pp, u8 moreToFollow){ - TreeView *p = *pp; +static TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){ if( p==0 ){ - *pp = p = sqlite3_malloc64( sizeof(*p) ); - if( p==0 ) return; + p = sqlite3_malloc64( sizeof(*p) ); + if( p==0 ) return 0; memset(p, 0, sizeof(*p)); }else{ p->iLevel++; } assert( moreToFollow==0 || moreToFollow==1 ); - if( p->iLevel<(int)sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow; + if( p->iLevelbLine) ) p->bLine[p->iLevel] = moreToFollow; + return p; } /* ** Finished with one layer of the tree */ -static void sqlite3TreeViewPop(TreeView **pp){ - TreeView *p = *pp; +static void sqlite3TreeViewPop(TreeView *p){ if( p==0 ) return; p->iLevel--; - if( p->iLevel<0 ){ - sqlite3_free(p); - *pp = 0; - } + if( p->iLevel<0 ) sqlite3_free(p); } /* ** Generate a single line of output for the tree, with a prefix that contains ** all the appropriate tree lines */ -SQLITE_PRIVATE void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){ +static void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){ va_list ap; int i; StrAccum acc; - char zBuf[1000]; + char zBuf[500]; sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); if( p ){ - for(i=0; iiLevel && i<(int)sizeof(p->bLine)-1; i++){ + for(i=0; iiLevel && ibLine)-1; i++){ sqlite3_str_append(&acc, p->bLine[i] ? "| " : " ", 4); } sqlite3_str_append(&acc, p->bLine[i] ? "|-- " : "'-- ", 4); } if( zFormat!=0 ){ @@ -31568,61 +30888,14 @@ /* ** Shorthand for starting a new tree item that consists of a single label */ static void sqlite3TreeViewItem(TreeView *p, const char *zLabel,u8 moreFollows){ - sqlite3TreeViewPush(&p, moreFollows); + p = sqlite3TreeViewPush(p, moreFollows); sqlite3TreeViewLine(p, "%s", zLabel); } -/* -** Show a list of Column objects in tree format. -*/ -SQLITE_PRIVATE void sqlite3TreeViewColumnList( - TreeView *pView, - const Column *aCol, - int nCol, - u8 moreToFollow -){ - int i; - sqlite3TreeViewPush(&pView, moreToFollow); - sqlite3TreeViewLine(pView, "COLUMNS"); - for(i=0; ipOuter); }else{ sqlite3TreeViewLine(pView, "WITH (0x%p)", pWith); } if( pWith->nCte>0 ){ - sqlite3TreeViewPush(&pView, moreToFollow); + pView = sqlite3TreeViewPush(pView, 1); for(i=0; inCte; i++){ StrAccum x; char zLine[1000]; const struct Cte *pCte = &pWith->a[i]; sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); @@ -31648,94 +30921,59 @@ sqlite3_str_appendf(&x, "%c%s", cSep, pCte->pCols->a[j].zEName); cSep = ','; } sqlite3_str_appendf(&x, ")"); } - if( pCte->eM10d!=M10d_Any ){ - sqlite3_str_appendf(&x, " %sMATERIALIZED", - pCte->eM10d==M10d_No ? "NOT " : ""); - } if( pCte->pUse ){ sqlite3_str_appendf(&x, " (pUse=0x%p, nUse=%d)", pCte->pUse, pCte->pUse->nUse); } sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, inCte-1); sqlite3TreeViewSelect(pView, pCte->pSelect, 0); - sqlite3TreeViewPop(&pView); + sqlite3TreeViewPop(pView); } - sqlite3TreeViewPop(&pView); + sqlite3TreeViewPop(pView); } } /* ** Generate a human-readable description of a SrcList object. */ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ int i; - if( pSrc==0 ) return; for(i=0; inSrc; i++){ const SrcItem *pItem = &pSrc->a[i]; StrAccum x; - int n = 0; - char zLine[1000]; + char zLine[100]; sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); x.printfFlags |= SQLITE_PRINTF_INTERNAL; sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem); if( pItem->pTab ){ sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx", pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab, pItem->colUsed); } - if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==(JT_LEFT|JT_RIGHT) ){ - sqlite3_str_appendf(&x, " FULL-OUTER-JOIN"); - }else if( pItem->fg.jointype & JT_LEFT ){ + if( pItem->fg.jointype & JT_LEFT ){ sqlite3_str_appendf(&x, " LEFT-JOIN"); - }else if( pItem->fg.jointype & JT_RIGHT ){ - sqlite3_str_appendf(&x, " RIGHT-JOIN"); }else if( pItem->fg.jointype & JT_CROSS ){ sqlite3_str_appendf(&x, " CROSS-JOIN"); } - if( pItem->fg.jointype & JT_LTORJ ){ - sqlite3_str_appendf(&x, " LTORJ"); - } if( pItem->fg.fromDDL ){ sqlite3_str_appendf(&x, " DDL"); } if( pItem->fg.isCte ){ sqlite3_str_appendf(&x, " CteUse=0x%p", pItem->u2.pCteUse); } - if( pItem->fg.isOn || (pItem->fg.isUsing==0 && pItem->u3.pOn!=0) ){ - sqlite3_str_appendf(&x, " ON"); - } - if( pItem->fg.isTabFunc ) sqlite3_str_appendf(&x, " isTabFunc"); - if( pItem->fg.isCorrelated ) sqlite3_str_appendf(&x, " isCorrelated"); - if( pItem->fg.isMaterialized ) sqlite3_str_appendf(&x, " isMaterialized"); - if( pItem->fg.viaCoroutine ) sqlite3_str_appendf(&x, " viaCoroutine"); - if( pItem->fg.notCte ) sqlite3_str_appendf(&x, " notCte"); - if( pItem->fg.isNestedFrom ) sqlite3_str_appendf(&x, " isNestedFrom"); - sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, inSrc-1); - n = 0; - if( pItem->pSelect ) n++; - if( pItem->fg.isTabFunc ) n++; - if( pItem->fg.isUsing ) n++; - if( pItem->fg.isUsing ){ - sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING"); - } if( pItem->pSelect ){ - if( pItem->pTab ){ - Table *pTab = pItem->pTab; - sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1); - } - assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); - sqlite3TreeViewSelect(pView, pItem->pSelect, (--n)>0); + sqlite3TreeViewSelect(pView, pItem->pSelect, 0); } if( pItem->fg.isTabFunc ){ sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); } - sqlite3TreeViewPop(&pView); + sqlite3TreeViewPop(pView); } } /* ** Generate a human-readable description of a Select object. @@ -31745,15 +30983,15 @@ int cnt = 0; if( p==0 ){ sqlite3TreeViewLine(pView, "nil-SELECT"); return; } - sqlite3TreeViewPush(&pView, moreToFollow); + pView = sqlite3TreeViewPush(pView, moreToFollow); if( p->pWith ){ sqlite3TreeViewWith(pView, p->pWith, 1); cnt = 1; - sqlite3TreeViewPush(&pView, 1); + sqlite3TreeViewPush(pView, 1); } do{ if( p->selFlags & SF_WhereBegin ){ sqlite3TreeViewLine(pView, "sqlite3WhereBegin()"); }else{ @@ -31763,11 +31001,11 @@ ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p->selId, p, p->selFlags, (int)p->nSelectRow ); } - if( cnt++ ) sqlite3TreeViewPop(&pView); + if( cnt++ ) sqlite3TreeViewPop(pView); if( p->pPrior ){ n = 1000; }else{ n = 0; if( p->pSrc && p->pSrc->nSrc ) n++; @@ -31786,45 +31024,45 @@ } n--; #ifndef SQLITE_OMIT_WINDOWFUNC if( p->pWin ){ Window *pX; - sqlite3TreeViewPush(&pView, (n--)>0); + pView = sqlite3TreeViewPush(pView, (n--)>0); sqlite3TreeViewLine(pView, "window-functions"); for(pX=p->pWin; pX; pX=pX->pNextWin){ sqlite3TreeViewWinFunc(pView, pX, pX->pNextWin!=0); } - sqlite3TreeViewPop(&pView); + sqlite3TreeViewPop(pView); } #endif if( p->pSrc && p->pSrc->nSrc ){ - sqlite3TreeViewPush(&pView, (n--)>0); + pView = sqlite3TreeViewPush(pView, (n--)>0); sqlite3TreeViewLine(pView, "FROM"); sqlite3TreeViewSrcList(pView, p->pSrc); - sqlite3TreeViewPop(&pView); + sqlite3TreeViewPop(pView); } if( p->pWhere ){ sqlite3TreeViewItem(pView, "WHERE", (n--)>0); sqlite3TreeViewExpr(pView, p->pWhere, 0); - sqlite3TreeViewPop(&pView); + sqlite3TreeViewPop(pView); } if( p->pGroupBy ){ sqlite3TreeViewExprList(pView, p->pGroupBy, (n--)>0, "GROUPBY"); } if( p->pHaving ){ sqlite3TreeViewItem(pView, "HAVING", (n--)>0); sqlite3TreeViewExpr(pView, p->pHaving, 0); - sqlite3TreeViewPop(&pView); + sqlite3TreeViewPop(pView); } #ifndef SQLITE_OMIT_WINDOWFUNC if( p->pWinDefn ){ Window *pX; sqlite3TreeViewItem(pView, "WINDOW", (n--)>0); for(pX=p->pWinDefn; pX; pX=pX->pNextWin){ sqlite3TreeViewWindow(pView, pX, pX->pNextWin!=0); } - sqlite3TreeViewPop(&pView); + sqlite3TreeViewPop(pView); } #endif if( p->pOrderBy ){ sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY"); } @@ -31832,13 +31070,13 @@ sqlite3TreeViewItem(pView, "LIMIT", (n--)>0); sqlite3TreeViewExpr(pView, p->pLimit->pLeft, p->pLimit->pRight!=0); if( p->pLimit->pRight ){ sqlite3TreeViewItem(pView, "OFFSET", (n--)>0); sqlite3TreeViewExpr(pView, p->pLimit->pRight, 0); - sqlite3TreeViewPop(&pView); + sqlite3TreeViewPop(pView); } - sqlite3TreeViewPop(&pView); + sqlite3TreeViewPop(pView); } if( p->pPrior ){ const char *zOp = "UNION"; switch( p->op ){ case TK_ALL: zOp = "UNION ALL"; break; @@ -31847,11 +31085,11 @@ } sqlite3TreeViewItem(pView, zOp, 1); } p = p->pPrior; }while( p!=0 ); - sqlite3TreeViewPop(&pView); + sqlite3TreeViewPop(pView); } #ifndef SQLITE_OMIT_WINDOWFUNC /* ** Generate a description of starting or stopping bounds @@ -31863,28 +31101,28 @@ u8 moreToFollow /* True if more to follow */ ){ switch( eBound ){ case TK_UNBOUNDED: { sqlite3TreeViewItem(pView, "UNBOUNDED", moreToFollow); - sqlite3TreeViewPop(&pView); + sqlite3TreeViewPop(pView); break; } case TK_CURRENT: { sqlite3TreeViewItem(pView, "CURRENT", moreToFollow); - sqlite3TreeViewPop(&pView); + sqlite3TreeViewPop(pView); break; } case TK_PRECEDING: { sqlite3TreeViewItem(pView, "PRECEDING", moreToFollow); sqlite3TreeViewExpr(pView, pExpr, 0); - sqlite3TreeViewPop(&pView); + sqlite3TreeViewPop(pView); break; } case TK_FOLLOWING: { sqlite3TreeViewItem(pView, "FOLLOWING", moreToFollow); sqlite3TreeViewExpr(pView, pExpr, 0); - sqlite3TreeViewPop(&pView); + sqlite3TreeViewPop(pView); break; } } } #endif /* SQLITE_OMIT_WINDOWFUNC */ @@ -31893,17 +31131,16 @@ /* ** Generate a human-readable explanation for a Window object */ SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ int nElement = 0; - if( pWin==0 ) return; if( pWin->pFilter ){ sqlite3TreeViewItem(pView, "FILTER", 1); sqlite3TreeViewExpr(pView, pWin->pFilter, 0); - sqlite3TreeViewPop(&pView); + sqlite3TreeViewPop(pView); } - sqlite3TreeViewPush(&pView, more); + pView = sqlite3TreeViewPush(pView, more); if( pWin->zName ){ sqlite3TreeViewLine(pView, "OVER %s (%p)", pWin->zName, pWin); }else{ sqlite3TreeViewLine(pView, "OVER (%p)", pWin); } @@ -31910,13 +31147,13 @@ if( pWin->zBase ) nElement++; if( pWin->pOrderBy ) nElement++; if( pWin->eFrmType ) nElement++; if( pWin->eExclude ) nElement++; if( pWin->zBase ){ - sqlite3TreeViewPush(&pView, (--nElement)>0); + sqlite3TreeViewPush(pView, (--nElement)>0); sqlite3TreeViewLine(pView, "window: %s", pWin->zBase); - sqlite3TreeViewPop(&pView); + sqlite3TreeViewPop(pView); } if( pWin->pPartition ){ sqlite3TreeViewExprList(pView, pWin->pPartition, nElement>0,"PARTITION-BY"); } if( pWin->pOrderBy ){ @@ -31930,11 +31167,11 @@ sqlite3_snprintf(sizeof(zBuf),zBuf,"%s%s",zFrmType, pWin->bImplicitFrame ? " (implied)" : ""); sqlite3TreeViewItem(pView, zBuf, (--nElement)>0); sqlite3TreeViewBound(pView, pWin->eStart, pWin->pStart, 1); sqlite3TreeViewBound(pView, pWin->eEnd, pWin->pEnd, 0); - sqlite3TreeViewPop(&pView); + sqlite3TreeViewPop(pView); } if( pWin->eExclude ){ char zBuf[30]; const char *zExclude; switch( pWin->eExclude ){ @@ -31945,29 +31182,28 @@ default: sqlite3_snprintf(sizeof(zBuf),zBuf,"invalid(%d)", pWin->eExclude); zExclude = zBuf; break; } - sqlite3TreeViewPush(&pView, 0); + sqlite3TreeViewPush(pView, 0); sqlite3TreeViewLine(pView, "EXCLUDE %s", zExclude); - sqlite3TreeViewPop(&pView); + sqlite3TreeViewPop(pView); } - sqlite3TreeViewPop(&pView); + sqlite3TreeViewPop(pView); } #endif /* SQLITE_OMIT_WINDOWFUNC */ #ifndef SQLITE_OMIT_WINDOWFUNC /* ** Generate a human-readable explanation for a Window Function object */ SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){ - if( pWin==0 ) return; - sqlite3TreeViewPush(&pView, more); + pView = sqlite3TreeViewPush(pView, more); sqlite3TreeViewLine(pView, "WINFUNC %s(%d)", - pWin->pWFunc->zName, pWin->pWFunc->nArg); + pWin->pFunc->zName, pWin->pFunc->nArg); sqlite3TreeViewWindow(pView, pWin, 0); - sqlite3TreeViewPop(&pView); + sqlite3TreeViewPop(pView); } #endif /* SQLITE_OMIT_WINDOWFUNC */ /* ** Generate a human-readable explanation of an expression tree. @@ -31974,36 +31210,30 @@ */ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ const char *zBinOp = 0; /* Binary operator */ const char *zUniOp = 0; /* Unary operator */ char zFlgs[200]; - sqlite3TreeViewPush(&pView, moreToFollow); + pView = sqlite3TreeViewPush(pView, moreToFollow); if( pExpr==0 ){ sqlite3TreeViewLine(pView, "nil"); - sqlite3TreeViewPop(&pView); + sqlite3TreeViewPop(pView); return; } - if( pExpr->flags || pExpr->affExpr || pExpr->vvaFlags || pExpr->pAggInfo ){ + if( pExpr->flags || pExpr->affExpr || pExpr->vvaFlags ){ StrAccum x; sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0); sqlite3_str_appendf(&x, " fg.af=%x.%c", pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n'); - if( ExprHasProperty(pExpr, EP_OuterON) ){ - sqlite3_str_appendf(&x, " outer.iJoin=%d", pExpr->w.iJoin); - } - if( ExprHasProperty(pExpr, EP_InnerON) ){ - sqlite3_str_appendf(&x, " inner.iJoin=%d", pExpr->w.iJoin); + if( ExprHasProperty(pExpr, EP_FromJoin) ){ + sqlite3_str_appendf(&x, " iRJT=%d", pExpr->w.iRightJoinTable); } if( ExprHasProperty(pExpr, EP_FromDDL) ){ sqlite3_str_appendf(&x, " DDL"); } if( ExprHasVVAProperty(pExpr, EP_Immutable) ){ sqlite3_str_appendf(&x, " IMMUTABLE"); } - if( pExpr->pAggInfo!=0 ){ - sqlite3_str_appendf(&x, " agg-column[%d]", pExpr->iAgg); - } sqlite3StrAccumFinish(&x); }else{ zFlgs[0] = 0; } switch( pExpr->op ){ @@ -32216,21 +31446,11 @@ sqlite3TreeViewLine(pView, "subquery-expr flags=0x%x", pExpr->flags); sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); break; } case TK_IN: { - sqlite3_str *pStr = sqlite3_str_new(0); - char *z; - sqlite3_str_appendf(pStr, "IN flags=0x%x", pExpr->flags); - if( pExpr->iTable ) sqlite3_str_appendf(pStr, " iTable=%d",pExpr->iTable); - if( ExprHasProperty(pExpr, EP_Subrtn) ){ - sqlite3_str_appendf(pStr, " subrtn(%d,%d)", - pExpr->y.sub.regReturn, pExpr->y.sub.iAddr); - } - z = sqlite3_str_finish(pStr); - sqlite3TreeViewLine(pView, z); - sqlite3_free(z); + sqlite3TreeViewLine(pView, "IN flags=0x%x", pExpr->flags); sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); if( ExprUseXSelect(pExpr) ){ sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); }else{ sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0); @@ -32350,11 +31570,11 @@ sqlite3TreeViewExpr(pView, pExpr->pRight, 0); }else if( zUniOp ){ sqlite3TreeViewLine(pView, "%s%s", zUniOp, zFlgs); sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); } - sqlite3TreeViewPop(&pView); + sqlite3TreeViewPop(pView); } /* ** Generate a human-readable explanation of an expression list. @@ -32372,39 +31592,27 @@ sqlite3TreeViewLine(pView, "%s", zLabel); for(i=0; inExpr; i++){ int j = pList->a[i].u.x.iOrderByCol; char *zName = pList->a[i].zEName; int moreToFollow = inExpr - 1; + if( pList->a[i].eEName!=ENAME_NAME ) zName = 0; if( j || zName ){ - sqlite3TreeViewPush(&pView, moreToFollow); + sqlite3TreeViewPush(pView, moreToFollow); moreToFollow = 0; sqlite3TreeViewLine(pView, 0); if( zName ){ - switch( pList->a[i].fg.eEName ){ - default: - fprintf(stdout, "AS %s ", zName); - break; - case ENAME_TAB: - fprintf(stdout, "TABLE-ALIAS-NAME(\"%s\") ", zName); - if( pList->a[i].fg.bUsed ) fprintf(stdout, "(used) "); - if( pList->a[i].fg.bUsingTerm ) fprintf(stdout, "(USING-term) "); - if( pList->a[i].fg.bNoExpand ) fprintf(stdout, "(NoExpand) "); - break; - case ENAME_SPAN: - fprintf(stdout, "SPAN(\"%s\") ", zName); - break; - } + fprintf(stdout, "AS %s ", zName); } if( j ){ fprintf(stdout, "iOrderByCol=%d", j); } fprintf(stdout, "\n"); fflush(stdout); } sqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow); if( j || zName ){ - sqlite3TreeViewPop(&pView); + sqlite3TreeViewPop(pView); } } } } SQLITE_PRIVATE void sqlite3TreeViewExprList( @@ -32411,381 +31619,14 @@ TreeView *pView, const ExprList *pList, u8 moreToFollow, const char *zLabel ){ - sqlite3TreeViewPush(&pView, moreToFollow); + pView = sqlite3TreeViewPush(pView, moreToFollow); sqlite3TreeViewBareExprList(pView, pList, zLabel); - sqlite3TreeViewPop(&pView); -} - -/* -** Generate a human-readable explanation of an id-list. -*/ -SQLITE_PRIVATE void sqlite3TreeViewBareIdList( - TreeView *pView, - const IdList *pList, - const char *zLabel -){ - if( zLabel==0 || zLabel[0]==0 ) zLabel = "LIST"; - if( pList==0 ){ - sqlite3TreeViewLine(pView, "%s (empty)", zLabel); - }else{ - int i; - sqlite3TreeViewLine(pView, "%s", zLabel); - for(i=0; inId; i++){ - char *zName = pList->a[i].zName; - int moreToFollow = inId - 1; - if( zName==0 ) zName = "(null)"; - sqlite3TreeViewPush(&pView, moreToFollow); - sqlite3TreeViewLine(pView, 0); - if( pList->eU4==EU4_NONE ){ - fprintf(stdout, "%s\n", zName); - }else if( pList->eU4==EU4_IDX ){ - fprintf(stdout, "%s (%d)\n", zName, pList->a[i].u4.idx); - }else{ - assert( pList->eU4==EU4_EXPR ); - if( pList->a[i].u4.pExpr==0 ){ - fprintf(stdout, "%s (pExpr=NULL)\n", zName); - }else{ - fprintf(stdout, "%s\n", zName); - sqlite3TreeViewPush(&pView, inId-1); - sqlite3TreeViewExpr(pView, pList->a[i].u4.pExpr, 0); - sqlite3TreeViewPop(&pView); - } - } - sqlite3TreeViewPop(&pView); - } - } -} -SQLITE_PRIVATE void sqlite3TreeViewIdList( - TreeView *pView, - const IdList *pList, - u8 moreToFollow, - const char *zLabel -){ - sqlite3TreeViewPush(&pView, moreToFollow); - sqlite3TreeViewBareIdList(pView, pList, zLabel); - sqlite3TreeViewPop(&pView); -} - -/* -** Generate a human-readable explanation of a list of Upsert objects -*/ -SQLITE_PRIVATE void sqlite3TreeViewUpsert( - TreeView *pView, - const Upsert *pUpsert, - u8 moreToFollow -){ - if( pUpsert==0 ) return; - sqlite3TreeViewPush(&pView, moreToFollow); - while( pUpsert ){ - int n; - sqlite3TreeViewPush(&pView, pUpsert->pNextUpsert!=0 || moreToFollow); - sqlite3TreeViewLine(pView, "ON CONFLICT DO %s", - pUpsert->isDoUpdate ? "UPDATE" : "NOTHING"); - n = (pUpsert->pUpsertSet!=0) + (pUpsert->pUpsertWhere!=0); - sqlite3TreeViewExprList(pView, pUpsert->pUpsertTarget, (n--)>0, "TARGET"); - sqlite3TreeViewExprList(pView, pUpsert->pUpsertSet, (n--)>0, "SET"); - if( pUpsert->pUpsertWhere ){ - sqlite3TreeViewItem(pView, "WHERE", (n--)>0); - sqlite3TreeViewExpr(pView, pUpsert->pUpsertWhere, 0); - sqlite3TreeViewPop(&pView); - } - sqlite3TreeViewPop(&pView); - pUpsert = pUpsert->pNextUpsert; - } - sqlite3TreeViewPop(&pView); -} - -#if TREETRACE_ENABLED -/* -** Generate a human-readable diagram of the data structure that go -** into generating an DELETE statement. -*/ -SQLITE_PRIVATE void sqlite3TreeViewDelete( - const With *pWith, - const SrcList *pTabList, - const Expr *pWhere, - const ExprList *pOrderBy, - const Expr *pLimit, - const Trigger *pTrigger -){ - int n = 0; - TreeView *pView = 0; - sqlite3TreeViewPush(&pView, 0); - sqlite3TreeViewLine(pView, "DELETE"); - if( pWith ) n++; - if( pTabList ) n++; - if( pWhere ) n++; - if( pOrderBy ) n++; - if( pLimit ) n++; - if( pTrigger ) n++; - if( pWith ){ - sqlite3TreeViewPush(&pView, (--n)>0); - sqlite3TreeViewWith(pView, pWith, 0); - sqlite3TreeViewPop(&pView); - } - if( pTabList ){ - sqlite3TreeViewPush(&pView, (--n)>0); - sqlite3TreeViewLine(pView, "FROM"); - sqlite3TreeViewSrcList(pView, pTabList); - sqlite3TreeViewPop(&pView); - } - if( pWhere ){ - sqlite3TreeViewPush(&pView, (--n)>0); - sqlite3TreeViewLine(pView, "WHERE"); - sqlite3TreeViewExpr(pView, pWhere, 0); - sqlite3TreeViewPop(&pView); - } - if( pOrderBy ){ - sqlite3TreeViewExprList(pView, pOrderBy, (--n)>0, "ORDER-BY"); - } - if( pLimit ){ - sqlite3TreeViewPush(&pView, (--n)>0); - sqlite3TreeViewLine(pView, "LIMIT"); - sqlite3TreeViewExpr(pView, pLimit, 0); - sqlite3TreeViewPop(&pView); - } - if( pTrigger ){ - sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1); - } - sqlite3TreeViewPop(&pView); -} -#endif /* TREETRACE_ENABLED */ - -#if TREETRACE_ENABLED -/* -** Generate a human-readable diagram of the data structure that go -** into generating an INSERT statement. -*/ -SQLITE_PRIVATE void sqlite3TreeViewInsert( - const With *pWith, - const SrcList *pTabList, - const IdList *pColumnList, - const Select *pSelect, - const ExprList *pExprList, - int onError, - const Upsert *pUpsert, - const Trigger *pTrigger -){ - TreeView *pView = 0; - int n = 0; - const char *zLabel = "INSERT"; - switch( onError ){ - case OE_Replace: zLabel = "REPLACE"; break; - case OE_Ignore: zLabel = "INSERT OR IGNORE"; break; - case OE_Rollback: zLabel = "INSERT OR ROLLBACK"; break; - case OE_Abort: zLabel = "INSERT OR ABORT"; break; - case OE_Fail: zLabel = "INSERT OR FAIL"; break; - } - sqlite3TreeViewPush(&pView, 0); - sqlite3TreeViewLine(pView, zLabel); - if( pWith ) n++; - if( pTabList ) n++; - if( pColumnList ) n++; - if( pSelect ) n++; - if( pExprList ) n++; - if( pUpsert ) n++; - if( pTrigger ) n++; - if( pWith ){ - sqlite3TreeViewPush(&pView, (--n)>0); - sqlite3TreeViewWith(pView, pWith, 0); - sqlite3TreeViewPop(&pView); - } - if( pTabList ){ - sqlite3TreeViewPush(&pView, (--n)>0); - sqlite3TreeViewLine(pView, "INTO"); - sqlite3TreeViewSrcList(pView, pTabList); - sqlite3TreeViewPop(&pView); - } - if( pColumnList ){ - sqlite3TreeViewIdList(pView, pColumnList, (--n)>0, "COLUMNS"); - } - if( pSelect ){ - sqlite3TreeViewPush(&pView, (--n)>0); - sqlite3TreeViewLine(pView, "DATA-SOURCE"); - sqlite3TreeViewSelect(pView, pSelect, 0); - sqlite3TreeViewPop(&pView); - } - if( pExprList ){ - sqlite3TreeViewExprList(pView, pExprList, (--n)>0, "VALUES"); - } - if( pUpsert ){ - sqlite3TreeViewPush(&pView, (--n)>0); - sqlite3TreeViewLine(pView, "UPSERT"); - sqlite3TreeViewUpsert(pView, pUpsert, 0); - sqlite3TreeViewPop(&pView); - } - if( pTrigger ){ - sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1); - } - sqlite3TreeViewPop(&pView); -} -#endif /* TREETRACE_ENABLED */ - -#if TREETRACE_ENABLED -/* -** Generate a human-readable diagram of the data structure that go -** into generating an UPDATE statement. -*/ -SQLITE_PRIVATE void sqlite3TreeViewUpdate( - const With *pWith, - const SrcList *pTabList, - const ExprList *pChanges, - const Expr *pWhere, - int onError, - const ExprList *pOrderBy, - const Expr *pLimit, - const Upsert *pUpsert, - const Trigger *pTrigger -){ - int n = 0; - TreeView *pView = 0; - const char *zLabel = "UPDATE"; - switch( onError ){ - case OE_Replace: zLabel = "UPDATE OR REPLACE"; break; - case OE_Ignore: zLabel = "UPDATE OR IGNORE"; break; - case OE_Rollback: zLabel = "UPDATE OR ROLLBACK"; break; - case OE_Abort: zLabel = "UPDATE OR ABORT"; break; - case OE_Fail: zLabel = "UPDATE OR FAIL"; break; - } - sqlite3TreeViewPush(&pView, 0); - sqlite3TreeViewLine(pView, zLabel); - if( pWith ) n++; - if( pTabList ) n++; - if( pChanges ) n++; - if( pWhere ) n++; - if( pOrderBy ) n++; - if( pLimit ) n++; - if( pUpsert ) n++; - if( pTrigger ) n++; - if( pWith ){ - sqlite3TreeViewPush(&pView, (--n)>0); - sqlite3TreeViewWith(pView, pWith, 0); - sqlite3TreeViewPop(&pView); - } - if( pTabList ){ - sqlite3TreeViewPush(&pView, (--n)>0); - sqlite3TreeViewLine(pView, "FROM"); - sqlite3TreeViewSrcList(pView, pTabList); - sqlite3TreeViewPop(&pView); - } - if( pChanges ){ - sqlite3TreeViewExprList(pView, pChanges, (--n)>0, "SET"); - } - if( pWhere ){ - sqlite3TreeViewPush(&pView, (--n)>0); - sqlite3TreeViewLine(pView, "WHERE"); - sqlite3TreeViewExpr(pView, pWhere, 0); - sqlite3TreeViewPop(&pView); - } - if( pOrderBy ){ - sqlite3TreeViewExprList(pView, pOrderBy, (--n)>0, "ORDER-BY"); - } - if( pLimit ){ - sqlite3TreeViewPush(&pView, (--n)>0); - sqlite3TreeViewLine(pView, "LIMIT"); - sqlite3TreeViewExpr(pView, pLimit, 0); - sqlite3TreeViewPop(&pView); - } - if( pUpsert ){ - sqlite3TreeViewPush(&pView, (--n)>0); - sqlite3TreeViewLine(pView, "UPSERT"); - sqlite3TreeViewUpsert(pView, pUpsert, 0); - sqlite3TreeViewPop(&pView); - } - if( pTrigger ){ - sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1); - } - sqlite3TreeViewPop(&pView); -} -#endif /* TREETRACE_ENABLED */ - -#ifndef SQLITE_OMIT_TRIGGER -/* -** Show a human-readable graph of a TriggerStep -*/ -SQLITE_PRIVATE void sqlite3TreeViewTriggerStep( - TreeView *pView, - const TriggerStep *pStep, - u8 moreToFollow, - u8 showFullList -){ - int cnt = 0; - if( pStep==0 ) return; - sqlite3TreeViewPush(&pView, - moreToFollow || (showFullList && pStep->pNext!=0)); - do{ - if( cnt++ && pStep->pNext==0 ){ - sqlite3TreeViewPop(&pView); - sqlite3TreeViewPush(&pView, 0); - } - sqlite3TreeViewLine(pView, "%s", pStep->zSpan ? pStep->zSpan : "RETURNING"); - }while( showFullList && (pStep = pStep->pNext)!=0 ); - sqlite3TreeViewPop(&pView); -} - -/* -** Show a human-readable graph of a Trigger -*/ -SQLITE_PRIVATE void sqlite3TreeViewTrigger( - TreeView *pView, - const Trigger *pTrigger, - u8 moreToFollow, - u8 showFullList -){ - int cnt = 0; - if( pTrigger==0 ) return; - sqlite3TreeViewPush(&pView, - moreToFollow || (showFullList && pTrigger->pNext!=0)); - do{ - if( cnt++ && pTrigger->pNext==0 ){ - sqlite3TreeViewPop(&pView); - sqlite3TreeViewPush(&pView, 0); - } - sqlite3TreeViewLine(pView, "TRIGGER %s", pTrigger->zName); - sqlite3TreeViewPush(&pView, 0); - sqlite3TreeViewTriggerStep(pView, pTrigger->step_list, 0, 1); - sqlite3TreeViewPop(&pView); - }while( showFullList && (pTrigger = pTrigger->pNext)!=0 ); - sqlite3TreeViewPop(&pView); -} -#endif /* SQLITE_OMIT_TRIGGER */ - - -/* -** These simplified versions of the tree-view routines omit unnecessary -** parameters. These variants are intended to be used from a symbolic -** debugger, such as "gdb", during interactive debugging sessions. -** -** This routines are given external linkage so that they will always be -** accessible to the debugging, and to avoid warnings about unused -** functions. But these routines only exist in debugging builds, so they -** do not contaminate the interface. -*/ -SQLITE_PRIVATE void sqlite3ShowExpr(const Expr *p){ sqlite3TreeViewExpr(0,p,0); } -SQLITE_PRIVATE void sqlite3ShowExprList(const ExprList *p){ sqlite3TreeViewExprList(0,p,0,0);} -SQLITE_PRIVATE void sqlite3ShowIdList(const IdList *p){ sqlite3TreeViewIdList(0,p,0,0); } -SQLITE_PRIVATE void sqlite3ShowSrcList(const SrcList *p){ sqlite3TreeViewSrcList(0,p); } -SQLITE_PRIVATE void sqlite3ShowSelect(const Select *p){ sqlite3TreeViewSelect(0,p,0); } -SQLITE_PRIVATE void sqlite3ShowWith(const With *p){ sqlite3TreeViewWith(0,p,0); } -SQLITE_PRIVATE void sqlite3ShowUpsert(const Upsert *p){ sqlite3TreeViewUpsert(0,p,0); } -#ifndef SQLITE_OMIT_TRIGGER -SQLITE_PRIVATE void sqlite3ShowTriggerStep(const TriggerStep *p){ - sqlite3TreeViewTriggerStep(0,p,0,0); -} -SQLITE_PRIVATE void sqlite3ShowTriggerStepList(const TriggerStep *p){ - sqlite3TreeViewTriggerStep(0,p,0,1); -} -SQLITE_PRIVATE void sqlite3ShowTrigger(const Trigger *p){ sqlite3TreeViewTrigger(0,p,0,0); } -SQLITE_PRIVATE void sqlite3ShowTriggerList(const Trigger *p){ sqlite3TreeViewTrigger(0,p,0,1);} -#endif -#ifndef SQLITE_OMIT_WINDOWFUNC -SQLITE_PRIVATE void sqlite3ShowWindow(const Window *p){ sqlite3TreeViewWindow(0,p,0); } -SQLITE_PRIVATE void sqlite3ShowWinFunc(const Window *p){ sqlite3TreeViewWinFunc(0,p,0); } -#endif + sqlite3TreeViewPop(pView); +} #endif /* SQLITE_DEBUG */ /************** End of treeview.c ********************************************/ /************** Begin file random.c ******************************************/ @@ -32811,45 +31652,20 @@ /* All threads share a single random number generator. ** This structure is the current state of the generator. */ static SQLITE_WSD struct sqlite3PrngType { - u32 s[16]; /* 64 bytes of chacha20 state */ - u8 out[64]; /* Output bytes */ - u8 n; /* Output bytes remaining */ + unsigned char isInit; /* True if initialized */ + unsigned char i, j; /* State variables */ + unsigned char s[256]; /* State variables */ } sqlite3Prng; - -/* The RFC-7539 ChaCha20 block function -*/ -#define ROTL(a,b) (((a) << (b)) | ((a) >> (32 - (b)))) -#define QR(a, b, c, d) ( \ - a += b, d ^= a, d = ROTL(d,16), \ - c += d, b ^= c, b = ROTL(b,12), \ - a += b, d ^= a, d = ROTL(d, 8), \ - c += d, b ^= c, b = ROTL(b, 7)) -static void chacha_block(u32 *out, const u32 *in){ - int i; - u32 x[16]; - memcpy(x, in, 64); - for(i=0; i<10; i++){ - QR(x[0], x[4], x[ 8], x[12]); - QR(x[1], x[5], x[ 9], x[13]); - QR(x[2], x[6], x[10], x[14]); - QR(x[3], x[7], x[11], x[15]); - QR(x[0], x[5], x[10], x[15]); - QR(x[1], x[6], x[11], x[12]); - QR(x[2], x[7], x[ 8], x[13]); - QR(x[3], x[4], x[ 9], x[14]); - } - for(i=0; i<16; i++) out[i] = x[i]+in[i]; -} - /* ** Return N random bytes. */ SQLITE_API void sqlite3_randomness(int N, void *pBuf){ + unsigned char t; unsigned char *zBuf = pBuf; /* The "wsdPrng" macro will resolve to the pseudo-random number generator ** state vector. If writable static data is unsupported on the target, ** we have to locate the state vector at run-time. In the more common @@ -32875,50 +31691,57 @@ mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG); #endif sqlite3_mutex_enter(mutex); if( N<=0 || pBuf==0 ){ - wsdPrng.s[0] = 0; + wsdPrng.isInit = 0; sqlite3_mutex_leave(mutex); return; } /* Initialize the state of the random number generator once, - ** the first time this routine is called. + ** the first time this routine is called. The seed value does + ** not need to contain a lot of randomness since we are not + ** trying to do secure encryption or anything like that... + ** + ** Nothing in this file or anywhere else in SQLite does any kind of + ** encryption. The RC4 algorithm is being used as a PRNG (pseudo-random + ** number generator) not as an encryption device. */ - if( wsdPrng.s[0]==0 ){ + if( !wsdPrng.isInit ){ sqlite3_vfs *pVfs = sqlite3_vfs_find(0); - static const u32 chacha20_init[] = { - 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 - }; - memcpy(&wsdPrng.s[0], chacha20_init, 16); + int i; + char k[256]; + wsdPrng.j = 0; + wsdPrng.i = 0; if( NEVER(pVfs==0) ){ - memset(&wsdPrng.s[4], 0, 44); + memset(k, 0, sizeof(k)); }else{ - sqlite3OsRandomness(pVfs, 44, (char*)&wsdPrng.s[4]); + sqlite3OsRandomness(pVfs, 256, k); } - wsdPrng.s[15] = wsdPrng.s[12]; - wsdPrng.s[12] = 0; - wsdPrng.n = 0; + for(i=0; i<256; i++){ + wsdPrng.s[i] = (u8)i; + } + for(i=0; i<256; i++){ + wsdPrng.j += wsdPrng.s[i] + k[i]; + t = wsdPrng.s[wsdPrng.j]; + wsdPrng.s[wsdPrng.j] = wsdPrng.s[i]; + wsdPrng.s[i] = t; + } + wsdPrng.isInit = 1; } assert( N>0 ); - while( 1 /* exit by break */ ){ - if( N<=wsdPrng.n ){ - memcpy(zBuf, &wsdPrng.out[wsdPrng.n-N], N); - wsdPrng.n -= N; - break; - } - if( wsdPrng.n>0 ){ - memcpy(zBuf, wsdPrng.out, wsdPrng.n); - N -= wsdPrng.n; - zBuf += wsdPrng.n; - } - wsdPrng.s[12]++; - chacha_block((u32*)wsdPrng.out, wsdPrng.s); - wsdPrng.n = 64; - } + do{ + wsdPrng.i++; + t = wsdPrng.s[wsdPrng.i]; + wsdPrng.j += t; + wsdPrng.s[wsdPrng.i] = wsdPrng.s[wsdPrng.j]; + wsdPrng.s[wsdPrng.j] = t; + t += wsdPrng.s[wsdPrng.i]; + *(zBuf++) = wsdPrng.s[t]; + }while( --N ); sqlite3_mutex_leave(mutex); } #ifndef SQLITE_UNTESTABLE /* @@ -33939,30 +32762,10 @@ va_end(ap); sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, SQLITE_DYNAMIC); } } -/* -** Check for interrupts and invoke progress callback. -*/ -SQLITE_PRIVATE void sqlite3ProgressCheck(Parse *p){ - sqlite3 *db = p->db; - if( AtomicLoad(&db->u1.isInterrupted) ){ - p->nErr++; - p->rc = SQLITE_INTERRUPT; - } -#ifndef SQLITE_OMIT_PROGRESS_CALLBACK - if( db->xProgress && (++p->nProgressSteps)>=db->nProgressOps ){ - if( db->xProgress(db->pProgressArg) ){ - p->nErr++; - p->rc = SQLITE_INTERRUPT; - } - p->nProgressSteps = 0; - } -#endif -} - /* ** Add an error message to pParse->zErrMsg and increment pParse->nErr. ** ** This function should be used to report any error that occurs while ** compiling an SQL statement (i.e. within sqlite3_prepare()). The @@ -33974,11 +32777,11 @@ SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){ char *zMsg; va_list ap; sqlite3 *db = pParse->db; assert( db!=0 ); - assert( db->pParse==pParse || db->pParse->pToplevel==pParse ); + assert( db->pParse==pParse ); db->errByteOffset = -2; va_start(ap, zFormat); zMsg = sqlite3VMPrintf(db, zFormat, ap); va_end(ap); if( db->errByteOffset<-1 ) db->errByteOffset = -1; @@ -34416,18 +33219,15 @@ #if defined(_MSC_VER) #pragma warning(default : 4756) #endif /* -** Render an signed 64-bit integer as text. Store the result in zOut[] and -** return the length of the string that was stored, in bytes. The value -** returned does not include the zero terminator at the end of the output -** string. +** Render an signed 64-bit integer as text. Store the result in zOut[]. ** ** The caller must ensure that zOut[] is at least 21 bytes in size. */ -SQLITE_PRIVATE int sqlite3Int64ToText(i64 v, char *zOut){ +SQLITE_PRIVATE void sqlite3Int64ToText(i64 v, char *zOut){ int i; u64 x; char zTemp[22]; if( v<0 ){ x = (v==SMALLEST_INT64) ? ((u64)1)<<63 : (u64)-v; @@ -34434,19 +33234,16 @@ }else{ x = v; } i = sizeof(zTemp)-2; zTemp[sizeof(zTemp)-1] = 0; - while( 1 /*exit-by-break*/ ){ - zTemp[i] = (x%10) + '0'; + do{ + zTemp[i--] = (x%10) + '0'; x = x/10; - if( x==0 ) break; - i--; - }; - if( v<0 ) zTemp[--i] = '-'; - memcpy(zOut, &zTemp[i], sizeof(zTemp)-i); - return sizeof(zTemp)-1-i; + }while( x ); + if( v<0 ) zTemp[i--] = '-'; + memcpy(zOut, &zTemp[i+1], sizeof(zTemp)-1-i); } /* ** Compare the 19-character string zNum against the text representation ** value 2^63: 9223372036854775808. Return negative, zero, or positive @@ -35504,108 +34301,10 @@ i += pIn[i+1]; }while( ifirst; count = pH->count; } if( pHash ) *pHash = h; - while( count ){ + while( count-- ){ assert( elem!=0 ); if( sqlite3StrICmp(elem->pKey,pKey)==0 ){ return elem; } elem = elem->next; - count--; } return &nullElement; } /* Remove a single entry from the hash table given a pointer to that @@ -35892,109 +34590,109 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ static const char *const azName[] = { /* 0 */ "Savepoint" OpHelp(""), /* 1 */ "AutoCommit" OpHelp(""), /* 2 */ "Transaction" OpHelp(""), - /* 3 */ "Checkpoint" OpHelp(""), - /* 4 */ "JournalMode" OpHelp(""), - /* 5 */ "Vacuum" OpHelp(""), - /* 6 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"), - /* 7 */ "VUpdate" OpHelp("data=r[P3@P2]"), - /* 8 */ "Init" OpHelp("Start at P2"), - /* 9 */ "Goto" OpHelp(""), - /* 10 */ "Gosub" OpHelp(""), - /* 11 */ "InitCoroutine" OpHelp(""), - /* 12 */ "Yield" OpHelp(""), - /* 13 */ "MustBeInt" OpHelp(""), - /* 14 */ "Jump" OpHelp(""), - /* 15 */ "Once" OpHelp(""), - /* 16 */ "If" OpHelp(""), - /* 17 */ "IfNot" OpHelp(""), - /* 18 */ "IsType" OpHelp("if typeof(P1.P3) in P5 goto P2"), + /* 3 */ "SorterNext" OpHelp(""), + /* 4 */ "Prev" OpHelp(""), + /* 5 */ "Next" OpHelp(""), + /* 6 */ "Checkpoint" OpHelp(""), + /* 7 */ "JournalMode" OpHelp(""), + /* 8 */ "Vacuum" OpHelp(""), + /* 9 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"), + /* 10 */ "VUpdate" OpHelp("data=r[P3@P2]"), + /* 11 */ "Goto" OpHelp(""), + /* 12 */ "Gosub" OpHelp(""), + /* 13 */ "InitCoroutine" OpHelp(""), + /* 14 */ "Yield" OpHelp(""), + /* 15 */ "MustBeInt" OpHelp(""), + /* 16 */ "Jump" OpHelp(""), + /* 17 */ "Once" OpHelp(""), + /* 18 */ "If" OpHelp(""), /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"), - /* 20 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"), - /* 21 */ "SeekLT" OpHelp("key=r[P3@P4]"), - /* 22 */ "SeekLE" OpHelp("key=r[P3@P4]"), - /* 23 */ "SeekGE" OpHelp("key=r[P3@P4]"), - /* 24 */ "SeekGT" OpHelp("key=r[P3@P4]"), - /* 25 */ "IfNotOpen" OpHelp("if( !csr[P1] ) goto P2"), - /* 26 */ "IfNoHope" OpHelp("key=r[P3@P4]"), - /* 27 */ "NoConflict" OpHelp("key=r[P3@P4]"), - /* 28 */ "NotFound" OpHelp("key=r[P3@P4]"), - /* 29 */ "Found" OpHelp("key=r[P3@P4]"), - /* 30 */ "SeekRowid" OpHelp("intkey=r[P3]"), - /* 31 */ "NotExists" OpHelp("intkey=r[P3]"), - /* 32 */ "Last" OpHelp(""), - /* 33 */ "IfSmaller" OpHelp(""), - /* 34 */ "SorterSort" OpHelp(""), - /* 35 */ "Sort" OpHelp(""), - /* 36 */ "Rewind" OpHelp(""), - /* 37 */ "SorterNext" OpHelp(""), - /* 38 */ "Prev" OpHelp(""), - /* 39 */ "Next" OpHelp(""), - /* 40 */ "IdxLE" OpHelp("key=r[P3@P4]"), - /* 41 */ "IdxGT" OpHelp("key=r[P3@P4]"), - /* 42 */ "IdxLT" OpHelp("key=r[P3@P4]"), + /* 20 */ "IfNot" OpHelp(""), + /* 21 */ "IsNullOrType" OpHelp("if typeof(r[P1]) IN (P3,5) goto P2"), + /* 22 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"), + /* 23 */ "SeekLT" OpHelp("key=r[P3@P4]"), + /* 24 */ "SeekLE" OpHelp("key=r[P3@P4]"), + /* 25 */ "SeekGE" OpHelp("key=r[P3@P4]"), + /* 26 */ "SeekGT" OpHelp("key=r[P3@P4]"), + /* 27 */ "IfNotOpen" OpHelp("if( !csr[P1] ) goto P2"), + /* 28 */ "IfNoHope" OpHelp("key=r[P3@P4]"), + /* 29 */ "NoConflict" OpHelp("key=r[P3@P4]"), + /* 30 */ "NotFound" OpHelp("key=r[P3@P4]"), + /* 31 */ "Found" OpHelp("key=r[P3@P4]"), + /* 32 */ "SeekRowid" OpHelp("intkey=r[P3]"), + /* 33 */ "NotExists" OpHelp("intkey=r[P3]"), + /* 34 */ "Last" OpHelp(""), + /* 35 */ "IfSmaller" OpHelp(""), + /* 36 */ "SorterSort" OpHelp(""), + /* 37 */ "Sort" OpHelp(""), + /* 38 */ "Rewind" OpHelp(""), + /* 39 */ "IdxLE" OpHelp("key=r[P3@P4]"), + /* 40 */ "IdxGT" OpHelp("key=r[P3@P4]"), + /* 41 */ "IdxLT" OpHelp("key=r[P3@P4]"), + /* 42 */ "IdxGE" OpHelp("key=r[P3@P4]"), /* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), /* 44 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), - /* 45 */ "IdxGE" OpHelp("key=r[P3@P4]"), - /* 46 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), - /* 47 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), - /* 48 */ "Program" OpHelp(""), - /* 49 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), + /* 45 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), + /* 46 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), + /* 47 */ "Program" OpHelp(""), + /* 48 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), + /* 49 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), /* 50 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), /* 51 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), /* 52 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), /* 53 */ "Eq" OpHelp("IF r[P3]==r[P1]"), /* 54 */ "Gt" OpHelp("IF r[P3]>r[P1]"), /* 55 */ "Le" OpHelp("IF r[P3]<=r[P1]"), /* 56 */ "Lt" OpHelp("IF r[P3]=r[P1]"), /* 58 */ "ElseEq" OpHelp(""), - /* 59 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), - /* 60 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), - /* 61 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), - /* 62 */ "IncrVacuum" OpHelp(""), - /* 63 */ "VNext" OpHelp(""), - /* 64 */ "Filter" OpHelp("if key(P3@P4) not in filter(P1) goto P2"), + /* 59 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), + /* 60 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), + /* 61 */ "IncrVacuum" OpHelp(""), + /* 62 */ "VNext" OpHelp(""), + /* 63 */ "Filter" OpHelp("if key(P3@P4) not in filter(P1) goto P2"), + /* 64 */ "Init" OpHelp("Start at P2"), /* 65 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"), /* 66 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"), /* 67 */ "Return" OpHelp(""), /* 68 */ "EndCoroutine" OpHelp(""), /* 69 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), /* 70 */ "Halt" OpHelp(""), /* 71 */ "Integer" OpHelp("r[P2]=P1"), /* 72 */ "Int64" OpHelp("r[P2]=P4"), /* 73 */ "String" OpHelp("r[P2]='P4' (len=P1)"), - /* 74 */ "BeginSubrtn" OpHelp("r[P2]=NULL"), - /* 75 */ "Null" OpHelp("r[P2..P3]=NULL"), - /* 76 */ "SoftNull" OpHelp("r[P1]=NULL"), - /* 77 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), - /* 78 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"), - /* 79 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), - /* 80 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), - /* 81 */ "SCopy" OpHelp("r[P2]=r[P1]"), - /* 82 */ "IntCopy" OpHelp("r[P2]=r[P1]"), - /* 83 */ "FkCheck" OpHelp(""), - /* 84 */ "ResultRow" OpHelp("output=r[P1@P2]"), - /* 85 */ "CollSeq" OpHelp(""), - /* 86 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), - /* 87 */ "RealAffinity" OpHelp(""), - /* 88 */ "Cast" OpHelp("affinity(r[P1])"), - /* 89 */ "Permutation" OpHelp(""), - /* 90 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), - /* 91 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"), - /* 92 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"), - /* 93 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"), - /* 94 */ "Column" OpHelp("r[P3]=PX cursor P1 column P2"), - /* 95 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"), - /* 96 */ "Affinity" OpHelp("affinity(r[P1@P2])"), - /* 97 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), - /* 98 */ "Count" OpHelp("r[P2]=count()"), - /* 99 */ "ReadCookie" OpHelp(""), - /* 100 */ "SetCookie" OpHelp(""), - /* 101 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), + /* 74 */ "Null" OpHelp("r[P2..P3]=NULL"), + /* 75 */ "SoftNull" OpHelp("r[P1]=NULL"), + /* 76 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), + /* 77 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"), + /* 78 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), + /* 79 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), + /* 80 */ "SCopy" OpHelp("r[P2]=r[P1]"), + /* 81 */ "IntCopy" OpHelp("r[P2]=r[P1]"), + /* 82 */ "FkCheck" OpHelp(""), + /* 83 */ "ResultRow" OpHelp("output=r[P1@P2]"), + /* 84 */ "CollSeq" OpHelp(""), + /* 85 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), + /* 86 */ "RealAffinity" OpHelp(""), + /* 87 */ "Cast" OpHelp("affinity(r[P1])"), + /* 88 */ "Permutation" OpHelp(""), + /* 89 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), + /* 90 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"), + /* 91 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"), + /* 92 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"), + /* 93 */ "Column" OpHelp("r[P3]=PX"), + /* 94 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"), + /* 95 */ "Affinity" OpHelp("affinity(r[P1@P2])"), + /* 96 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), + /* 97 */ "Count" OpHelp("r[P2]=count()"), + /* 98 */ "ReadCookie" OpHelp(""), + /* 99 */ "SetCookie" OpHelp(""), + /* 100 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), + /* 101 */ "OpenRead" OpHelp("root=P2 iDb=P3"), /* 102 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), /* 103 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), /* 104 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"), /* 106 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), @@ -36001,1073 +34699,89 @@ /* 107 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), /* 108 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), /* 109 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), /* 110 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), /* 111 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), - /* 112 */ "OpenRead" OpHelp("root=P2 iDb=P3"), - /* 113 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), + /* 112 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), + /* 113 */ "OpenDup" OpHelp(""), /* 114 */ "BitNot" OpHelp("r[P2]= ~r[P1]"), - /* 115 */ "OpenDup" OpHelp(""), - /* 116 */ "OpenAutoindex" OpHelp("nColumn=P2"), + /* 115 */ "OpenAutoindex" OpHelp("nColumn=P2"), + /* 116 */ "OpenEphemeral" OpHelp("nColumn=P2"), /* 117 */ "String8" OpHelp("r[P2]='P4'"), - /* 118 */ "OpenEphemeral" OpHelp("nColumn=P2"), - /* 119 */ "SorterOpen" OpHelp(""), - /* 120 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), - /* 121 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), - /* 122 */ "Close" OpHelp(""), - /* 123 */ "ColumnsUsed" OpHelp(""), - /* 124 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"), - /* 125 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"), - /* 126 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), - /* 127 */ "NewRowid" OpHelp("r[P2]=rowid"), - /* 128 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), - /* 129 */ "RowCell" OpHelp(""), - /* 130 */ "Delete" OpHelp(""), - /* 131 */ "ResetCount" OpHelp(""), - /* 132 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), - /* 133 */ "SorterData" OpHelp("r[P2]=data"), - /* 134 */ "RowData" OpHelp("r[P2]=data"), - /* 135 */ "Rowid" OpHelp("r[P2]=PX rowid of P1"), - /* 136 */ "NullRow" OpHelp(""), - /* 137 */ "SeekEnd" OpHelp(""), - /* 138 */ "IdxInsert" OpHelp("key=r[P2]"), - /* 139 */ "SorterInsert" OpHelp("key=r[P2]"), - /* 140 */ "IdxDelete" OpHelp("key=r[P2@P3]"), - /* 141 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"), - /* 142 */ "IdxRowid" OpHelp("r[P2]=rowid"), - /* 143 */ "FinishSeek" OpHelp(""), - /* 144 */ "Destroy" OpHelp(""), - /* 145 */ "Clear" OpHelp(""), - /* 146 */ "ResetSorter" OpHelp(""), - /* 147 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"), - /* 148 */ "SqlExec" OpHelp(""), - /* 149 */ "ParseSchema" OpHelp(""), - /* 150 */ "LoadAnalysis" OpHelp(""), - /* 151 */ "DropTable" OpHelp(""), - /* 152 */ "DropIndex" OpHelp(""), + /* 118 */ "SorterOpen" OpHelp(""), + /* 119 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), + /* 120 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), + /* 121 */ "Close" OpHelp(""), + /* 122 */ "ColumnsUsed" OpHelp(""), + /* 123 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"), + /* 124 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"), + /* 125 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), + /* 126 */ "NewRowid" OpHelp("r[P2]=rowid"), + /* 127 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), + /* 128 */ "RowCell" OpHelp(""), + /* 129 */ "Delete" OpHelp(""), + /* 130 */ "ResetCount" OpHelp(""), + /* 131 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), + /* 132 */ "SorterData" OpHelp("r[P2]=data"), + /* 133 */ "RowData" OpHelp("r[P2]=data"), + /* 134 */ "Rowid" OpHelp("r[P2]=rowid"), + /* 135 */ "NullRow" OpHelp(""), + /* 136 */ "SeekEnd" OpHelp(""), + /* 137 */ "IdxInsert" OpHelp("key=r[P2]"), + /* 138 */ "SorterInsert" OpHelp("key=r[P2]"), + /* 139 */ "IdxDelete" OpHelp("key=r[P2@P3]"), + /* 140 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"), + /* 141 */ "IdxRowid" OpHelp("r[P2]=rowid"), + /* 142 */ "FinishSeek" OpHelp(""), + /* 143 */ "Destroy" OpHelp(""), + /* 144 */ "Clear" OpHelp(""), + /* 145 */ "ResetSorter" OpHelp(""), + /* 146 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"), + /* 147 */ "SqlExec" OpHelp(""), + /* 148 */ "ParseSchema" OpHelp(""), + /* 149 */ "LoadAnalysis" OpHelp(""), + /* 150 */ "DropTable" OpHelp(""), + /* 151 */ "DropIndex" OpHelp(""), + /* 152 */ "DropTrigger" OpHelp(""), /* 153 */ "Real" OpHelp("r[P2]=P4"), - /* 154 */ "DropTrigger" OpHelp(""), - /* 155 */ "IntegrityCk" OpHelp(""), - /* 156 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), - /* 157 */ "Param" OpHelp(""), - /* 158 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), - /* 159 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), - /* 160 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), - /* 161 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), - /* 162 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), - /* 163 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"), - /* 164 */ "AggValue" OpHelp("r[P3]=value N=P2"), - /* 165 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), - /* 166 */ "Expire" OpHelp(""), - /* 167 */ "CursorLock" OpHelp(""), - /* 168 */ "CursorUnlock" OpHelp(""), - /* 169 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), - /* 170 */ "VBegin" OpHelp(""), - /* 171 */ "VCreate" OpHelp(""), - /* 172 */ "VDestroy" OpHelp(""), - /* 173 */ "VOpen" OpHelp(""), - /* 174 */ "VInitIn" OpHelp("r[P2]=ValueList(P1,P3)"), - /* 175 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), - /* 176 */ "VRename" OpHelp(""), - /* 177 */ "Pagecount" OpHelp(""), - /* 178 */ "MaxPgcnt" OpHelp(""), - /* 179 */ "ClrSubtype" OpHelp("r[P1].subtype = 0"), - /* 180 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"), - /* 181 */ "Trace" OpHelp(""), - /* 182 */ "CursorHint" OpHelp(""), - /* 183 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), - /* 184 */ "Noop" OpHelp(""), - /* 185 */ "Explain" OpHelp(""), - /* 186 */ "Abortable" OpHelp(""), + /* 154 */ "IntegrityCk" OpHelp(""), + /* 155 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), + /* 156 */ "Param" OpHelp(""), + /* 157 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), + /* 158 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), + /* 159 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), + /* 160 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), + /* 161 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 162 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 163 */ "AggValue" OpHelp("r[P3]=value N=P2"), + /* 164 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), + /* 165 */ "Expire" OpHelp(""), + /* 166 */ "CursorLock" OpHelp(""), + /* 167 */ "CursorUnlock" OpHelp(""), + /* 168 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), + /* 169 */ "VBegin" OpHelp(""), + /* 170 */ "VCreate" OpHelp(""), + /* 171 */ "VDestroy" OpHelp(""), + /* 172 */ "VOpen" OpHelp(""), + /* 173 */ "VInitIn" OpHelp("r[P2]=ValueList(P1,P3)"), + /* 174 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), + /* 175 */ "VRename" OpHelp(""), + /* 176 */ "Pagecount" OpHelp(""), + /* 177 */ "MaxPgcnt" OpHelp(""), + /* 178 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"), + /* 179 */ "Trace" OpHelp(""), + /* 180 */ "CursorHint" OpHelp(""), + /* 181 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), + /* 182 */ "Noop" OpHelp(""), + /* 183 */ "Explain" OpHelp(""), + /* 184 */ "Abortable" OpHelp(""), }; return azName[i]; } #endif /************** End of opcodes.c *********************************************/ -/************** Begin file os_kv.c *******************************************/ -/* -** 2022-09-06 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains an experimental VFS layer that operates on a -** Key/Value storage engine where both keys and values must be pure -** text. -*/ -/* #include */ -#if SQLITE_OS_KV || (SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL)) - -/***************************************************************************** -** Debugging logic -*/ - -/* SQLITE_KV_TRACE() is used for tracing calls to kvstorage routines. */ -#if 0 -#define SQLITE_KV_TRACE(X) printf X -#else -#define SQLITE_KV_TRACE(X) -#endif - -/* SQLITE_KV_LOG() is used for tracing calls to the VFS interface */ -#if 0 -#define SQLITE_KV_LOG(X) printf X -#else -#define SQLITE_KV_LOG(X) -#endif - - -/* -** Forward declaration of objects used by this VFS implementation -*/ -typedef struct KVVfsFile KVVfsFile; - -/* A single open file. There are only two files represented by this -** VFS - the database and the rollback journal. -*/ -struct KVVfsFile { - sqlite3_file base; /* IO methods */ - const char *zClass; /* Storage class */ - int isJournal; /* True if this is a journal file */ - unsigned int nJrnl; /* Space allocated for aJrnl[] */ - char *aJrnl; /* Journal content */ - int szPage; /* Last known page size */ - sqlite3_int64 szDb; /* Database file size. -1 means unknown */ - char *aData; /* Buffer to hold page data */ -}; -#define SQLITE_KVOS_SZ 133073 - -/* -** Methods for KVVfsFile -*/ -static int kvvfsClose(sqlite3_file*); -static int kvvfsReadDb(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); -static int kvvfsReadJrnl(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); -static int kvvfsWriteDb(sqlite3_file*,const void*,int iAmt, sqlite3_int64); -static int kvvfsWriteJrnl(sqlite3_file*,const void*,int iAmt, sqlite3_int64); -static int kvvfsTruncateDb(sqlite3_file*, sqlite3_int64 size); -static int kvvfsTruncateJrnl(sqlite3_file*, sqlite3_int64 size); -static int kvvfsSyncDb(sqlite3_file*, int flags); -static int kvvfsSyncJrnl(sqlite3_file*, int flags); -static int kvvfsFileSizeDb(sqlite3_file*, sqlite3_int64 *pSize); -static int kvvfsFileSizeJrnl(sqlite3_file*, sqlite3_int64 *pSize); -static int kvvfsLock(sqlite3_file*, int); -static int kvvfsUnlock(sqlite3_file*, int); -static int kvvfsCheckReservedLock(sqlite3_file*, int *pResOut); -static int kvvfsFileControlDb(sqlite3_file*, int op, void *pArg); -static int kvvfsFileControlJrnl(sqlite3_file*, int op, void *pArg); -static int kvvfsSectorSize(sqlite3_file*); -static int kvvfsDeviceCharacteristics(sqlite3_file*); - -/* -** Methods for sqlite3_vfs -*/ -static int kvvfsOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *); -static int kvvfsDelete(sqlite3_vfs*, const char *zName, int syncDir); -static int kvvfsAccess(sqlite3_vfs*, const char *zName, int flags, int *); -static int kvvfsFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut); -static void *kvvfsDlOpen(sqlite3_vfs*, const char *zFilename); -static int kvvfsRandomness(sqlite3_vfs*, int nByte, char *zOut); -static int kvvfsSleep(sqlite3_vfs*, int microseconds); -static int kvvfsCurrentTime(sqlite3_vfs*, double*); -static int kvvfsCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); - -static sqlite3_vfs sqlite3OsKvvfsObject = { - 1, /* iVersion */ - sizeof(KVVfsFile), /* szOsFile */ - 1024, /* mxPathname */ - 0, /* pNext */ - "kvvfs", /* zName */ - 0, /* pAppData */ - kvvfsOpen, /* xOpen */ - kvvfsDelete, /* xDelete */ - kvvfsAccess, /* xAccess */ - kvvfsFullPathname, /* xFullPathname */ - kvvfsDlOpen, /* xDlOpen */ - 0, /* xDlError */ - 0, /* xDlSym */ - 0, /* xDlClose */ - kvvfsRandomness, /* xRandomness */ - kvvfsSleep, /* xSleep */ - kvvfsCurrentTime, /* xCurrentTime */ - 0, /* xGetLastError */ - kvvfsCurrentTimeInt64 /* xCurrentTimeInt64 */ -}; - -/* Methods for sqlite3_file objects referencing a database file -*/ -static sqlite3_io_methods kvvfs_db_io_methods = { - 1, /* iVersion */ - kvvfsClose, /* xClose */ - kvvfsReadDb, /* xRead */ - kvvfsWriteDb, /* xWrite */ - kvvfsTruncateDb, /* xTruncate */ - kvvfsSyncDb, /* xSync */ - kvvfsFileSizeDb, /* xFileSize */ - kvvfsLock, /* xLock */ - kvvfsUnlock, /* xUnlock */ - kvvfsCheckReservedLock, /* xCheckReservedLock */ - kvvfsFileControlDb, /* xFileControl */ - kvvfsSectorSize, /* xSectorSize */ - kvvfsDeviceCharacteristics, /* xDeviceCharacteristics */ - 0, /* xShmMap */ - 0, /* xShmLock */ - 0, /* xShmBarrier */ - 0, /* xShmUnmap */ - 0, /* xFetch */ - 0 /* xUnfetch */ -}; - -/* Methods for sqlite3_file objects referencing a rollback journal -*/ -static sqlite3_io_methods kvvfs_jrnl_io_methods = { - 1, /* iVersion */ - kvvfsClose, /* xClose */ - kvvfsReadJrnl, /* xRead */ - kvvfsWriteJrnl, /* xWrite */ - kvvfsTruncateJrnl, /* xTruncate */ - kvvfsSyncJrnl, /* xSync */ - kvvfsFileSizeJrnl, /* xFileSize */ - kvvfsLock, /* xLock */ - kvvfsUnlock, /* xUnlock */ - kvvfsCheckReservedLock, /* xCheckReservedLock */ - kvvfsFileControlJrnl, /* xFileControl */ - kvvfsSectorSize, /* xSectorSize */ - kvvfsDeviceCharacteristics, /* xDeviceCharacteristics */ - 0, /* xShmMap */ - 0, /* xShmLock */ - 0, /* xShmBarrier */ - 0, /* xShmUnmap */ - 0, /* xFetch */ - 0 /* xUnfetch */ -}; - -/****** Storage subsystem **************************************************/ -#include -#include -#include - -/* Forward declarations for the low-level storage engine -*/ -static int kvstorageWrite(const char*, const char *zKey, const char *zData); -static int kvstorageDelete(const char*, const char *zKey); -static int kvstorageRead(const char*, const char *zKey, char *zBuf, int nBuf); -#define KVSTORAGE_KEY_SZ 32 - -/* Expand the key name with an appropriate prefix and put the result -** zKeyOut[]. The zKeyOut[] buffer is assumed to hold at least -** KVSTORAGE_KEY_SZ bytes. -*/ -static void kvstorageMakeKey( - const char *zClass, - const char *zKeyIn, - char *zKeyOut -){ - sqlite3_snprintf(KVSTORAGE_KEY_SZ, zKeyOut, "kvvfs-%s-%s", zClass, zKeyIn); -} - -/* Write content into a key. zClass is the particular namespace of the -** underlying key/value store to use - either "local" or "session". -** -** Both zKey and zData are zero-terminated pure text strings. -** -** Return the number of errors. -*/ -static int kvstorageWrite( - const char *zClass, - const char *zKey, - const char *zData -){ - FILE *fd; - char zXKey[KVSTORAGE_KEY_SZ]; - kvstorageMakeKey(zClass, zKey, zXKey); - fd = fopen(zXKey, "wb"); - if( fd ){ - SQLITE_KV_TRACE(("KVVFS-WRITE %-15s (%d) %.50s%s\n", zXKey, - (int)strlen(zData), zData, - strlen(zData)>50 ? "..." : "")); - fputs(zData, fd); - fclose(fd); - return 0; - }else{ - return 1; - } -} - -/* Delete a key (with its corresponding data) from the key/value -** namespace given by zClass. If the key does not previously exist, -** this routine is a no-op. -*/ -static int kvstorageDelete(const char *zClass, const char *zKey){ - char zXKey[KVSTORAGE_KEY_SZ]; - kvstorageMakeKey(zClass, zKey, zXKey); - unlink(zXKey); - SQLITE_KV_TRACE(("KVVFS-DELETE %-15s\n", zXKey)); - return 0; -} - -/* Read the value associated with a zKey from the key/value namespace given -** by zClass and put the text data associated with that key in the first -** nBuf bytes of zBuf[]. The value might be truncated if zBuf is not large -** enough to hold it all. The value put into zBuf must always be zero -** terminated, even if it gets truncated because nBuf is not large enough. -** -** Return the total number of bytes in the data, without truncation, and -** not counting the final zero terminator. Return -1 if the key does -** not exist. -** -** If nBuf<=0 then this routine simply returns the size of the data without -** actually reading it. -*/ -static int kvstorageRead( - const char *zClass, - const char *zKey, - char *zBuf, - int nBuf -){ - FILE *fd; - struct stat buf; - char zXKey[KVSTORAGE_KEY_SZ]; - kvstorageMakeKey(zClass, zKey, zXKey); - if( access(zXKey, R_OK)!=0 - || stat(zXKey, &buf)!=0 - || !S_ISREG(buf.st_mode) - ){ - SQLITE_KV_TRACE(("KVVFS-READ %-15s (-1)\n", zXKey)); - return -1; - } - if( nBuf<=0 ){ - return (int)buf.st_size; - }else if( nBuf==1 ){ - zBuf[0] = 0; - SQLITE_KV_TRACE(("KVVFS-READ %-15s (%d)\n", zXKey, - (int)buf.st_size)); - return (int)buf.st_size; - } - if( nBuf > buf.st_size + 1 ){ - nBuf = buf.st_size + 1; - } - fd = fopen(zXKey, "rb"); - if( fd==0 ){ - SQLITE_KV_TRACE(("KVVFS-READ %-15s (-1)\n", zXKey)); - return -1; - }else{ - sqlite3_int64 n = fread(zBuf, 1, nBuf-1, fd); - fclose(fd); - zBuf[n] = 0; - SQLITE_KV_TRACE(("KVVFS-READ %-15s (%lld) %.50s%s\n", zXKey, - n, zBuf, n>50 ? "..." : "")); - return (int)n; - } -} - -/* -** An internal level of indirection which enables us to replace the -** kvvfs i/o methods with JavaScript implementations in WASM builds. -** Maintenance reminder: if this struct changes in any way, the JSON -** rendering of its structure must be updated in -** sqlite3_wasm_enum_json(). There are no binary compatibility -** concerns, so it does not need an iVersion member. This file is -** necessarily always compiled together with sqlite3_wasm_enum_json(), -** and JS code dynamically creates the mapping of members based on -** that JSON description. -*/ -typedef struct sqlite3_kvvfs_methods sqlite3_kvvfs_methods; -struct sqlite3_kvvfs_methods { - int (*xRead)(const char *zClass, const char *zKey, char *zBuf, int nBuf); - int (*xWrite)(const char *zClass, const char *zKey, const char *zData); - int (*xDelete)(const char *zClass, const char *zKey); - const int nKeySize; -}; - -/* -** This object holds the kvvfs I/O methods which may be swapped out -** for JavaScript-side implementations in WASM builds. In such builds -** it cannot be const, but in native builds it should be so that -** the compiler can hopefully optimize this level of indirection out. -** That said, kvvfs is intended primarily for use in WASM builds. -** -** Note that this is not explicitly flagged as static because the -** amalgamation build will tag it with SQLITE_PRIVATE. -*/ -#ifndef SQLITE_WASM -const -#endif -SQLITE_PRIVATE sqlite3_kvvfs_methods sqlite3KvvfsMethods = { -kvstorageRead, -kvstorageWrite, -kvstorageDelete, -KVSTORAGE_KEY_SZ -}; - -/****** Utility subroutines ************************************************/ - -/* -** Encode binary into the text encoded used to persist on disk. -** The output text is stored in aOut[], which must be at least -** nData+1 bytes in length. -** -** Return the actual length of the encoded text, not counting the -** zero terminator at the end. -** -** Encoding format -** --------------- -** -** * Non-zero bytes are encoded as upper-case hexadecimal -** -** * A sequence of one or more zero-bytes that are not at the -** beginning of the buffer are encoded as a little-endian -** base-26 number using a..z. "a" means 0. "b" means 1, -** "z" means 25. "ab" means 26. "ac" means 52. And so forth. -** -** * Because there is no overlap between the encoding characters -** of hexadecimal and base-26 numbers, it is always clear where -** one stops and the next begins. -*/ -static int kvvfsEncode(const char *aData, int nData, char *aOut){ - int i, j; - const unsigned char *a = (const unsigned char*)aData; - for(i=j=0; i>4]; - aOut[j++] = "0123456789ABCDEF"[c&0xf]; - }else{ - /* A sequence of 1 or more zeros is stored as a little-endian - ** base-26 number using a..z as the digits. So one zero is "b". - ** Two zeros is "c". 25 zeros is "z", 26 zeros is "ab", 27 is "bb", - ** and so forth. - */ - int k; - for(k=1; i+k0 ){ - aOut[j++] = 'a'+(k%26); - k /= 26; - } - } - } - aOut[j] = 0; - return j; -} - -static const signed char kvvfsHexValue[256] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, - -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 -}; - -/* -** Decode the text encoding back to binary. The binary content is -** written into pOut, which must be at least nOut bytes in length. -** -** The return value is the number of bytes actually written into aOut[]. -*/ -static int kvvfsDecode(const char *a, char *aOut, int nOut){ - int i, j; - int c; - const unsigned char *aIn = (const unsigned char*)a; - i = 0; - j = 0; - while( 1 ){ - c = kvvfsHexValue[aIn[i]]; - if( c<0 ){ - int n = 0; - int mult = 1; - c = aIn[i]; - if( c==0 ) break; - while( c>='a' && c<='z' ){ - n += (c - 'a')*mult; - mult *= 26; - c = aIn[++i]; - } - if( j+n>nOut ) return -1; - memset(&aOut[j], 0, n); - j += n; - if( c==0 || mult==1 ) break; /* progress stalled if mult==1 */ - }else{ - aOut[j] = c<<4; - c = kvvfsHexValue[aIn[++i]]; - if( c<0 ) break; - aOut[j++] += c; - i++; - } - } - return j; -} - -/* -** Decode a complete journal file. Allocate space in pFile->aJrnl -** and store the decoding there. Or leave pFile->aJrnl set to NULL -** if an error is encountered. -** -** The first few characters of the text encoding will be a little-endian -** base-26 number (digits a..z) that is the total number of bytes -** in the decoded journal file image. This base-26 number is followed -** by a single space, then the encoding of the journal. The space -** separator is required to act as a terminator for the base-26 number. -*/ -static void kvvfsDecodeJournal( - KVVfsFile *pFile, /* Store decoding in pFile->aJrnl */ - const char *zTxt, /* Text encoding. Zero-terminated */ - int nTxt /* Bytes in zTxt, excluding zero terminator */ -){ - unsigned int n = 0; - int c, i, mult; - i = 0; - mult = 1; - while( (c = zTxt[i++])>='a' && c<='z' ){ - n += (zTxt[i] - 'a')*mult; - mult *= 26; - } - sqlite3_free(pFile->aJrnl); - pFile->aJrnl = sqlite3_malloc64( n ); - if( pFile->aJrnl==0 ){ - pFile->nJrnl = 0; - return; - } - pFile->nJrnl = n; - n = kvvfsDecode(zTxt+i, pFile->aJrnl, pFile->nJrnl); - if( nnJrnl ){ - sqlite3_free(pFile->aJrnl); - pFile->aJrnl = 0; - pFile->nJrnl = 0; - } -} - -/* -** Read or write the "sz" element, containing the database file size. -*/ -static sqlite3_int64 kvvfsReadFileSize(KVVfsFile *pFile){ - char zData[50]; - zData[0] = 0; - sqlite3KvvfsMethods.xRead(pFile->zClass, "sz", zData, sizeof(zData)-1); - return strtoll(zData, 0, 0); -} -static int kvvfsWriteFileSize(KVVfsFile *pFile, sqlite3_int64 sz){ - char zData[50]; - sqlite3_snprintf(sizeof(zData), zData, "%lld", sz); - return sqlite3KvvfsMethods.xWrite(pFile->zClass, "sz", zData); -} - -/****** sqlite3_io_methods methods ******************************************/ - -/* -** Close an kvvfs-file. -*/ -static int kvvfsClose(sqlite3_file *pProtoFile){ - KVVfsFile *pFile = (KVVfsFile *)pProtoFile; - - SQLITE_KV_LOG(("xClose %s %s\n", pFile->zClass, - pFile->isJournal ? "journal" : "db")); - sqlite3_free(pFile->aJrnl); - sqlite3_free(pFile->aData); - return SQLITE_OK; -} - -/* -** Read from the -journal file. -*/ -static int kvvfsReadJrnl( - sqlite3_file *pProtoFile, - void *zBuf, - int iAmt, - sqlite_int64 iOfst -){ - KVVfsFile *pFile = (KVVfsFile*)pProtoFile; - assert( pFile->isJournal ); - SQLITE_KV_LOG(("xRead('%s-journal',%d,%lld)\n", pFile->zClass, iAmt, iOfst)); - if( pFile->aJrnl==0 ){ - int szTxt = kvstorageRead(pFile->zClass, "jrnl", 0, 0); - char *aTxt; - if( szTxt<=4 ){ - return SQLITE_IOERR; - } - aTxt = sqlite3_malloc64( szTxt+1 ); - if( aTxt==0 ) return SQLITE_NOMEM; - kvstorageRead(pFile->zClass, "jrnl", aTxt, szTxt+1); - kvvfsDecodeJournal(pFile, aTxt, szTxt); - sqlite3_free(aTxt); - if( pFile->aJrnl==0 ) return SQLITE_IOERR; - } - if( iOfst+iAmt>pFile->nJrnl ){ - return SQLITE_IOERR_SHORT_READ; - } - memcpy(zBuf, pFile->aJrnl+iOfst, iAmt); - return SQLITE_OK; -} - -/* -** Read from the database file. -*/ -static int kvvfsReadDb( - sqlite3_file *pProtoFile, - void *zBuf, - int iAmt, - sqlite_int64 iOfst -){ - KVVfsFile *pFile = (KVVfsFile*)pProtoFile; - unsigned int pgno; - int got, n; - char zKey[30]; - char *aData = pFile->aData; - assert( iOfst>=0 ); - assert( iAmt>=0 ); - SQLITE_KV_LOG(("xRead('%s-db',%d,%lld)\n", pFile->zClass, iAmt, iOfst)); - if( iOfst+iAmt>=512 ){ - if( (iOfst % iAmt)!=0 ){ - return SQLITE_IOERR_READ; - } - if( (iAmt & (iAmt-1))!=0 || iAmt<512 || iAmt>65536 ){ - return SQLITE_IOERR_READ; - } - pFile->szPage = iAmt; - pgno = 1 + iOfst/iAmt; - }else{ - pgno = 1; - } - sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno); - got = sqlite3KvvfsMethods.xRead(pFile->zClass, zKey, - aData, SQLITE_KVOS_SZ-1); - if( got<0 ){ - n = 0; - }else{ - aData[got] = 0; - if( iOfst+iAmt<512 ){ - int k = iOfst+iAmt; - aData[k*2] = 0; - n = kvvfsDecode(aData, &aData[2000], SQLITE_KVOS_SZ-2000); - if( n>=iOfst+iAmt ){ - memcpy(zBuf, &aData[2000+iOfst], iAmt); - n = iAmt; - }else{ - n = 0; - } - }else{ - n = kvvfsDecode(aData, zBuf, iAmt); - } - } - if( nzClass, iAmt, iOfst)); - if( iEnd>=0x10000000 ) return SQLITE_FULL; - if( pFile->aJrnl==0 || pFile->nJrnlaJrnl, iEnd); - if( aNew==0 ){ - return SQLITE_IOERR_NOMEM; - } - pFile->aJrnl = aNew; - if( pFile->nJrnlaJrnl+pFile->nJrnl, 0, iOfst-pFile->nJrnl); - } - pFile->nJrnl = iEnd; - } - memcpy(pFile->aJrnl+iOfst, zBuf, iAmt); - return SQLITE_OK; -} - -/* -** Write into the database file. -*/ -static int kvvfsWriteDb( - sqlite3_file *pProtoFile, - const void *zBuf, - int iAmt, - sqlite_int64 iOfst -){ - KVVfsFile *pFile = (KVVfsFile*)pProtoFile; - unsigned int pgno; - char zKey[30]; - char *aData = pFile->aData; - SQLITE_KV_LOG(("xWrite('%s-db',%d,%lld)\n", pFile->zClass, iAmt, iOfst)); - assert( iAmt>=512 && iAmt<=65536 ); - assert( (iAmt & (iAmt-1))==0 ); - assert( pFile->szPage<0 || pFile->szPage==iAmt ); - pFile->szPage = iAmt; - pgno = 1 + iOfst/iAmt; - sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno); - kvvfsEncode(zBuf, iAmt, aData); - if( sqlite3KvvfsMethods.xWrite(pFile->zClass, zKey, aData) ){ - return SQLITE_IOERR; - } - if( iOfst+iAmt > pFile->szDb ){ - pFile->szDb = iOfst + iAmt; - } - return SQLITE_OK; -} - -/* -** Truncate an kvvfs-file. -*/ -static int kvvfsTruncateJrnl(sqlite3_file *pProtoFile, sqlite_int64 size){ - KVVfsFile *pFile = (KVVfsFile *)pProtoFile; - SQLITE_KV_LOG(("xTruncate('%s-journal',%lld)\n", pFile->zClass, size)); - assert( size==0 ); - sqlite3KvvfsMethods.xDelete(pFile->zClass, "jrnl"); - sqlite3_free(pFile->aJrnl); - pFile->aJrnl = 0; - pFile->nJrnl = 0; - return SQLITE_OK; -} -static int kvvfsTruncateDb(sqlite3_file *pProtoFile, sqlite_int64 size){ - KVVfsFile *pFile = (KVVfsFile *)pProtoFile; - if( pFile->szDb>size - && pFile->szPage>0 - && (size % pFile->szPage)==0 - ){ - char zKey[50]; - unsigned int pgno, pgnoMax; - SQLITE_KV_LOG(("xTruncate('%s-db',%lld)\n", pFile->zClass, size)); - pgno = 1 + size/pFile->szPage; - pgnoMax = 2 + pFile->szDb/pFile->szPage; - while( pgno<=pgnoMax ){ - sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno); - sqlite3KvvfsMethods.xDelete(pFile->zClass, zKey); - pgno++; - } - pFile->szDb = size; - return kvvfsWriteFileSize(pFile, size) ? SQLITE_IOERR : SQLITE_OK; - } - return SQLITE_IOERR; -} - -/* -** Sync an kvvfs-file. -*/ -static int kvvfsSyncJrnl(sqlite3_file *pProtoFile, int flags){ - int i, n; - KVVfsFile *pFile = (KVVfsFile *)pProtoFile; - char *zOut; - SQLITE_KV_LOG(("xSync('%s-journal')\n", pFile->zClass)); - if( pFile->nJrnl<=0 ){ - return kvvfsTruncateJrnl(pProtoFile, 0); - } - zOut = sqlite3_malloc64( pFile->nJrnl*2 + 50 ); - if( zOut==0 ){ - return SQLITE_IOERR_NOMEM; - } - n = pFile->nJrnl; - i = 0; - do{ - zOut[i++] = 'a' + (n%26); - n /= 26; - }while( n>0 ); - zOut[i++] = ' '; - kvvfsEncode(pFile->aJrnl, pFile->nJrnl, &zOut[i]); - i = sqlite3KvvfsMethods.xWrite(pFile->zClass, "jrnl", zOut); - sqlite3_free(zOut); - return i ? SQLITE_IOERR : SQLITE_OK; -} -static int kvvfsSyncDb(sqlite3_file *pProtoFile, int flags){ - return SQLITE_OK; -} - -/* -** Return the current file-size of an kvvfs-file. -*/ -static int kvvfsFileSizeJrnl(sqlite3_file *pProtoFile, sqlite_int64 *pSize){ - KVVfsFile *pFile = (KVVfsFile *)pProtoFile; - SQLITE_KV_LOG(("xFileSize('%s-journal')\n", pFile->zClass)); - *pSize = pFile->nJrnl; - return SQLITE_OK; -} -static int kvvfsFileSizeDb(sqlite3_file *pProtoFile, sqlite_int64 *pSize){ - KVVfsFile *pFile = (KVVfsFile *)pProtoFile; - SQLITE_KV_LOG(("xFileSize('%s-db')\n", pFile->zClass)); - if( pFile->szDb>=0 ){ - *pSize = pFile->szDb; - }else{ - *pSize = kvvfsReadFileSize(pFile); - } - return SQLITE_OK; -} - -/* -** Lock an kvvfs-file. -*/ -static int kvvfsLock(sqlite3_file *pProtoFile, int eLock){ - KVVfsFile *pFile = (KVVfsFile *)pProtoFile; - assert( !pFile->isJournal ); - SQLITE_KV_LOG(("xLock(%s,%d)\n", pFile->zClass, eLock)); - - if( eLock!=SQLITE_LOCK_NONE ){ - pFile->szDb = kvvfsReadFileSize(pFile); - } - return SQLITE_OK; -} - -/* -** Unlock an kvvfs-file. -*/ -static int kvvfsUnlock(sqlite3_file *pProtoFile, int eLock){ - KVVfsFile *pFile = (KVVfsFile *)pProtoFile; - assert( !pFile->isJournal ); - SQLITE_KV_LOG(("xUnlock(%s,%d)\n", pFile->zClass, eLock)); - if( eLock==SQLITE_LOCK_NONE ){ - pFile->szDb = -1; - } - return SQLITE_OK; -} - -/* -** Check if another file-handle holds a RESERVED lock on an kvvfs-file. -*/ -static int kvvfsCheckReservedLock(sqlite3_file *pProtoFile, int *pResOut){ - SQLITE_KV_LOG(("xCheckReservedLock\n")); - *pResOut = 0; - return SQLITE_OK; -} - -/* -** File control method. For custom operations on an kvvfs-file. -*/ -static int kvvfsFileControlJrnl(sqlite3_file *pProtoFile, int op, void *pArg){ - SQLITE_KV_LOG(("xFileControl(%d) on journal\n", op)); - return SQLITE_NOTFOUND; -} -static int kvvfsFileControlDb(sqlite3_file *pProtoFile, int op, void *pArg){ - SQLITE_KV_LOG(("xFileControl(%d) on database\n", op)); - if( op==SQLITE_FCNTL_SYNC ){ - KVVfsFile *pFile = (KVVfsFile *)pProtoFile; - int rc = SQLITE_OK; - SQLITE_KV_LOG(("xSync('%s-db')\n", pFile->zClass)); - if( pFile->szDb>0 && 0!=kvvfsWriteFileSize(pFile, pFile->szDb) ){ - rc = SQLITE_IOERR; - } - return rc; - } - return SQLITE_NOTFOUND; -} - -/* -** Return the sector-size in bytes for an kvvfs-file. -*/ -static int kvvfsSectorSize(sqlite3_file *pFile){ - return 512; -} - -/* -** Return the device characteristic flags supported by an kvvfs-file. -*/ -static int kvvfsDeviceCharacteristics(sqlite3_file *pProtoFile){ - return 0; -} - -/****** sqlite3_vfs methods *************************************************/ - -/* -** Open an kvvfs file handle. -*/ -static int kvvfsOpen( - sqlite3_vfs *pProtoVfs, - const char *zName, - sqlite3_file *pProtoFile, - int flags, - int *pOutFlags -){ - KVVfsFile *pFile = (KVVfsFile*)pProtoFile; - if( zName==0 ) zName = ""; - SQLITE_KV_LOG(("xOpen(\"%s\")\n", zName)); - if( strcmp(zName, "local")==0 - || strcmp(zName, "session")==0 - ){ - pFile->isJournal = 0; - pFile->base.pMethods = &kvvfs_db_io_methods; - }else - if( strcmp(zName, "local-journal")==0 - || strcmp(zName, "session-journal")==0 - ){ - pFile->isJournal = 1; - pFile->base.pMethods = &kvvfs_jrnl_io_methods; - }else{ - return SQLITE_CANTOPEN; - } - if( zName[0]=='s' ){ - pFile->zClass = "session"; - }else{ - pFile->zClass = "local"; - } - pFile->aData = sqlite3_malloc64(SQLITE_KVOS_SZ); - if( pFile->aData==0 ){ - return SQLITE_NOMEM; - } - pFile->aJrnl = 0; - pFile->nJrnl = 0; - pFile->szPage = -1; - pFile->szDb = -1; - return SQLITE_OK; -} - -/* -** Delete the file located at zPath. If the dirSync argument is true, -** ensure the file-system modifications are synced to disk before -** returning. -*/ -static int kvvfsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ - if( strcmp(zPath, "local-journal")==0 ){ - sqlite3KvvfsMethods.xDelete("local", "jrnl"); - }else - if( strcmp(zPath, "session-journal")==0 ){ - sqlite3KvvfsMethods.xDelete("session", "jrnl"); - } - return SQLITE_OK; -} - -/* -** Test for access permissions. Return true if the requested permission -** is available, or false otherwise. -*/ -static int kvvfsAccess( - sqlite3_vfs *pProtoVfs, - const char *zPath, - int flags, - int *pResOut -){ - SQLITE_KV_LOG(("xAccess(\"%s\")\n", zPath)); - if( strcmp(zPath, "local-journal")==0 ){ - *pResOut = sqlite3KvvfsMethods.xRead("local", "jrnl", 0, 0)>0; - }else - if( strcmp(zPath, "session-journal")==0 ){ - *pResOut = sqlite3KvvfsMethods.xRead("session", "jrnl", 0, 0)>0; - }else - if( strcmp(zPath, "local")==0 ){ - *pResOut = sqlite3KvvfsMethods.xRead("local", "sz", 0, 0)>0; - }else - if( strcmp(zPath, "session")==0 ){ - *pResOut = sqlite3KvvfsMethods.xRead("session", "sz", 0, 0)>0; - }else - { - *pResOut = 0; - } - SQLITE_KV_LOG(("xAccess returns %d\n",*pResOut)); - return SQLITE_OK; -} - -/* -** Populate buffer zOut with the full canonical pathname corresponding -** to the pathname in zPath. zOut is guaranteed to point to a buffer -** of at least (INST_MAX_PATHNAME+1) bytes. -*/ -static int kvvfsFullPathname( - sqlite3_vfs *pVfs, - const char *zPath, - int nOut, - char *zOut -){ - size_t nPath; -#ifdef SQLITE_OS_KV_ALWAYS_LOCAL - zPath = "local"; -#endif - nPath = strlen(zPath); - SQLITE_KV_LOG(("xFullPathname(\"%s\")\n", zPath)); - if( nOut -static int kvvfsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){ - static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; - struct timeval sNow; - (void)gettimeofday(&sNow, 0); /* Cannot fail given valid arguments */ - *pTimeOut = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000; - return SQLITE_OK; -} -#endif /* SQLITE_OS_KV || SQLITE_OS_UNIX */ - -#if SQLITE_OS_KV -/* -** This routine is called initialize the KV-vfs as the default VFS. -*/ -SQLITE_API int sqlite3_os_init(void){ - return sqlite3_vfs_register(&sqlite3OsKvvfsObject, 1); -} -SQLITE_API int sqlite3_os_end(void){ - return SQLITE_OK; -} -#endif /* SQLITE_OS_KV */ - -#if SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL) -SQLITE_PRIVATE int sqlite3KvvfsInit(void){ - return sqlite3_vfs_register(&sqlite3OsKvvfsObject, 0); -} -#endif - -/************** End of os_kv.c ***********************************************/ /************** Begin file os_unix.c *****************************************/ /* ** 2004 May 22 ** ** The author disclaims copyright to this source code. In place of @@ -37139,11 +34853,11 @@ # define SQLITE_ENABLE_LOCKING_STYLE 0 # endif #endif /* Use pread() and pwrite() if they are available */ -#if defined(__APPLE__) || defined(__linux__) +#if defined(__APPLE__) # define HAVE_PREAD 1 # define HAVE_PWRITE 1 #endif #if defined(HAVE_PREAD64) && defined(HAVE_PWRITE64) # undef USE_PREAD @@ -37154,20 +34868,19 @@ #endif /* ** standard include files. */ -#include /* amalgamator: keep */ -#include /* amalgamator: keep */ +#include +#include #include #include -#include /* amalgamator: keep */ +#include /* #include */ -#include /* amalgamator: keep */ +#include #include -#if (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) \ - && !defined(SQLITE_WASI) +#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 # include #endif #if SQLITE_ENABLE_LOCKING_STYLE /* # include */ @@ -37251,50 +34964,13 @@ /* ** Maximum supported symbolic links */ #define SQLITE_MAX_SYMLINKS 100 -/* -** Remove and stub certain info for WASI (WebAssembly System -** Interface) builds. -*/ -#ifdef SQLITE_WASI -# undef HAVE_FCHMOD -# undef HAVE_FCHOWN -# undef HAVE_MREMAP -# define HAVE_MREMAP 0 -# ifndef SQLITE_DEFAULT_UNIX_VFS -# define SQLITE_DEFAULT_UNIX_VFS "unix-dotfile" - /* ^^^ should SQLITE_DEFAULT_UNIX_VFS be "unix-none"? */ -# endif -# ifndef F_RDLCK -# define F_RDLCK 0 -# define F_WRLCK 1 -# define F_UNLCK 2 -# if __LONG_MAX == 0x7fffffffL -# define F_GETLK 12 -# define F_SETLK 13 -# define F_SETLKW 14 -# else -# define F_GETLK 5 -# define F_SETLK 6 -# define F_SETLKW 7 -# endif -# endif -#else /* !SQLITE_WASI */ -# ifndef HAVE_FCHMOD -# define HAVE_FCHMOD -# endif -#endif /* SQLITE_WASI */ - -#ifdef SQLITE_WASI -# define osGetpid(X) (pid_t)1 -#else /* Always cast the getpid() return type for compatibility with ** kernel modules in VxWorks. */ -# define osGetpid(X) (pid_t)getpid() -#endif +#define osGetpid(X) (pid_t)getpid() /* ** Only set the lastErrno if the error code is a real error and not ** a normal expected return code of SQLITE_BUSY or SQLITE_OK */ @@ -37562,15 +35238,11 @@ { "pwrite64", (sqlite3_syscall_ptr)0, 0 }, #endif #define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off64_t))\ aSyscall[13].pCurrent) -#if defined(HAVE_FCHMOD) { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 }, -#else - { "fchmod", (sqlite3_syscall_ptr)0, 0 }, -#endif #define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent) #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE { "fallocate", (sqlite3_syscall_ptr)posix_fallocate, 0 }, #else @@ -37602,20 +35274,18 @@ #else { "geteuid", (sqlite3_syscall_ptr)0, 0 }, #endif #define osGeteuid ((uid_t(*)(void))aSyscall[21].pCurrent) -#if (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) \ - && !defined(SQLITE_WASI) +#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 { "mmap", (sqlite3_syscall_ptr)mmap, 0 }, #else { "mmap", (sqlite3_syscall_ptr)0, 0 }, #endif #define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[22].pCurrent) -#if (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) \ - && !defined(SQLITE_WASI) +#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 { "munmap", (sqlite3_syscall_ptr)munmap, 0 }, #else { "munmap", (sqlite3_syscall_ptr)0, 0 }, #endif #define osMunmap ((int(*)(void*,size_t))aSyscall[23].pCurrent) @@ -37797,13 +35467,10 @@ if( fd<0 ){ if( errno==EINTR ) continue; break; } if( fd>=SQLITE_MINIMUM_FILE_DESCRIPTOR ) break; - if( (f & (O_EXCL|O_CREAT))==(O_EXCL|O_CREAT) ){ - (void)osUnlink(z); - } osClose(fd); sqlite3_log(SQLITE_WARNING, "attempt to open \"%s\" as file descriptor %d", z, fd); fd = -1; if( osOpen("/dev/null", O_RDONLY, m)<0 ) break; @@ -38762,11 +36429,11 @@ ** still short of its goal. The following chart shows the allowed ** transitions and the inserted intermediate states: ** ** UNLOCKED -> SHARED ** SHARED -> RESERVED -** SHARED -> EXCLUSIVE +** SHARED -> (PENDING) -> EXCLUSIVE ** RESERVED -> (PENDING) -> EXCLUSIVE ** PENDING -> EXCLUSIVE ** ** This routine will only increase a lock. Use the sqlite3OsUnlock() ** routine to lower a locking level. @@ -38795,24 +36462,23 @@ ** ** A process may only obtain a RESERVED lock after it has a SHARED lock. ** A RESERVED lock is implemented by grabbing a write-lock on the ** 'reserved byte'. ** - ** An EXCLUSIVE lock may only be requested after either a SHARED or - ** RESERVED lock is held. An EXCLUSIVE lock is implemented by obtaining - ** a write-lock on the entire 'shared byte range'. Since all other locks - ** require a read-lock on one of the bytes within this range, this ensures - ** that no other locks are held on the database. + ** A process may only obtain a PENDING lock after it has obtained a + ** SHARED lock. A PENDING lock is implemented by obtaining a write-lock + ** on the 'pending byte'. This ensures that no new SHARED locks can be + ** obtained, but existing SHARED locks are allowed to persist. A process + ** does not have to obtain a RESERVED lock on the way to a PENDING lock. + ** This property is used by the algorithm for rolling back a journal file + ** after a crash. ** - ** If a process that holds a RESERVED lock requests an EXCLUSIVE, then - ** a PENDING lock is obtained first. A PENDING lock is implemented by - ** obtaining a write-lock on the 'pending byte'. This ensures that no new - ** SHARED locks can be obtained, but existing SHARED locks are allowed to - ** persist. If the call to this function fails to obtain the EXCLUSIVE - ** lock in this case, it holds the PENDING lock intead. The client may - ** then re-attempt the EXCLUSIVE lock later on, after existing SHARED - ** locks have cleared. + ** An EXCLUSIVE lock, obtained after a PENDING lock is held, is + ** implemented by obtaining a write-lock on the entire 'shared byte + ** range'. Since all other locks require a read-lock on one of the bytes + ** within this range, this ensures that no other locks are held on the + ** database. */ int rc = SQLITE_OK; unixFile *pFile = (unixFile*)id; unixInodeInfo *pInode; struct flock lock; @@ -38879,11 +36545,11 @@ ** be released. */ lock.l_len = 1L; lock.l_whence = SEEK_SET; if( eFileLock==SHARED_LOCK - || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLock==RESERVED_LOCK) + || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLockeFileLock = PENDING_LOCK; - pInode->eFileLock = PENDING_LOCK; } } /* If control gets to this point, then actually go ahead and make @@ -38979,14 +36642,18 @@ pFile->transCntrChng = 0; pFile->dbUpdate = 0; pFile->inNormalWrite = 1; } #endif + if( rc==SQLITE_OK ){ pFile->eFileLock = eFileLock; pInode->eFileLock = eFileLock; + }else if( eFileLock==EXCLUSIVE_LOCK ){ + pFile->eFileLock = PENDING_LOCK; + pInode->eFileLock = PENDING_LOCK; } end_lock: sqlite3_mutex_leave(pInode->pLockMutex); OSTRACE(("LOCK %d %s %s (unix)\n", pFile->h, azFileLock(eFileLock), @@ -40388,10 +38055,16 @@ */ /* ** Seek to the offset passed as the second argument, then read cnt ** bytes into pBuf. Return the number of bytes actually read. +** +** NB: If you define USE_PREAD or USE_PREAD64, then it might also +** be necessary to define _XOPEN_SOURCE to be 500. This varies from +** one system to another. Since SQLite does not define USE_PREAD +** in any form by default, we will not attempt to define _XOPEN_SOURCE. +** See tickets #2741 and #2681. ** ** To avoid stomping the errno value on a failed read the lastErrno value ** is set before returning. */ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){ @@ -42963,39 +40636,30 @@ ** pVfs->mxPathname bytes. */ static int unixGetTempname(int nBuf, char *zBuf){ const char *zDir; int iLimit = 0; - int rc = SQLITE_OK; /* It's odd to simulate an io-error here, but really this is just ** using the io-error infrastructure to test that SQLite handles this ** function failing. */ zBuf[0] = 0; SimulateIOError( return SQLITE_IOERR ); - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); zDir = unixTempFileDir(); - if( zDir==0 ){ - rc = SQLITE_IOERR_GETTEMPPATH; - }else{ - do{ - u64 r; - sqlite3_randomness(sizeof(r), &r); - assert( nBuf>2 ); - zBuf[nBuf-2] = 0; - sqlite3_snprintf(nBuf, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX"%llx%c", - zDir, r, 0); - if( zBuf[nBuf-2]!=0 || (iLimit++)>10 ){ - rc = SQLITE_ERROR; - break; - } - }while( osAccess(zBuf,0)==0 ); - } - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); - return rc; + if( zDir==0 ) return SQLITE_IOERR_GETTEMPPATH; + do{ + u64 r; + sqlite3_randomness(sizeof(r), &r); + assert( nBuf>2 ); + zBuf[nBuf-2] = 0; + sqlite3_snprintf(nBuf, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX"%llx%c", + zDir, r, 0); + if( zBuf[nBuf-2]!=0 || (iLimit++)>10 ) return SQLITE_ERROR; + }while( osAccess(zBuf,0)==0 ); + return SQLITE_OK; } #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) /* ** Routine to transform a unixFile into a proxy-locking unixFile. @@ -43134,27 +40798,24 @@ ** "-journalNN" ** "-walNN" ** ** where NN is a decimal number. The NN naming schemes are ** used by the test_multiplex.c module. - ** - ** In normal operation, the journal file name will always contain - ** a '-' character. However in 8+3 filename mode, or if a corrupt - ** rollback journal specifies a super-journal with a goofy name, then - ** the '-' might be missing or the '-' might be the first character in - ** the filename. In that case, just return SQLITE_OK with *pMode==0. */ nDb = sqlite3Strlen30(zPath) - 1; - while( nDb>0 && zPath[nDb]!='.' ){ - if( zPath[nDb]=='-' ){ - memcpy(zDb, zPath, nDb); - zDb[nDb] = '\0'; - rc = getFileMode(zDb, pMode, pUid, pGid); - break; - } + while( zPath[nDb]!='-' ){ + /* In normal operation, the journal file name will always contain + ** a '-' character. However in 8+3 filename mode, or if a corrupt + ** rollback journal specifies a super-journal with a goofy name, then + ** the '-' might be missing. */ + if( nDb==0 || zPath[nDb]=='.' ) return SQLITE_OK; nDb--; } + memcpy(zDb, zPath, nDb); + zDb[nDb] = '\0'; + + rc = getFileMode(zDb, pMode, pUid, pGid); }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){ *pMode = 0600; }else if( flags & SQLITE_OPEN_URI ){ /* If this is a main database file and the file was opened using a URI ** filename, check for the "modeof" parameter. If present, interpret @@ -43540,101 +41201,90 @@ } return SQLITE_OK; } /* -** A pathname under construction -*/ -typedef struct DbPath DbPath; -struct DbPath { - int rc; /* Non-zero following any error */ - int nSymlink; /* Number of symlinks resolved */ - char *zOut; /* Write the pathname here */ - int nOut; /* Bytes of space available to zOut[] */ - int nUsed; /* Bytes of zOut[] currently being used */ -}; - -/* Forward reference */ -static void appendAllPathElements(DbPath*,const char*); - -/* -** Append a single path element to the DbPath under construction -*/ -static void appendOnePathElement( - DbPath *pPath, /* Path under construction, to which to append zName */ - const char *zName, /* Name to append to pPath. Not zero-terminated */ - int nName /* Number of significant bytes in zName */ -){ - assert( nName>0 ); - assert( zName!=0 ); - if( zName[0]=='.' ){ - if( nName==1 ) return; - if( zName[1]=='.' && nName==2 ){ - if( pPath->nUsed>1 ){ - assert( pPath->zOut[0]=='/' ); - while( pPath->zOut[--pPath->nUsed]!='/' ){} - } - return; - } - } - if( pPath->nUsed + nName + 2 >= pPath->nOut ){ - pPath->rc = SQLITE_ERROR; - return; - } - pPath->zOut[pPath->nUsed++] = '/'; - memcpy(&pPath->zOut[pPath->nUsed], zName, nName); - pPath->nUsed += nName; -#if defined(HAVE_READLINK) && defined(HAVE_LSTAT) - if( pPath->rc==SQLITE_OK ){ - const char *zIn; - struct stat buf; - pPath->zOut[pPath->nUsed] = 0; - zIn = pPath->zOut; - if( osLstat(zIn, &buf)!=0 ){ - if( errno!=ENOENT ){ - pPath->rc = unixLogError(SQLITE_CANTOPEN_BKPT, "lstat", zIn); - } - }else if( S_ISLNK(buf.st_mode) ){ - ssize_t got; - char zLnk[SQLITE_MAX_PATHLEN+2]; - if( pPath->nSymlink++ > SQLITE_MAX_SYMLINK ){ - pPath->rc = SQLITE_CANTOPEN_BKPT; - return; - } - got = osReadlink(zIn, zLnk, sizeof(zLnk)-2); - if( got<=0 || got>=(ssize_t)sizeof(zLnk)-2 ){ - pPath->rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zIn); - return; - } - zLnk[got] = 0; - if( zLnk[0]=='/' ){ - pPath->nUsed = 0; - }else{ - pPath->nUsed -= nName + 1; - } - appendAllPathElements(pPath, zLnk); - } - } -#endif -} - -/* -** Append all path elements in zPath to the DbPath under construction. -*/ -static void appendAllPathElements( - DbPath *pPath, /* Path under construction, to which to append zName */ - const char *zPath /* Path to append to pPath. Is zero-terminated */ -){ - int i = 0; - int j = 0; - do{ - while( zPath[i] && zPath[i]!='/' ){ i++; } - if( i>j ){ - appendOnePathElement(pPath, &zPath[j], i-j); - } - j = i+1; - }while( zPath[i++] ); +** If the last component of the pathname in z[0]..z[j-1] is something +** other than ".." then back it out and return true. If the last +** component is empty or if it is ".." then return false. +*/ +static int unixBackupDir(const char *z, int *pJ){ + int j = *pJ; + int i; + if( j<=0 ) return 0; + for(i=j-1; i>0 && z[i-1]!='/'; i--){} + if( i==0 ) return 0; + if( z[i]=='.' && i==j-2 && z[i+1]=='.' ) return 0; + *pJ = i-1; + return 1; +} + +/* +** Convert a relative pathname into a full pathname. Also +** simplify the pathname as follows: +** +** Remove all instances of /./ +** Remove all isntances of /X/../ for any X +*/ +static int mkFullPathname( + const char *zPath, /* Input path */ + char *zOut, /* Output buffer */ + int nOut /* Allocated size of buffer zOut */ +){ + int nPath = sqlite3Strlen30(zPath); + int iOff = 0; + int i, j; + if( zPath[0]!='/' ){ + if( osGetcwd(zOut, nOut-2)==0 ){ + return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath); + } + iOff = sqlite3Strlen30(zOut); + zOut[iOff++] = '/'; + } + if( (iOff+nPath+1)>nOut ){ + /* SQLite assumes that xFullPathname() nul-terminates the output buffer + ** even if it returns an error. */ + zOut[iOff] = '\0'; + return SQLITE_CANTOPEN_BKPT; + } + sqlite3_snprintf(nOut-iOff, &zOut[iOff], "%s", zPath); + + /* Remove duplicate '/' characters. Except, two // at the beginning + ** of a pathname is allowed since this is important on windows. */ + for(i=j=1; zOut[i]; i++){ + zOut[j++] = zOut[i]; + while( zOut[i]=='/' && zOut[i+1]=='/' ) i++; + } + zOut[j] = 0; + + assert( zOut[0]=='/' ); + for(i=j=0; zOut[i]; i++){ + if( zOut[i]=='/' ){ + /* Skip over internal "/." directory components */ + if( zOut[i+1]=='.' && zOut[i+2]=='/' ){ + i += 1; + continue; + } + + /* If this is a "/.." directory component then back out the + ** previous term of the directory if it is something other than "..". + */ + if( zOut[i+1]=='.' + && zOut[i+2]=='.' + && zOut[i+3]=='/' + && unixBackupDir(zOut, &j) + ){ + i += 2; + continue; + } + } + if( ALWAYS(j>=0) ) zOut[j] = zOut[i]; + j++; + } + if( NEVER(j==0) ) zOut[j++] = '/'; + zOut[j] = 0; + return SQLITE_OK; } /* ** Turn a relative pathname into a full pathname. The relative path ** is stored as a nul-terminated string in the buffer pointed to by @@ -43648,30 +41298,89 @@ sqlite3_vfs *pVfs, /* Pointer to vfs object */ const char *zPath, /* Possibly relative input path */ int nOut, /* Size of output buffer in bytes */ char *zOut /* Output buffer */ ){ - DbPath path; +#if !defined(HAVE_READLINK) || !defined(HAVE_LSTAT) + return mkFullPathname(zPath, zOut, nOut); +#else + int rc = SQLITE_OK; + int nByte; + int nLink = 0; /* Number of symbolic links followed so far */ + const char *zIn = zPath; /* Input path for each iteration of loop */ + char *zDel = 0; + + assert( pVfs->mxPathname==MAX_PATHNAME ); UNUSED_PARAMETER(pVfs); - path.rc = 0; - path.nUsed = 0; - path.nSymlink = 0; - path.nOut = nOut; - path.zOut = zOut; - if( zPath[0]!='/' ){ - char zPwd[SQLITE_MAX_PATHLEN+2]; - if( osGetcwd(zPwd, sizeof(zPwd)-2)==0 ){ - return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath); - } - appendAllPathElements(&path, zPwd); - } - appendAllPathElements(&path, zPath); - zOut[path.nUsed] = 0; - if( path.rc || path.nUsed<2 ) return SQLITE_CANTOPEN_BKPT; - if( path.nSymlink ) return SQLITE_OK_SYMLINK; - return SQLITE_OK; -} + + /* It's odd to simulate an io-error here, but really this is just + ** using the io-error infrastructure to test that SQLite handles this + ** function failing. This function could fail if, for example, the + ** current working directory has been unlinked. + */ + SimulateIOError( return SQLITE_ERROR ); + + do { + + /* Call stat() on path zIn. Set bLink to true if the path is a symbolic + ** link, or false otherwise. */ + int bLink = 0; + struct stat buf; + if( osLstat(zIn, &buf)!=0 ){ + if( errno!=ENOENT ){ + rc = unixLogError(SQLITE_CANTOPEN_BKPT, "lstat", zIn); + } + }else{ + bLink = S_ISLNK(buf.st_mode); + } + + if( bLink ){ + nLink++; + if( zDel==0 ){ + zDel = sqlite3_malloc(nOut); + if( zDel==0 ) rc = SQLITE_NOMEM_BKPT; + }else if( nLink>=SQLITE_MAX_SYMLINKS ){ + rc = SQLITE_CANTOPEN_BKPT; + } + + if( rc==SQLITE_OK ){ + nByte = osReadlink(zIn, zDel, nOut-1); + if( nByte<0 ){ + rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zIn); + }else{ + if( zDel[0]!='/' ){ + int n; + for(n = sqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--); + if( nByte+n+1>nOut ){ + rc = SQLITE_CANTOPEN_BKPT; + }else{ + memmove(&zDel[n], zDel, nByte+1); + memcpy(zDel, zIn, n); + nByte += n; + } + } + zDel[nByte] = '\0'; + } + } + + zIn = zDel; + } + + assert( rc!=SQLITE_OK || zIn!=zOut || zIn[0]=='/' ); + if( rc==SQLITE_OK && zIn!=zOut ){ + rc = mkFullPathname(zIn, zOut, nOut); + } + if( bLink==0 ) break; + zIn = zOut; + }while( rc==SQLITE_OK ); + + sqlite3_free(zDel); + if( rc==SQLITE_OK && nLink ) rc = SQLITE_OK_SYMLINK; + return rc; +#endif /* HAVE_READLINK && HAVE_LSTAT */ +} + #ifndef SQLITE_OMIT_LOAD_EXTENSION /* ** Interfaces for opening a shared library, finding entry points ** within the shared library, and closing the shared library. @@ -43782,11 +41491,11 @@ ** requested from the underlying operating system, a number which ** might be greater than or equal to the argument, but not less ** than the argument. */ static int unixSleep(sqlite3_vfs *NotUsed, int microseconds){ -#if OS_VXWORKS || _POSIX_C_SOURCE >= 199309L +#if OS_VXWORKS struct timespec sp; sp.tv_sec = microseconds / 1000000; sp.tv_nsec = (microseconds % 1000000) * 1000; nanosleep(&sp, NULL); @@ -45164,20 +42873,12 @@ ** correctly. See ticket [bb3a86e890c8e96ab] */ assert( ArraySize(aSyscall)==29 ); /* Register all VFSes defined in the aVfs[] array */ for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ -#ifdef SQLITE_DEFAULT_UNIX_VFS - sqlite3_vfs_register(&aVfs[i], - 0==strcmp(aVfs[i].zName,SQLITE_DEFAULT_UNIX_VFS)); -#else sqlite3_vfs_register(&aVfs[i], i==0); -#endif } -#ifdef SQLITE_OS_KV_OPTIONAL - sqlite3KvvfsInit(); -#endif unixBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); #ifndef SQLITE_OMIT_WAL /* Validate lock assumptions */ assert( SQLITE_SHM_NLOCK==8 ); /* Number of available locks */ @@ -47136,16 +44837,14 @@ SQLITE_API int sqlite3_win32_set_directory8( unsigned long type, /* Identifier for directory being set or reset */ const char *zValue /* New value for directory being set or reset */ ){ char **ppDirectory = 0; - int rc; #ifndef SQLITE_OMIT_AUTOINIT - rc = sqlite3_initialize(); + int rc = sqlite3_initialize(); if( rc ) return rc; #endif - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); if( type==SQLITE_WIN32_DATA_DIRECTORY_TYPE ){ ppDirectory = &sqlite3_data_directory; }else if( type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE ){ ppDirectory = &sqlite3_temp_directory; } @@ -47156,23 +44855,18 @@ if( ppDirectory ){ char *zCopy = 0; if( zValue && zValue[0] ){ zCopy = sqlite3_mprintf("%s", zValue); if ( zCopy==0 ){ - rc = SQLITE_NOMEM_BKPT; - goto set_directory8_done; + return SQLITE_NOMEM_BKPT; } } sqlite3_free(*ppDirectory); *ppDirectory = zCopy; - rc = SQLITE_OK; - }else{ - rc = SQLITE_ERROR; + return SQLITE_OK; } -set_directory8_done: - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); - return rc; + return SQLITE_ERROR; } /* ** This function is the same as sqlite3_win32_set_directory (below); however, ** it accepts a UTF-16 string. @@ -49942,23 +47636,10 @@ } } return 0; } -/* -** If sqlite3_temp_directory is defined, take the mutex and return true. -** -** If sqlite3_temp_directory is NULL (undefined), omit the mutex and -** return false. -*/ -static int winTempDirDefined(void){ - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); - if( sqlite3_temp_directory!=0 ) return 1; - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); - return 0; -} - /* ** Create a temporary file name and store the resulting pointer into pzBuf. ** The pointer returned in pzBuf must be freed via sqlite3_free(). */ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ @@ -49991,27 +47672,24 @@ ** has been explicitly set by the application; otherwise, use the one ** configured by the operating system. */ nDir = nMax - (nPre + 15); assert( nDir>0 ); - if( winTempDirDefined() ){ + if( sqlite3_temp_directory ){ int nDirLen = sqlite3Strlen30(sqlite3_temp_directory); if( nDirLen>0 ){ if( !winIsDirSep(sqlite3_temp_directory[nDirLen-1]) ){ nDirLen++; } if( nDirLen>nDir ){ - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); sqlite3_free(zBuf); OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); return winLogError(SQLITE_ERROR, 0, "winGetTempname1", 0); } sqlite3_snprintf(nMax, zBuf, "%s", sqlite3_temp_directory); } - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); } - #if defined(__CYGWIN__) else{ static const char *azDirs[] = { 0, /* getenv("SQLITE_TMPDIR") */ 0, /* getenv("TMPDIR") */ @@ -50796,11 +48474,11 @@ /* ** Turn a relative pathname into a full pathname. Write the full ** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname ** bytes in size. */ -static int winFullPathnameNoMutex( +static int winFullPathname( sqlite3_vfs *pVfs, /* Pointer to vfs object */ const char *zRelative, /* Possibly relative input path */ int nFull, /* Size of output buffer in bytes */ char *zFull /* Output buffer */ ){ @@ -50975,24 +48653,10 @@ }else{ return SQLITE_IOERR_NOMEM_BKPT; } #endif } -static int winFullPathname( - sqlite3_vfs *pVfs, /* Pointer to vfs object */ - const char *zRelative, /* Possibly relative input path */ - int nFull, /* Size of output buffer in bytes */ - char *zFull /* Output buffer */ -){ - int rc; - MUTEX_LOGIC( sqlite3_mutex *pMutex; ) - MUTEX_LOGIC( pMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR); ) - sqlite3_mutex_enter(pMutex); - rc = winFullPathnameNoMutex(pVfs, zRelative, nFull, zFull); - sqlite3_mutex_leave(pMutex); - return rc; -} #ifndef SQLITE_OMIT_LOAD_EXTENSION /* ** Interfaces for opening a shared library, finding entry points ** within the shared library, and closing the shared library. @@ -51525,11 +49189,10 @@ static int memdbWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst); static int memdbTruncate(sqlite3_file*, sqlite3_int64 size); static int memdbSync(sqlite3_file*, int flags); static int memdbFileSize(sqlite3_file*, sqlite3_int64 *pSize); static int memdbLock(sqlite3_file*, int); -static int memdbUnlock(sqlite3_file*, int); /* static int memdbCheckReservedLock(sqlite3_file*, int *pResOut);// not used */ static int memdbFileControl(sqlite3_file*, int op, void *pArg); /* static int memdbSectorSize(sqlite3_file*); // not used */ static int memdbDeviceCharacteristics(sqlite3_file*); static int memdbFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); @@ -51584,11 +49247,11 @@ memdbWrite, /* xWrite */ memdbTruncate, /* xTruncate */ memdbSync, /* xSync */ memdbFileSize, /* xFileSize */ memdbLock, /* xLock */ - memdbUnlock, /* xUnlock */ + memdbLock, /* xUnlock - same as xLock in this case */ 0, /* memdbCheckReservedLock, */ /* xCheckReservedLock */ memdbFileControl, /* xFileControl */ 0, /* memdbSectorSize,*/ /* xSectorSize */ memdbDeviceCharacteristics, /* xDeviceCharacteristics */ 0, /* xShmMap */ @@ -51785,87 +49448,45 @@ */ static int memdbLock(sqlite3_file *pFile, int eLock){ MemFile *pThis = (MemFile*)pFile; MemStore *p = pThis->pStore; int rc = SQLITE_OK; - if( eLock<=pThis->eLock ) return SQLITE_OK; + if( eLock==pThis->eLock ) return SQLITE_OK; memdbEnter(p); - - assert( p->nWrLock==0 || p->nWrLock==1 ); - assert( pThis->eLock<=SQLITE_LOCK_SHARED || p->nWrLock==1 ); - assert( pThis->eLock==SQLITE_LOCK_NONE || p->nRdLock>=1 ); - - if( eLock>SQLITE_LOCK_SHARED && (p->mFlags & SQLITE_DESERIALIZE_READONLY) ){ - rc = SQLITE_READONLY; - }else{ - switch( eLock ){ - case SQLITE_LOCK_SHARED: { - assert( pThis->eLock==SQLITE_LOCK_NONE ); - if( p->nWrLock>0 ){ - rc = SQLITE_BUSY; - }else{ - p->nRdLock++; - } - break; - }; - - case SQLITE_LOCK_RESERVED: - case SQLITE_LOCK_PENDING: { - assert( pThis->eLock>=SQLITE_LOCK_SHARED ); - if( ALWAYS(pThis->eLock==SQLITE_LOCK_SHARED) ){ - if( p->nWrLock>0 ){ - rc = SQLITE_BUSY; - }else{ - p->nWrLock = 1; - } - } - break; - } - - default: { - assert( eLock==SQLITE_LOCK_EXCLUSIVE ); - assert( pThis->eLock>=SQLITE_LOCK_SHARED ); - if( p->nRdLock>1 ){ - rc = SQLITE_BUSY; - }else if( pThis->eLock==SQLITE_LOCK_SHARED ){ - p->nWrLock = 1; - } - break; - } - } + if( eLock>SQLITE_LOCK_SHARED ){ + if( p->mFlags & SQLITE_DESERIALIZE_READONLY ){ + rc = SQLITE_READONLY; + }else if( pThis->eLock<=SQLITE_LOCK_SHARED ){ + if( p->nWrLock ){ + rc = SQLITE_BUSY; + }else{ + p->nWrLock = 1; + } + } + }else if( eLock==SQLITE_LOCK_SHARED ){ + if( pThis->eLock > SQLITE_LOCK_SHARED ){ + assert( p->nWrLock==1 ); + p->nWrLock = 0; + }else if( p->nWrLock ){ + rc = SQLITE_BUSY; + }else{ + p->nRdLock++; + } + }else{ + assert( eLock==SQLITE_LOCK_NONE ); + if( pThis->eLock>SQLITE_LOCK_SHARED ){ + assert( p->nWrLock==1 ); + p->nWrLock = 0; + } + assert( p->nRdLock>0 ); + p->nRdLock--; } if( rc==SQLITE_OK ) pThis->eLock = eLock; memdbLeave(p); return rc; } -/* -** Unlock an memdb-file. -*/ -static int memdbUnlock(sqlite3_file *pFile, int eLock){ - MemFile *pThis = (MemFile*)pFile; - MemStore *p = pThis->pStore; - if( eLock>=pThis->eLock ) return SQLITE_OK; - memdbEnter(p); - - assert( eLock==SQLITE_LOCK_SHARED || eLock==SQLITE_LOCK_NONE ); - if( eLock==SQLITE_LOCK_SHARED ){ - if( ALWAYS(pThis->eLock>SQLITE_LOCK_SHARED) ){ - p->nWrLock--; - } - }else{ - if( pThis->eLock>SQLITE_LOCK_SHARED ){ - p->nWrLock--; - } - p->nRdLock--; - } - - pThis->eLock = eLock; - memdbLeave(p); - return SQLITE_OK; -} - #if 0 /* ** This interface is only used for crash recovery, which does not ** occur on an in-memory database. */ @@ -51969,11 +49590,11 @@ int szName; UNUSED_PARAMETER(pVfs); memset(pFile, 0, sizeof(*pFile)); szName = sqlite3Strlen30(zName); - if( szName>1 && (zName[0]=='/' || zName[0]=='\\') ){ + if( szName>1 && zName[0]=='/' ){ int i; #ifndef SQLITE_MUTEX_OMIT sqlite3_mutex *pVfsMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); #endif sqlite3_mutex_enter(pVfsMutex); @@ -52316,17 +49937,10 @@ } sqlite3_mutex_leave(db->mutex); return rc; } -/* -** Return true if the VFS is the memvfs. -*/ -SQLITE_PRIVATE int sqlite3IsMemdb(const sqlite3_vfs *pVfs){ - return pVfs==&memdb_vfs; -} - /* ** This routine is called when the extension is loaded. ** Register the new VFS. */ SQLITE_PRIVATE int sqlite3MemdbInit(void){ @@ -52802,11 +50416,11 @@ ** pointers). */ struct PCache { PgHdr *pDirty, *pDirtyTail; /* List of dirty pages in LRU order */ PgHdr *pSynced; /* Last synced page in dirty page list */ - i64 nRefSum; /* Sum of ref counts over all pages */ + int nRefSum; /* Sum of ref counts over all pages */ int szCache; /* Configured cache size */ int szSpill; /* Size before spilling occurs */ int szPage; /* Size of every page in this cache */ int szExtra; /* Size of extra space for each page */ u8 bPurgeable; /* True if pages are on backing store */ @@ -52827,56 +50441,37 @@ */ #if defined(SQLITE_DEBUG) && 0 int sqlite3PcacheTrace = 2; /* 0: off 1: simple 2: cache dumps */ int sqlite3PcacheMxDump = 9999; /* Max cache entries for pcacheDump() */ # define pcacheTrace(X) if(sqlite3PcacheTrace){sqlite3DebugPrintf X;} - static void pcachePageTrace(int i, sqlite3_pcache_page *pLower){ + void pcacheDump(PCache *pCache){ + int N; + int i, j; + sqlite3_pcache_page *pLower; PgHdr *pPg; unsigned char *a; - int j; - pPg = (PgHdr*)pLower->pExtra; - printf("%3lld: nRef %2d flgs %02x data ", i, pPg->nRef, pPg->flags); - a = (unsigned char *)pLower->pBuf; - for(j=0; j<12; j++) printf("%02x", a[j]); - printf(" ptr %p\n", pPg); - } - static void pcacheDump(PCache *pCache){ - int N; - int i; - sqlite3_pcache_page *pLower; if( sqlite3PcacheTrace<2 ) return; if( pCache->pCache==0 ) return; N = sqlite3PcachePagecount(pCache); if( N>sqlite3PcacheMxDump ) N = sqlite3PcacheMxDump; for(i=1; i<=N; i++){ pLower = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, i, 0); if( pLower==0 ) continue; - pcachePageTrace(i, pLower); - if( ((PgHdr*)pLower)->pPage==0 ){ + pPg = (PgHdr*)pLower->pExtra; + printf("%3d: nRef %2d flgs %02x data ", i, pPg->nRef, pPg->flags); + a = (unsigned char *)pLower->pBuf; + for(j=0; j<12; j++) printf("%02x", a[j]); + printf("\n"); + if( pPg->pPage==0 ){ sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, pLower, 0); } } } -#else + #else # define pcacheTrace(X) -# define pcachePageTrace(PGNO, X) # define pcacheDump(X) -#endif - -/* -** Return 1 if pPg is on the dirty list for pCache. Return 0 if not. -** This routine runs inside of assert() statements only. -*/ -#ifdef SQLITE_DEBUG -static int pageOnDirtyList(PCache *pCache, PgHdr *pPg){ - PgHdr *p; - for(p=pCache->pDirty; p; p=p->pDirtyNext){ - if( p==pPg ) return 1; - } - return 0; -} #endif /* ** Check invariants on a PgHdr entry. Return true if everything is OK. ** Return false if any invariant is violated. @@ -52893,17 +50488,12 @@ assert( pPg->pgno>0 || pPg->pPager==0 ); /* Page number is 1 or more */ pCache = pPg->pCache; assert( pCache!=0 ); /* Every page has an associated PCache */ if( pPg->flags & PGHDR_CLEAN ){ assert( (pPg->flags & PGHDR_DIRTY)==0 );/* Cannot be both CLEAN and DIRTY */ - assert( !pageOnDirtyList(pCache, pPg) );/* CLEAN pages not on dirty list */ - }else{ - assert( (pPg->flags & PGHDR_DIRTY)!=0 );/* If not CLEAN must be DIRTY */ - assert( pPg->pDirtyNext==0 || pPg->pDirtyNext->pDirtyPrev==pPg ); - assert( pPg->pDirtyPrev==0 || pPg->pDirtyPrev->pDirtyNext==pPg ); - assert( pPg->pDirtyPrev!=0 || pCache->pDirty==pPg ); - assert( pageOnDirtyList(pCache, pPg) ); + assert( pCache->pDirty!=pPg ); /* CLEAN pages not on dirty list */ + assert( pCache->pDirtyTail!=pPg ); } /* WRITEABLE pages must also be DIRTY */ if( pPg->flags & PGHDR_WRITEABLE ){ assert( pPg->flags & PGHDR_DIRTY ); /* WRITEABLE implies DIRTY */ } @@ -53173,13 +50763,12 @@ eCreate = createFlag & pCache->eCreate; assert( eCreate==0 || eCreate==1 || eCreate==2 ); assert( createFlag==0 || pCache->eCreate==eCreate ); assert( createFlag==0 || eCreate==1+(!pCache->bPurgeable||!pCache->pDirty) ); pRes = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate); - pcacheTrace(("%p.FETCH %d%s (result: %p) ",pCache,pgno, + pcacheTrace(("%p.FETCH %d%s (result: %p)\n",pCache,pgno, createFlag?" create":"",pRes)); - pcachePageTrace(pgno, pRes); return pRes; } /* ** If the sqlite3PcacheFetch() routine is unable to allocate a new @@ -53303,11 +50892,10 @@ if( (--p->nRef)==0 ){ if( p->flags&PGHDR_CLEAN ){ pcacheUnpin(p); }else{ pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); - assert( sqlite3PcachePageSanity(p) ); } } } /* @@ -53338,20 +50926,20 @@ /* ** Make sure the page is marked as dirty. If it isn't dirty already, ** make it so. */ SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){ - assert( p->nRef>0 ); + assert( p->nRef>0 || p->pCache->bPurgeable==0 ); + testcase( p->nRef==0 ); assert( sqlite3PcachePageSanity(p) ); if( p->flags & (PGHDR_CLEAN|PGHDR_DONT_WRITE) ){ /*OPTIMIZATION-IF-FALSE*/ p->flags &= ~PGHDR_DONT_WRITE; if( p->flags & PGHDR_CLEAN ){ p->flags ^= (PGHDR_DIRTY|PGHDR_CLEAN); pcacheTrace(("%p.DIRTY %d\n",p->pCache,p->pgno)); assert( (p->flags & (PGHDR_DIRTY|PGHDR_CLEAN))==PGHDR_DIRTY ); pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD); - assert( sqlite3PcachePageSanity(p) ); } assert( sqlite3PcachePageSanity(p) ); } } @@ -53410,28 +50998,18 @@ /* ** Change the page number of page p to newPgno. */ SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){ PCache *pCache = p->pCache; - sqlite3_pcache_page *pOther; assert( p->nRef>0 ); assert( newPgno>0 ); assert( sqlite3PcachePageSanity(p) ); pcacheTrace(("%p.MOVE %d -> %d\n",pCache,p->pgno,newPgno)); - pOther = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, newPgno, 0); - if( pOther ){ - PgHdr *pXPage = (PgHdr*)pOther->pExtra; - assert( pXPage->nRef==0 ); - pXPage->nRef++; - pCache->nRefSum++; - sqlite3PcacheDrop(pXPage); - } sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno); p->pgno = newPgno; if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){ pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); - assert( sqlite3PcachePageSanity(p) ); } } /* ** Drop every cache entry whose page number is greater than "pgno". The @@ -53576,18 +51154,18 @@ ** Return the total number of references to all pages held by the cache. ** ** This is not the total number of pages referenced, but the sum of the ** reference count for all pages. */ -SQLITE_PRIVATE i64 sqlite3PcacheRefCount(PCache *pCache){ +SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache *pCache){ return pCache->nRefSum; } /* ** Return the number of references to the page supplied as an argument. */ -SQLITE_PRIVATE i64 sqlite3PcachePageRefcount(PgHdr *p){ +SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr *p){ return p->nRef; } /* ** Return the total number of pages in the cache. @@ -53725,17 +51303,16 @@ ** runtime using sqlite3_config(SQLITE_CONFIG_PCACHE_HDRSZ, &size). The ** sizes of the extensions sum to 272 bytes on x64 for 3.8.10, but this ** size can vary according to architecture, compile-time options, and ** SQLite library version number. ** -** Historical note: It used to be that if the SQLITE_PCACHE_SEPARATE_HEADER -** was defined, then the page content would be held in a separate memory -** allocation from the PgHdr1. This was intended to avoid clownshoe memory -** allocations. However, the btree layer needs a small (16-byte) overrun -** area after the page content buffer. The header serves as that overrun -** area. Therefore SQLITE_PCACHE_SEPARATE_HEADER was discontinued to avoid -** any possibility of a memory error. +** If SQLITE_PCACHE_SEPARATE_HEADER is defined, then the extension is obtained +** using a separate memory allocation from the database page content. This +** seeks to overcome the "clownshoe" problem (also called "internal +** fragmentation" in academic literature) of allocating a few bytes more +** than a power of two with the memory allocator rounding up to the next +** power of two, and leaving the rounded-up space unused. ** ** This module tracks pointers to PgHdr1 objects. Only pcache.c communicates ** with this module. Information is passed back and forth as PgHdr1 pointers. ** ** The pcache.c and pager.c modules deal pointers to PgHdr objects. @@ -53776,44 +51353,34 @@ typedef struct PgFreeslot PgFreeslot; typedef struct PGroup PGroup; /* ** Each cache entry is represented by an instance of the following -** structure. A buffer of PgHdr1.pCache->szPage bytes is allocated -** directly before this structure and is used to cache the page content. -** -** When reading a corrupt database file, it is possible that SQLite might -** read a few bytes (no more than 16 bytes) past the end of the page buffer. -** It will only read past the end of the page buffer, never write. This -** object is positioned immediately after the page buffer to serve as an -** overrun area, so that overreads are harmless. -** -** Variables isBulkLocal and isAnchor were once type "u8". That works, +** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of +** PgHdr1.pCache->szPage bytes is allocated directly before this structure +** in memory. +** +** Note: Variables isBulkLocal and isAnchor were once type "u8". That works, ** but causes a 2-byte gap in the structure for most architectures (since ** pointers must be either 4 or 8-byte aligned). As this structure is located ** in memory directly after the associated page data, if the database is ** corrupt, code at the b-tree layer may overread the page buffer and ** read part of this structure before the corruption is detected. This ** can cause a valgrind error if the unitialized gap is accessed. Using u16 -** ensures there is no such gap, and therefore no bytes of uninitialized -** memory in the structure. -** -** The pLruNext and pLruPrev pointers form a double-linked circular list -** of all pages that are unpinned. The PGroup.lru element (which should be -** the only element on the list with PgHdr1.isAnchor set to 1) forms the -** beginning and the end of the list. +** ensures there is no such gap, and therefore no bytes of unitialized memory +** in the structure. */ struct PgHdr1 { - sqlite3_pcache_page page; /* Base class. Must be first. pBuf & pExtra */ - unsigned int iKey; /* Key value (page number) */ - u16 isBulkLocal; /* This page from bulk local storage */ - u16 isAnchor; /* This is the PGroup.lru element */ - PgHdr1 *pNext; /* Next in hash table chain */ - PCache1 *pCache; /* Cache that currently owns this page */ - PgHdr1 *pLruNext; /* Next in circular LRU list of unpinned pages */ - PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */ - /* NB: pLruPrev is only valid if pLruNext!=0 */ + sqlite3_pcache_page page; /* Base class. Must be first. pBuf & pExtra */ + unsigned int iKey; /* Key value (page number) */ + u16 isBulkLocal; /* This page from bulk local storage */ + u16 isAnchor; /* This is the PGroup.lru element */ + PgHdr1 *pNext; /* Next in hash table chain */ + PCache1 *pCache; /* Cache that currently owns this page */ + PgHdr1 *pLruNext; /* Next in LRU list of unpinned pages */ + PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */ + /* NB: pLruPrev is only valid if pLruNext!=0 */ }; /* ** A page is pinned if it is not on the LRU list. To be "pinned" means ** that the page is in active use and must not be deallocated. @@ -54135,17 +51702,29 @@ assert( pcache1.separateCache==0 ); assert( pCache->pGroup==&pcache1.grp ); pcache1LeaveMutex(pCache->pGroup); #endif if( benignMalloc ){ sqlite3BeginBenignMalloc(); } +#ifdef SQLITE_PCACHE_SEPARATE_HEADER + pPg = pcache1Alloc(pCache->szPage); + p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra); + if( !pPg || !p ){ + pcache1Free(pPg); + sqlite3_free(p); + pPg = 0; + } +#else pPg = pcache1Alloc(pCache->szAlloc); +#endif if( benignMalloc ){ sqlite3EndBenignMalloc(); } #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT pcache1EnterMutex(pCache->pGroup); #endif if( pPg==0 ) return 0; +#ifndef SQLITE_PCACHE_SEPARATE_HEADER p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage]; +#endif p->page.pBuf = pPg; p->page.pExtra = &p[1]; p->isBulkLocal = 0; p->isAnchor = 0; p->pLruPrev = 0; /* Initializing this saves a valgrind error */ @@ -54165,10 +51744,13 @@ if( p->isBulkLocal ){ p->pNext = pCache->pFree; pCache->pFree = p; }else{ pcache1Free(p->page.pBuf); +#ifdef SQLITE_PCACHE_SEPARATE_HEADER + sqlite3_free(p); +#endif } (*pCache->pnPurgeable)--; } /* @@ -54805,30 +52387,27 @@ unsigned int iNew ){ PCache1 *pCache = (PCache1 *)p; PgHdr1 *pPage = (PgHdr1 *)pPg; PgHdr1 **pp; - unsigned int hOld, hNew; + unsigned int h; assert( pPage->iKey==iOld ); assert( pPage->pCache==pCache ); - assert( iOld!=iNew ); /* The page number really is changing */ pcache1EnterMutex(pCache->pGroup); - assert( pcache1FetchNoMutex(p, iOld, 0)==pPage ); /* pPg really is iOld */ - hOld = iOld%pCache->nHash; - pp = &pCache->apHash[hOld]; + h = iOld%pCache->nHash; + pp = &pCache->apHash[h]; while( (*pp)!=pPage ){ pp = &(*pp)->pNext; } *pp = pPage->pNext; - assert( pcache1FetchNoMutex(p, iNew, 0)==0 ); /* iNew not in cache */ - hNew = iNew%pCache->nHash; + h = iNew%pCache->nHash; pPage->iKey = iNew; - pPage->pNext = pCache->apHash[hNew]; - pCache->apHash[hNew] = pPage; + pPage->pNext = pCache->apHash[h]; + pCache->apHash[h] = pPage; if( iNew>pCache->iMaxKey ){ pCache->iMaxKey = iNew; } pcache1LeaveMutex(pCache->pGroup); @@ -54931,10 +52510,13 @@ while( (nReq<0 || nFreeisAnchor==0 ){ nFree += pcache1MemSize(p->page.pBuf); +#ifdef SQLITE_PCACHE_SEPARATE_HEADER + nFree += sqlite3MemSize(p); +#endif assert( PAGE_IS_UNPINNED(p) ); pcache1PinPage(p); pcache1RemoveFromHash(p, 1); } pcache1LeaveMutex(&pcache1.grp); @@ -56314,11 +53896,10 @@ u16 nExtra; /* Add this many bytes to each in-memory page */ i16 nReserve; /* Number of unused bytes at end of each page */ u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */ u32 sectorSize; /* Assumed sector size during rollback */ Pgno mxPgno; /* Maximum allowed size of the database */ - Pgno lckPgno; /* Page number for the locking page */ i64 pageSize; /* Number of bytes in a page */ i64 journalSizeLimit; /* Size limit for persistent journal files */ char *zFilename; /* Name of the database file */ char *zJournal; /* Name of the journal file */ int (*xBusyHandler)(void*); /* Function to call when busy */ @@ -57301,11 +54882,11 @@ ** pPager at the current location. The super-journal name must be the last ** thing written to a journal file. If the pager is in full-sync mode, the ** journal file descriptor is advanced to the next sector boundary before ** anything is written. The format is: ** -** + 4 bytes: PAGER_SJ_PGNO. +** + 4 bytes: PAGER_MJ_PGNO. ** + N bytes: super-journal filename in utf-8. ** + 4 bytes: N (length of super-journal name in bytes, no nul-terminator). ** + 4 bytes: super-journal name checksum. ** + 8 bytes: aJournalMagic[]. ** @@ -57349,11 +54930,11 @@ iHdrOff = pPager->journalOff; /* Write the super-journal data to the end of the journal file. If ** an error occurs, return the error code to the caller. */ - if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_SJ_PGNO(pPager)))) + if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_MJ_PGNO(pPager)))) || (0 != (rc = sqlite3OsWrite(pPager->jfd, zSuper, nSuper, iHdrOff+4))) || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nSuper, nSuper))) || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nSuper+4, cksum))) || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8, iHdrOff+4+nSuper+8))) @@ -57859,11 +55440,11 @@ ** to the database file, then the IO error code is returned. If data ** is successfully read from the (sub-)journal file but appears to be ** corrupted, SQLITE_DONE is returned. Data is considered corrupted in ** two circumstances: ** -** * If the record page-number is illegal (0 or PAGER_SJ_PGNO), or +** * If the record page-number is illegal (0 or PAGER_MJ_PGNO), or ** * If the record is being rolled back from the main journal file ** and the checksum field does not match the record content. ** ** Neither of these two scenarios are possible during a savepoint rollback. ** @@ -57919,11 +55500,11 @@ /* Sanity checking on the page. This is more important that I originally ** thought. If a power failure occurs while the journal is being written, ** it could cause invalid data to be written into the journal. We need to ** detect this invalid data (with high probability) and ignore it. */ - if( pgno==0 || pgno==PAGER_SJ_PGNO(pPager) ){ + if( pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){ assert( !isSavepnt ); return SQLITE_DONE; } if( pgno>(Pgno)pPager->dbSize || sqlite3BitvecTest(pDone, pgno) ){ return SQLITE_OK; @@ -58256,11 +55837,10 @@ }else if( (currentSize+szPage)<=newSize ){ char *pTmp = pPager->pTmpSpace; memset(pTmp, 0, szPage); testcase( (newSize-szPage) == currentSize ); testcase( (newSize-szPage) > currentSize ); - sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &newSize); rc = sqlite3OsWrite(pPager->fd, pTmp, szPage, newSize-szPage); } if( rc==SQLITE_OK ){ pPager->dbFileSize = nPage; } @@ -58568,11 +56148,11 @@ if( rc==SQLITE_OK && zSuper[0] && res ){ /* If there was a super-journal and this routine will return success, ** see if it is possible to delete the super-journal. */ assert( zSuper==&pPager->pTmpSpace[4] ); - memset(pPager->pTmpSpace, 0, 4); + memset(&zSuper[-4], 0, 4); rc = pager_delsuper(pPager, zSuper); testcase( rc!=SQLITE_OK ); } if( isHot && nPlayback ){ sqlite3_log(SQLITE_NOTICE_RECOVER_ROLLBACK, "recovered %d pages from %s", @@ -59189,10 +56769,11 @@ ** the xSync primitive is called and is relevant to all platforms. ** ** Numeric values associated with these states are OFF==1, NORMAL=2, ** and FULL=3. */ +#ifndef SQLITE_OMIT_PAGER_PRAGMAS SQLITE_PRIVATE void sqlite3PagerSetFlags( Pager *pPager, /* The pager to set safety level for */ unsigned pgFlags /* Various flags */ ){ unsigned level = pgFlags & PAGER_SYNCHRONOUS_MASK; @@ -59223,10 +56804,11 @@ pPager->doNotSpill &= ~SPILLFLAG_OFF; }else{ pPager->doNotSpill |= SPILLFLAG_OFF; } } +#endif /* ** The following global variable is incremented whenever the library ** attempts to open a temporary file. This information is used for ** testing and analysis only. @@ -59376,11 +56958,10 @@ if( rc==SQLITE_OK ){ sqlite3PageFree(pPager->pTmpSpace); pPager->pTmpSpace = pNew; pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize); pPager->pageSize = pageSize; - pPager->lckPgno = (Pgno)(PENDING_BYTE/pageSize) + 1; }else{ sqlite3PageFree(pNew); } } @@ -60324,10 +57905,11 @@ int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */ int pcacheSize = sqlite3PcacheSize(); /* Bytes to allocate for PCache */ u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */ const char *zUri = 0; /* URI args to copy */ int nUriByte = 1; /* Number of bytes of URI args at *zUri */ + int nUri = 0; /* Number of URI parameters */ /* Figure out how much space is required for each journal file-handle ** (there are two of them, the main journal and the sub-journal). */ journalFileSize = ROUND8(sqlite3JournalSize(pVfs)); @@ -60371,10 +57953,11 @@ nPathname = sqlite3Strlen30(zPathname); z = zUri = &zFilename[sqlite3Strlen30(zFilename)+1]; while( *z ){ z += strlen(z)+1; z += strlen(z)+1; + nUri++; } nUriByte = (int)(&z[1] - zUri); assert( nUriByte>=1 ); if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){ /* This branch is taken when the journal path required by @@ -60626,11 +58209,22 @@ pPager->exclusiveMode = (u8)tempFile; pPager->changeCountDone = pPager->tempFile; pPager->memDb = (u8)memDb; pPager->readOnly = (u8)readOnly; assert( useJournal || pPager->tempFile ); - sqlite3PagerSetFlags(pPager, (SQLITE_DEFAULT_SYNCHRONOUS+1)|PAGER_CACHESPILL); + pPager->noSync = pPager->tempFile; + if( pPager->noSync ){ + assert( pPager->fullSync==0 ); + assert( pPager->extraSync==0 ); + assert( pPager->syncFlags==0 ); + assert( pPager->walSyncFlags==0 ); + }else{ + pPager->fullSync = 1; + pPager->extraSync = 0; + pPager->syncFlags = SQLITE_SYNC_NORMAL; + pPager->walSyncFlags = SQLITE_SYNC_NORMAL | (SQLITE_SYNC_NORMAL<<2); + } /* pPager->pFirst = 0; */ /* pPager->pFirstSynced = 0; */ /* pPager->pLast = 0; */ pPager->nExtra = (u16)nExtra; pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT; @@ -61133,11 +58727,11 @@ noContent = (flags & PAGER_GET_NOCONTENT)!=0; if( pPg->pPager && !noContent ){ /* In this case the pcache already contains an initialized copy of ** the page. Return without further ado. */ - assert( pgno!=PAGER_SJ_PGNO(pPager) ); + assert( pgno!=PAGER_MJ_PGNO(pPager) ); pPager->aStat[PAGER_STAT_HIT]++; return SQLITE_OK; }else{ /* The pager cache has created a new page. Its content needs to @@ -61144,11 +58738,11 @@ ** be initialized. But first some error checks: ** ** (*) obsolete. Was: maximum page number is 2^31 ** (2) Never try to fetch the locking page */ - if( pgno==PAGER_SJ_PGNO(pPager) ){ + if( pgno==PAGER_MJ_PGNO(pPager) ){ rc = SQLITE_CORRUPT_BKPT; goto pager_acquire_err; } pPg->pPager = pPager; @@ -61404,11 +58998,10 @@ int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; int nSpill; if( pPager->tempFile ){ flags |= (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL); - flags |= SQLITE_OPEN_EXCLUSIVE; nSpill = sqlite3Config.nStmtSpill; }else{ flags |= SQLITE_OPEN_MAIN_JOURNAL; nSpill = jrnlBufferSize(pPager); } @@ -61440,11 +59033,10 @@ } if( rc!=SQLITE_OK ){ sqlite3BitvecDestroy(pPager->pInJournal); pPager->pInJournal = 0; - pPager->journalOff = 0; }else{ assert( pPager->eState==PAGER_WRITER_LOCKED ); pPager->eState = PAGER_WRITER_CACHEMOD; } @@ -61545,11 +59137,11 @@ i64 iOff = pPager->journalOff; /* We should never write to the journal file the page that ** contains the database locks. The following assert verifies ** that we do not. */ - assert( pPg->pgno!=PAGER_SJ_PGNO(pPager) ); + assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) ); assert( pPager->journalHdr<=pPager->journalOff ); pData2 = pPg->pData; cksum = pager_cksum(pPager, (u8*)pData2); @@ -61724,11 +59316,11 @@ for(ii=0; iipgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){ - if( pg!=PAGER_SJ_PGNO(pPager) ){ + if( pg!=PAGER_MJ_PGNO(pPager) ){ rc = sqlite3PagerGet(pPager, pg, &pPage, 0); if( rc==SQLITE_OK ){ rc = pager_write(pPage); if( pPage->flags&PGHDR_NEED_SYNC ){ needSync = 1; @@ -61887,11 +59479,11 @@ UNUSED_PARAMETER(isDirectMode); #else # define DIRECT_MODE isDirectMode #endif - if( !pPager->changeCountDone && pPager->dbSize>0 ){ + if( !pPager->changeCountDone && ALWAYS(pPager->dbSize>0) ){ PgHdr *pPgHdr; /* Reference to page 1 */ assert( !pPager->tempFile && isOpen(pPager->fd) ); /* Open page 1 of the file for writing. */ @@ -62202,11 +59794,11 @@ ** image was extended as part of the current transaction and then the ** last page in the db image moved to the free-list. In this case the ** last page is never written out to disk, leaving the database file ** undersized. Fix this now if it is the case. */ if( pPager->dbSize>pPager->dbFileSize ){ - Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_SJ_PGNO(pPager)); + Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_MJ_PGNO(pPager)); assert( pPager->eState==PAGER_WRITER_DBMOD ); rc = pager_truncate(pPager, nNew); if( rc!=SQLITE_OK ) goto commit_phase_one_exit; } @@ -62627,15 +60219,11 @@ ** The return value to this routine is always safe to use with ** sqlite3_uri_parameter() and sqlite3_filename_database() and friends. */ SQLITE_PRIVATE const char *sqlite3PagerFilename(const Pager *pPager, int nullIfMemDb){ static const char zFake[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - if( nullIfMemDb && (pPager->memDb || sqlite3IsMemdb(pPager->pVfs)) ){ - return &zFake[4]; - }else{ - return pPager->zFilename; - } + return (nullIfMemDb && pPager->memDb) ? &zFake[4] : pPager->zFilename; } /* ** Return the VFS structure for the pager. */ @@ -64109,44 +61697,23 @@ } assert( nByte>=8 ); assert( (nByte&0x00000007)==0 ); assert( nByte<=65536 ); - assert( nByte%4==0 ); - if( !nativeCksum ){ + if( nativeCksum ){ + do { + s1 += *aData++ + s2; + s2 += *aData++ + s1; + }while( aDatapageSize))+1)) +# define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt) /* ** These macros define the location of the pointer-map entry for a ** database page. The first argument to each is the number of usable ** bytes on each page of the database (often 1024). The second is the @@ -68235,19 +65802,19 @@ ** within an expression that is an argument to another macro ** (sqliteMallocRaw), it is not possible to use conditional compilation. ** So, this macro is defined instead. */ #ifndef SQLITE_OMIT_AUTOVACUUM -#define ISAUTOVACUUM(pBt) (pBt->autoVacuum) +#define ISAUTOVACUUM (pBt->autoVacuum) #else -#define ISAUTOVACUUM(pBt) 0 +#define ISAUTOVACUUM 0 #endif /* -** This structure is passed around through all the PRAGMA integrity_check -** checking routines in order to keep track of some global state information. +** This structure is passed around through all the sanity checking routines +** in order to keep track of some global state information. ** ** The aRef[] array is allocated so that there is 1 bit for each page in ** the database. As the integrity-check proceeds, for each page used in ** the database the corresponding bit is set. This allows integrity-check to ** detect pages that are used twice and orphaned pages (both of which @@ -68259,16 +65826,14 @@ Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */ u8 *aPgRef; /* 1 bit per page in the db (see above) */ Pgno nPage; /* Number of pages in the database */ int mxErr; /* Stop accumulating errors when this reaches zero */ int nErr; /* Number of messages written to zErrMsg so far */ - int rc; /* SQLITE_OK, SQLITE_NOMEM, or SQLITE_INTERRUPT */ - u32 nStep; /* Number of steps into the integrity_check process */ + int bOomFault; /* A memory allocation error has occurred */ const char *zPfx; /* Error message prefix */ - Pgno v0; /* Value for first %u substitution in zPfx (root page) */ - Pgno v1; /* Value for second %u substitution in zPfx (current pg) */ - int v2; /* Value for third %d substitution in zPfx */ + Pgno v1; /* Value for first %u substitution in zPfx */ + int v2; /* Value for second %d substitution in zPfx */ StrAccum errMsg; /* Accumulate the error message text here */ u32 *heap; /* Min-heap used for analyzing cell coverage */ sqlite3 *db; /* Database connection running the check */ }; @@ -68531,11 +66096,10 @@ ** db using sqlite3SchemaToIndex(). */ SQLITE_PRIVATE int sqlite3SchemaMutexHeld(sqlite3 *db, int iDb, Schema *pSchema){ Btree *p; assert( db!=0 ); - if( db->pVfs==0 && db->nDb==0 ) return 1; if( pSchema ) iDb = sqlite3SchemaToIndex(db, pSchema); assert( iDb>=0 && iDbnDb ); if( !sqlite3_mutex_held(db->mutex) ) return 0; if( iDb==1 ) return 1; p = db->aDb[iDb].pBt; @@ -68727,12 +66291,12 @@ */ #ifdef SQLITE_DEBUG int corruptPageError(int lineno, MemPage *p){ char *zMsg; sqlite3BeginBenignMalloc(); - zMsg = sqlite3_mprintf("database corruption page %u of %s", - p->pgno, sqlite3PagerFilename(p->pBt->pPager, 0) + zMsg = sqlite3_mprintf("database corruption page %d of %s", + (int)p->pgno, sqlite3PagerFilename(p->pBt->pPager, 0) ); sqlite3EndBenignMalloc(); if( zMsg ){ sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg); } @@ -68805,11 +66369,11 @@ if( isIndex ){ HashElem *p; int bSeen = 0; for(p=sqliteHashFirst(&pSchema->idxHash); p; p=sqliteHashNext(p)){ Index *pIdx = (Index *)sqliteHashData(p); - if( pIdx->tnum==iRoot ){ + if( pIdx->tnum==(int)iRoot ){ if( bSeen ){ /* Two or more indexes share the same root page. There must ** be imposter tables. So just return true. The assert is not ** useful in that case. */ return 1; @@ -69398,11 +66962,11 @@ } /* ** In this version of BtreeMoveto, pKey is a packed index record ** such as is generated by the OP_MakeRecord opcode. Unpack the -** record and then call sqlite3BtreeIndexMoveto() to do the work. +** record and then call BtreeMovetoUnpacked() to do the work. */ static int btreeMoveto( BtCursor *pCur, /* Cursor open on the btree to be searched */ const void *pKey, /* Packed key if the btree is an index */ i64 nKey, /* Integer key for tables. Size of pKey for indices */ @@ -69537,29 +67101,12 @@ ** and number of the varargs parameters) is determined by the eHintType ** parameter. See the definitions of the BTREE_HINT_* macros for details. */ SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor *pCur, int eHintType, ...){ /* Used only by system that substitute their own storage engine */ -#ifdef SQLITE_DEBUG - if( ALWAYS(eHintType==BTREE_HINT_RANGE) ){ - va_list ap; - Expr *pExpr; - Walker w; - memset(&w, 0, sizeof(w)); - w.xExprCallback = sqlite3CursorRangeHintExprCheck; - va_start(ap, eHintType); - pExpr = va_arg(ap, Expr*); - w.u.aMem = va_arg(ap, Mem*); - va_end(ap); - assert( pExpr!=0 ); - assert( w.u.aMem!=0 ); - sqlite3WalkExpr(&w, pExpr); - } -#endif /* SQLITE_DEBUG */ -} -#endif /* SQLITE_ENABLE_CURSOR_HINTS */ - +} +#endif /* ** Provide flag hints to the cursor. */ SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor *pCur, unsigned x){ @@ -69640,11 +67187,11 @@ } assert( offset <= (int)pBt->usableSize-5 ); pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage); if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){ - TRACE(("PTRMAP_UPDATE: %u->(%u,%u)\n", key, eType, parent)); + TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent)); *pRC= rc = sqlite3PagerWrite(pDbPage); if( rc==SQLITE_OK ){ pPtrmap[offset] = eType; put4byte(&pPtrmap[offset+1], parent); } @@ -69839,35 +67386,31 @@ ** This routine is a high-runner. */ iKey = *pIter; if( iKey>=0x80 ){ u8 x; - iKey = (iKey<<7) ^ (x = *++pIter); - if( x>=0x80 ){ - iKey = (iKey<<7) ^ (x = *++pIter); - if( x>=0x80 ){ - iKey = (iKey<<7) ^ 0x10204000 ^ (x = *++pIter); - if( x>=0x80 ){ - iKey = (iKey<<7) ^ 0x4000 ^ (x = *++pIter); - if( x>=0x80 ){ - iKey = (iKey<<7) ^ 0x4000 ^ (x = *++pIter); - if( x>=0x80 ){ - iKey = (iKey<<7) ^ 0x4000 ^ (x = *++pIter); - if( x>=0x80 ){ - iKey = (iKey<<7) ^ 0x4000 ^ (x = *++pIter); - if( x>=0x80 ){ - iKey = (iKey<<8) ^ 0x8000 ^ (*++pIter); - } - } - } - } - } - }else{ - iKey ^= 0x204000; - } - }else{ - iKey ^= 0x4000; + iKey = ((iKey&0x7f)<<7) | ((x = *++pIter) & 0x7f); + if( x>=0x80 ){ + iKey = (iKey<<7) | ((x =*++pIter) & 0x7f); + if( x>=0x80 ){ + iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); + if( x>=0x80 ){ + iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); + if( x>=0x80 ){ + iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); + if( x>=0x80 ){ + iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); + if( x>=0x80 ){ + iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); + if( x>=0x80 ){ + iKey = (iKey<<8) | (*++pIter); + } + } + } + } + } + } } } pIter++; pInfo->nKey = *(i64*)&iKey; @@ -69939,16 +67482,14 @@ ** data area of the btree-page. The return number includes the cell ** data header and the local payload, but not any overflow page or ** the space used by the cell pointer. ** ** cellSizePtrNoPayload() => table internal nodes -** cellSizePtrTableLeaf() => table leaf nodes -** cellSizePtr() => index internal nodes -** cellSizeIdxLeaf() => index leaf nodes +** cellSizePtr() => all index nodes & table leaf nodes */ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ - u8 *pIter = pCell + 4; /* For looping over bytes of pCell */ + u8 *pIter = pCell + pPage->childPtrSize; /* For looping over bytes of pCell */ u8 *pEnd; /* End mark for a varint */ u32 nSize; /* Size value to return */ #ifdef SQLITE_DEBUG /* The value returned by this function should always be the same as @@ -69957,62 +67498,26 @@ ** this function verifies that this invariant is not violated. */ CellInfo debuginfo; pPage->xParseCell(pPage, pCell, &debuginfo); #endif - assert( pPage->childPtrSize==4 ); nSize = *pIter; if( nSize>=0x80 ){ pEnd = &pIter[8]; nSize &= 0x7f; do{ nSize = (nSize<<7) | (*++pIter & 0x7f); }while( *(pIter)>=0x80 && pItermaxLocal ); - testcase( nSize==(u32)pPage->maxLocal+1 ); - if( nSize<=pPage->maxLocal ){ - nSize += (u32)(pIter - pCell); - assert( nSize>4 ); - }else{ - int minLocal = pPage->minLocal; - nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4); - testcase( nSize==pPage->maxLocal ); - testcase( nSize==(u32)pPage->maxLocal+1 ); - if( nSize>pPage->maxLocal ){ - nSize = minLocal; - } - nSize += 4 + (u16)(pIter - pCell); - } - assert( nSize==debuginfo.nSize || CORRUPT_DB ); - return (u16)nSize; -} -static u16 cellSizePtrIdxLeaf(MemPage *pPage, u8 *pCell){ - u8 *pIter = pCell; /* For looping over bytes of pCell */ - u8 *pEnd; /* End mark for a varint */ - u32 nSize; /* Size value to return */ - -#ifdef SQLITE_DEBUG - /* The value returned by this function should always be the same as - ** the (CellInfo.nSize) value found by doing a full parse of the - ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of - ** this function verifies that this invariant is not violated. */ - CellInfo debuginfo; - pPage->xParseCell(pPage, pCell, &debuginfo); -#endif - - assert( pPage->childPtrSize==0 ); - nSize = *pIter; - if( nSize>=0x80 ){ - pEnd = &pIter[8]; - nSize &= 0x7f; - do{ - nSize = (nSize<<7) | (*++pIter & 0x7f); - }while( *(pIter)>=0x80 && pIterintKey ){ + /* pIter now points at the 64-bit integer key value, a variable length + ** integer. The following block moves pIter to point at the first byte + ** past the end of the key value. */ + pEnd = &pIter[9]; + while( (*pIter++)&0x80 && pItermaxLocal ); testcase( nSize==(u32)pPage->maxLocal+1 ); if( nSize<=pPage->maxLocal ){ nSize += (u32)(pIter - pCell); if( nSize<4 ) nSize = 4; @@ -70048,62 +67553,10 @@ pEnd = pIter + 9; while( (*pIter++)&0x80 && pIterxParseCell(pPage, pCell, &debuginfo); -#endif - - nSize = *pIter; - if( nSize>=0x80 ){ - pEnd = &pIter[8]; - nSize &= 0x7f; - do{ - nSize = (nSize<<7) | (*++pIter & 0x7f); - }while( *(pIter)>=0x80 && pItermaxLocal ); - testcase( nSize==(u32)pPage->maxLocal+1 ); - if( nSize<=pPage->maxLocal ){ - nSize += (u32)(pIter - pCell); - if( nSize<4 ) nSize = 4; - }else{ - int minLocal = pPage->minLocal; - nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4); - testcase( nSize==pPage->maxLocal ); - testcase( nSize==(u32)pPage->maxLocal+1 ); - if( nSize>pPage->maxLocal ){ - nSize = minLocal; - } - nSize += 4 + (u16)(pIter - pCell); - } - assert( nSize==debuginfo.nSize || CORRUPT_DB ); - return (u16)nSize; -} #ifdef SQLITE_DEBUG /* This variation on cellSizePtr() is used inside of assert() statements ** only. */ @@ -70113,11 +67566,11 @@ #endif #ifndef SQLITE_OMIT_AUTOVACUUM /* ** The cell pCell is currently part of page pSrc but will ultimately be part -** of pPage. (pSrc and pPage are often the same.) If pCell contains a +** of pPage. (pSrc and pPager are often the same.) If pCell contains a ** pointer to an overflow page, insert an entry into the pointer-map for ** the overflow page that will be valid after pCell has been moved to pPage. */ static void ptrmapPutOvflPtr(MemPage *pPage, MemPage *pSrc, u8 *pCell,int *pRC){ CellInfo info; @@ -70169,11 +67622,12 @@ assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( pPage->pBt!=0 ); assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE ); assert( pPage->nOverflow==0 ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - data = pPage->aData; + temp = 0; + src = data = pPage->aData; hdr = pPage->hdrOffset; cellOffset = pPage->cellOffset; nCell = pPage->nCell; assert( nCell==get2byte(&data[hdr+3]) || CORRUPT_DB ); iCellFirst = cellOffset + 2*nCell; @@ -70203,11 +67657,11 @@ if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PAGE(pPage); sz2 = get2byte(&data[iFree2+2]); if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage); memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz)); sz += sz2; - }else if( iFree+sz>usableSize ){ + }else if( NEVER(iFree+sz>usableSize) ){ return SQLITE_CORRUPT_PAGE(pPage); } cbrk = top+sz; assert( cbrk+(iFree-top) <= usableSize ); @@ -70223,42 +67677,43 @@ } cbrk = usableSize; iCellLast = usableSize - 4; iCellStart = get2byte(&data[hdr+5]); - if( nCell>0 ){ - temp = sqlite3PagerTempSpace(pPage->pBt->pPager); - memcpy(&temp[iCellStart], &data[iCellStart], usableSize - iCellStart); - src = temp; - for(i=0; iiCellLast ){ - return SQLITE_CORRUPT_PAGE(pPage); - } - assert( pc>=0 && pc<=iCellLast ); - size = pPage->xCellSize(pPage, &src[pc]); - cbrk -= size; - if( cbrkusableSize ){ - return SQLITE_CORRUPT_PAGE(pPage); - } - assert( cbrk+size<=usableSize && cbrk>=iCellStart ); - testcase( cbrk+size==usableSize ); - testcase( pc+size==usableSize ); - put2byte(pAddr, cbrk); - memcpy(&data[cbrk], &src[pc], size); - } + for(i=0; iiCellLast ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + assert( pc>=iCellStart && pc<=iCellLast ); + size = pPage->xCellSize(pPage, &src[pc]); + cbrk -= size; + if( cbrkusableSize ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + assert( cbrk+size<=usableSize && cbrk>=iCellStart ); + testcase( cbrk+size==usableSize ); + testcase( pc+size==usableSize ); + put2byte(pAddr, cbrk); + if( temp==0 ){ + if( cbrk==pc ) continue; + temp = sqlite3PagerTempSpace(pPage->pBt->pPager); + memcpy(&temp[iCellStart], &data[iCellStart], usableSize - iCellStart); + src = temp; + } + memcpy(&data[cbrk], &src[pc], size); } data[hdr+7] = 0; -defragment_out: + defragment_out: assert( pPage->nFree>=0 ); if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){ return SQLITE_CORRUPT_PAGE(pPage); } assert( cbrk>=iCellFirst ); @@ -70286,23 +67741,21 @@ */ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){ const int hdr = pPg->hdrOffset; /* Offset to page header */ u8 * const aData = pPg->aData; /* Page data */ int iAddr = hdr + 1; /* Address of ptr to pc */ - u8 *pTmp = &aData[iAddr]; /* Temporary ptr into aData[] */ - int pc = get2byte(pTmp); /* Address of a free slot */ + int pc = get2byte(&aData[iAddr]); /* Address of a free slot */ int x; /* Excess size of the slot */ int maxPC = pPg->pBt->usableSize - nByte; /* Max address for a usable slot */ int size; /* Size of the free slot */ assert( pc>0 ); while( pc<=maxPC ){ /* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each ** freeblock form a big-endian integer which is the size of the freeblock ** in bytes, including the 4-byte header. */ - pTmp = &aData[pc+2]; - size = get2byte(pTmp); + size = get2byte(&aData[pc+2]); if( (x = size - nByte)>=0 ){ testcase( x==4 ); testcase( x==3 ); if( x<4 ){ /* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total @@ -70311,10 +67764,11 @@ /* Remove the slot from the free-list. Update the number of ** fragmented bytes within the page. */ memcpy(&aData[iAddr], &aData[pc], 2); aData[hdr+7] += (u8)x; + testcase( pc+x>maxPC ); return &aData[pc]; }else if( x+pc > maxPC ){ /* This slot extends off the end of the usable part of the page */ *pRc = SQLITE_CORRUPT_PAGE(pPg); return 0; @@ -70324,15 +67778,14 @@ put2byte(&aData[pc+2], x); } return &aData[pc + x]; } iAddr = pc; - pTmp = &aData[pc]; - pc = get2byte(pTmp); - if( pc<=iAddr ){ + pc = get2byte(&aData[pc]); + if( pc<=iAddr+size ){ if( pc ){ - /* The next slot in the chain comes before the current slot */ + /* The next slot in the chain is not past the end of the current slot */ *pRc = SQLITE_CORRUPT_PAGE(pPg); } return 0; } } @@ -70354,16 +67807,15 @@ ** all the space together, however. This routine will avoid using ** the first two bytes past the cell pointer area since presumably this ** allocation is being made in order to insert a new cell, so we will ** also end up needing a new cell pointer. */ -static SQLITE_INLINE int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ +static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ const int hdr = pPage->hdrOffset; /* Local cache of pPage->hdrOffset */ u8 * const data = pPage->aData; /* Local cache of pPage->aData */ int top; /* First byte of cell content area */ int rc = SQLITE_OK; /* Integer return code */ - u8 *pTmp; /* Temp ptr into data[] */ int gap; /* First byte of gap between cell pointers and cell content */ assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( pPage->pBt ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); @@ -70378,20 +67830,18 @@ /* EVIDENCE-OF: R-29356-02391 If the database uses a 65536-byte page size ** and the reserved space is zero (the usual value for reserved space) ** then the cell content offset of an empty page wants to be 65536. ** However, that integer is too large to be stored in a 2-byte unsigned ** integer, so a value of 0 is used in its place. */ - pTmp = &data[hdr+5]; - top = get2byte(pTmp); + top = get2byte(&data[hdr+5]); + assert( top<=(int)pPage->pBt->usableSize ); /* by btreeComputeFreeSpace() */ if( gap>top ){ if( top==0 && pPage->pBt->usableSize==65536 ){ top = 65536; }else{ return SQLITE_CORRUPT_PAGE(pPage); } - }else if( top>(int)pPage->pBt->usableSize ){ - return SQLITE_CORRUPT_PAGE(pPage); } /* If there is enough space between gap and top for one more cell pointer, ** and if the freelist is not empty, then search the ** freelist looking for a slot big enough to satisfy the request. @@ -70462,19 +67912,18 @@ u8 nFrag = 0; /* Reduction in fragmentation */ u16 iOrigSize = iSize; /* Original value of iSize */ u16 x; /* Offset to cell content area */ u32 iEnd = iStart + iSize; /* First byte past the iStart buffer */ unsigned char *data = pPage->aData; /* Page content */ - u8 *pTmp; /* Temporary ptr into data[] */ assert( pPage->pBt!=0 ); assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( CORRUPT_DB || iStart>=pPage->hdrOffset+6+pPage->childPtrSize ); assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( iSize>=4 ); /* Minimum cell size is 4 */ - assert( CORRUPT_DB || iStart<=pPage->pBt->usableSize-4 ); + assert( iStart<=pPage->pBt->usableSize-4 ); /* The list of freeblocks must be in ascending order. Find the ** spot on the list where iStart should be inserted. */ hdr = pPage->hdrOffset; @@ -70481,11 +67930,11 @@ iPtr = hdr + 1; if( data[iPtr+1]==0 && data[iPtr]==0 ){ iFreeBlk = 0; /* Shortcut for the case when the freelist is empty */ }else{ while( (iFreeBlk = get2byte(&data[iPtr]))data[hdr+7] ) return SQLITE_CORRUPT_PAGE(pPage); data[hdr+7] -= nFrag; } - pTmp = &data[hdr+5]; - x = get2byte(pTmp); - if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){ - /* Overwrite deleted information with zeros when the secure_delete - ** option is enabled */ - memset(&data[iStart], 0, iSize); - } + x = get2byte(&data[hdr+5]); if( iStart<=x ){ /* The new freeblock is at the beginning of the cell content area, ** so just extend the cell content area rather than create another ** freelist entry */ if( iStartpBt->btsFlags & BTS_FAST_SECURE ){ + /* Overwrite deleted information with zeros when the secure_delete + ** option is enabled */ + memset(&data[iStart], 0, iSize); + } + put2byte(&data[iStart], iFreeBlk); + put2byte(&data[iStart+2], iSize); pPage->nFree += iOrigSize; return SQLITE_OK; } /* @@ -70557,71 +68005,61 @@ ** and initialize fields of the MemPage structure accordingly. ** ** Only the following combinations are supported. Anything different ** indicates a corrupt database files: ** -** PTF_ZERODATA (0x02, 2) -** PTF_LEAFDATA | PTF_INTKEY (0x05, 5) -** PTF_ZERODATA | PTF_LEAF (0x0a, 10) -** PTF_LEAFDATA | PTF_INTKEY | PTF_LEAF (0x0d, 13) +** PTF_ZERODATA +** PTF_ZERODATA | PTF_LEAF +** PTF_LEAFDATA | PTF_INTKEY +** PTF_LEAFDATA | PTF_INTKEY | PTF_LEAF */ static int decodeFlags(MemPage *pPage, int flagByte){ BtShared *pBt; /* A copy of pPage->pBt */ assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + pPage->leaf = (u8)(flagByte>>3); assert( PTF_LEAF == 1<<3 ); + flagByte &= ~PTF_LEAF; + pPage->childPtrSize = 4-4*pPage->leaf; + pPage->xCellSize = cellSizePtr; pBt = pPage->pBt; - pPage->max1bytePayload = pBt->max1bytePayload; - if( flagByte>=(PTF_ZERODATA | PTF_LEAF) ){ - pPage->childPtrSize = 0; - pPage->leaf = 1; - if( flagByte==(PTF_LEAFDATA | PTF_INTKEY | PTF_LEAF) ){ + if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){ + /* EVIDENCE-OF: R-07291-35328 A value of 5 (0x05) means the page is an + ** interior table b-tree page. */ + assert( (PTF_LEAFDATA|PTF_INTKEY)==5 ); + /* EVIDENCE-OF: R-26900-09176 A value of 13 (0x0d) means the page is a + ** leaf table b-tree page. */ + assert( (PTF_LEAFDATA|PTF_INTKEY|PTF_LEAF)==13 ); + pPage->intKey = 1; + if( pPage->leaf ){ pPage->intKeyLeaf = 1; - pPage->xCellSize = cellSizePtrTableLeaf; pPage->xParseCell = btreeParseCellPtr; - pPage->intKey = 1; - pPage->maxLocal = pBt->maxLeaf; - pPage->minLocal = pBt->minLeaf; - }else if( flagByte==(PTF_ZERODATA | PTF_LEAF) ){ - pPage->intKey = 0; - pPage->intKeyLeaf = 0; - pPage->xCellSize = cellSizePtrIdxLeaf; - pPage->xParseCell = btreeParseCellPtrIndex; - pPage->maxLocal = pBt->maxLocal; - pPage->minLocal = pBt->minLocal; - }else{ - pPage->intKey = 0; - pPage->intKeyLeaf = 0; - pPage->xCellSize = cellSizePtrIdxLeaf; - pPage->xParseCell = btreeParseCellPtrIndex; - return SQLITE_CORRUPT_PAGE(pPage); - } - }else{ - pPage->childPtrSize = 4; - pPage->leaf = 0; - if( flagByte==(PTF_ZERODATA) ){ - pPage->intKey = 0; - pPage->intKeyLeaf = 0; - pPage->xCellSize = cellSizePtr; - pPage->xParseCell = btreeParseCellPtrIndex; - pPage->maxLocal = pBt->maxLocal; - pPage->minLocal = pBt->minLocal; - }else if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){ + }else{ pPage->intKeyLeaf = 0; pPage->xCellSize = cellSizePtrNoPayload; pPage->xParseCell = btreeParseCellPtrNoPayload; - pPage->intKey = 1; - pPage->maxLocal = pBt->maxLeaf; - pPage->minLocal = pBt->minLeaf; - }else{ - pPage->intKey = 0; - pPage->intKeyLeaf = 0; - pPage->xCellSize = cellSizePtr; - pPage->xParseCell = btreeParseCellPtrIndex; - return SQLITE_CORRUPT_PAGE(pPage); - } - } + } + pPage->maxLocal = pBt->maxLeaf; + pPage->minLocal = pBt->minLeaf; + }else if( flagByte==PTF_ZERODATA ){ + /* EVIDENCE-OF: R-43316-37308 A value of 2 (0x02) means the page is an + ** interior index b-tree page. */ + assert( (PTF_ZERODATA)==2 ); + /* EVIDENCE-OF: R-59615-42828 A value of 10 (0x0a) means the page is a + ** leaf index b-tree page. */ + assert( (PTF_ZERODATA|PTF_LEAF)==10 ); + pPage->intKey = 0; + pPage->intKeyLeaf = 0; + pPage->xParseCell = btreeParseCellPtrIndex; + pPage->maxLocal = pBt->maxLocal; + pPage->minLocal = pBt->minLocal; + }else{ + /* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is + ** an error. */ + return SQLITE_CORRUPT_PAGE(pPage); + } + pPage->max1bytePayload = pBt->max1bytePayload; return SQLITE_OK; } /* ** Compute the amount of freespace on the page. In other words, fill @@ -70968,11 +68406,11 @@ if( pCur ){ pCur->iPage--; pCur->pPage = pCur->apPage[pCur->iPage]; } testcase( pgno==0 ); - assert( pgno!=0 || rc!=SQLITE_OK ); + assert( pgno!=0 || rc==SQLITE_CORRUPT ); return rc; } /* ** Release a MemPage. This should be called once for each prior @@ -72404,13 +69842,10 @@ put4byte(pCell+info.nSize-4, iTo); break; } } }else{ - if( pCell+4 > pPage->aData+pPage->pBt->usableSize ){ - return SQLITE_CORRUPT_PAGE(pPage); - } if( get4byte(pCell)==iFrom ){ put4byte(pCell, iTo); break; } } @@ -72455,11 +69890,11 @@ assert( sqlite3_mutex_held(pBt->mutex) ); assert( pDbPage->pBt==pBt ); if( iDbPage<3 ) return SQLITE_CORRUPT_BKPT; /* Move page iDbPage from its current location to page number iFreePage */ - TRACE(("AUTOVACUUM: Moving %u to free page %u (ptr page %u type %u)\n", + TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n", iDbPage, iFreePage, iPtrPage, eType)); rc = sqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage, isCommit); if( rc!=SQLITE_OK ){ return rc; } @@ -72593,21 +70028,16 @@ eMode = BTALLOC_LE; iNear = nFin; } do { MemPage *pFreePg; - Pgno dbSize = btreePagecount(pBt); rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iNear, eMode); if( rc!=SQLITE_OK ){ releasePage(pLastPg); return rc; } releasePage(pFreePg); - if( iFreePg>dbSize ){ - releasePage(pLastPg); - return SQLITE_CORRUPT_BKPT; - } }while( bCommit && iFreePg>nFin ); assert( iFreePgpBt; + assert( cursorOwnsBtShared(pCur) ); assert( pCur->eState==CURSOR_VALID ); assert( pCur->iPageiPage>=0 ); if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){ @@ -73926,12 +71358,11 @@ pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); pCur->aiIdx[pCur->iPage] = pCur->ix; pCur->apPage[pCur->iPage] = pCur->pPage; pCur->ix = 0; pCur->iPage++; - return getAndInitPage(pCur->pBt, newPgno, &pCur->pPage, pCur, - pCur->curPagerFlags); + return getAndInitPage(pBt, newPgno, &pCur->pPage, pCur, pCur->curPagerFlags); } #ifdef SQLITE_DEBUG /* ** Page pParent is an internal (non-leaf) tree page. This function @@ -74033,11 +71464,11 @@ assert( pCur->skipNext!=SQLITE_OK ); return pCur->skipNext; } sqlite3BtreeClearCursor(pCur); } - rc = getAndInitPage(pCur->pBt, pCur->pgnoRoot, &pCur->pPage, + rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->pPage, 0, pCur->curPagerFlags); if( rc!=SQLITE_OK ){ pCur->eState = CURSOR_INVALID; return rc; } @@ -74157,29 +71588,13 @@ /* Move the cursor to the last entry in the table. Return SQLITE_OK ** on success. Set *pRes to 0 if the cursor actually points to something ** or set *pRes to 1 if the table is empty. */ -static SQLITE_NOINLINE int btreeLast(BtCursor *pCur, int *pRes){ - int rc = moveToRoot(pCur); - if( rc==SQLITE_OK ){ - assert( pCur->eState==CURSOR_VALID ); - *pRes = 0; - rc = moveToRightmost(pCur); - if( rc==SQLITE_OK ){ - pCur->curFlags |= BTCF_AtLast; - }else{ - pCur->curFlags &= ~BTCF_AtLast; - } - }else if( rc==SQLITE_EMPTY ){ - assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); - *pRes = 1; - rc = SQLITE_OK; - } - return rc; -} SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ + int rc; + assert( cursorOwnsBtShared(pCur) ); assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); /* If the cursor already points to the last entry, this is a no-op. */ if( CURSOR_VALID==pCur->eState && (pCur->curFlags & BTCF_AtLast)!=0 ){ @@ -74196,11 +71611,27 @@ assert( pCur->pPage->leaf ); #endif *pRes = 0; return SQLITE_OK; } - return btreeLast(pCur, pRes); + + rc = moveToRoot(pCur); + if( rc==SQLITE_OK ){ + assert( pCur->eState==CURSOR_VALID ); + *pRes = 0; + rc = moveToRightmost(pCur); + if( rc==SQLITE_OK ){ + pCur->curFlags |= BTCF_AtLast; + }else{ + pCur->curFlags &= ~BTCF_AtLast; + } + }else if( rc==SQLITE_EMPTY ){ + assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); + *pRes = 1; + rc = SQLITE_OK; + } + return rc; } /* Move the cursor so that it points to an entry in a table (a.k.a INTKEY) ** table near the key intKey. Return a success code. ** @@ -74364,73 +71795,10 @@ pCur->info.nSize = 0; assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); return rc; } -/* -** Compare the "idx"-th cell on the page the cursor pCur is currently -** pointing to to pIdxKey using xRecordCompare. Return negative or -** zero if the cell is less than or equal pIdxKey. Return positive -** if unknown. -** -** Return value negative: Cell at pCur[idx] less than pIdxKey -** -** Return value is zero: Cell at pCur[idx] equals pIdxKey -** -** Return value positive: Nothing is known about the relationship -** of the cell at pCur[idx] and pIdxKey. -** -** This routine is part of an optimization. It is always safe to return -** a positive value as that will cause the optimization to be skipped. -*/ -static int indexCellCompare( - BtCursor *pCur, - int idx, - UnpackedRecord *pIdxKey, - RecordCompare xRecordCompare -){ - MemPage *pPage = pCur->pPage; - int c; - int nCell; /* Size of the pCell cell in bytes */ - u8 *pCell = findCellPastPtr(pPage, idx); - - nCell = pCell[0]; - if( nCell<=pPage->max1bytePayload ){ - /* This branch runs if the record-size field of the cell is a - ** single byte varint and the record fits entirely on the main - ** b-tree page. */ - testcase( pCell+nCell+1==pPage->aDataEnd ); - c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey); - }else if( !(pCell[1] & 0x80) - && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal - ){ - /* The record-size field is a 2 byte varint and the record - ** fits entirely on the main b-tree page. */ - testcase( pCell+nCell+2==pPage->aDataEnd ); - c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey); - }else{ - /* If the record extends into overflow pages, do not attempt - ** the optimization. */ - c = 99; - } - return c; -} - -/* -** Return true (non-zero) if pCur is current pointing to the last -** page of a table. -*/ -static int cursorOnLastPage(BtCursor *pCur){ - int i; - assert( pCur->eState==CURSOR_VALID ); - for(i=0; iiPage; i++){ - MemPage *pPage = pCur->apPage[i]; - if( pCur->aiIdx[i]nCell ) return 0; - } - return 1; -} - /* Move the cursor so that it points to an entry in an index table ** near the key pIdxKey. Return a success code. ** ** If an exact match is not found, then the cursor is always ** left pointing at a leaf page which would hold the entry if it @@ -74477,64 +71845,25 @@ assert( pIdxKey->default_rc==1 || pIdxKey->default_rc==0 || pIdxKey->default_rc==-1 ); - - /* Check to see if we can skip a lot of work. Two cases: - ** - ** (1) If the cursor is already pointing to the very last cell - ** in the table and the pIdxKey search key is greater than or - ** equal to that last cell, then no movement is required. - ** - ** (2) If the cursor is on the last page of the table and the first - ** cell on that last page is less than or equal to the pIdxKey - ** search key, then we can start the search on the current page - ** without needing to go back to root. - */ - if( pCur->eState==CURSOR_VALID - && pCur->pPage->leaf - && cursorOnLastPage(pCur) - ){ - int c; - if( pCur->ix==pCur->pPage->nCell-1 - && (c = indexCellCompare(pCur, pCur->ix, pIdxKey, xRecordCompare))<=0 - && pIdxKey->errCode==SQLITE_OK - ){ - *pRes = c; - return SQLITE_OK; /* Cursor already pointing at the correct spot */ - } - if( pCur->iPage>0 - && indexCellCompare(pCur, 0, pIdxKey, xRecordCompare)<=0 - && pIdxKey->errCode==SQLITE_OK - ){ - pCur->curFlags &= ~BTCF_ValidOvfl; - if( !pCur->pPage->isInit ){ - return SQLITE_CORRUPT_BKPT; - } - goto bypass_moveto_root; /* Start search on the current page */ - } - pIdxKey->errCode = SQLITE_OK; - } - rc = moveToRoot(pCur); if( rc ){ if( rc==SQLITE_EMPTY ){ assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); *pRes = -1; return SQLITE_OK; } return rc; } - -bypass_moveto_root: assert( pCur->pPage ); assert( pCur->pPage->isInit ); assert( pCur->eState==CURSOR_VALID ); assert( pCur->pPage->nCell > 0 ); - assert( pCur->curIntKey==0 ); - assert( pIdxKey!=0 ); + assert( pCur->iPage==0 || pCur->apPage[0]->intKey==pCur->curIntKey ); + assert( pCur->curIntKey || pIdxKey ); for(;;){ int lwr, upr, idx, c; Pgno chldPg; MemPage *pPage = pCur->pPage; u8 *pCell; /* Pointer to current cell in pPage */ @@ -74544,11 +71873,11 @@ ** not run. If this is not the root-page, then the moveToChild() routine ** would have already detected db corruption. Similarly, pPage must ** be the right kind (index or table) of b-tree page. Otherwise ** a moveToChild() or moveToRoot() call would have detected corruption. */ assert( pPage->nCell>0 ); - assert( pPage->intKey==0 ); + assert( pPage->intKey==(pIdxKey==0) ); lwr = 0; upr = pPage->nCell-1; idx = upr>>1; /* idx = (lwr+upr)/2; */ for(;;){ int nCell; /* Size of the pCell cell in bytes */ @@ -74741,12 +72070,18 @@ } } pPage = pCur->pPage; idx = ++pCur->ix; - if( sqlite3FaultSim(412) ) pPage->isInit = 0; - if( !pPage->isInit ){ + if( !pPage->isInit || sqlite3FaultSim(412) ){ + /* The only known way for this to happen is for there to be a + ** recursive SQL function that does a DELETE operation as part of a + ** SELECT which deletes content out from under an active cursor + ** in a corrupt database file where the table being DELETE-ed from + ** has pages in common with the table being queried. See TH3 + ** module cov1/btree78.test testcase 220 (2018-06-08) for an + ** example. */ return SQLITE_CORRUPT_BKPT; } if( idx>=pPage->nCell ){ if( !pPage->leaf ){ @@ -74918,12 +72253,12 @@ assert( sqlite3_mutex_held(pBt->mutex) ); assert( eMode==BTALLOC_ANY || (nearby>0 && IfNotOmitAV(pBt->autoVacuum)) ); pPage1 = pBt->pPage1; mxPage = btreePagecount(pBt); - /* EVIDENCE-OF: R-21003-45125 The 4-byte big-endian integer at offset 36 - ** stores the total number of pages on the freelist. */ + /* EVIDENCE-OF: R-05119-02637 The 4-byte big-endian integer at offset 36 + ** stores stores the total number of pages on the freelist. */ n = get4byte(&pPage1->aData[36]); testcase( n==mxPage-1 ); if( n>=mxPage ){ return SQLITE_CORRUPT_BKPT; } @@ -75005,11 +72340,11 @@ } *pPgno = iTrunk; memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); *ppPage = pTrunk; pTrunk = 0; - TRACE(("ALLOCATE: %u trunk - %u free pages left\n", *pPgno, n-1)); + TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); }else if( k>(u32)(pBt->usableSize/4 - 2) ){ /* Value of k is out of range. Database corruption */ rc = SQLITE_CORRUPT_PGNO(iTrunk); goto end_allocate_page; #ifndef SQLITE_OMIT_AUTOVACUUM @@ -75071,11 +72406,11 @@ } put4byte(&pPrevTrunk->aData[0], iNewTrunk); } } pTrunk = 0; - TRACE(("ALLOCATE: %u trunk - %u free pages left\n", *pPgno, n-1)); + TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); #endif }else if( k>0 ){ /* Extract a leaf from the trunk */ u32 closest; Pgno iPage; @@ -75116,12 +72451,12 @@ if( !searchList || (iPage==nearby || (iPagepgno, n-1)); rc = sqlite3PagerWrite(pTrunk->pDbPage); if( rc ) goto end_allocate_page; if( closestnPage)); + TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage)); assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) ); rc = btreeGetUnusedPage(pBt, pBt->nPage, &pPg, bNoContent); if( rc==SQLITE_OK ){ rc = sqlite3PagerWrite(pPg->pDbPage); releasePage(pPg); @@ -75196,11 +72531,11 @@ rc = sqlite3PagerWrite((*ppPage)->pDbPage); if( rc!=SQLITE_OK ){ releasePage(*ppPage); *ppPage = 0; } - TRACE(("ALLOCATE: %u from end of file\n", *pPgno)); + TRACE(("ALLOCATE: %d from end of file\n", *pPgno)); } assert( CORRUPT_DB || *pPgno!=PENDING_BYTE_PAGE(pBt) ); end_allocate_page: @@ -75264,11 +72599,11 @@ } /* If the database supports auto-vacuum, write an entry in the pointer-map ** to indicate that the page is free. */ - if( ISAUTOVACUUM(pBt) ){ + if( ISAUTOVACUUM ){ ptrmapPut(pBt, iPage, PTRMAP_FREEPAGE, 0, &rc); if( rc ) goto freepage_out; } /* Now manipulate the actual database free-list structure. There are two @@ -75324,11 +72659,11 @@ if( pPage && (pBt->btsFlags & BTS_SECURE_DELETE)==0 ){ sqlite3PagerDontWrite(pPage->pDbPage); } rc = btreeSetHasContent(pBt, iPage); } - TRACE(("FREE-PAGE: %u leaf on trunk page %u\n",pPage->pgno,pTrunk->pgno)); + TRACE(("FREE-PAGE: %d leaf on trunk page %d\n",pPage->pgno,pTrunk->pgno)); goto freepage_out; } } /* If control flows to this point, then it was not possible to add the @@ -75345,11 +72680,11 @@ goto freepage_out; } put4byte(pPage->aData, iTrunk); put4byte(&pPage->aData[4], 0); put4byte(&pPage1->aData[32], iPage); - TRACE(("FREE-PAGE: %u new trunk page replacing %u\n", pPage->pgno, iTrunk)); + TRACE(("FREE-PAGE: %d new trunk page replacing %d\n", pPage->pgno, iTrunk)); freepage_out: if( pPage ){ pPage->isInit = 0; } @@ -75668,10 +73003,16 @@ data = pPage->aData; ptr = &pPage->aCellIdx[2*idx]; assert( pPage->pBt->usableSize > (u32)(ptr-data) ); pc = get2byte(ptr); hdr = pPage->hdrOffset; +#if 0 /* Not required. Omit for efficiency */ + if( pcnCell*2 ){ + *pRC = SQLITE_CORRUPT_BKPT; + return; + } +#endif testcase( pc==(u32)get2byte(&data[hdr+5]) ); testcase( pc+sz==pPage->pBt->usableSize ); if( pc+sz > pPage->pBt->usableSize ){ *pRC = SQLITE_CORRUPT_BKPT; return; @@ -75705,136 +73046,43 @@ ** in pPage->apOvfl[] and make it point to the cell content (either ** in pTemp or the original pCell) and also record its index. ** Allocating a new entry in pPage->aCell[] implies that ** pPage->nOverflow is incremented. ** -** The insertCellFast() routine below works exactly the same as -** insertCell() except that it lacks the pTemp and iChild parameters -** which are assumed zero. Other than that, the two routines are the -** same. -** -** Fixes or enhancements to this routine should be reflected in -** insertCellFast()! +** *pRC must be SQLITE_OK when this routine is called. */ -static int insertCell( +static void insertCell( MemPage *pPage, /* Page into which we are copying */ int i, /* New cell becomes the i-th cell of the page */ u8 *pCell, /* Content of the new cell */ int sz, /* Bytes of content in pCell */ u8 *pTemp, /* Temp storage space for pCell, if needed */ - Pgno iChild /* If non-zero, replace first 4 bytes with this value */ + Pgno iChild, /* If non-zero, replace first 4 bytes with this value */ + int *pRC /* Read and write return code from here */ ){ int idx = 0; /* Where to write new cell content in data[] */ int j; /* Loop counter */ u8 *data; /* The content of the whole page */ u8 *pIns; /* The point in pPage->aCellIdx[] where no cell inserted */ + assert( *pRC==SQLITE_OK ); assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); assert( MX_CELL(pPage->pBt)<=10921 ); assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB ); assert( pPage->nOverflow<=ArraySize(pPage->apOvfl) ); assert( ArraySize(pPage->apOvfl)==ArraySize(pPage->aiOvfl) ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( sz==pPage->xCellSize(pPage, pCell) || CORRUPT_DB ); assert( pPage->nFree>=0 ); - assert( iChild>0 ); if( pPage->nOverflow || sz+2>pPage->nFree ){ if( pTemp ){ memcpy(pTemp, pCell, sz); pCell = pTemp; } - put4byte(pCell, iChild); - j = pPage->nOverflow++; - /* Comparison against ArraySize-1 since we hold back one extra slot - ** as a contingency. In other words, never need more than 3 overflow - ** slots but 4 are allocated, just to be safe. */ - assert( j < ArraySize(pPage->apOvfl)-1 ); - pPage->apOvfl[j] = pCell; - pPage->aiOvfl[j] = (u16)i; - - /* When multiple overflows occur, they are always sequential and in - ** sorted order. This invariants arise because multiple overflows can - ** only occur when inserting divider cells into the parent page during - ** balancing, and the dividers are adjacent and sorted. - */ - assert( j==0 || pPage->aiOvfl[j-1]<(u16)i ); /* Overflows in sorted order */ - assert( j==0 || i==pPage->aiOvfl[j-1]+1 ); /* Overflows are sequential */ - }else{ - int rc = sqlite3PagerWrite(pPage->pDbPage); - if( NEVER(rc!=SQLITE_OK) ){ - return rc; - } - assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - data = pPage->aData; - assert( &data[pPage->cellOffset]==pPage->aCellIdx ); - rc = allocateSpace(pPage, sz, &idx); - if( rc ){ return rc; } - /* The allocateSpace() routine guarantees the following properties - ** if it returns successfully */ - assert( idx >= 0 ); - assert( idx >= pPage->cellOffset+2*pPage->nCell+2 || CORRUPT_DB ); - assert( idx+sz <= (int)pPage->pBt->usableSize ); - pPage->nFree -= (u16)(2 + sz); - /* In a corrupt database where an entry in the cell index section of - ** a btree page has a value of 3 or less, the pCell value might point - ** as many as 4 bytes in front of the start of the aData buffer for - ** the source page. Make sure this does not cause problems by not - ** reading the first 4 bytes */ - memcpy(&data[idx+4], pCell+4, sz-4); - put4byte(&data[idx], iChild); - pIns = pPage->aCellIdx + i*2; - memmove(pIns+2, pIns, 2*(pPage->nCell - i)); - put2byte(pIns, idx); - pPage->nCell++; - /* increment the cell count */ - if( (++data[pPage->hdrOffset+4])==0 ) data[pPage->hdrOffset+3]++; - assert( get2byte(&data[pPage->hdrOffset+3])==pPage->nCell || CORRUPT_DB ); -#ifndef SQLITE_OMIT_AUTOVACUUM - if( pPage->pBt->autoVacuum ){ - int rc2 = SQLITE_OK; - /* The cell may contain a pointer to an overflow page. If so, write - ** the entry for the overflow page into the pointer map. - */ - ptrmapPutOvflPtr(pPage, pPage, pCell, &rc2); - if( rc2 ) return rc2; - } -#endif - } - return SQLITE_OK; -} - -/* -** This variant of insertCell() assumes that the pTemp and iChild -** parameters are both zero. Use this variant in sqlite3BtreeInsert() -** for performance improvement, and also so that this variant is only -** called from that one place, and is thus inlined, and thus runs must -** faster. -** -** Fixes or enhancements to this routine should be reflected into -** the insertCell() routine. -*/ -static int insertCellFast( - MemPage *pPage, /* Page into which we are copying */ - int i, /* New cell becomes the i-th cell of the page */ - u8 *pCell, /* Content of the new cell */ - int sz /* Bytes of content in pCell */ -){ - int idx = 0; /* Where to write new cell content in data[] */ - int j; /* Loop counter */ - u8 *data; /* The content of the whole page */ - u8 *pIns; /* The point in pPage->aCellIdx[] where no cell inserted */ - - assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); - assert( MX_CELL(pPage->pBt)<=10921 ); - assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB ); - assert( pPage->nOverflow<=ArraySize(pPage->apOvfl) ); - assert( ArraySize(pPage->apOvfl)==ArraySize(pPage->aiOvfl) ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - assert( sz==pPage->xCellSize(pPage, pCell) || CORRUPT_DB ); - assert( pPage->nFree>=0 ); - assert( pPage->nOverflow==0 ); - if( sz+2>pPage->nFree ){ + if( iChild ){ + put4byte(pCell, iChild); + } j = pPage->nOverflow++; /* Comparison against ArraySize-1 since we hold back one extra slot ** as a contingency. In other words, never need more than 3 overflow ** slots but 4 are allocated, just to be safe. */ assert( j < ArraySize(pPage->apOvfl)-1 ); @@ -75849,43 +73097,51 @@ assert( j==0 || pPage->aiOvfl[j-1]<(u16)i ); /* Overflows in sorted order */ assert( j==0 || i==pPage->aiOvfl[j-1]+1 ); /* Overflows are sequential */ }else{ int rc = sqlite3PagerWrite(pPage->pDbPage); if( rc!=SQLITE_OK ){ - return rc; + *pRC = rc; + return; } assert( sqlite3PagerIswriteable(pPage->pDbPage) ); data = pPage->aData; assert( &data[pPage->cellOffset]==pPage->aCellIdx ); rc = allocateSpace(pPage, sz, &idx); - if( rc ){ return rc; } + if( rc ){ *pRC = rc; return; } /* The allocateSpace() routine guarantees the following properties ** if it returns successfully */ assert( idx >= 0 ); assert( idx >= pPage->cellOffset+2*pPage->nCell+2 || CORRUPT_DB ); assert( idx+sz <= (int)pPage->pBt->usableSize ); pPage->nFree -= (u16)(2 + sz); - memcpy(&data[idx], pCell, sz); + if( iChild ){ + /* In a corrupt database where an entry in the cell index section of + ** a btree page has a value of 3 or less, the pCell value might point + ** as many as 4 bytes in front of the start of the aData buffer for + ** the source page. Make sure this does not cause problems by not + ** reading the first 4 bytes */ + memcpy(&data[idx+4], pCell+4, sz-4); + put4byte(&data[idx], iChild); + }else{ + memcpy(&data[idx], pCell, sz); + } pIns = pPage->aCellIdx + i*2; memmove(pIns+2, pIns, 2*(pPage->nCell - i)); put2byte(pIns, idx); pPage->nCell++; /* increment the cell count */ if( (++data[pPage->hdrOffset+4])==0 ) data[pPage->hdrOffset+3]++; assert( get2byte(&data[pPage->hdrOffset+3])==pPage->nCell || CORRUPT_DB ); #ifndef SQLITE_OMIT_AUTOVACUUM if( pPage->pBt->autoVacuum ){ - int rc2 = SQLITE_OK; /* The cell may contain a pointer to an overflow page. If so, write ** the entry for the overflow page into the pointer map. */ - ptrmapPutOvflPtr(pPage, pPage, pCell, &rc2); - if( rc2 ) return rc2; + ptrmapPutOvflPtr(pPage, pPage, pCell, pRC); } #endif } - return SQLITE_OK; } /* ** The following parameters determine how many adjacent pages get involved ** in a balancing operation. NN is the number of neighbors on either side @@ -75982,20 +73238,18 @@ /* ** Make sure the cell sizes at idx, idx+1, ..., idx+N-1 have been ** computed. */ static void populateCellCache(CellArray *p, int idx, int N){ - MemPage *pRef = p->pRef; - u16 *szCell = p->szCell; assert( idx>=0 && idx+N<=p->nCell ); while( N>0 ){ assert( p->apCell[idx]!=0 ); - if( szCell[idx]==0 ){ - szCell[idx] = pRef->xCellSize(pRef, p->apCell[idx]); + if( p->szCell[idx]==0 ){ + p->szCell[idx] = p->pRef->xCellSize(p->pRef, p->apCell[idx]); }else{ assert( CORRUPT_DB || - szCell[idx]==pRef->xCellSize(pRef, p->apCell[idx]) ); + p->szCell[idx]==p->pRef->xCellSize(p->pRef, p->apCell[idx]) ); } idx++; N--; } } @@ -76047,11 +73301,11 @@ int k; /* Current slot in pCArray->apEnd[] */ u8 *pSrcEnd; /* Current pCArray->apEnd[k] value */ assert( i(u32)usableSize) ){ j = 0; } + if( j>(u32)usableSize ){ j = 0; } memcpy(&pTmp[j], &aData[j], usableSize - j); for(k=0; pCArray->ixNx[k]<=i && ALWAYS(kapEnd[k]; @@ -76191,54 +73445,43 @@ ){ u8 * const aData = pPg->aData; u8 * const pEnd = &aData[pPg->pBt->usableSize]; u8 * const pStart = &aData[pPg->hdrOffset + 8 + pPg->childPtrSize]; int nRet = 0; - int i, j; + int i; int iEnd = iFirst + nCell; - int nFree = 0; - int aOfst[10]; - int aAfter[10]; + u8 *pFree = 0; + int szFree = 0; for(i=iFirst; iapCell[i]; if( SQLITE_WITHIN(pCell, pStart, pEnd) ){ int sz; - int iAfter; - int iOfst; /* No need to use cachedCellSize() here. The sizes of all cells that ** are to be freed have already been computing while deciding which ** cells need freeing */ sz = pCArray->szCell[i]; assert( sz>0 ); - iOfst = (u16)(pCell - aData); - iAfter = iOfst+sz; - for(j=0; j=nFree ){ - if( nFree>=sizeof(aOfst)/sizeof(aOfst[0]) ){ - for(j=0; jpEnd ) return 0; - nFree++; + if( pFree!=(pCell + sz) ){ + if( pFree ){ + assert( pFree>aData && (pFree - aData)<65536 ); + freeSpace(pPg, (u16)(pFree - aData), szFree); + } + pFree = pCell; + szFree = sz; + if( pFree+sz>pEnd ){ + return 0; + } + }else{ + pFree = pCell; + szFree += sz; } nRet++; } } - for(j=0; jaData && (pFree - aData)<65536 ); + freeSpace(pPg, (u16)(pFree - aData), szFree); } return nRet; } /* @@ -76289,11 +73532,11 @@ nCell -= nTail; } pData = &aData[get2byteNotZero(&aData[hdr+5])]; if( pDatapPg->aDataEnd) ) goto editpage_fail; + if( pData>pPg->aDataEnd ) goto editpage_fail; /* Add cells to the start of the page */ if( iNewpgno, &rc); if( szCell>pNew->minLocal ){ ptrmapPutOvflPtr(pNew, pNew, pCell, &rc); } } @@ -76461,12 +73704,12 @@ pStop = &pCell[9]; while( ((*(pOut++) = *(pCell++))&0x80) && pCellnCell, pSpace, (int)(pOut-pSpace), - 0, pPage->pgno); + insertCell(pParent, pParent->nCell, pSpace, (int)(pOut-pSpace), + 0, pPage->pgno, &rc); } /* Set the right-child pointer of pParent to point to the new page. */ put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew); @@ -76571,11 +73814,11 @@ } /* If this is an auto-vacuum database, update the pointer-map entries ** for any b-tree or overflow pages that pTo now contains the pointers to. */ - if( ISAUTOVACUUM(pBt) ){ + if( ISAUTOVACUUM ){ *pRC = setChildPtrmaps(pTo); } } } @@ -76649,10 +73892,12 @@ int szNew[NB+2]; /* Combined size of cells placed on i-th page */ u8 *aSpace1; /* Space for copies of dividers cells */ Pgno pgno; /* Temp var to store a page number in */ u8 abDone[NB+2]; /* True after i'th new page is populated */ Pgno aPgno[NB+2]; /* Page numbers of new pages before shuffling */ + Pgno aPgOrder[NB+2]; /* Copy of aPgno[] used for sorting pages */ + u16 aPgFlags[NB+2]; /* flags field of new pages before shuffling */ CellArray b; /* Parsed information on cells being balanced */ memset(abDone, 0, sizeof(abDone)); memset(&b, 0, sizeof(b)); pBt = pParent->pBt; @@ -76995,21 +74240,19 @@ r = cntNew[i-1] - 1; d = r + 1 - leafData; (void)cachedCellSize(&b, d); do{ - int szR, szD; assert( d szLeft-(szR+(i==k-1?0:2)))){ + && (bBulk || szRight+b.szCell[d]+2 > szLeft-(b.szCell[r]+(i==k-1?0:2)))){ break; } - szRight += szD + 2; - szLeft -= szR + 2; + szRight += b.szCell[d] + 2; + szLeft -= b.szCell[r] + 2; cntNew[i-1] = r; r--; d--; }while( r>=0 ); szNew[i] = szRight; @@ -77026,11 +74269,11 @@ ** (2) pPage is a virtual root page. A virtual root page is when ** the real root page is page 1 and we are the only child of ** that page. */ assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) || CORRUPT_DB); - TRACE(("BALANCE: old: %u(nc=%u) %u(nc=%u) %u(nc=%u)\n", + TRACE(("BALANCE: old: %d(nc=%d) %d(nc=%d) %d(nc=%d)\n", apOld[0]->pgno, apOld[0]->nCell, nOld>=2 ? apOld[1]->pgno : 0, nOld>=2 ? apOld[1]->nCell : 0, nOld>=3 ? apOld[2]->pgno : 0, nOld>=3 ? apOld[2]->nCell : 0 )); @@ -77059,11 +74302,11 @@ apNew[i] = pNew; nNew++; cntOld[i] = b.nCell; /* Set the pointer-map entry for the new sibling page. */ - if( ISAUTOVACUUM(pBt) ){ + if( ISAUTOVACUUM ){ ptrmapPut(pBt, pNew->pgno, PTRMAP_BTREE, pParent->pgno, &rc); if( rc!=SQLITE_OK ){ goto balance_cleanup; } } @@ -77074,48 +74317,51 @@ ** Reassign page numbers so that the new pages are in ascending order. ** This helps to keep entries in the disk file in order so that a scan ** of the table is closer to a linear scan through the file. That in turn ** helps the operating system to deliver pages from the disk more rapidly. ** - ** An O(N*N) sort algorithm is used, but since N is never more than NB+2 - ** (5), that is not a performance concern. + ** An O(n^2) insertion sort algorithm is used, but since n is never more + ** than (NB+2) (a small constant), that should not be a problem. ** ** When NB==3, this one optimization makes the database about 25% faster ** for large insertions and deletions. */ for(i=0; ipgno; - assert( apNew[i]->pDbPage->flags & PGHDR_WRITEABLE ); - assert( apNew[i]->pDbPage->flags & PGHDR_DIRTY ); - } - for(i=0; ipgno < apNew[iB]->pgno ) iB = j; - } - - /* If apNew[i] has a page number that is bigger than any of the - ** subsequence apNew[i] entries, then swap apNew[i] with the subsequent - ** entry that has the smallest page number (which we know to be - ** entry apNew[iB]). - */ - if( iB!=i ){ - Pgno pgnoA = apNew[i]->pgno; - Pgno pgnoB = apNew[iB]->pgno; - Pgno pgnoTemp = (PENDING_BYTE/pBt->pageSize)+1; - u16 fgA = apNew[i]->pDbPage->flags; - u16 fgB = apNew[iB]->pDbPage->flags; - sqlite3PagerRekey(apNew[i]->pDbPage, pgnoTemp, fgB); - sqlite3PagerRekey(apNew[iB]->pDbPage, pgnoA, fgA); - sqlite3PagerRekey(apNew[i]->pDbPage, pgnoB, fgB); - apNew[i]->pgno = pgnoB; - apNew[iB]->pgno = pgnoA; - } - } - - TRACE(("BALANCE: new: %u(%u nc=%u) %u(%u nc=%u) %u(%u nc=%u) " - "%u(%u nc=%u) %u(%u nc=%u)\n", + aPgOrder[i] = aPgno[i] = apNew[i]->pgno; + aPgFlags[i] = apNew[i]->pDbPage->flags; + for(j=0; ji ){ + sqlite3PagerRekey(apNew[iBest]->pDbPage, pBt->nPage+iBest+1, 0); + } + sqlite3PagerRekey(apNew[i]->pDbPage, pgno, aPgFlags[iBest]); + apNew[i]->pgno = pgno; + } + } + + TRACE(("BALANCE: new: %d(%d nc=%d) %d(%d nc=%d) %d(%d nc=%d) " + "%d(%d nc=%d) %d(%d nc=%d)\n", apNew[0]->pgno, szNew[0], cntNew[0], nNew>=2 ? apNew[1]->pgno : 0, nNew>=2 ? szNew[1] : 0, nNew>=2 ? cntNew[1] - cntNew[0] - !leafData : 0, nNew>=3 ? apNew[2]->pgno : 0, nNew>=3 ? szNew[2] : 0, nNew>=3 ? cntNew[2] - cntNew[1] - !leafData : 0, @@ -77152,11 +74398,11 @@ ** If the sibling pages are not leaves, then the pointer map entry ** associated with the right-child of each sibling may also need to be ** updated. This happens below, after the sibling pages have been ** populated, not here. */ - if( ISAUTOVACUUM(pBt) ){ + if( ISAUTOVACUUM ){ MemPage *pOld; MemPage *pNew = pOld = apNew[0]; int cntOldNext = pNew->nCell + pNew->nOverflow; int iNew = 0; int iOld = 0; @@ -77249,11 +74495,11 @@ pSrcEnd = b.apEnd[k]; if( SQLITE_WITHIN(pSrcEnd, pCell, pCell+sz) ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; } - rc = insertCell(pParent, nxDiv+i, pCell, sz, pTemp, pNew->pgno); + insertCell(pParent, nxDiv+i, pCell, sz, pTemp, pNew->pgno, &rc); if( rc!=SQLITE_OK ) goto balance_cleanup; assert( sqlite3PagerIswriteable(pParent->pDbPage) ); } /* Now update the actual sibling pages. The order in which they are updated @@ -77345,11 +74591,11 @@ - apNew[0]->nCell*2) || rc!=SQLITE_OK ); copyNodeContent(apNew[0], pParent, &rc); freePage(apNew[0], &rc); - }else if( ISAUTOVACUUM(pBt) && !leafCorrection ){ + }else if( ISAUTOVACUUM && !leafCorrection ){ /* Fix the pointer map entries associated with the right-child of each ** sibling page. All other pointer map entries have already been taken ** care of. */ for(i=0; iaData[8]); @@ -77356,21 +74602,21 @@ ptrmapPut(pBt, key, PTRMAP_BTREE, apNew[i]->pgno, &rc); } } assert( pParent->isInit ); - TRACE(("BALANCE: finished: old=%u new=%u cells=%u\n", + TRACE(("BALANCE: finished: old=%d new=%d cells=%d\n", nOld, nNew, b.nCell)); /* Free any old pages that were not reused as new pages. */ for(i=nNew; iisInit ){ + if( ISAUTOVACUUM && rc==SQLITE_OK && apNew[0]->isInit ){ /* The ptrmapCheckPages() contains assert() statements that verify that ** all pointer map pages are set correctly. This is helpful while ** debugging. This is usually disabled because a corrupt database may ** cause an assert() statement to fail. */ ptrmapCheckPages(apNew, nNew); @@ -77428,11 +74674,11 @@ */ rc = sqlite3PagerWrite(pRoot->pDbPage); if( rc==SQLITE_OK ){ rc = allocateBtreePage(pBt,&pChild,&pgnoChild,pRoot->pgno,0); copyNodeContent(pRoot, pChild, &rc); - if( ISAUTOVACUUM(pBt) ){ + if( ISAUTOVACUUM ){ ptrmapPut(pBt, pgnoChild, PTRMAP_BTREE, pRoot->pgno, &rc); } } if( rc ){ *ppChild = 0; @@ -77441,11 +74687,11 @@ } assert( sqlite3PagerIswriteable(pChild->pDbPage) ); assert( sqlite3PagerIswriteable(pRoot->pDbPage) ); assert( pChild->nCell==pRoot->nCell || CORRUPT_DB ); - TRACE(("BALANCE: copy root %u into %u\n", pRoot->pgno, pChild->pgno)); + TRACE(("BALANCE: copy root %d into %d\n", pRoot->pgno, pChild->pgno)); /* Copy the overflow cells from pRoot to pChild */ memcpy(pChild->aiOvfl, pRoot->aiOvfl, pRoot->nOverflow*sizeof(pRoot->aiOvfl[0])); memcpy(pChild->apOvfl, pRoot->apOvfl, @@ -77494,10 +74740,11 @@ ** balance_deeper() ** balance_nonroot() */ static int balance(BtCursor *pCur){ int rc = SQLITE_OK; + const int nMin = pCur->pBt->usableSize * 2 / 3; u8 aBalanceQuickSpace[13]; u8 *pFree = 0; VVA_ONLY( int balance_quick_called = 0 ); VVA_ONLY( int balance_deeper_called = 0 ); @@ -77505,15 +74752,11 @@ do { int iPage; MemPage *pPage = pCur->pPage; if( NEVER(pPage->nFree<0) && btreeComputeFreeSpace(pPage) ) break; - if( pPage->nOverflow==0 && pPage->nFree*3<=(int)pCur->pBt->usableSize*2 ){ - /* No rebalance required as long as: - ** (1) There are no overflow cells - ** (2) The amount of free space on the page is less than 2/3rds of - ** the total usable space on the page. */ + if( pPage->nOverflow==0 && pPage->nFree<=nMin ){ break; }else if( (iPage = pCur->iPage)==0 ){ if( pPage->nOverflow && (rc = anotherValidCursor(pCur))==SQLITE_OK ){ /* The root page of the b-tree is overfull. In this case call the ** balance_deeper() function to create a new child for the root-page @@ -77532,15 +74775,10 @@ assert( pCur->pPage->nOverflow ); } }else{ break; } - }else if( sqlite3PagerPageRefcount(pPage->pDbPage)>1 ){ - /* The page being written is not a root page, and there is currently - ** more than one reference to it. This only happens if the page is one - ** of its own ancestor pages. Corruption. */ - rc = SQLITE_CORRUPT_BKPT; }else{ MemPage * const pParent = pCur->apPage[iPage-1]; int const iIdx = pCur->aiIdx[iPage-1]; rc = sqlite3PagerWrite(pParent->pDbPage); @@ -77667,31 +74905,31 @@ return SQLITE_OK; } /* ** Overwrite the cell that cursor pCur is pointing to with fresh content -** contained in pX. In this variant, pCur is pointing to an overflow -** cell. +** contained in pX. */ -static SQLITE_NOINLINE int btreeOverwriteOverflowCell( - BtCursor *pCur, /* Cursor pointing to cell to ovewrite */ - const BtreePayload *pX /* Content to write into the cell */ -){ +static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){ int iOffset; /* Next byte of pX->pData to write */ int nTotal = pX->nData + pX->nZero; /* Total bytes of to write */ int rc; /* Return code */ MemPage *pPage = pCur->pPage; /* Page being written */ BtShared *pBt; /* Btree */ Pgno ovflPgno; /* Next overflow page to write */ u32 ovflPageSize; /* Size to write on overflow page */ - assert( pCur->info.nLocalinfo.pPayload + pCur->info.nLocal > pPage->aDataEnd + || pCur->info.pPayload < pPage->aData + pPage->cellOffset + ){ + return SQLITE_CORRUPT_BKPT; + } /* Overwrite the local portion first */ rc = btreeOverwriteContent(pPage, pCur->info.pPayload, pX, 0, pCur->info.nLocal); if( rc ) return rc; + if( pCur->info.nLocal==nTotal ) return SQLITE_OK; /* Now overwrite the overflow pages */ iOffset = pCur->info.nLocal; assert( nTotal>=0 ); assert( iOffset>=0 ); @@ -77717,33 +74955,10 @@ iOffset += ovflPageSize; }while( iOffsetnData + pX->nZero; /* Total bytes of to write */ - MemPage *pPage = pCur->pPage; /* Page being written */ - - if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd - || pCur->info.pPayload < pPage->aData + pPage->cellOffset - ){ - return SQLITE_CORRUPT_BKPT; - } - if( pCur->info.nLocal==nTotal ){ - /* The entire cell is local */ - return btreeOverwriteContent(pPage, pCur->info.pPayload, pX, - 0, pCur->info.nLocal); - }else{ - /* The cell contains overflow content */ - return btreeOverwriteOverflowCell(pCur, pX); - } -} - /* ** Insert a new record into the BTree. The content of the new record ** is described by the pX object. The pCur cursor is used only to ** define what table the record should be inserted into, and is left @@ -77757,11 +74972,11 @@ ** For an index btree (used for indexes and WITHOUT ROWID tables), the ** key is an arbitrary byte sequence stored in pX.pKey,nKey. The ** pX.pData,nData,nZero fields must be zero. ** ** If the seekResult parameter is non-zero, then a successful call to -** sqlite3BtreeIndexMoveto() to seek cursor pCur to (pKey,nKey) has already +** MovetoUnpacked() to seek cursor pCur to (pKey,nKey) has already ** been performed. In other words, if seekResult!=0 then the cursor ** is currently pointing to a cell that will be adjacent to the cell ** to be inserted. If seekResult<0 then pCur points to a cell that is ** smaller then (pKey,nKey). If seekResult>0 then pCur points to a cell ** that is larger than (pKey,nKey). @@ -77775,18 +74990,19 @@ */ SQLITE_PRIVATE int sqlite3BtreeInsert( BtCursor *pCur, /* Insert data into the table of this cursor */ const BtreePayload *pX, /* Content of the row to be inserted */ int flags, /* True if this is likely an append */ - int seekResult /* Result of prior IndexMoveto() call */ + int seekResult /* Result of prior MovetoUnpacked() call */ ){ int rc; int loc = seekResult; /* -1: before desired location +1: after */ int szNew = 0; int idx; MemPage *pPage; Btree *p = pCur->pBtree; + BtShared *pBt = p->pBt; unsigned char *oldCell; unsigned char *newCell = 0; assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND|BTREE_PREFORMAT))==flags ); assert( (flags & BTREE_PREFORMAT)==0 || seekResult || pCur->pKeyInfo==0 ); @@ -77801,11 +75017,11 @@ ** that the cursor is already where it needs to be and returns without ** doing any work. To avoid thwarting these optimizations, it is important ** not to clear the cursor here. */ if( pCur->curFlags & BTCF_Multiple ){ - rc = saveAllCursors(p->pBt, pCur->pgnoRoot, pCur); + rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur); if( rc ) return rc; if( loc && pCur->iPage<0 ){ /* This can only happen if the schema is corrupt such that there is more ** than one table or index with the same root page as used by the cursor. ** Which can only happen if the SQLITE_NoSchemaError flag was set when @@ -77813,24 +75029,19 @@ ** set the flag, load the schema, and then unset the flag. */ return SQLITE_CORRUPT_BKPT; } } - /* Ensure that the cursor is not in the CURSOR_FAULT state and that it - ** points to a valid cell. - */ if( pCur->eState>=CURSOR_REQUIRESEEK ){ - testcase( pCur->eState==CURSOR_REQUIRESEEK ); - testcase( pCur->eState==CURSOR_FAULT ); rc = moveToRoot(pCur); if( rc && rc!=SQLITE_EMPTY ) return rc; } assert( cursorOwnsBtShared(pCur) ); assert( (pCur->curFlags & BTCF_WriteFlag)!=0 - && p->pBt->inTransaction==TRANS_WRITE - && (p->pBt->btsFlags & BTS_READ_ONLY)==0 ); + && pBt->inTransaction==TRANS_WRITE + && (pBt->btsFlags & BTS_READ_ONLY)==0 ); assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); /* Assert that the caller has been consistent. If this cursor was opened ** expecting an index b-tree, then the caller should be inserting blob ** keys with no associated data. If the cursor was opened expecting an @@ -77930,47 +75141,43 @@ pPage = pCur->pPage; assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) ); assert( pPage->leaf || !pPage->intKey ); if( pPage->nFree<0 ){ - if( NEVER(pCur->eState>CURSOR_INVALID) ){ - /* ^^^^^--- due to the moveToRoot() call above */ + if( pCur->eState>CURSOR_INVALID ){ rc = SQLITE_CORRUPT_BKPT; }else{ rc = btreeComputeFreeSpace(pPage); } if( rc ) return rc; } - TRACE(("INSERT: table=%u nkey=%lld ndata=%u page=%u %s\n", + TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n", pCur->pgnoRoot, pX->nKey, pX->nData, pPage->pgno, loc==0 ? "overwrite" : "new entry")); - assert( pPage->isInit || CORRUPT_DB ); - newCell = p->pBt->pTmpSpace; + assert( pPage->isInit ); + newCell = pBt->pTmpSpace; assert( newCell!=0 ); - assert( BTREE_PREFORMAT==OPFLAG_PREFORMAT ); if( flags & BTREE_PREFORMAT ){ rc = SQLITE_OK; - szNew = p->pBt->nPreformatSize; + szNew = pBt->nPreformatSize; if( szNew<4 ) szNew = 4; - if( ISAUTOVACUUM(p->pBt) && szNew>pPage->maxLocal ){ + if( ISAUTOVACUUM && szNew>pPage->maxLocal ){ CellInfo info; pPage->xParseCell(pPage, newCell, &info); if( info.nPayload!=info.nLocal ){ Pgno ovfl = get4byte(&newCell[szNew-4]); - ptrmapPut(p->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, &rc); - if( NEVER(rc) ) goto end_insert; + ptrmapPut(pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, &rc); } } }else{ rc = fillInCell(pPage, newCell, pX, &szNew); - if( rc ) goto end_insert; } + if( rc ) goto end_insert; assert( szNew==pPage->xCellSize(pPage, newCell) ); - assert( szNew <= MX_CELL_SIZE(p->pBt) ); + assert( szNew <= MX_CELL_SIZE(pBt) ); idx = pCur->ix; - pCur->info.nSize = 0; if( loc==0 ){ CellInfo info; assert( idx>=0 ); if( idx>=pPage->nCell ){ return SQLITE_CORRUPT_BKPT; @@ -77985,11 +75192,11 @@ } BTREE_CLEAR_CELL(rc, pPage, oldCell, info); testcase( pCur->curFlags & BTCF_ValidOvfl ); invalidateOverflowCache(pCur); if( info.nSize==szNew && info.nLocal==info.nPayload - && (!ISAUTOVACUUM(p->pBt) || szNewminLocal) + && (!ISAUTOVACUUM || szNewminLocal) ){ /* Overwrite the old cell with the new if they are the same size. ** We could also try to do this if the old cell is smaller, then add ** the leftover space to the free list. But experiments show that ** doing that is no faster then skipping this optimization and just @@ -78015,11 +75222,11 @@ idx = ++pCur->ix; pCur->curFlags &= ~BTCF_ValidNKey; }else{ assert( pPage->leaf ); } - rc = insertCellFast(pPage, idx, newCell, szNew); + insertCell(pPage, idx, newCell, szNew, 0, 0, &rc); assert( pPage->nOverflow==0 || rc==SQLITE_OK ); assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 ); /* If no error has occurred and pPage has an overflow cell, call balance() ** to redistribute the cells within the tree. Since balance() may move @@ -78039,10 +75246,11 @@ ** the b-tree if possible. If the cursor is left pointing to the last ** entry in the table, and the next row inserted has an integer key ** larger than the largest existing key, it is possible to insert the ** row without seeking the cursor. This can be a big performance boost. */ + pCur->info.nSize = 0; if( pPage->nOverflow ){ assert( rc==SQLITE_OK ); pCur->curFlags &= ~(BTCF_ValidNKey); rc = balance(pCur); @@ -78087,22 +75295,19 @@ ** calling sqlite3BtreeInsert() with the BTREE_PREFORMAT flag specified. ** ** SQLITE_OK is returned if successful, or an SQLite error code otherwise. */ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 iKey){ + int rc = SQLITE_OK; BtShared *pBt = pDest->pBt; u8 *aOut = pBt->pTmpSpace; /* Pointer to next output buffer */ const u8 *aIn; /* Pointer to next input buffer */ u32 nIn; /* Size of input buffer aIn[] */ u32 nRem; /* Bytes of data still to copy */ getCellInfo(pSrc); - if( pSrc->info.nPayload<0x80 ){ - *(aOut++) = pSrc->info.nPayload; - }else{ - aOut += sqlite3PutVarint(aOut, pSrc->info.nPayload); - } + aOut += putVarint32(aOut, pSrc->info.nPayload); if( pDest->pKeyInfo==0 ) aOut += putVarint(aOut, iKey); nIn = pSrc->info.nLocal; aIn = pSrc->info.pPayload; if( aIn+nIn>pSrc->pPage->aDataEnd ){ return SQLITE_CORRUPT_BKPT; @@ -78109,13 +75314,11 @@ } nRem = pSrc->info.nPayload; if( nIn==nRem && nInpPage->maxLocal ){ memcpy(aOut, aIn, nIn); pBt->nPreformatSize = nIn + (aOut - pBt->pTmpSpace); - return SQLITE_OK; }else{ - int rc = SQLITE_OK; Pager *pSrcPager = pSrc->pBt->pPager; u8 *pPgnoOut = 0; Pgno ovflIn = 0; DbPage *pPageIn = 0; MemPage *pPageOut = 0; @@ -78163,11 +75366,11 @@ if( rc==SQLITE_OK && nRem>0 && ALWAYS(pPgnoOut) ){ Pgno pgnoNew; MemPage *pNew = 0; rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0); put4byte(pPgnoOut, pgnoNew); - if( ISAUTOVACUUM(pBt) && pPageOut ){ + if( ISAUTOVACUUM && pPageOut ){ ptrmapPut(pBt, pgnoNew, PTRMAP_OVERFLOW2, pPageOut->pgno, &rc); } releasePage(pPageOut); pPageOut = pNew; if( pPageOut ){ @@ -78179,12 +75382,13 @@ } }while( nRem>0 && rc==SQLITE_OK ); releasePage(pPageOut); sqlite3PagerUnref(pPageIn); - return rc; } + + return rc; } /* ** Delete the entry that the cursor is pointing to. ** @@ -78239,13 +75443,10 @@ } pCell = findCell(pPage, iCellIdx); if( pPage->nFree<0 && btreeComputeFreeSpace(pPage) ){ return SQLITE_CORRUPT_BKPT; } - if( pCell<&pPage->aCellIdx[pPage->nCell] ){ - return SQLITE_CORRUPT_BKPT; - } /* If the BTREE_SAVEPOSITION bit is on, then the cursor position must ** be preserved following this delete operation. If the current delete ** will cause a b-tree rebalance, then this is done by saving the cursor ** key and leaving the cursor in CURSOR_REQUIRESEEK state before @@ -78262,12 +75463,11 @@ ** bPreserve==2 Cursor won't move. Set CURSOR_SKIPNEXT. */ bPreserve = (flags & BTREE_SAVEPOSITION)!=0; if( bPreserve ){ if( !pPage->leaf - || (pPage->nFree+pPage->xCellSize(pPage,pCell)+2) > - (int)(pBt->usableSize*2/3) + || (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3) || pPage->nCell==1 /* See dbfuzz001.test for a test case */ ){ /* A b-tree rebalance will be required after deleting this entry. ** Save the cursor key. */ rc = saveCursorKey(pCur); @@ -78338,11 +75538,11 @@ assert( MX_CELL_SIZE(pBt) >= nCell ); pTmp = pBt->pTmpSpace; assert( pTmp!=0 ); rc = sqlite3PagerWrite(pLeaf->pDbPage); if( rc==SQLITE_OK ){ - rc = insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n); + insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc); } dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc); if( rc ) return rc; } @@ -78359,19 +75559,11 @@ ** on the leaf node first. If the balance proceeds far enough up the ** tree that we can be sure that any problem in the internal node has ** been corrected, so be it. Otherwise, after balancing the leaf node, ** walk the cursor up the tree to the internal node and balance it as ** well. */ - assert( pCur->pPage->nOverflow==0 ); - assert( pCur->pPage->nFree>=0 ); - if( pCur->pPage->nFree*3<=(int)pCur->pBt->usableSize*2 ){ - /* Optimization: If the free space is less than 2/3rds of the page, - ** then balance() will always be a no-op. No need to invoke it. */ - rc = SQLITE_OK; - }else{ - rc = balance(pCur); - } + rc = balance(pCur); if( rc==SQLITE_OK && pCur->iPage>iCellDepth ){ releasePageNotNull(pCur->pPage); pCur->iPage--; while( pCur->iPage>iCellDepth ){ releasePage(pCur->apPage[pCur->iPage--]); @@ -78937,70 +76129,33 @@ SQLITE_PRIVATE Pager *sqlite3BtreePager(Btree *p){ return p->pBt->pPager; } #ifndef SQLITE_OMIT_INTEGRITY_CHECK -/* -** Record an OOM error during integrity_check -*/ -static void checkOom(IntegrityCk *pCheck){ - pCheck->rc = SQLITE_NOMEM; - pCheck->mxErr = 0; /* Causes integrity_check processing to stop */ - if( pCheck->nErr==0 ) pCheck->nErr++; -} - -/* -** Invoke the progress handler, if appropriate. Also check for an -** interrupt. -*/ -static void checkProgress(IntegrityCk *pCheck){ - sqlite3 *db = pCheck->db; - if( AtomicLoad(&db->u1.isInterrupted) ){ - pCheck->rc = SQLITE_INTERRUPT; - pCheck->nErr++; - pCheck->mxErr = 0; - } -#ifndef SQLITE_OMIT_PROGRESS_CALLBACK - if( db->xProgress ){ - assert( db->nProgressOps>0 ); - pCheck->nStep++; - if( (pCheck->nStep % db->nProgressOps)==0 - && db->xProgress(db->pProgressArg) - ){ - pCheck->rc = SQLITE_INTERRUPT; - pCheck->nErr++; - pCheck->mxErr = 0; - } - } -#endif -} - /* ** Append a message to the error message string. */ static void checkAppendMsg( IntegrityCk *pCheck, const char *zFormat, ... ){ va_list ap; - checkProgress(pCheck); if( !pCheck->mxErr ) return; pCheck->mxErr--; pCheck->nErr++; va_start(ap, zFormat); if( pCheck->errMsg.nChar ){ sqlite3_str_append(&pCheck->errMsg, "\n", 1); } if( pCheck->zPfx ){ - sqlite3_str_appendf(&pCheck->errMsg, pCheck->zPfx, - pCheck->v0, pCheck->v1, pCheck->v2); + sqlite3_str_appendf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2); } sqlite3_str_vappendf(&pCheck->errMsg, zFormat, ap); va_end(ap); if( pCheck->errMsg.accError==SQLITE_NOMEM ){ - checkOom(pCheck); + pCheck->bOomFault = 1; } } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ #ifndef SQLITE_OMIT_INTEGRITY_CHECK @@ -79031,17 +76186,18 @@ ** ** Also check that the page number is in bounds. */ static int checkRef(IntegrityCk *pCheck, Pgno iPage){ if( iPage>pCheck->nPage || iPage==0 ){ - checkAppendMsg(pCheck, "invalid page number %u", iPage); + checkAppendMsg(pCheck, "invalid page number %d", iPage); return 1; } if( getPageReferenced(pCheck, iPage) ){ - checkAppendMsg(pCheck, "2nd reference to page %u", iPage); + checkAppendMsg(pCheck, "2nd reference to page %d", iPage); return 1; } + if( AtomicLoad(&pCheck->db->u1.isInterrupted) ) return 1; setPageReferenced(pCheck, iPage); return 0; } #ifndef SQLITE_OMIT_AUTOVACUUM @@ -79060,18 +76216,18 @@ u8 ePtrmapType; Pgno iPtrmapParent; rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent); if( rc!=SQLITE_OK ){ - if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) checkOom(pCheck); - checkAppendMsg(pCheck, "Failed to read ptrmap key=%u", iChild); + if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) pCheck->bOomFault = 1; + checkAppendMsg(pCheck, "Failed to read ptrmap key=%d", iChild); return; } if( ePtrmapType!=eType || iPtrmapParent!=iParent ){ checkAppendMsg(pCheck, - "Bad ptr map entry key=%u expected=(%u,%u) got=(%u,%u)", + "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)", iChild, eType, iParent, ePtrmapType, iPtrmapParent); } } #endif @@ -79092,11 +76248,11 @@ DbPage *pOvflPage; unsigned char *pOvflData; if( checkRef(pCheck, iPage) ) break; N--; if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage, 0) ){ - checkAppendMsg(pCheck, "failed to get page %u", iPage); + checkAppendMsg(pCheck, "failed to get page %d", iPage); break; } pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage); if( isFreeList ){ u32 n = (u32)get4byte(&pOvflData[4]); @@ -79105,11 +76261,11 @@ checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0); } #endif if( n>pCheck->pBt->usableSize/4-2 ){ checkAppendMsg(pCheck, - "freelist leaf count too big on page %u", iPage); + "freelist leaf count too big on page %d", iPage); N--; }else{ for(i=0; i<(int)n; i++){ Pgno iFreePage = get4byte(&pOvflData[8+i*4]); #ifndef SQLITE_OMIT_AUTOVACUUM @@ -79137,11 +76293,11 @@ iPage = get4byte(pOvflData); sqlite3PagerUnref(pOvflPage); } if( N && nErrAtStart==pCheck->nErr ){ checkAppendMsg(pCheck, - "%s is %u but should be %u", + "%s is %d but should be %d", isFreeList ? "size" : "overflow list length", expected-N, expected); } } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ @@ -79167,13 +76323,11 @@ ** entry represents the span of a cell or freeblock on a btree page. ** The upper 16 bits are the index of the first byte of a range and the ** lower 16 bits are the index of the last byte of that range. */ static void btreeHeapInsert(u32 *aHeap, u32 x){ - u32 j, i; - assert( aHeap!=0 ); - i = ++aHeap[0]; + u32 j, i = ++aHeap[0]; aHeap[i] = x; while( (j = i/2)>0 && aHeap[j]>aHeap[i] ){ x = aHeap[j]; aHeap[j] = aHeap[i]; aHeap[i] = x; @@ -79246,18 +76400,16 @@ int saved_v2 = pCheck->v2; u8 savedIsInit = 0; /* Check that the page exists */ - checkProgress(pCheck); - if( pCheck->mxErr==0 ) goto end_of_check; pBt = pCheck->pBt; usableSize = pBt->usableSize; if( iPage==0 ) return 0; if( checkRef(pCheck, iPage) ) return 0; - pCheck->zPfx = "Tree %u page %u: "; - pCheck->v0 = pCheck->v1 = iPage; + pCheck->zPfx = "Page %u: "; + pCheck->v1 = iPage; if( (rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0 ){ checkAppendMsg(pCheck, "unable to get the page. error code=%d", rc); goto end_of_check; } @@ -79279,11 +76431,11 @@ } data = pPage->aData; hdr = pPage->hdrOffset; /* Set up for cell analysis */ - pCheck->zPfx = "Tree %u page %u cell %u: "; + pCheck->zPfx = "On tree page %u cell %d: "; contentOffset = get2byteNotZero(&data[hdr+5]); assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */ /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the ** number of cells on the page. */ @@ -79299,11 +76451,11 @@ if( !pPage->leaf ){ /* Analyze the right-child page of internal pages */ pgno = get4byte(&data[hdr+8]); #ifndef SQLITE_OMIT_AUTOVACUUM if( pBt->autoVacuum ){ - pCheck->zPfx = "Tree %u page %u right child: "; + pCheck->zPfx = "On page %u at right child: "; checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage); } #endif depth = checkTreePage(pCheck, pgno, &maxKey, maxKey); keyCanBeEqual = 0; @@ -79323,11 +76475,11 @@ pCheck->v2 = i; assert( pCellIdx==&data[cellStart + i*2] ); pc = get2byteAligned(pCellIdx); pCellIdx -= 2; if( pcusableSize-4 ){ - checkAppendMsg(pCheck, "Offset %u out of range %u..%u", + checkAppendMsg(pCheck, "Offset %d out of range %d..%d", pc, contentOffset, usableSize-4); doCoverageCheck = 0; continue; } pCell = &data[pc]; @@ -79455,11 +76607,11 @@ ** EVIDENCE-OF: R-07161-27322 The one-byte integer at offset 7 gives the ** number of fragmented free bytes within the cell content area. */ if( heap[0]==0 && nFrag!=data[hdr+7] ){ checkAppendMsg(pCheck, - "Fragmentation of %u bytes reported as %u on page %u", + "Fragmentation of %d bytes reported as %d on page %u", nFrag, data[hdr+7], iPage); } } end_of_check: @@ -79493,18 +76645,17 @@ ** and the checks to make sure every page is referenced are also skipped, ** since obviously it is not possible to know which pages are covered by ** the unverified btrees. Except, if aRoot[1] is 1, then the freelist ** checks are still performed. */ -SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( +SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck( sqlite3 *db, /* Database connection that is running the check */ Btree *p, /* The btree to be checked */ Pgno *aRoot, /* An array of root pages numbers for individual trees */ int nRoot, /* Number of entries in aRoot[] */ int mxErr, /* Stop reporting errors after this many */ - int *pnErr, /* OUT: Write number of errors seen to this variable */ - char **pzOut /* OUT: Write the error message string here */ + int *pnErr /* Write number of errors seen to this variable */ ){ Pgno i; IntegrityCk sCheck; BtShared *pBt = p->pBt; u64 savedDbFlags = pBt->db->flags; @@ -79523,40 +76674,46 @@ sqlite3BtreeEnter(p); assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE ); VVA_ONLY( nRef = sqlite3PagerRefcount(pBt->pPager) ); assert( nRef>=0 ); - memset(&sCheck, 0, sizeof(sCheck)); sCheck.db = db; sCheck.pBt = pBt; sCheck.pPager = pBt->pPager; sCheck.nPage = btreePagecount(sCheck.pBt); sCheck.mxErr = mxErr; + sCheck.nErr = 0; + sCheck.bOomFault = 0; + sCheck.zPfx = 0; + sCheck.v1 = 0; + sCheck.v2 = 0; + sCheck.aPgRef = 0; + sCheck.heap = 0; sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH); sCheck.errMsg.printfFlags = SQLITE_PRINTF_INTERNAL; if( sCheck.nPage==0 ){ goto integrity_ck_cleanup; } sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1); if( !sCheck.aPgRef ){ - checkOom(&sCheck); + sCheck.bOomFault = 1; goto integrity_ck_cleanup; } sCheck.heap = (u32*)sqlite3PageMalloc( pBt->pageSize ); if( sCheck.heap==0 ){ - checkOom(&sCheck); + sCheck.bOomFault = 1; goto integrity_ck_cleanup; } i = PENDING_BYTE_PAGE(pBt); if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i); /* Check the integrity of the freelist */ if( bCkFreelist ){ - sCheck.zPfx = "Freelist: "; + sCheck.zPfx = "Main freelist: "; checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]), get4byte(&pBt->pPage1->aData[36])); sCheck.zPfx = 0; } @@ -79569,11 +76726,11 @@ Pgno mxInHdr; for(i=0; (int)ipPage1->aData[52]); if( mx!=mxInHdr ){ checkAppendMsg(&sCheck, - "max rootpage (%u) disagrees with header (%u)", + "max rootpage (%d) disagrees with header (%d)", mx, mxInHdr ); } }else if( get4byte(&pBt->pPage1->aData[64])!=0 ){ checkAppendMsg(&sCheck, @@ -79600,23 +76757,23 @@ */ if( !bPartial ){ for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){ #ifdef SQLITE_OMIT_AUTOVACUUM if( getPageReferenced(&sCheck, i)==0 ){ - checkAppendMsg(&sCheck, "Page %u: never used", i); + checkAppendMsg(&sCheck, "Page %d is never used", i); } #else /* If the database supports auto-vacuum, make sure no tables contain ** references to pointer-map pages. */ if( getPageReferenced(&sCheck, i)==0 && (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){ - checkAppendMsg(&sCheck, "Page %u: never used", i); + checkAppendMsg(&sCheck, "Page %d is never used", i); } if( getPageReferenced(&sCheck, i)!=0 && (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){ - checkAppendMsg(&sCheck, "Page %u: pointer map referenced", i); + checkAppendMsg(&sCheck, "Pointer map page %d is referenced", i); } #endif } } @@ -79623,21 +76780,20 @@ /* Clean up and report errors. */ integrity_ck_cleanup: sqlite3PageFree(sCheck.heap); sqlite3_free(sCheck.aPgRef); - *pnErr = sCheck.nErr; - if( sCheck.nErr==0 ){ + if( sCheck.bOomFault ){ sqlite3_str_reset(&sCheck.errMsg); - *pzOut = 0; - }else{ - *pzOut = sqlite3StrAccumFinish(&sCheck.errMsg); + sCheck.nErr++; } + *pnErr = sCheck.nErr; + if( sCheck.nErr==0 ) sqlite3_str_reset(&sCheck.errMsg); /* Make sure this analysis did not leave any unref() pages. */ assert( nRef==sqlite3PagerRefcount(pBt->pPager) ); sqlite3BtreeLeave(p); - return sCheck.rc; + return sqlite3StrAccumFinish(&sCheck.errMsg); } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ /* ** Return the full pathname of the underlying database file. Return @@ -79898,21 +77054,10 @@ /* ** Return the size of the header added to each page by this module. */ SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void){ return ROUND8(sizeof(MemPage)); } -/* -** If no transaction is active and the database is not a temp-db, clear -** the in-memory pager cache. -*/ -SQLITE_PRIVATE void sqlite3BtreeClearCache(Btree *p){ - BtShared *pBt = p->pBt; - if( pBt->inTransaction==TRANS_NONE ){ - sqlite3PagerClearCache(pBt->pPager); - } -} - #if !defined(SQLITE_OMIT_SHARED_CACHE) /* ** Return true if the Btree passed as the only argument is sharable. */ SQLITE_PRIVATE int sqlite3BtreeSharable(Btree *p){ @@ -80819,21 +77964,20 @@ /* Work-around for GCC bug ** https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96270 */ i64 x; assert( (p->flags&MEM_Int)*2==sizeof(x) ); memcpy(&x, (char*)&p->u, (p->flags&MEM_Int)*2); - p->n = sqlite3Int64ToText(x, zBuf); + sqlite3Int64ToText(x, zBuf); #else - p->n = sqlite3Int64ToText(p->u.i, zBuf); + sqlite3Int64ToText(p->u.i, zBuf); #endif }else{ sqlite3StrAccumInit(&acc, 0, zBuf, sz, 0); sqlite3_str_appendf(&acc, "%!.15g", (p->flags & MEM_IntReal)!=0 ? (double)p->u.i : p->u.r); assert( acc.zText==zBuf && acc.mxAlloc<=0 ); zBuf[acc.nChar] = 0; /* Fast version of sqlite3StrAccumFinish(&acc) */ - p->n = acc.nChar; } } #ifdef SQLITE_DEBUG /* @@ -80857,11 +78001,10 @@ ** true if everything is ok and false if there is a problem. ** ** This routine is for use inside of assert() statements only. */ SQLITE_PRIVATE int sqlite3VdbeMemValidStrRep(Mem *p){ - Mem tmp; char zBuf[100]; char *z; int i, j, incr; if( (p->flags & MEM_Str)==0 ) return 1; if( p->flags & MEM_Term ){ @@ -80874,12 +78017,11 @@ assert( p->z[p->n]==0 ); assert( p->enc==SQLITE_UTF8 || p->z[(p->n+1)&~1]==0 ); assert( p->enc==SQLITE_UTF8 || p->z[((p->n+1)&~1)+1]==0 ); } if( (p->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 ) return 1; - memcpy(&tmp, p, sizeof(tmp)); - vdbeMemRenderNum(sizeof(zBuf), zBuf, &tmp); + vdbeMemRenderNum(sizeof(zBuf), zBuf, p); z = p->z; i = j = 0; incr = 1; if( p->enc!=SQLITE_UTF8 ){ incr = 2; @@ -81144,11 +78286,11 @@ return SQLITE_NOMEM_BKPT; } vdbeMemRenderNum(nByte, pMem->z, pMem); assert( pMem->z!=0 ); - assert( pMem->n==(int)sqlite3Strlen30NN(pMem->z) ); + pMem->n = sqlite3Strlen30NN(pMem->z); pMem->enc = SQLITE_UTF8; pMem->flags |= MEM_Str|MEM_Term; if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal); sqlite3VdbeChangeEncoding(pMem, enc); return SQLITE_OK; @@ -81165,22 +78307,20 @@ SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ sqlite3_context ctx; Mem t; assert( pFunc!=0 ); assert( pMem!=0 ); - assert( pMem->db!=0 ); assert( pFunc->xFinalize!=0 ); assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef ); - assert( sqlite3_mutex_held(pMem->db->mutex) ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); memset(&ctx, 0, sizeof(ctx)); memset(&t, 0, sizeof(t)); t.flags = MEM_Null; t.db = pMem->db; ctx.pOut = &t; ctx.pMem = pMem; ctx.pFunc = pFunc; - ctx.enc = ENC(t.db); pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */ assert( (pMem->flags & MEM_Dyn)==0 ); if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc); memcpy(pMem, &t, sizeof(t)); return ctx.isError; @@ -81198,18 +78338,16 @@ SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem *pAccum, Mem *pOut, FuncDef *pFunc){ sqlite3_context ctx; assert( pFunc!=0 ); assert( pFunc->xValue!=0 ); assert( (pAccum->flags & MEM_Null)!=0 || pFunc==pAccum->u.pDef ); - assert( pAccum->db!=0 ); - assert( sqlite3_mutex_held(pAccum->db->mutex) ); + assert( pAccum->db==0 || sqlite3_mutex_held(pAccum->db->mutex) ); memset(&ctx, 0, sizeof(ctx)); sqlite3VdbeMemSetNull(pOut); ctx.pOut = pOut; ctx.pMem = pAccum; ctx.pFunc = pFunc; - ctx.enc = ENC(pAccum->db); pFunc->xValue(&ctx); return ctx.isError; } #endif /* SQLITE_OMIT_WINDOWFUNC */ @@ -81271,18 +78409,10 @@ if( VdbeMemDynamic(p) || p->szMalloc ){ vdbeMemClear(p); } } -/* Like sqlite3VdbeMemRelease() but faster for cases where we -** know in advance that the Mem is not MEM_Dyn or MEM_Agg. -*/ -SQLITE_PRIVATE void sqlite3VdbeMemReleaseMalloc(Mem *p){ - assert( !VdbeMemDynamic(p) ); - if( p->szMalloc ) vdbeMemClear(p); -} - /* ** Convert a 64-bit IEEE double into a 64-bit signed integer. ** If the double is out of range of a 64-bit signed integer then ** return the closest available 64-bit signed integer. */ @@ -81384,39 +78514,36 @@ if( pMem->flags & MEM_Null ) return ifNull; return sqlite3VdbeRealValue(pMem)!=0.0; } /* -** The MEM structure is already a MEM_Real or MEM_IntReal. Try to -** make it a MEM_Int if we can. +** The MEM structure is already a MEM_Real. Try to also make it a +** MEM_Int if we can. */ SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){ + i64 ix; assert( pMem!=0 ); - assert( pMem->flags & (MEM_Real|MEM_IntReal) ); + assert( pMem->flags & MEM_Real ); assert( !sqlite3VdbeMemIsRowSet(pMem) ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); - if( pMem->flags & MEM_IntReal ){ - MemSetTypeFlag(pMem, MEM_Int); - }else{ - i64 ix = doubleToInt64(pMem->u.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. - */ - if( pMem->u.r==ix && ix>SMALLEST_INT64 && ixu.i = ix; - MemSetTypeFlag(pMem, MEM_Int); - } + ix = doubleToInt64(pMem->u.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. + */ + if( pMem->u.r==ix && ix>SMALLEST_INT64 && ixu.i = ix; + MemSetTypeFlag(pMem, MEM_Int); } } /* ** Convert pMem to type integer. Invalidate any prior representations. @@ -81460,20 +78587,10 @@ return r1==0.0 || (memcmp(&r1, &r2, sizeof(r1))==0 && i >= -2251799813685248LL && i < 2251799813685248LL); } -/* Convert a floating point value to its closest integer. Do so in -** a way that avoids 'outside the range of representable values' warnings -** from UBSAN. -*/ -SQLITE_PRIVATE i64 sqlite3RealToI64(double r){ - if( r<=(double)SMALLEST_INT64 ) return SMALLEST_INT64; - if( r>=(double)LARGEST_INT64) return LARGEST_INT64; - return (i64)r; -} - /* ** Convert pMem so that it has type MEM_Real or MEM_Int. ** Invalidate any prior representations. ** ** Every effort is made to force the conversion, even if the input @@ -81491,11 +78608,11 @@ sqlite3_int64 ix; assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); rc = sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc); if( ((rc==0 || rc==1) && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1) - || sqlite3RealSameAsInt(pMem->u.r, (ix = sqlite3RealToI64(pMem->u.r))) + || sqlite3RealSameAsInt(pMem->u.r, (ix = (i64)pMem->u.r)) ){ pMem->u.i = ix; MemSetTypeFlag(pMem, MEM_Int); }else{ MemSetTypeFlag(pMem, MEM_Real); @@ -81543,11 +78660,10 @@ assert( MEM_Str==(MEM_Blob>>3) ); pMem->flags |= (pMem->flags&MEM_Blob)>>3; sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding); assert( pMem->flags & MEM_Str || pMem->db->mallocFailed ); pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero); - if( encoding!=SQLITE_UTF8 ) pMem->n &= ~1; return sqlite3VdbeChangeEncoding(pMem, encoding); } } return SQLITE_OK; } @@ -81837,17 +78953,10 @@ ** 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. -** -** The "enc" parameter is the text encoding for the string, or zero -** to store a blob. -** -** If n is negative, then the string consists of all bytes up to but -** excluding the first zero character. The n parameter must be -** non-negative for blobs. */ SQLITE_PRIVATE int sqlite3VdbeMemSetStr( Mem *pMem, /* Memory cell to set to string value */ const char *z, /* String pointer */ i64 n, /* Bytes in string, or negative */ @@ -81854,16 +78963,15 @@ u8 enc, /* Encoding of z. 0 for BLOBs */ void (*xDel)(void*) /* Destructor function */ ){ i64 nByte = n; /* New value for pMem->n */ int iLimit; /* Maximum allowed string or blob size */ - u16 flags; /* New value for pMem->flags */ + u16 flags = 0; /* New value for pMem->flags */ assert( pMem!=0 ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( !sqlite3VdbeMemIsRowSet(pMem) ); - assert( enc!=0 || n>=0 ); /* If z is a NULL pointer, set pMem to contain an SQL NULL. */ if( !z ){ sqlite3VdbeMemSetNull(pMem); return SQLITE_OK; @@ -81872,34 +78980,19 @@ 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 ){ nByte = strlen(z); }else{ for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){} } - flags= MEM_Str|MEM_Term; - }else if( enc==0 ){ - flags = MEM_Blob; - enc = SQLITE_UTF8; - }else{ - flags = MEM_Str; - } - if( nByte>iLimit ){ - if( xDel && xDel!=SQLITE_TRANSIENT ){ - if( xDel==SQLITE_DYNAMIC ){ - sqlite3DbFree(pMem->db, (void*)z); - }else{ - xDel((void*)z); - } - } - sqlite3VdbeMemSetNull(pMem); - return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG); + 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). @@ -81907,10 +79000,13 @@ if( xDel==SQLITE_TRANSIENT ){ i64 nAlloc = nByte; if( flags&MEM_Term ){ nAlloc += (enc==SQLITE_UTF8?1:2); } + if( nByte>iLimit ){ + return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG); + } testcase( nAlloc==0 ); testcase( nAlloc==31 ); testcase( nAlloc==32 ); if( sqlite3VdbeMemClearAndResize(pMem, (int)MAX(nAlloc,32)) ){ return SQLITE_NOMEM_BKPT; @@ -81928,18 +79024,30 @@ } } pMem->n = (int)(nByte & 0x7fffffff); pMem->flags = flags; - pMem->enc = enc; + if( enc ){ + pMem->enc = enc; +#ifdef SQLITE_ENABLE_SESSION + }else if( pMem->db==0 ){ + pMem->enc = SQLITE_UTF8; +#endif + }else{ + assert( pMem->db!=0 ); + pMem->enc = ENC(pMem->db); + } #ifndef SQLITE_OMIT_UTF16 if( enc>SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){ return SQLITE_NOMEM_BKPT; } #endif + if( nByte>iLimit ){ + return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG); + } return SQLITE_OK; } /* @@ -82188,13 +79296,10 @@ assert( ExprUseXList(p) ); pList = p->x.pList; if( pList ) nVal = pList->nExpr; assert( !ExprHasProperty(p, EP_IntValue) ); pFunc = sqlite3FindFunction(db, p->u.zToken, nVal, enc, 0); -#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION - if( pFunc==0 ) return SQLITE_OK; -#endif assert( pFunc ); if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0 || (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL) ){ return SQLITE_OK; @@ -82216,32 +79321,32 @@ if( pVal==0 ){ rc = SQLITE_NOMEM_BKPT; goto value_from_function_out; } + assert( pCtx->pParse->rc==SQLITE_OK ); memset(&ctx, 0, sizeof(ctx)); ctx.pOut = pVal; ctx.pFunc = pFunc; - ctx.enc = ENC(db); pFunc->xSFunc(&ctx, nVal, apVal); if( ctx.isError ){ rc = ctx.isError; sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal)); }else{ sqlite3ValueApplyAffinity(pVal, aff, SQLITE_UTF8); assert( rc==SQLITE_OK ); rc = sqlite3VdbeChangeEncoding(pVal, enc); - if( NEVER(rc==SQLITE_OK && sqlite3VdbeMemTooBig(pVal)) ){ + if( rc==SQLITE_OK && sqlite3VdbeMemTooBig(pVal) ){ rc = SQLITE_TOOBIG; pCtx->pParse->nErr++; } } + pCtx->pParse->rc = rc; value_from_function_out: if( rc!=SQLITE_OK ){ pVal = 0; - pCtx->pParse->rc = rc; } if( apVal ){ for(i=0; iu.zToken,0); rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx); testcase( rc!=SQLITE_OK ); if( *ppVal ){ -#ifdef SQLITE_ENABLE_STAT4 - rc = ExpandBlob(*ppVal); -#else - /* zero-blobs only come from functions, not literal values. And - ** functions are only processed under STAT4 */ - assert( (ppVal[0][0].flags & MEM_Zero)==0 ); -#endif - sqlite3VdbeMemCast(*ppVal, aff, enc); - sqlite3ValueApplyAffinity(*ppVal, affinity, enc); + sqlite3VdbeMemCast(*ppVal, aff, SQLITE_UTF8); + sqlite3ValueApplyAffinity(*ppVal, affinity, SQLITE_UTF8); } return rc; } /* Handle negative integers in a single step. This is needed in the @@ -82687,13 +79785,10 @@ Mem *p = (Mem*)pVal; assert( (p->flags & MEM_Null)==0 || (p->flags & (MEM_Str|MEM_Blob))==0 ); if( (p->flags & MEM_Str)!=0 && pVal->enc==enc ){ return p->n; } - if( (p->flags & MEM_Str)!=0 && enc!=SQLITE_UTF8 && pVal->enc!=SQLITE_UTF8 ){ - return p->n; - } if( (p->flags & MEM_Blob)!=0 ){ if( p->flags & MEM_Zero ){ return p->n + p->u.nZero; }else{ return p->n; @@ -82735,16 +79830,16 @@ p = sqlite3DbMallocRawNN(db, sizeof(Vdbe) ); if( p==0 ) return 0; memset(&p->aOp, 0, sizeof(Vdbe)-offsetof(Vdbe,aOp)); p->db = db; if( db->pVdbe ){ - db->pVdbe->ppVPrev = &p->pVNext; + db->pVdbe->pPrev = p; } - p->pVNext = db->pVdbe; - p->ppVPrev = &db->pVdbe; + p->pNext = db->pVdbe; + p->pPrev = 0; db->pVdbe = p; - assert( p->eVdbeState==VDBE_INIT_STATE ); + p->iVdbeMagic = VDBE_MAGIC_INIT; p->pParse = pParse; pParse->pVdbe = p; assert( pParse->aLabel==0 ); assert( pParse->nLabel==0 ); assert( p->nOpAlloc==0 ); @@ -82820,32 +79915,25 @@ return 0; } #endif /* -** Swap byte-code between two VDBE structures. -** -** This happens after pB was previously run and returned -** SQLITE_SCHEMA. The statement was then reprepared in pA. -** This routine transfers the new bytecode in pA over to pB -** so that pB can be run again. The old pB byte code is -** moved back to pA so that it will be cleaned up when pA is -** finalized. +** Swap all content between two VDBE structures. */ SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){ - Vdbe tmp, *pTmp, **ppTmp; + Vdbe tmp, *pTmp; char *zTmp; assert( pA->db==pB->db ); tmp = *pA; *pA = *pB; *pB = tmp; - pTmp = pA->pVNext; - pA->pVNext = pB->pVNext; - pB->pVNext = pTmp; - ppTmp = pA->ppVPrev; - pA->ppVPrev = pB->ppVPrev; - pB->ppVPrev = ppTmp; + 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_ENABLE_NORMALIZE zTmp = pA->zNormSql; @@ -82892,11 +79980,11 @@ if( nNew > p->db->aLimit[SQLITE_LIMIT_VDBE_OP] ){ sqlite3OomFault(p->db); return SQLITE_NOMEM; } - assert( nOp<=(int)(1024/sizeof(Op)) ); + assert( nOp<=(1024/sizeof(Op)) ); assert( nNew>=(v->nOpAlloc+nOp) ); pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op)); if( pNew ){ p->szOpAlloc = sqlite3DbMallocSize(p->db, pNew); v->nOpAlloc = p->szOpAlloc/sizeof(Op); @@ -82917,12 +80005,10 @@ ** sqlite3MisuseError(lineno) ** sqlite3CantopenError(lineno) */ static void test_addop_breakpoint(int pc, Op *pOp){ static int n = 0; - (void)pc; - (void)pOp; n++; } #endif /* @@ -82950,11 +80036,11 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ int i; VdbeOp *pOp; i = p->nOp; - assert( p->eVdbeState==VDBE_INIT_STATE ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); assert( op>=0 && op<0xff ); if( p->nOpAlloc<=i ){ return growOp3(p, op, p1, p2, p3); } assert( p->aOp!=0 ); @@ -82969,19 +80055,19 @@ pOp->p4.p = 0; pOp->p4type = P4_NOTUSED; #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS pOp->zComment = 0; #endif -#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) - pOp->nExec = 0; - pOp->nCycle = 0; -#endif #ifdef SQLITE_DEBUG if( p->db->flags & SQLITE_VdbeAddopTrace ){ sqlite3VdbePrintOp(0, i, &p->aOp[i]); test_addop_breakpoint(i, &p->aOp[i]); } +#endif +#ifdef VDBE_PROFILE + pOp->cycles = 0; + pOp->cnt = 0; #endif #ifdef SQLITE_VDBE_COVERAGE pOp->iSrcLine = 0; #endif return i; @@ -83095,11 +80181,10 @@ pCtx->argc = nArg; pCtx->iOp = sqlite3VdbeCurrentAddr(v); addr = sqlite3VdbeAddOp4(v, eCallCtx ? OP_PureFunc : OP_Function, p1, p2, p3, (char*)pCtx, P4_FUNCCTX); sqlite3VdbeChangeP5(v, eCallCtx & NC_SelfRef); - sqlite3MayAbort(pParse); return addr; } /* ** Add an opcode that includes the p4 value with a P4_INT64 or @@ -83146,16 +80231,15 @@ ** Add a new OP_Explain opcode. ** ** If the bPush flag is true, then make this opcode the parent for ** subsequent Explains until sqlite3VdbeExplainPop() is called. */ -SQLITE_PRIVATE int sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){ - int addr = 0; -#if !defined(SQLITE_DEBUG) +SQLITE_PRIVATE void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){ +#ifndef SQLITE_DEBUG /* Always include the OP_Explain opcodes if SQLITE_DEBUG is defined. ** But omit them (for performance) during production builds */ - if( pParse->explain==2 || IS_STMT_SCANSTATUS(pParse->db) ) + if( pParse->explain==2 ) #endif { char *zMsg; Vdbe *v; va_list ap; @@ -83163,19 +80247,17 @@ va_start(ap, zFmt); zMsg = sqlite3VMPrintf(pParse->db, zFmt, ap); va_end(ap); v = pParse->pVdbe; iThis = v->nOp; - addr = sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0, + sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0, zMsg, P4_DYNAMIC); - sqlite3ExplainBreakpoint(bPush?"PUSH":"", sqlite3VdbeGetLastOp(v)->p4.z); + sqlite3ExplainBreakpoint(bPush?"PUSH":"", sqlite3VdbeGetOp(v,-1)->p4.z); if( bPush){ pParse->addrExplain = iThis; } - sqlite3VdbeScanStatus(v, iThis, 0, 0, 0, 0); } - return addr; } /* ** Pop the EXPLAIN QUERY PLAN stack one level. */ @@ -83279,21 +80361,18 @@ }else{ #ifdef SQLITE_DEBUG int i; for(i=p->nLabelAlloc; iaLabel[i] = -1; #endif - if( nNewSize>=100 && (nNewSize/100)>(p->nLabelAlloc/100) ){ - sqlite3ProgressCheck(p); - } p->nLabelAlloc = nNewSize; p->aLabel[j] = v->nOp; } } SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){ Parse *p = v->pParse; int j = ADDR(x); - assert( v->eVdbeState==VDBE_INIT_STATE ); + assert( v->iVdbeMagic==VDBE_MAGIC_INIT ); assert( j<-p->nLabel ); assert( j>=0 ); #ifdef SQLITE_DEBUG if( p->db->flags & SQLITE_VdbeAddopTrace ){ printf("RESOLVE LABEL %d to %d\n", x, v->nOp); @@ -83309,24 +80388,18 @@ /* ** Mark the VDBE as one that can only be run one time. */ SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe *p){ - sqlite3VdbeAddOp2(p, OP_Expire, 1, 1); + p->runOnlyOnce = 1; } /* -** Mark the VDBE as one that can be run multiple times. +** Mark the VDBE as one that can only be run multiple times. */ SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe *p){ - int i; - for(i=1; ALWAYS(inOp); i++){ - if( ALWAYS(p->aOp[i].opcode==OP_Expire) ){ - p->aOp[1].opcode = OP_Noop; - break; - } - } + p->runOnlyOnce = 0; } #ifdef SQLITE_DEBUG /* sqlite3AssertMayAbort() logic */ /* @@ -83426,22 +80499,19 @@ int hasCreateTable = 0; int hasCreateIndex = 0; int hasInitCoroutine = 0; Op *pOp; VdbeOpIter sIter; - - if( v==0 ) return 0; memset(&sIter, 0, sizeof(sIter)); sIter.v = v; while( (pOp = opIterNext(&sIter))!=0 ){ int opcode = pOp->opcode; if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename || opcode==OP_VDestroy || opcode==OP_VCreate || opcode==OP_ParseSchema - || opcode==OP_Function || opcode==OP_PureFunc || ((opcode==OP_Halt || opcode==OP_HaltIfNull) && ((pOp->p1)!=SQLITE_OK && pOp->p2==OE_Abort)) ){ hasAbort = 1; break; @@ -83512,11 +80582,11 @@ ** and store that value in *pMaxFuncArgs. ** ** (3) Update the Vdbe.readOnly and Vdbe.bIsReader flags to accurately ** indicate what the prepared statement actually does. ** -** (4) (discontinued) +** (4) Initialize the p4.xAdvance pointer on opcodes that use it. ** ** (5) Reclaim the memory allocated for storing labels. ** ** This routine will only function correctly if the mkopcodeh.tcl generator ** script numbers the opcodes correctly. Changes to this routine must be @@ -83528,12 +80598,12 @@ Parse *pParse = p->pParse; int *aLabel = pParse->aLabel; p->readOnly = 1; p->bIsReader = 0; pOp = &p->aOp[p->nOp-1]; - assert( p->aOp[0].opcode==OP_Init ); - while( 1 /* Loop termates when it reaches the OP_Init opcode */ ){ + while(1){ + /* Only JUMP opcodes and the short list of special opcodes in the switch ** below need to be considered. The mkopcodeh.tcl generator script groups ** all these opcodes together near the front of the opcode list. Skip ** any opcode that does not need processing by virtual of the fact that ** it is larger than SQLITE_MX_JUMP_OPCODE, as a performance optimization. @@ -83558,13 +80628,28 @@ case OP_JournalMode: { p->readOnly = 0; p->bIsReader = 1; break; } - case OP_Init: { + case OP_Next: + case OP_SorterNext: { + pOp->p4.xAdvance = sqlite3BtreeNext; + pOp->p4type = P4_ADVANCE; + /* The code generator never codes any of these opcodes as a jump + ** to a label. They are always coded as a jump backwards to a + ** known address */ + assert( pOp->p2>=0 ); + break; + } + case OP_Prev: { + pOp->p4.xAdvance = sqlite3BtreePrevious; + pOp->p4type = P4_ADVANCE; + /* The code generator never codes any of these opcodes as a jump + ** to a label. They are always coded as a jump backwards to a + ** known address */ assert( pOp->p2>=0 ); - goto resolve_p2_values_loop_exit; + break; } #ifndef SQLITE_OMIT_VIRTUALTABLE case OP_VUpdate: { if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; break; @@ -83594,112 +80679,25 @@ /* The mkopcodeh.tcl script has so arranged things that the only ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to ** have non-negative values for P2. */ assert( (sqlite3OpcodeProperty[pOp->opcode]&OPFLG_JUMP)==0 || pOp->p2>=0); } - assert( pOp>p->aOp ); + if( pOp==p->aOp ) break; pOp--; } -resolve_p2_values_loop_exit: - if( aLabel ){ - sqlite3DbNNFreeNN(p->db, pParse->aLabel); - pParse->aLabel = 0; - } + sqlite3DbFree(p->db, pParse->aLabel); + pParse->aLabel = 0; pParse->nLabel = 0; *pMaxFuncArgs = nMaxArgs; assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) ); } -#ifdef SQLITE_DEBUG -/* -** Check to see if a subroutine contains a jump to a location outside of -** the subroutine. If a jump outside the subroutine is detected, add code -** that will cause the program to halt with an error message. -** -** The subroutine consists of opcodes between iFirst and iLast. Jumps to -** locations within the subroutine are acceptable. iRetReg is a register -** that contains the return address. Jumps to outside the range of iFirst -** through iLast are also acceptable as long as the jump destination is -** an OP_Return to iReturnAddr. -** -** A jump to an unresolved label means that the jump destination will be -** beyond the current address. That is normally a jump to an early -** termination and is consider acceptable. -** -** This routine only runs during debug builds. The purpose is (of course) -** to detect invalid escapes out of a subroutine. The OP_Halt opcode -** is generated rather than an assert() or other error, so that ".eqp full" -** will still work to show the original bytecode, to aid in debugging. -*/ -SQLITE_PRIVATE void sqlite3VdbeNoJumpsOutsideSubrtn( - Vdbe *v, /* The byte-code program under construction */ - int iFirst, /* First opcode of the subroutine */ - int iLast, /* Last opcode of the subroutine */ - int iRetReg /* Subroutine return address register */ -){ - VdbeOp *pOp; - Parse *pParse; - int i; - sqlite3_str *pErr = 0; - assert( v!=0 ); - pParse = v->pParse; - assert( pParse!=0 ); - if( pParse->nErr ) return; - assert( iLast>=iFirst ); - assert( iLastnOp ); - pOp = &v->aOp[iFirst]; - for(i=iFirst; i<=iLast; i++, pOp++){ - if( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 ){ - int iDest = pOp->p2; /* Jump destination */ - if( iDest==0 ) continue; - if( pOp->opcode==OP_Gosub ) continue; - if( iDest<0 ){ - int j = ADDR(iDest); - assert( j>=0 ); - if( j>=-pParse->nLabel || pParse->aLabel[j]<0 ){ - continue; - } - iDest = pParse->aLabel[j]; - } - if( iDestiLast ){ - int j = iDest; - for(; jnOp; j++){ - VdbeOp *pX = &v->aOp[j]; - if( pX->opcode==OP_Return ){ - if( pX->p1==iRetReg ) break; - continue; - } - if( pX->opcode==OP_Noop ) continue; - if( pX->opcode==OP_Explain ) continue; - if( pErr==0 ){ - pErr = sqlite3_str_new(0); - }else{ - sqlite3_str_appendchar(pErr, 1, '\n'); - } - sqlite3_str_appendf(pErr, - "Opcode at %d jumps to %d which is outside the " - "subroutine at %d..%d", - i, iDest, iFirst, iLast); - break; - } - } - } - } - if( pErr ){ - char *zErr = sqlite3_str_finish(pErr); - sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_INTERNAL, OE_Abort, 0, zErr, 0); - sqlite3_free(zErr); - sqlite3MayAbort(pParse); - } -} -#endif /* SQLITE_DEBUG */ - /* ** Return the address of the next instruction to be inserted. */ SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe *p){ - assert( p->eVdbeState==VDBE_INIT_STATE ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); return p->nOp; } /* ** Verify that at least N opcode slots are available in p without @@ -83780,11 +80778,11 @@ int iLineno /* Source-file line number of first opcode */ ){ int i; VdbeOp *pOut, *pFirst; assert( nOp>0 ); - assert( p->eVdbeState==VDBE_INIT_STATE ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); if( p->nOp + nOp > p->nOpAlloc && growOpArray(p, nOp) ){ return 0; } pFirst = pOut = &p->aOp[p->nOp]; for(i=0; idb) ){ - sqlite3_int64 nByte = (p->nScan+1) * sizeof(ScanStatus); - ScanStatus *aNew; - aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte); - if( aNew ){ - ScanStatus *pNew = &aNew[p->nScan++]; - memset(pNew, 0, sizeof(ScanStatus)); - pNew->addrExplain = addrExplain; - pNew->addrLoop = addrLoop; - pNew->addrVisit = addrVisit; - pNew->nEst = nEst; - pNew->zName = sqlite3DbStrDup(p->db, zName); - p->aScan = aNew; - } - } -} - -/* -** Add the range of instructions from addrStart to addrEnd (inclusive) to -** the set of those corresponding to the sqlite3_stmt_scanstatus() counters -** associated with the OP_Explain instruction at addrExplain. The -** sum of the sqlite3Hwtime() values for each of these instructions -** will be returned for SQLITE_SCANSTAT_NCYCLE requests. -*/ -SQLITE_PRIVATE void sqlite3VdbeScanStatusRange( - Vdbe *p, - int addrExplain, - int addrStart, - int addrEnd -){ - if( IS_STMT_SCANSTATUS(p->db) ){ - ScanStatus *pScan = 0; - int ii; - for(ii=p->nScan-1; ii>=0; ii--){ - pScan = &p->aScan[ii]; - if( pScan->addrExplain==addrExplain ) break; - pScan = 0; - } - if( pScan ){ - if( addrEnd<0 ) addrEnd = sqlite3VdbeCurrentAddr(p)-1; - for(ii=0; iiaAddrRange); ii+=2){ - if( pScan->aAddrRange[ii]==0 ){ - pScan->aAddrRange[ii] = addrStart; - pScan->aAddrRange[ii+1] = addrEnd; - break; - } - } - } - } -} - -/* -** Set the addresses for the SQLITE_SCANSTAT_NLOOP and SQLITE_SCANSTAT_NROW -** counters for the query element associated with the OP_Explain at -** addrExplain. -*/ -SQLITE_PRIVATE void sqlite3VdbeScanStatusCounters( - Vdbe *p, - int addrExplain, - int addrLoop, - int addrVisit -){ - if( IS_STMT_SCANSTATUS(p->db) ){ - ScanStatus *pScan = 0; - int ii; - for(ii=p->nScan-1; ii>=0; ii--){ - pScan = &p->aScan[ii]; - if( pScan->addrExplain==addrExplain ) break; - pScan = 0; - } - if( pScan ){ - pScan->addrLoop = addrLoop; - pScan->addrVisit = addrVisit; - } - } -} -#endif /* defined(SQLITE_ENABLE_STMT_SCANSTATUS) */ + sqlite3_int64 nByte = (p->nScan+1) * sizeof(ScanStatus); + ScanStatus *aNew; + aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte); + if( aNew ){ + ScanStatus *pNew = &aNew[p->nScan++]; + pNew->addrExplain = addrExplain; + pNew->addrLoop = addrLoop; + pNew->addrVisit = addrVisit; + pNew->nEst = nEst; + pNew->zName = sqlite3DbStrDup(p->db, zName); + p->aScan = aNew; + } +} +#endif /* ** Change the value of the opcode, or P1, P2, P3, or P5 operands ** for a specific instruction. */ SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe *p, int addr, u8 iNewOpcode){ - assert( addr>=0 ); sqlite3VdbeGetOp(p,addr)->opcode = iNewOpcode; } SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe *p, int addr, int val){ - assert( addr>=0 ); sqlite3VdbeGetOp(p,addr)->p1 = val; } SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){ - assert( addr>=0 || p->db->mallocFailed ); sqlite3VdbeGetOp(p,addr)->p2 = val; } SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe *p, int addr, int val){ - assert( addr>=0 ); sqlite3VdbeGetOp(p,addr)->p3 = val; } SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u16 p5){ assert( p->nOp>0 || p->db->mallocFailed ); if( p->nOp>0 ) p->aOp[p->nOp-1].p5 = p5; } -/* -** If the previous opcode is an OP_Column that delivers results -** into register iDest, then add the OPFLAG_TYPEOFARG flag to that -** opcode. -*/ -SQLITE_PRIVATE void sqlite3VdbeTypeofColumn(Vdbe *p, int iDest){ - VdbeOp *pOp = sqlite3VdbeGetLastOp(p); - if( pOp->p3==iDest && pOp->opcode==OP_Column ){ - pOp->p5 |= OPFLAG_TYPEOFARG; - } -} - /* ** Change the P2 operand of instruction addr so that it points to ** the address of the next instruction to be coded. */ SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){ @@ -83971,11 +80890,11 @@ assert( p->aOp[addr].opcode==OP_Once || p->aOp[addr].opcode==OP_If || p->aOp[addr].opcode==OP_FkIfZero ); assert( p->aOp[addr].p4type==0 ); #ifdef SQLITE_VDBE_COVERAGE - sqlite3VdbeGetLastOp(p)->iSrcLine = 0; /* Erase VdbeCoverage() macros */ + sqlite3VdbeGetOp(p,-1)->iSrcLine = 0; /* Erase VdbeCoverage() macros */ #endif p->nOp--; }else{ sqlite3VdbeChangeP2(p, addr, p->nOp); } @@ -83985,27 +80904,25 @@ /* ** If the input FuncDef structure is ephemeral, then free it. If ** the FuncDef is not ephermal, then do nothing. */ static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){ - assert( db!=0 ); if( (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){ - sqlite3DbNNFreeNN(db, pDef); + sqlite3DbFreeNN(db, pDef); } } /* ** Delete a P4 value if necessary. */ static SQLITE_NOINLINE void freeP4Mem(sqlite3 *db, Mem *p){ if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); - sqlite3DbNNFreeNN(db, p); + sqlite3DbFreeNN(db, p); } static SQLITE_NOINLINE void freeP4FuncCtx(sqlite3 *db, sqlite3_context *p){ - assert( db!=0 ); freeEphemeralFunction(db, p->pFunc); - sqlite3DbNNFreeNN(db, p); + sqlite3DbFreeNN(db, p); } static void freeP4(sqlite3 *db, int p4type, void *p4){ assert( db ); switch( p4type ){ case P4_FUNCCTX: { @@ -84013,12 +80930,13 @@ break; } case P4_REAL: case P4_INT64: case P4_DYNAMIC: + case P4_DYNBLOB: case P4_INTARRAY: { - if( p4 ) sqlite3DbNNFreeNN(db, p4); + sqlite3DbFree(db, p4); break; } case P4_KEYINFO: { if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4); break; @@ -84052,23 +80970,19 @@ ** 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(sqlite3 *db, Op *aOp, int nOp){ - assert( nOp>=0 ); - assert( db!=0 ); if( aOp ){ - Op *pOp = &aOp[nOp-1]; - while(1){ /* Exit via break */ + Op *pOp; + for(pOp=&aOp[nOp-1]; pOp>=aOp; pOp--){ if( pOp->p4type <= P4_FREE_IF_LE ) freeP4(db, pOp->p4type, pOp->p4.p); #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS sqlite3DbFree(db, pOp->zComment); #endif - if( pOp==aOp ) break; - pOp--; } - sqlite3DbNNFreeNN(db, aOp); + sqlite3DbFreeNN(db, aOp); } } /* ** Link the SubProgram object passed as the second argument into the linked @@ -84124,11 +81038,11 @@ int iFirst, /* Index of first register to be released */ int N, /* Number of registers to release */ u32 mask, /* Mask of registers to NOT release */ int bUndefine /* If true, mark registers as undefined */ ){ - if( N==0 || OptimizationDisabled(pParse->db, SQLITE_ReleaseReg) ) return; + if( N==0 ) return; assert( pParse->pVdbe ); assert( iFirst>=1 ); assert( iFirst+N-1<=pParse->nMem ); if( N<=31 && mask!=0 ){ while( N>0 && (mask&1)!=0 ){ @@ -84188,11 +81102,11 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){ Op *pOp; sqlite3 *db; assert( p!=0 ); db = p->db; - assert( p->eVdbeState==VDBE_INIT_STATE ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); assert( p->aOp!=0 || db->mallocFailed ); if( db->mallocFailed ){ if( n!=P4_VTAB ) freeP4(db, n, (void*)*(char**)&zP4); return; } @@ -84233,11 +81147,11 @@ assert( n!=P4_INT32 && n!=P4_VTAB ); assert( n<=0 ); if( p->db->mallocFailed ){ freeP4(p->db, n, pP4); }else{ - assert( pP4!=0 || n==P4_DYNAMIC ); + assert( pP4!=0 ); assert( p->nOp>0 ); pOp = &p->aOp[p->nOp-1]; assert( pOp->p4type==P4_NOTUSED ); pOp->p4type = n; pOp->p4.p = pP4; @@ -84295,17 +81209,17 @@ #ifdef SQLITE_VDBE_COVERAGE /* ** Set the value if the iSrcLine field for the previously coded instruction. */ SQLITE_PRIVATE void sqlite3VdbeSetLineNumber(Vdbe *v, int iLine){ - sqlite3VdbeGetLastOp(v)->iSrcLine = iLine; + sqlite3VdbeGetOp(v,-1)->iSrcLine = iLine; } #endif /* SQLITE_VDBE_COVERAGE */ /* -** Return the opcode for a given address. The address must be non-negative. -** See sqlite3VdbeGetLastOp() to get the most recently added opcode. +** 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 @@ -84316,25 +81230,22 @@ */ SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(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->eVdbeState==VDBE_INIT_STATE ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); + if( addr<0 ){ + addr = p->nOp - 1; + } assert( (addr>=0 && addrnOp) || p->db->mallocFailed ); if( p->db->mallocFailed ){ return (VdbeOp*)&dummy; }else{ return &p->aOp[addr]; } } -/* Return the most recently added opcode -*/ -VdbeOp * sqlite3VdbeGetLastOp(Vdbe *p){ - return sqlite3VdbeGetOp(p, p->nOp - 1); -} - #if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) /* ** Return an integer value for one of the parameters to the opcode pOp ** determined by character c. */ @@ -84386,15 +81297,12 @@ if( c=='P' ){ c = zSynopsis[++ii]; if( c=='4' ){ sqlite3_str_appendall(&x, zP4); }else if( c=='X' ){ - if( pOp->zComment && pOp->zComment[0] ){ - sqlite3_str_appendall(&x, pOp->zComment); - seenCom = 1; - break; - } + sqlite3_str_appendall(&x, pOp->zComment); + seenCom = 1; }else{ int v1 = translateP(c, pOp); int v2; if( strncmp(zSynopsis+ii+1, "@P", 2)==0 ){ ii += 3; @@ -84618,10 +81526,14 @@ break; } case P4_SUBPROGRAM: { zP4 = "program"; break; + } + case P4_DYNBLOB: + case P4_ADVANCE: { + break; } case P4_TABLE: { zP4 = pOp->p4.pTab->zName; break; } @@ -84750,44 +81662,25 @@ } #endif /* ** Initialize an array of N Mem element. -** -** This is a high-runner, so only those fields that really do need to -** be initialized are set. The Mem structure is organized so that -** the fields that get initialized are nearby and hopefully on the same -** cache line. -** -** Mem.flags = flags -** Mem.db = db -** Mem.szMalloc = 0 -** -** All other fields of Mem can safely remain uninitialized for now. They -** will be initialized before use. */ static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){ - if( N>0 ){ - do{ - p->flags = flags; - p->db = db; - p->szMalloc = 0; + while( (N--)>0 ){ + p->db = db; + p->flags = flags; + p->szMalloc = 0; #ifdef SQLITE_DEBUG - p->pScopyFrom = 0; + p->pScopyFrom = 0; #endif - p++; - }while( (--N)>0 ); + p++; } } /* -** Release auxiliary memory held in an array of N Mem elements. -** -** After this routine returns, all Mem elements in the array will still -** be valid. Those Mem elements that were not holding auxiliary resources -** will be unchanged. Mem elements which had something freed will be -** set to MEM_Undefined. +** Release an array of N Mem elements */ static void releaseMemArray(Mem *p, int N){ if( p && N ){ Mem *pEnd = &p[N]; sqlite3 *db = p->db; @@ -84816,21 +81709,16 @@ testcase( p->flags & MEM_Agg ); testcase( p->flags & MEM_Dyn ); if( p->flags&(MEM_Agg|MEM_Dyn) ){ testcase( (p->flags & MEM_Dyn)!=0 && p->xDel==sqlite3VdbeFrameMemDel ); sqlite3VdbeMemRelease(p); - p->flags = MEM_Undefined; }else if( p->szMalloc ){ - sqlite3DbNNFreeNN(db, p->zMalloc); + sqlite3DbFreeNN(db, p->zMalloc); p->szMalloc = 0; - p->flags = MEM_Undefined; } -#ifdef SQLITE_DEBUG - else{ - p->flags = MEM_Undefined; - } -#endif + + p->flags = MEM_Undefined; }while( (++p)nChildMem]; assert( sqlite3VdbeFrameIsValid(p) ); for(i=0; inChildCsr; i++){ - if( apCsr[i] ) sqlite3VdbeFreeCursorNN(p->v, apCsr[i]); + sqlite3VdbeFreeCursor(p->v, apCsr[i]); } releaseMemArray(aMem, p->nChildMem); sqlite3VdbeDeleteAuxData(p->v->db, &p->pAuxData, -1, 0); sqlite3DbFree(p->v->db, p); } @@ -85024,18 +81912,19 @@ int bListSubprogs = (p->explain==1 || (db->flags & SQLITE_TriggerEQP)!=0); Op *aOp; /* Array of opcodes */ Op *pOp; /* Current opcode */ assert( p->explain ); - assert( p->eVdbeState==VDBE_RUN_STATE ); + assert( p->iVdbeMagic==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 ** sqlite3_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 sqlite3_column_text() or ** sqlite3_column_text16() failed. */ sqlite3OomFault(db); @@ -85088,11 +81977,11 @@ sqlite3VdbeMemSetNull(pMem+7); #endif sqlite3VdbeMemSetStr(pMem+5, zP4, -1, SQLITE_UTF8, sqlite3_free); p->nResColumn = 8; } - p->pResultRow = pMem; + p->pResultSet = pMem; if( db->mallocFailed ){ p->rc = SQLITE_NOMEM; rc = SQLITE_ERROR; }else{ p->rc = SQLITE_OK; @@ -85178,15 +82067,15 @@ ** statement. */ static void *allocSpace( struct ReusableSpace *p, /* Bulk memory available for allocation */ void *pBuf, /* Pointer to a prior allocation */ - sqlite3_int64 nByte /* Bytes of memory needed. */ + sqlite3_int64 nByte /* Bytes of memory needed */ ){ assert( EIGHT_BYTE_ALIGNMENT(p->pSpace) ); if( pBuf==0 ){ - nByte = ROUND8P(nByte); + nByte = ROUND8(nByte); if( nByte <= p->nFree ){ p->nFree -= nByte; pBuf = &p->pSpace[p->nFree]; }else{ p->nNeeded += nByte; @@ -85199,23 +82088,22 @@ /* ** Rewind the VDBE back to the beginning in preparation for ** running it. */ SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){ -#if defined(SQLITE_DEBUG) +#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) int i; #endif assert( p!=0 ); - assert( p->eVdbeState==VDBE_INIT_STATE - || p->eVdbeState==VDBE_READY_STATE - || p->eVdbeState==VDBE_HALT_STATE ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT || p->iVdbeMagic==VDBE_MAGIC_RESET ); /* There should be at least one opcode. */ assert( p->nOp>0 ); - p->eVdbeState = VDBE_READY_STATE; + /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */ + p->iVdbeMagic = VDBE_MAGIC_RUN; #ifdef SQLITE_DEBUG for(i=0; inMem; i++){ assert( p->aMem[i].db==p->db ); } @@ -85228,12 +82116,12 @@ p->minWriteFileFormat = 255; p->iStatement = 0; p->nFkConstraint = 0; #ifdef VDBE_PROFILE for(i=0; inOp; i++){ - p->aOp[i].nExec = 0; - p->aOp[i].nCycle = 0; + p->aOp[i].cnt = 0; + p->aOp[i].cycles = 0; } #endif } /* @@ -85267,11 +82155,11 @@ struct ReusableSpace x; /* Reusable bulk memory */ assert( p!=0 ); assert( p->nOp>0 ); assert( pParse!=0 ); - assert( p->eVdbeState==VDBE_INIT_STATE ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); assert( pParse==p->pParse ); p->pVList = pParse->pVList; pParse->pVList = 0; db = p->db; assert( db->mallocFailed==0 ); @@ -85290,11 +82178,11 @@ /* Figure out how much reusable memory is available at the end of the ** opcode array. This extra memory will be reallocated for other elements ** of the prepared statement. */ - n = ROUND8P(sizeof(Op)*p->nOp); /* Bytes of opcode memory used */ + n = ROUND8(sizeof(Op)*p->nOp); /* Bytes of opcode memory used */ x.pSpace = &((u8*)p->aOp)[n]; /* Unused opcode memory */ assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) ); x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused memory */ assert( x.nFree>=0 ); assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) ); @@ -85338,18 +82226,24 @@ x.nNeeded = 0; p->aMem = allocSpace(&x, 0, nMem*sizeof(Mem)); p->aVar = allocSpace(&x, 0, nVar*sizeof(Mem)); p->apArg = allocSpace(&x, 0, nArg*sizeof(Mem*)); p->apCsr = allocSpace(&x, 0, nCursor*sizeof(VdbeCursor*)); +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + p->anExec = allocSpace(&x, 0, p->nOp*sizeof(i64)); +#endif if( x.nNeeded ){ x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded); x.nFree = x.nNeeded; if( !db->mallocFailed ){ p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem)); p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem)); p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*)); p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*)); +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64)); +#endif } } if( db->mallocFailed ){ p->nVar = 0; @@ -85360,22 +82254,25 @@ p->nVar = (ynVar)nVar; initMemArray(p->aVar, nVar, db, MEM_Null); p->nMem = nMem; initMemArray(p->aMem, nMem, db, MEM_Undefined); memset(p->apCsr, 0, nCursor*sizeof(VdbeCursor*)); +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + memset(p->anExec, 0, p->nOp*sizeof(i64)); +#endif } sqlite3VdbeRewind(p); } /* ** Close a VDBE cursor and release all the resources that cursor ** happens to hold. */ SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ - if( pCx ) sqlite3VdbeFreeCursorNN(p,pCx); -} -SQLITE_PRIVATE void sqlite3VdbeFreeCursorNN(Vdbe *p, VdbeCursor *pCx){ + if( pCx==0 ){ + return; + } switch( pCx->eCurType ){ case CURTYPE_SORTER: { sqlite3VdbeSorterClose(p->db, pCx); break; } @@ -85399,16 +82296,18 @@ /* ** Close all cursors in the current frame. */ static void closeCursorsInFrame(Vdbe *p){ - int i; - for(i=0; inCursor; i++){ - VdbeCursor *pC = p->apCsr[i]; - if( pC ){ - sqlite3VdbeFreeCursorNN(p, pC); - p->apCsr[i] = 0; + if( p->apCsr ){ + int i; + for(i=0; inCursor; i++){ + VdbeCursor *pC = p->apCsr[i]; + if( pC ){ + sqlite3VdbeFreeCursor(p, pC); + p->apCsr[i] = 0; + } } } } /* @@ -85417,10 +82316,13 @@ ** control to the main program. */ SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){ Vdbe *v = pFrame->v; closeCursorsInFrame(v); +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + v->anExec = pFrame->anExec; +#endif v->aOp = pFrame->aOp; v->nOp = pFrame->nOp; v->aMem = pFrame->aMem; v->nMem = pFrame->nMem; v->apCsr = pFrame->apCsr; @@ -85450,11 +82352,13 @@ p->pFrame = 0; p->nFrame = 0; } assert( p->nFrame==0 ); closeCursorsInFrame(p); - releaseMemArray(p->aMem, p->nMem); + if( p->aMem ){ + releaseMemArray(p->aMem, p->nMem); + } while( p->pDelFrame ){ VdbeFrame *pDel = p->pDelFrame; p->pDelFrame = pDel->pParent; sqlite3VdbeFrameDelete(pDel); } @@ -85797,11 +82701,11 @@ if( sqlite3_stmt_busy((sqlite3_stmt*)p) ){ cnt++; if( p->readOnly==0 ) nWrite++; if( p->bIsReader ) nRead++; } - p = p->pVNext; + p = p->pNext; } assert( cnt==db->nVdbeActive ); assert( nWrite==db->nVdbeWrite ); assert( nRead==db->nVdbeRead ); } @@ -85890,12 +82794,11 @@ || (!deferred && p->nFkConstraint>0) ){ p->rc = SQLITE_CONSTRAINT_FOREIGNKEY; p->errorAction = OE_Abort; sqlite3VdbeError(p, "FOREIGN KEY constraint failed"); - if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)==0 ) return SQLITE_ERROR; - return SQLITE_CONSTRAINT_FOREIGNKEY; + return SQLITE_ERROR; } return SQLITE_OK; } #endif @@ -85930,20 +82833,22 @@ ** Then the internal cache might have been left in an inconsistent ** state. We need to rollback the statement transaction, if there is ** one, or the complete transaction if there is no statement transaction. */ - assert( p->eVdbeState==VDBE_RUN_STATE ); + if( p->iVdbeMagic!=VDBE_MAGIC_RUN ){ + return SQLITE_OK; + } if( db->mallocFailed ){ p->rc = SQLITE_NOMEM_BKPT; } closeAllCursors(p); checkActiveVdbeCnt(db); /* No commit or rollback needed if the program never started or if the ** SQL statement does not read or write a database file. */ - if( p->bIsReader ){ + if( p->pc>=0 && p->bIsReader ){ int mrc; /* Primary error code from p->rc */ int eStatementOp = 0; int isSpecialError; /* Set to true if a 'special' error */ /* Lock all btrees used by the statement */ @@ -86031,12 +82936,10 @@ db->nDeferredCons = 0; db->nDeferredImmCons = 0; db->flags &= ~(u64)SQLITE_DeferFKs; sqlite3CommitInternalChanges(db); } - }else if( p->rc==SQLITE_SCHEMA && db->nVdbeActive>1 ){ - p->nChange = 0; }else{ sqlite3RollbackAll(db, SQLITE_OK); p->nChange = 0; } db->nStatement = 0; @@ -86089,17 +82992,19 @@ /* Release the locks */ sqlite3VdbeLeave(p); } /* We have successfully halted and closed the VM. Record this fact. */ - db->nVdbeActive--; - if( !p->readOnly ) db->nVdbeWrite--; - if( p->bIsReader ) db->nVdbeRead--; - assert( db->nVdbeActive>=db->nVdbeRead ); - assert( db->nVdbeRead>=db->nVdbeWrite ); - assert( db->nVdbeWrite>=0 ); - p->eVdbeState = VDBE_HALT_STATE; + if( p->pc>=0 ){ + db->nVdbeActive--; + if( !p->readOnly ) db->nVdbeWrite--; + if( p->bIsReader ) db->nVdbeRead--; + assert( db->nVdbeActive>=db->nVdbeRead ); + assert( db->nVdbeRead>=db->nVdbeWrite ); + assert( db->nVdbeWrite>=0 ); + } + p->iVdbeMagic = VDBE_MAGIC_HALT; checkActiveVdbeCnt(db); if( db->mallocFailed ){ p->rc = SQLITE_NOMEM_BKPT; } @@ -86177,12 +83082,12 @@ ** ** 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_RUN_STATE or VDBE_HALT_STATE back to -** VDBE_READY_STATE. +** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to +** VDBE_MAGIC_INIT. */ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){ #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) int i; #endif @@ -86192,11 +83097,11 @@ /* 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. */ - if( p->eVdbeState==VDBE_RUN_STATE ) sqlite3VdbeHalt(p); + sqlite3VdbeHalt(p); /* If the VDBE has been 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. @@ -86206,10 +83111,17 @@ if( db->pErr || p->zErrMsg ){ sqlite3VdbeTransferError(p); }else{ db->errCode = p->rc; } + 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 sqlite3_step(). For consistency (since sqlite3_step() was + ** called), set the database error in this case as well. + */ + sqlite3ErrorWithMsg(db, p->rc, p->zErrMsg ? "%s" : 0, p->zErrMsg); } /* Reset register contents and reclaim error message memory. */ #ifdef SQLITE_DEBUG @@ -86222,11 +83134,11 @@ #endif if( p->zErrMsg ){ sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = 0; } - p->pResultRow = 0; + p->pResultSet = 0; #ifdef SQLITE_DEBUG p->nWrite = 0; #endif /* Save profiling information from this VDBE run. @@ -86250,37 +83162,33 @@ } if( pc!='\n' ) fprintf(out, "\n"); } for(i=0; inOp; i++){ char zHdr[100]; - i64 cnt = p->aOp[i].nExec; - i64 cycles = p->aOp[i].nCycle; sqlite3_snprintf(sizeof(zHdr), zHdr, "%6u %12llu %8llu ", - cnt, - cycles, - cnt>0 ? cycles/cnt : 0 + p->aOp[i].cnt, + p->aOp[i].cycles, + p->aOp[i].cnt>0 ? p->aOp[i].cycles/p->aOp[i].cnt : 0 ); fprintf(out, "%s", zHdr); sqlite3VdbePrintOp(out, i, &p->aOp[i]); } fclose(out); } } #endif + p->iVdbeMagic = VDBE_MAGIC_RESET; return p->rc & db->errMask; } /* ** 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 sqlite3VdbeFinalize(Vdbe *p){ int rc = SQLITE_OK; - assert( VDBE_RUN_STATE>VDBE_READY_STATE ); - assert( VDBE_HALT_STATE>VDBE_READY_STATE ); - assert( VDBE_INIT_STATEeVdbeState>=VDBE_READY_STATE ){ + if( p->iVdbeMagic==VDBE_MAGIC_RUN || p->iVdbeMagic==VDBE_MAGIC_HALT ){ rc = sqlite3VdbeReset(p); assert( (rc & p->db->errMask)==rc ); } sqlite3VdbeDelete(p); return rc; @@ -86328,36 +83236,33 @@ ** ** The difference between this function and sqlite3VdbeDelete() is that ** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with ** the database connection and frees the object itself. */ -static void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ +SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ SubProgram *pSub, *pNext; - assert( db!=0 ); assert( p->db==0 || p->db==db ); - if( p->aColName ){ - releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); - sqlite3DbNNFreeNN(db, p->aColName); - } + releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); for(pSub=p->pProgram; pSub; pSub=pNext){ pNext = pSub->pNext; vdbeFreeOpArray(db, pSub->aOp, pSub->nOp); sqlite3DbFree(db, pSub); } - if( p->eVdbeState!=VDBE_INIT_STATE ){ + if( p->iVdbeMagic!=VDBE_MAGIC_INIT ){ releaseMemArray(p->aVar, p->nVar); - if( p->pVList ) sqlite3DbNNFreeNN(db, p->pVList); - if( p->pFree ) sqlite3DbNNFreeNN(db, p->pFree); + sqlite3DbFree(db, p->pVList); + sqlite3DbFree(db, p->pFree); } vdbeFreeOpArray(db, p->aOp, p->nOp); - if( p->zSql ) sqlite3DbNNFreeNN(db, p->zSql); + sqlite3DbFree(db, p->aColName); + sqlite3DbFree(db, p->zSql); #ifdef SQLITE_ENABLE_NORMALIZE sqlite3DbFree(db, p->zNormSql); { - DblquoteStr *pThis, *pNxt; - for(pThis=p->pDblStr; pThis; pThis=pNxt){ - pNxt = pThis->pNextStr; + DblquoteStr *pThis, *pNext; + for(pThis=p->pDblStr; pThis; pThis=pNext){ + pNext = pThis->pNextStr; sqlite3DbFree(db, pThis); } } #endif #ifdef SQLITE_ENABLE_STMT_SCANSTATUS @@ -86377,21 +83282,24 @@ SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){ sqlite3 *db; assert( p!=0 ); db = p->db; - assert( db!=0 ); assert( sqlite3_mutex_held(db->mutex) ); sqlite3VdbeClearObject(db, p); - if( db->pnBytesFreed==0 ){ - assert( p->ppVPrev!=0 ); - *p->ppVPrev = p->pVNext; - if( p->pVNext ){ - p->pVNext->ppVPrev = p->ppVPrev; - } - } - sqlite3DbNNFreeNN(db, p); + 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->iVdbeMagic = VDBE_MAGIC_DEAD; + p->db = 0; + sqlite3DbFreeNN(db, p); } /* ** The cursor "p" has a pending seek operation that has not yet been ** carried out. Seek the cursor now. If an error occurs, return @@ -86421,11 +83329,11 @@ ** pointed to was deleted out from under it. Or maybe the btree was ** rebalanced. Whatever the cause, try to restore "p" to the place it ** is supposed to be pointing. If the row was deleted out from under the ** cursor, set the cursor to point to a NULL row. */ -SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeHandleMovedCursor(VdbeCursor *p){ +static int SQLITE_NOINLINE handleMovedCursor(VdbeCursor *p){ int isDifferentRow, rc; assert( p->eCurType==CURTYPE_BTREE ); assert( p->uc.pCursor!=0 ); assert( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ); rc = sqlite3BtreeCursorRestore(p->uc.pCursor, &isDifferentRow); @@ -86437,13 +83345,45 @@ /* ** Check to ensure that the cursor is valid. Restore the cursor ** if need be. Return any I/O error from the restore operation. */ SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){ - assert( p->eCurType==CURTYPE_BTREE || IsNullCursor(p) ); + assert( p->eCurType==CURTYPE_BTREE ); + if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ + return handleMovedCursor(p); + } + return SQLITE_OK; +} + +/* +** Make sure the cursor p is ready to read or write the row to which it +** was last positioned. Return an error code if an OOM fault or I/O error +** prevents us from positioning the cursor to its correct position. +** +** If a MoveTo operation is pending on the given cursor, then do that +** MoveTo now. If no move is pending, check to see if the row has been +** deleted out from under the cursor and if it has, mark the row as +** a NULL row. +** +** If the cursor is already pointing to the correct row and that row has +** not been deleted out from under the cursor, then this routine is a no-op. +*/ +SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, u32 *piCol){ + VdbeCursor *p = *pp; + assert( p->eCurType==CURTYPE_BTREE || p->eCurType==CURTYPE_PSEUDO ); + if( p->deferredMoveto ){ + u32 iMap; + assert( !p->isEphemeral ); + if( p->ub.aAltMap && (iMap = p->ub.aAltMap[1+*piCol])>0 && !p->nullRow ){ + *pp = p->pAltCursor; + *piCol = iMap - 1; + return SQLITE_OK; + } + return sqlite3VdbeFinishMoveto(p); + } if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ - return sqlite3VdbeHandleMovedCursor(p); + return handleMovedCursor(p); } return SQLITE_OK; } /* @@ -86450,11 +83390,11 @@ ** The following functions: ** ** sqlite3VdbeSerialType() ** sqlite3VdbeSerialTypeLen() ** sqlite3VdbeSerialLen() -** sqlite3VdbeSerialPut() <--- in-lined into OP_MakeRecord as of 2022-04-02 +** sqlite3VdbeSerialPut() ** sqlite3VdbeSerialGet() ** ** 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 @@ -86562,11 +83502,11 @@ #endif /* inlined into OP_MakeRecord */ /* ** The sizes for serial types less than 128 */ -SQLITE_PRIVATE const u8 sqlite3SmallTypeSizes[128] = { +static const u8 sqlite3SmallTypeSizes[] = { /* 0 1 2 3 4 5 6 7 8 9 */ /* 0 */ 0, 1, 2, 3, 4, 6, 8, 8, 0, 0, /* 10 */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, /* 20 */ 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, /* 30 */ 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, @@ -86631,11 +83571,11 @@ ** 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 -SQLITE_PRIVATE u64 sqlite3FloatSwap(u64 in){ +static u64 floatSwap(u64 in){ union { u64 r; u32 i[2]; } u; u32 t; @@ -86644,12 +83584,63 @@ t = u.i[0]; u.i[0] = u.i[1]; u.i[1] = t; return u.r; } -#endif /* SQLITE_MIXED_ENDIAN_64BIT_FLOAT */ +# 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[]. The caller is responsible +** for allocating enough space to buf[] to hold the entire field, exclusive +** of the pMem->u.nZero bytes for a MEM_Zero value. +** +** 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 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){ + 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->u.r) ); + memcpy(&v, &pMem->u.r, sizeof(v)); + swapMixedEndianFloat(v); + }else{ + v = pMem->u.i; + } + len = i = sqlite3SmallTypeSizes[serial_type]; + assert( i>0 ); + do{ + buf[--i] = (u8)(v&0xFF); + v >>= 8; + }while( i ); + return len; + } + + /* String or blob */ + if( serial_type>=12 ){ + assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.nZero:0) + == (int)sqlite3VdbeSerialTypeLen(serial_type) ); + len = pMem->n; + if( len>0 ) memcpy(buf, pMem->z, len); + return len; + } + + /* NULL or constants 0 or 1 */ + return 0; +} /* Input "x" is a sequence of unsigned characters that represent a ** big-endian integer. Return the equivalent native integer */ #define ONE_BYTE_INT(x) ((i8)(x)[0]) @@ -86811,14 +83802,14 @@ SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord( KeyInfo *pKeyInfo /* Description of the record */ ){ UnpackedRecord *p; /* Unpacked record to return */ int nByte; /* Number of bytes required for *p */ - nByte = ROUND8P(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1); + nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1); p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); if( !p ) return 0; - p->aMem = (Mem*)&((char*)p)[ROUND8P(sizeof(UnpackedRecord))]; + p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))]; assert( pKeyInfo->aSortFlags!=0 ); p->pKeyInfo = pKeyInfo; p->nField = pKeyInfo->nKeyField + 1; return p; } @@ -87050,12 +84041,12 @@ if( prcErr ) *prcErr = SQLITE_NOMEM_BKPT; rc = 0; }else{ rc = pColl->xCmp(pColl->pUser, c1.n, v1, c2.n, v2); } - sqlite3VdbeMemReleaseMalloc(&c1); - sqlite3VdbeMemReleaseMalloc(&c2); + sqlite3VdbeMemRelease(&c1); + sqlite3VdbeMemRelease(&c2); return rc; } } /* @@ -87312,26 +84303,18 @@ /* If bSkip is true, then the caller has already determined that the first ** two elements in the keys are equal. Fix the various stack variables so ** that this routine begins comparing at the second field. */ if( bSkip ){ - u32 s1 = aKey1[1]; - if( s1<0x80 ){ - idx1 = 2; - }else{ - idx1 = 1 + sqlite3GetVarint32(&aKey1[1], &s1); - } + u32 s1; + idx1 = 1 + getVarint32(&aKey1[1], s1); szHdr1 = aKey1[0]; d1 = szHdr1 + sqlite3VdbeSerialTypeLen(s1); i = 1; pRhs++; }else{ - if( (szHdr1 = aKey1[0])<0x80 ){ - idx1 = 1; - }else{ - idx1 = sqlite3GetVarint32(aKey1, &szHdr1); - } + idx1 = getVarint32(aKey1, szHdr1); d1 = szHdr1; i = 0; } if( d1>(unsigned)nKey1 ){ pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; @@ -87342,21 +84325,21 @@ assert( pPKey2->pKeyInfo->nAllField>=pPKey2->nField || CORRUPT_DB ); assert( pPKey2->pKeyInfo->aSortFlags!=0 ); assert( pPKey2->pKeyInfo->nKeyField>0 ); assert( idx1<=szHdr1 || CORRUPT_DB ); - while( 1 /*exit-by-break*/ ){ + do{ u32 serial_type; /* RHS is an integer */ if( pRhs->flags & (MEM_Int|MEM_IntReal) ){ testcase( pRhs->flags & MEM_Int ); testcase( pRhs->flags & MEM_IntReal ); serial_type = aKey1[idx1]; testcase( serial_type==12 ); if( serial_type>=10 ){ - rc = serial_type==10 ? -1 : +1; + rc = +1; }else if( serial_type==0 ){ rc = -1; }else if( serial_type==7 ){ sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); rc = -sqlite3IntFloatCompare(pRhs->u.i, mem1.u.r); @@ -87377,11 +84360,11 @@ if( serial_type>=10 ){ /* Serial types 12 or greater are strings and blobs (greater than ** numbers). Types 10 and 11 are currently "reserved for future ** use", so it doesn't really matter what the results of comparing ** them to numberic values are. */ - rc = serial_type==10 ? -1 : +1; + rc = +1; }else if( serial_type==0 ){ rc = -1; }else{ sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); if( serial_type==7 ){ @@ -87458,11 +84441,11 @@ } /* RHS is null */ else{ serial_type = aKey1[idx1]; - rc = (serial_type!=0 && serial_type!=10); + rc = (serial_type!=0); } if( rc!=0 ){ int sortFlags = pPKey2->pKeyInfo->aSortFlags[i]; if( sortFlags ){ @@ -87480,17 +84463,12 @@ i++; if( i==pPKey2->nField ) break; pRhs++; d1 += sqlite3VdbeSerialTypeLen(serial_type); - if( d1>(unsigned)nKey1 ) break; idx1 += sqlite3VarintLen(serial_type); - if( idx1>=(unsigned)szHdr1 ){ - pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; - return 0; /* Corrupt index */ - } - } + }while( idx1<(unsigned)szHdr1 && d1<=(unsigned)nKey1 ); /* 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 sqlite3VdbeMemRelease(&mem1). */ assert( mem1.szMalloc==0 ); @@ -87588,12 +84566,11 @@ default: return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2); } - assert( pPKey2->u.i == pPKey2->aMem[0].u.i ); - v = pPKey2->u.i; + v = pPKey2->aMem[0].u.i; if( v>lhs ){ res = pPKey2->r1; }else if( vr2; }else if( pPKey2->nField>1 ){ @@ -87624,22 +84601,16 @@ const u8 *aKey1 = (const u8*)pKey1; int serial_type; int res; assert( pPKey2->aMem[0].flags & MEM_Str ); - assert( pPKey2->aMem[0].n == pPKey2->n ); - assert( pPKey2->aMem[0].z == pPKey2->u.z ); vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo); - serial_type = (signed char)(aKey1[1]); - -vrcs_restart: + serial_type = (u8)(aKey1[1]); + if( serial_type >= 0x80 ){ + sqlite3GetVarint32(&aKey1[1], (u32*)&serial_type); + } if( serial_type<12 ){ - if( serial_type<0 ){ - sqlite3GetVarint32(&aKey1[1], (u32*)&serial_type); - if( serial_type>=12 ) goto vrcs_restart; - assert( CORRUPT_DB ); - } res = pPKey2->r1; /* (pKey1/nKey1) is a number or a null */ }else if( !(serial_type & 0x01) ){ res = pPKey2->r2; /* (pKey1/nKey1) is a blob */ }else{ int nCmp; @@ -87649,19 +84620,19 @@ nStr = (serial_type-12) / 2; if( (szHdr + nStr) > nKey1 ){ pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; return 0; /* Corruption */ } - nCmp = MIN( pPKey2->n, nStr ); - res = memcmp(&aKey1[szHdr], pPKey2->u.z, nCmp); + nCmp = MIN( pPKey2->aMem[0].n, nStr ); + res = memcmp(&aKey1[szHdr], pPKey2->aMem[0].z, nCmp); if( res>0 ){ res = pPKey2->r2; }else if( res<0 ){ res = pPKey2->r1; }else{ - res = nStr - pPKey2->n; + res = nStr - pPKey2->aMem[0].n; if( res==0 ){ if( pPKey2->nField>1 ){ res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1); }else{ res = pPKey2->default_rc; @@ -87712,22 +84683,19 @@ }else{ p->r1 = -1; p->r2 = 1; } if( (flags & MEM_Int) ){ - p->u.i = p->aMem[0].u.i; return vdbeRecordCompareInt; } testcase( flags & MEM_Real ); testcase( flags & MEM_Null ); testcase( flags & MEM_Blob ); if( (flags & (MEM_Real|MEM_IntReal|MEM_Null|MEM_Blob))==0 && p->pKeyInfo->aColl[0]==0 ){ assert( flags & MEM_Str ); - p->u.z = p->aMem[0].z; - p->n = p->aMem[0].n; return vdbeRecordCompareString; } } return sqlite3VdbeRecordCompare; @@ -87796,18 +84764,18 @@ } /* Fetch the integer off the end of the index record */ sqlite3VdbeSerialGet((u8*)&m.z[m.n-lenRowid], typeRowid, &v); *rowid = v.u.i; - sqlite3VdbeMemReleaseMalloc(&m); + sqlite3VdbeMemRelease(&m); return SQLITE_OK; /* Jump here if database corruption is detected after m has been ** allocated. Free the m object and return SQLITE_CORRUPT. */ idx_rowid_corruption: testcase( m.szMalloc!=0 ); - sqlite3VdbeMemReleaseMalloc(&m); + sqlite3VdbeMemRelease(&m); return SQLITE_CORRUPT_BKPT; } /* ** Compare the key of the index entry that cursor pC is pointing to against @@ -87845,11 +84813,11 @@ rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m); if( rc ){ return rc; } *res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, pUnpacked, 0); - sqlite3VdbeMemReleaseMalloc(&m); + sqlite3VdbeMemRelease(&m); return SQLITE_OK; } /* ** This routine sets the value to be returned by subsequent calls to @@ -87887,11 +84855,11 @@ ** prepared statements. The flag is set to 1 for an immediate expiration ** and set to 2 for an advisory expiration. */ SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3 *db, int iCode){ Vdbe *p; - for(p = db->pVdbe; p; p=p->pVNext){ + for(p = db->pVdbe; p; p=p->pNext){ p->expired = iCode+1; } } /* @@ -87980,24 +84948,10 @@ return 0; } return 1; } -#if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG) -/* -** This Walker callback is used to help verify that calls to -** sqlite3BtreeCursorHint() with opcode BTREE_HINT_RANGE have -** byte-code register values correctly initialized. -*/ -SQLITE_PRIVATE int sqlite3CursorRangeHintExprCheck(Walker *pWalker, Expr *pExpr){ - if( pExpr->op==TK_REGISTER ){ - assert( (pWalker->u.aMem[pExpr->iTable].flags & MEM_Undefined)==0 ); - } - return WRC_Continue; -} -#endif /* SQLITE_ENABLE_CURSOR_HINTS && SQLITE_DEBUG */ - #ifndef SQLITE_OMIT_VIRTUALTABLE /* ** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored ** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored ** in memory obtained from sqlite3DbMalloc). @@ -88022,18 +84976,17 @@ ** ** This function is used to free UnpackedRecord structures allocated by ** the vdbeUnpackRecord() function found in vdbeapi.c. */ static void vdbeFreeUnpacked(sqlite3 *db, int nField, UnpackedRecord *p){ - assert( db!=0 ); if( p ){ int i; for(i=0; iaMem[i]; - if( pMem->zMalloc ) sqlite3VdbeMemReleaseMalloc(pMem); + if( pMem->zMalloc ) sqlite3VdbeMemRelease(pMem); } - sqlite3DbNNFreeNN(db, p); + sqlite3DbFreeNN(db, p); } } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ #ifdef SQLITE_ENABLE_PREUPDATE_HOOK @@ -88100,11 +85053,11 @@ if( preupdate.aNew ){ int i; for(i=0; inField; i++){ sqlite3VdbeMemRelease(&preupdate.aNew[i]); } - sqlite3DbNNFreeNN(db, preupdate.aNew); + sqlite3DbFreeNN(db, preupdate.aNew); } } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ /************** End of vdbeaux.c *********************************************/ @@ -88124,11 +85077,10 @@ ** This file contains code use to implement APIs that are part of the ** VDBE. */ /* #include "sqliteInt.h" */ /* #include "vdbeInt.h" */ -/* #include "opcodes.h" */ #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 @@ -88218,13 +85170,11 @@ Vdbe *v = (Vdbe*)pStmt; sqlite3 *db = v->db; if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT; sqlite3_mutex_enter(db->mutex); checkProfileCallback(db, v); - assert( v->eVdbeState>=VDBE_READY_STATE ); - rc = sqlite3VdbeReset(v); - sqlite3VdbeDelete(v); + rc = sqlite3VdbeFinalize(v); rc = sqlite3ApiExit(db, rc); sqlite3LeaveMutexAndCloseZombie(db); } return rc; } @@ -88380,11 +85330,11 @@ SQLITE_NULL, /* 0x1d (not possible) */ SQLITE_INTEGER, /* 0x1e (not possible) */ SQLITE_NULL, /* 0x1f (not possible) */ SQLITE_FLOAT, /* 0x20 INTREAL */ SQLITE_NULL, /* 0x21 (not possible) */ - SQLITE_FLOAT, /* 0x22 INTREAL + TEXT */ + SQLITE_TEXT, /* 0x22 INTREAL + TEXT */ SQLITE_NULL, /* 0x23 (not possible) */ SQLITE_FLOAT, /* 0x24 (not possible) */ SQLITE_NULL, /* 0x25 (not possible) */ SQLITE_FLOAT, /* 0x26 (not possible) */ SQLITE_NULL, /* 0x27 (not possible) */ @@ -88428,13 +85378,10 @@ assert( eType == aType[pVal->flags&MEM_AffMask] ); } #endif return aType[pVal->flags&MEM_AffMask]; } -SQLITE_API int sqlite3_value_encoding(sqlite3_value *pVal){ - return pVal->enc; -} /* Return true if a parameter to xUpdate represents an unchanged column */ SQLITE_API int sqlite3_value_nochange(sqlite3_value *pVal){ return (pVal->flags&(MEM_Null|MEM_Zero))==(MEM_Null|MEM_Zero); } @@ -88460,13 +85407,10 @@ pNew->flags |= MEM_Ephem; if( sqlite3VdbeMemMakeWriteable(pNew)!=SQLITE_OK ){ sqlite3ValueFree(pNew); pNew = 0; } - }else if( pNew->flags & MEM_Null ){ - /* Do not duplicate pointer values */ - pNew->flags &= ~(MEM_Term|MEM_Subtype); } return pNew; } /* Destroy an sqlite3_value object previously obtained from @@ -88493,26 +85437,20 @@ 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 */ ){ - Mem *pOut = pCtx->pOut; - int rc = sqlite3VdbeMemSetStr(pOut, z, n, enc, xDel); + int rc = sqlite3VdbeMemSetStr(pCtx->pOut, z, n, enc, xDel); if( rc ){ if( rc==SQLITE_TOOBIG ){ sqlite3_result_error_toobig(pCtx); }else{ /* The only errors possible from sqlite3VdbeMemSetStr are ** SQLITE_TOOBIG and SQLITE_NOMEM */ assert( rc==SQLITE_NOMEM ); sqlite3_result_error_nomem(pCtx); } - return; - } - sqlite3VdbeChangeEncoding(pOut, pCtx->enc); - if( sqlite3VdbeMemTooBig(pOut) ){ - sqlite3_result_error_toobig(pCtx); } } static int invokeValueDestructor( const void *p, /* Value to destroy */ void (*xDel)(void*), /* The destructor */ @@ -88615,14 +85553,11 @@ void (*xDel)(void *), unsigned char enc ){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); assert( xDel!=SQLITE_DYNAMIC ); - if( enc!=SQLITE_UTF8 ){ - if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; - n &= ~(u64)1; - } + if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; if( n>0x7fffffff ){ (void)invokeValueDestructor(z, xDel, pCtx); }else{ setResultStrOrError(pCtx, z, (int)n, enc, xDel); } @@ -88633,48 +85568,43 @@ const void *z, int n, void (*xDel)(void *) ){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - setResultStrOrError(pCtx, z, n & ~(u64)1, SQLITE_UTF16NATIVE, xDel); + setResultStrOrError(pCtx, z, n, SQLITE_UTF16NATIVE, xDel); } SQLITE_API void sqlite3_result_text16be( sqlite3_context *pCtx, const void *z, int n, void (*xDel)(void *) ){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - setResultStrOrError(pCtx, z, n & ~(u64)1, SQLITE_UTF16BE, xDel); + setResultStrOrError(pCtx, z, n, SQLITE_UTF16BE, xDel); } SQLITE_API void sqlite3_result_text16le( sqlite3_context *pCtx, const void *z, int n, void (*xDel)(void *) ){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - setResultStrOrError(pCtx, z, n & ~(u64)1, SQLITE_UTF16LE, xDel); + setResultStrOrError(pCtx, z, n, SQLITE_UTF16LE, xDel); } #endif /* SQLITE_OMIT_UTF16 */ SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){ - Mem *pOut = pCtx->pOut; assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - sqlite3VdbeMemCopy(pOut, pValue); - sqlite3VdbeChangeEncoding(pOut, pCtx->enc); - if( sqlite3VdbeMemTooBig(pOut) ){ - sqlite3_result_error_toobig(pCtx); - } + sqlite3VdbeMemCopy(pCtx->pOut, pValue); } SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){ - sqlite3_result_zeroblob64(pCtx, n>0 ? n : 0); + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemSetZeroBlob(pCtx->pOut, n); } SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){ Mem *pOut = pCtx->pOut; assert( sqlite3_mutex_held(pOut->db->mutex) ); if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){ - sqlite3_result_error_toobig(pCtx); return SQLITE_TOOBIG; } #ifndef SQLITE_OMIT_INCRBLOB sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n); return SQLITE_OK; @@ -88686,12 +85616,12 @@ pCtx->isError = errCode ? errCode : -1; #ifdef SQLITE_DEBUG if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode; #endif if( pCtx->pOut->flags & MEM_Null ){ - setResultStrOrError(pCtx, sqlite3ErrStr(errCode), -1, SQLITE_UTF8, - SQLITE_STATIC); + sqlite3VdbeMemSetStr(pCtx->pOut, sqlite3ErrStr(errCode), -1, + SQLITE_UTF8, SQLITE_STATIC); } } /* Force an SQLITE_TOOBIG error. */ SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){ @@ -88761,87 +85691,84 @@ static int sqlite3Step(Vdbe *p){ sqlite3 *db; int rc; assert(p); + if( p->iVdbeMagic!=VDBE_MAGIC_RUN ){ + /* We used to require that sqlite3_reset() be called before retrying + ** sqlite3_step() after any error or after SQLITE_DONE. But beginning + ** with version 3.7.0, we changed this so that sqlite3_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 sqlite3_step() returned something other than a SQLITE_LOCKED + ** or SQLITE_BUSY error. + */ +#ifdef SQLITE_OMIT_AUTORESET + if( (rc = p->rc&0xff)==SQLITE_BUSY || rc==SQLITE_LOCKED ){ + sqlite3_reset((sqlite3_stmt*)p); + }else{ + return SQLITE_MISUSE_BKPT; + } +#else + sqlite3_reset((sqlite3_stmt*)p); +#endif + } + + /* Check that malloc() has not failed. If it has, return early. */ db = p->db; - if( p->eVdbeState!=VDBE_RUN_STATE ){ - restart_step: - if( p->eVdbeState==VDBE_READY_STATE ){ - if( p->expired ){ - p->rc = SQLITE_SCHEMA; - rc = SQLITE_ERROR; - if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 ){ - /* If this statement was prepared using saved SQL and an - ** error has occurred, then return the error code in p->rc to the - ** caller. Set the error code in the database handle to the same - ** value. - */ - rc = sqlite3VdbeTransferError(p); - } - goto end_of_step; - } - - /* If there are no other statements currently running, then - ** reset the interrupt flag. This prevents a call to sqlite3_interrupt - ** from interrupting a statement that has not yet started. - */ - if( db->nVdbeActive==0 ){ - AtomicStore(&db->u1.isInterrupted, 0); - } - - assert( db->nVdbeWrite>0 || db->autoCommit==0 - || (db->nDeferredCons==0 && db->nDeferredImmCons==0) - ); + if( db->mallocFailed ){ + p->rc = SQLITE_NOMEM; + return SQLITE_NOMEM_BKPT; + } + + if( p->pc<0 && p->expired ){ + p->rc = SQLITE_SCHEMA; + rc = SQLITE_ERROR; + if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 ){ + /* If this statement was prepared using saved SQL and an + ** error has occurred, then return the error code in p->rc to the + ** caller. Set the error code in the database handle to the same value. + */ + rc = sqlite3VdbeTransferError(p); + } + 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 sqlite3_interrupt + ** from interrupting a statement that has not yet started. + */ + if( db->nVdbeActive==0 ){ + AtomicStore(&db->u1.isInterrupted, 0); + } + + assert( db->nVdbeWrite>0 || db->autoCommit==0 + || (db->nDeferredCons==0 && db->nDeferredImmCons==0) + ); #ifndef SQLITE_OMIT_TRACE - if( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0 - && !db->init.busy && p->zSql ){ - sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime); - }else{ - assert( p->startTime==0 ); - } -#endif - - db->nVdbeActive++; - if( p->readOnly==0 ) db->nVdbeWrite++; - if( p->bIsReader ) db->nVdbeRead++; - p->pc = 0; - p->eVdbeState = VDBE_RUN_STATE; - }else - - if( ALWAYS(p->eVdbeState==VDBE_HALT_STATE) ){ - /* We used to require that sqlite3_reset() be called before retrying - ** sqlite3_step() after any error or after SQLITE_DONE. But beginning - ** with version 3.7.0, we changed this so that sqlite3_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 sqlite3_step() returned something other than a SQLITE_LOCKED - ** or SQLITE_BUSY error. - */ -#ifdef SQLITE_OMIT_AUTORESET - if( (rc = p->rc&0xff)==SQLITE_BUSY || rc==SQLITE_LOCKED ){ - sqlite3_reset((sqlite3_stmt*)p); - }else{ - return SQLITE_MISUSE_BKPT; - } -#else - sqlite3_reset((sqlite3_stmt*)p); -#endif - assert( p->eVdbeState==VDBE_READY_STATE ); - goto restart_step; - } - } - + if( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0 + && !db->init.busy && p->zSql ){ + sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime); + }else{ + assert( p->startTime==0 ); + } +#endif + + db->nVdbeActive++; + if( p->readOnly==0 ) db->nVdbeWrite++; + if( p->bIsReader ) db->nVdbeRead++; + p->pc = 0; + } #ifdef SQLITE_DEBUG p->rcApp = SQLITE_OK; #endif #ifndef SQLITE_OMIT_EXPLAIN if( p->explain ){ @@ -88852,21 +85779,16 @@ db->nVdbeExec++; rc = sqlite3VdbeExec(p); db->nVdbeExec--; } - if( rc==SQLITE_ROW ){ - assert( p->rc==SQLITE_OK ); - assert( db->mallocFailed==0 ); - db->errCode = SQLITE_ROW; - return SQLITE_ROW; - }else{ + if( rc!=SQLITE_ROW ){ #ifndef SQLITE_OMIT_TRACE /* If the statement completed successfully, invoke the profile callback */ checkProfileCallback(db, p); #endif - p->pResultRow = 0; + if( rc==SQLITE_DONE && db->autoCommit ){ assert( p->rc==SQLITE_OK ); p->rc = doWalCallbacks(db); if( p->rc!=SQLITE_OK ){ rc = SQLITE_ERROR; @@ -88909,10 +85831,11 @@ if( vdbeSafetyNotNull(v) ){ return SQLITE_MISUSE_BKPT; } db = v->db; sqlite3_mutex_enter(db->mutex); + v->doingRerun = 0; while( (rc = sqlite3Step(v))==SQLITE_SCHEMA && cnt++ < SQLITE_MAX_SCHEMA_RETRY ){ int savedPc = v->pc; rc = sqlite3Reprepare(v); if( rc!=SQLITE_OK ){ @@ -88934,17 +85857,11 @@ v->rc = rc = SQLITE_NOMEM_BKPT; } break; } sqlite3_reset(pStmt); - if( savedPc>=0 ){ - /* Setting minWriteFileFormat to 254 is a signal to the OP_Init and - ** OP_Trace opcodes to *not* perform SQLITE_TRACE_STMT because it has - ** already been done once on a prior invocation that failed due to - ** SQLITE_SCHEMA. tag-20220401a */ - v->minWriteFileFormat = 254; - } + if( savedPc>=0 ) v->doingRerun = 1; assert( v->expired==0 ); } sqlite3_mutex_leave(db->mutex); return rc; } @@ -88991,21 +85908,10 @@ SQLITE_API int sqlite3_vtab_nochange(sqlite3_context *p){ assert( p ); return sqlite3_value_nochange(p->pOut); } -/* -** The destructor function for a ValueList object. This needs to be -** a separate function, unknowable to the application, to ensure that -** calls to sqlite3_vtab_in_first()/sqlite3_vtab_in_next() that are not -** preceeded by activation of IN processing via sqlite3_vtab_int() do not -** try to access a fake ValueList object inserted by a hostile extension. -*/ -SQLITE_PRIVATE void sqlite3VdbeValueListFree(void *pToDelete){ - sqlite3_free(pToDelete); -} - /* ** Implementation of sqlite3_vtab_in_first() (if bNext==0) and ** sqlite3_vtab_in_next() (if bNext!=0). */ static int valueFromValueList( @@ -89016,19 +85922,12 @@ int rc; ValueList *pRhs; *ppOut = 0; if( pVal==0 ) return SQLITE_MISUSE; - if( (pVal->flags & MEM_Dyn)==0 || pVal->xDel!=sqlite3VdbeValueListFree ){ - return SQLITE_ERROR; - }else{ - assert( (pVal->flags&(MEM_TypeMask|MEM_Term|MEM_Subtype)) == - (MEM_Null|MEM_Term|MEM_Subtype) ); - assert( pVal->eSubtype=='p' ); - assert( pVal->u.zPType!=0 && strcmp(pVal->u.zPType,"ValueList")==0 ); - pRhs = (ValueList*)pVal->z; - } + pRhs = (ValueList*)sqlite3_value_pointer(pVal, "ValueList"); + if( pRhs==0 ) return SQLITE_MISUSE; if( bNext ){ rc = sqlite3BtreeNext(pRhs->pCsr, 0); }else{ int dummy = 0; rc = sqlite3BtreeFirst(pRhs->pCsr, &dummy); @@ -89244,11 +86143,11 @@ ** Return the number of values available from the current row of the ** currently executing statement pStmt. */ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt){ Vdbe *pVm = (Vdbe *)pStmt; - if( pVm==0 || pVm->pResultRow==0 ) return 0; + if( pVm==0 || pVm->pResultSet==0 ) return 0; return pVm->nResColumn; } /* ** Return a pointer to static memory containing an SQL NULL value. @@ -89267,19 +86166,19 @@ #if defined(SQLITE_DEBUG) && defined(__GNUC__) __attribute__((aligned(8))) #endif = { /* .u = */ {0}, - /* .z = */ (char*)0, - /* .n = */ (int)0, /* .flags = */ (u16)MEM_Null, /* .enc = */ (u8)0, /* .eSubtype = */ (u8)0, - /* .db = */ (sqlite3*)0, + /* .n = */ (int)0, + /* .z = */ (char*)0, + /* .zMalloc = */ (char*)0, /* .szMalloc = */ (int)0, /* .uTemp = */ (u32)0, - /* .zMalloc = */ (char*)0, + /* .db = */ (sqlite3*)0, /* .xDel = */ (void(*)(void*))0, #ifdef SQLITE_DEBUG /* .pScopyFrom = */ (Mem*)0, /* .mScopyFlags= */ 0, #endif @@ -89299,12 +86198,12 @@ pVm = (Vdbe *)pStmt; if( pVm==0 ) return (Mem*)columnNullValue(); assert( pVm->db ); sqlite3_mutex_enter(pVm->db->mutex); - if( pVm->pResultRow!=0 && inResColumn && i>=0 ){ - pOut = &pVm->pResultRow[i]; + if( pVm->pResultSet!=0 && inResColumn && i>=0 ){ + pOut = &pVm->pResultSet[i]; }else{ sqlite3Error(pVm->db, SQLITE_RANGE); pOut = (Mem*)columnNullValue(); } return pOut; @@ -89566,28 +86465,29 @@ ** 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, unsigned int i){ +static int vdbeUnbind(Vdbe *p, int i){ Mem *pVar; if( vdbeSafetyNotNull(p) ){ return SQLITE_MISUSE_BKPT; } sqlite3_mutex_enter(p->db->mutex); - if( p->eVdbeState!=VDBE_READY_STATE ){ + if( p->iVdbeMagic!=VDBE_MAGIC_RUN || p->pc>=0 ){ sqlite3Error(p->db, SQLITE_MISUSE); sqlite3_mutex_leave(p->db->mutex); sqlite3_log(SQLITE_MISUSE, "bind on a busy prepared statement: [%s]", p->zSql); return SQLITE_MISUSE_BKPT; } - if( i>=(unsigned int)p->nVar ){ + if( i<1 || i>p->nVar ){ sqlite3Error(p->db, SQLITE_RANGE); sqlite3_mutex_leave(p->db->mutex); return SQLITE_RANGE; } + i--; pVar = &p->aVar[i]; sqlite3VdbeMemRelease(pVar); pVar->flags = MEM_Null; p->db->errCode = SQLITE_OK; @@ -89620,11 +86520,11 @@ ){ Vdbe *p = (Vdbe *)pStmt; Mem *pVar; int rc; - rc = vdbeUnbind(p, (u32)(i-1)); + rc = vdbeUnbind(p, i); if( rc==SQLITE_OK ){ if( zData!=0 ){ pVar = &p->aVar[i-1]; rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel); if( rc==SQLITE_OK && encoding!=0 ){ @@ -89669,11 +86569,11 @@ return bindText(pStmt, i, zData, nData, xDel, 0); } SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){ int rc; Vdbe *p = (Vdbe *)pStmt; - rc = vdbeUnbind(p, (u32)(i-1)); + rc = vdbeUnbind(p, i); if( rc==SQLITE_OK ){ sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue); sqlite3_mutex_leave(p->db->mutex); } return rc; @@ -89682,21 +86582,21 @@ return sqlite3_bind_int64(p, i, (i64)iValue); } SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){ int rc; Vdbe *p = (Vdbe *)pStmt; - rc = vdbeUnbind(p, (u32)(i-1)); + rc = vdbeUnbind(p, i); if( rc==SQLITE_OK ){ sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue); sqlite3_mutex_leave(p->db->mutex); } return rc; } SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){ int rc; Vdbe *p = (Vdbe*)pStmt; - rc = vdbeUnbind(p, (u32)(i-1)); + rc = vdbeUnbind(p, i); if( rc==SQLITE_OK ){ sqlite3_mutex_leave(p->db->mutex); } return rc; } @@ -89707,11 +86607,11 @@ const char *zPTtype, void (*xDestructor)(void*) ){ int rc; Vdbe *p = (Vdbe*)pStmt; - rc = vdbeUnbind(p, (u32)(i-1)); + rc = vdbeUnbind(p, i); if( rc==SQLITE_OK ){ sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor); sqlite3_mutex_leave(p->db->mutex); }else if( xDestructor ){ xDestructor(pPtr); @@ -89734,25 +86634,22 @@ sqlite3_uint64 nData, void (*xDel)(void*), unsigned char enc ){ assert( xDel!=SQLITE_DYNAMIC ); - if( enc!=SQLITE_UTF8 ){ - if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; - nData &= ~(u16)1; - } + if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; return bindText(pStmt, i, zData, nData, xDel, enc); } #ifndef SQLITE_OMIT_UTF16 SQLITE_API int sqlite3_bind_text16( sqlite3_stmt *pStmt, int i, const void *zData, - int n, + int nData, void (*xDel)(void*) ){ - return bindText(pStmt, i, zData, n & ~(u64)1, xDel, SQLITE_UTF16NATIVE); + return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE); } #endif /* SQLITE_OMIT_UTF16 */ SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){ int rc; switch( sqlite3_value_type((sqlite3_value*)pValue) ){ @@ -89788,11 +86685,11 @@ return rc; } SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){ int rc; Vdbe *p = (Vdbe *)pStmt; - rc = vdbeUnbind(p, (u32)(i-1)); + rc = vdbeUnbind(p, i); if( rc==SQLITE_OK ){ #ifndef SQLITE_OMIT_INCRBLOB sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n); #else rc = sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n); @@ -89927,11 +86824,11 @@ /* ** Return true if the prepared statement is in need of being reset. */ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){ Vdbe *v = (Vdbe*)pStmt; - return v!=0 && v->eVdbeState==VDBE_RUN_STATE; + return v!=0 && v->iVdbeMagic==VDBE_MAGIC_RUN && v->pc>=0; } /* ** Return a pointer to the next prepared statement after pStmt associated ** with database connection pDb. If pStmt is NULL, return the first @@ -89948,11 +86845,11 @@ #endif sqlite3_mutex_enter(pDb->mutex); if( pStmt==0 ){ pNext = (sqlite3_stmt*)pDb->pVdbe; }else{ - pNext = (sqlite3_stmt*)((Vdbe*)pStmt)->pVNext; + pNext = (sqlite3_stmt*)((Vdbe*)pStmt)->pNext; } sqlite3_mutex_leave(pDb->mutex); return pNext; } @@ -89973,15 +86870,13 @@ if( op==SQLITE_STMTSTATUS_MEMUSED ){ sqlite3 *db = pVdbe->db; sqlite3_mutex_enter(db->mutex); v = 0; db->pnBytesFreed = (int*)&v; - assert( db->lookaside.pEnd==db->lookaside.pTrueEnd ); - db->lookaside.pEnd = db->lookaside.pStart; - sqlite3VdbeDelete(pVdbe); + sqlite3VdbeClearObject(db, pVdbe); + sqlite3DbFree(db, pVdbe); db->pnBytesFreed = 0; - db->lookaside.pEnd = db->lookaside.pTrueEnd; sqlite3_mutex_leave(db->mutex); }else{ v = pVdbe->aCounter[op]; if( resetFlag ) pVdbe->aCounter[op] = 0; } @@ -90239,73 +87134,27 @@ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS /* ** Return status data for a single loop within query pStmt. */ -SQLITE_API int sqlite3_stmt_scanstatus_v2( +SQLITE_API int sqlite3_stmt_scanstatus( sqlite3_stmt *pStmt, /* Prepared statement being queried */ - int iScan, /* Index of loop to report on */ + int idx, /* Index of loop to report on */ int iScanStatusOp, /* Which metric to return */ - int flags, void *pOut /* OUT: Write the answer here */ ){ Vdbe *p = (Vdbe*)pStmt; - VdbeOp *aOp = p->aOp; - int nOp = p->nOp; - ScanStatus *pScan = 0; - int idx; - - if( p->pFrame ){ - VdbeFrame *pFrame; - for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); - aOp = pFrame->aOp; - nOp = pFrame->nOp; - } - - if( iScan<0 ){ - int ii; - if( iScanStatusOp==SQLITE_SCANSTAT_NCYCLE ){ - i64 res = 0; - for(ii=0; iiaScan[idx]; - }else{ - /* If the COMPLEX flag is clear, then this function must ignore any - ** ScanStatus structures with ScanStatus.addrLoop set to 0. */ - for(idx=0; idxnScan; idx++){ - pScan = &p->aScan[idx]; - if( pScan->zName ){ - iScan--; - if( iScan<0 ) break; - } - } - } - if( idx>=p->nScan ) return 1; - + ScanStatus *pScan; + if( idx<0 || idx>=p->nScan ) return 1; + pScan = &p->aScan[idx]; switch( iScanStatusOp ){ case SQLITE_SCANSTAT_NLOOP: { - if( pScan->addrLoop>0 ){ - *(sqlite3_int64*)pOut = aOp[pScan->addrLoop].nExec; - }else{ - *(sqlite3_int64*)pOut = -1; - } + *(sqlite3_int64*)pOut = p->anExec[pScan->addrLoop]; break; } case SQLITE_SCANSTAT_NVISIT: { - if( pScan->addrVisit>0 ){ - *(sqlite3_int64*)pOut = aOp[pScan->addrVisit].nExec; - }else{ - *(sqlite3_int64*)pOut = -1; - } + *(sqlite3_int64*)pOut = p->anExec[pScan->addrVisit]; break; } case SQLITE_SCANSTAT_EST: { double r = 1.0; LogEst x = pScan->nEst; @@ -90320,93 +87169,37 @@ *(const char**)pOut = pScan->zName; break; } case SQLITE_SCANSTAT_EXPLAIN: { if( pScan->addrExplain ){ - *(const char**)pOut = aOp[ pScan->addrExplain ].p4.z; + *(const char**)pOut = p->aOp[ pScan->addrExplain ].p4.z; }else{ *(const char**)pOut = 0; } break; } case SQLITE_SCANSTAT_SELECTID: { if( pScan->addrExplain ){ - *(int*)pOut = aOp[ pScan->addrExplain ].p1; - }else{ - *(int*)pOut = -1; - } - break; - } - case SQLITE_SCANSTAT_PARENTID: { - if( pScan->addrExplain ){ - *(int*)pOut = aOp[ pScan->addrExplain ].p2; - }else{ - *(int*)pOut = -1; - } - break; - } - case SQLITE_SCANSTAT_NCYCLE: { - i64 res = 0; - if( pScan->aAddrRange[0]==0 ){ - res = -1; - }else{ - int ii; - for(ii=0; iiaAddrRange); ii+=2){ - int iIns = pScan->aAddrRange[ii]; - int iEnd = pScan->aAddrRange[ii+1]; - if( iIns==0 ) break; - if( iIns>0 ){ - while( iIns<=iEnd ){ - res += aOp[iIns].nCycle; - iIns++; - } - }else{ - int iOp; - for(iOp=0; iOpp1!=iEnd ) continue; - if( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_NCYCLE)==0 ){ - continue; - } - res += aOp[iOp].nCycle; - } - } - } - } - *(i64*)pOut = res; - break; - } - default: { - return 1; - } - } - return 0; -} - -/* -** Return status data for a single loop within query pStmt. -*/ -SQLITE_API int sqlite3_stmt_scanstatus( - sqlite3_stmt *pStmt, /* Prepared statement being queried */ - int iScan, /* Index of loop to report on */ - int iScanStatusOp, /* Which metric to return */ - void *pOut /* OUT: Write the answer here */ -){ - return sqlite3_stmt_scanstatus_v2(pStmt, iScan, iScanStatusOp, 0, pOut); + *(int*)pOut = p->aOp[ pScan->addrExplain ].p1; + }else{ + *(int*)pOut = -1; + } + break; + } + default: { + return 1; + } + } + return 0; } /* ** Zero all counters associated with the sqlite3_stmt_scanstatus() data. */ SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){ Vdbe *p = (Vdbe*)pStmt; - int ii; - for(ii=0; iinOp; ii++){ - Op *pOp = &p->aOp[ii]; - pOp->nExec = 0; - pOp->nCycle = 0; - } + memset(p->anExec, 0, p->nOp * sizeof(i64)); } #endif /* SQLITE_ENABLE_STMT_SCANSTATUS */ /************** End of vdbeapi.c *********************************************/ /************** Begin file vdbetrace.c ***************************************/ @@ -90738,13 +87531,10 @@ ** sqlite3MisuseError(lineno) ** sqlite3CantopenError(lineno) */ static void test_trace_breakpoint(int pc, Op *pOp, Vdbe *v){ static int n = 0; - (void)pc; - (void)pOp; - (void)v; n++; } #endif /* @@ -90874,16 +87664,16 @@ Mem *pMem = iCur>0 ? &p->aMem[p->nMem-iCur] : p->aMem; int nByte; VdbeCursor *pCx = 0; nByte = - ROUND8P(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + + ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0); assert( iCur>=0 && iCurnCursor ); if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/ - sqlite3VdbeFreeCursorNN(p, p->apCsr[iCur]); + sqlite3VdbeFreeCursor(p, p->apCsr[iCur]); p->apCsr[iCur] = 0; } /* There used to be a call to sqlite3VdbeMemClearAndResize() to make sure ** the pMem used to hold space for the cursor has enough storage available @@ -90909,11 +87699,11 @@ pCx->eCurType = eCurType; pCx->nField = nField; pCx->aOffset = &pCx->aType[nField]; if( eCurType==CURTYPE_BTREE ){ pCx->uc.pCursor = (BtCursor*) - &pMem->z[ROUND8P(sizeof(VdbeCursor))+2*sizeof(u32)*nField]; + &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField]; sqlite3BtreeCursorZero(pCx->uc.pCursor); } return pCx; } @@ -90922,12 +87712,11 @@ ** floating point value of rValue. Return true and set *piValue to the ** integer value if the string is in range to be an integer. Otherwise, ** return false. */ static int alsoAnInt(Mem *pRec, double rValue, i64 *piValue){ - i64 iValue; - iValue = sqlite3RealToI64(rValue); + i64 iValue = (double)rValue; if( sqlite3RealSameAsInt(rValue,iValue) ){ *piValue = iValue; return 1; } return 0==sqlite3Atoi64(pRec->z, piValue, pRec->n, pRec->enc); @@ -90979,14 +87768,10 @@ ** 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_FLEXNUM: -** If the value is text, then try to convert it into a number of -** some kind (integer or real) but do not make any other changes. -** ** SQLITE_AFF_TEXT: ** Convert pRec to a text representation. ** ** SQLITE_AFF_BLOB: ** SQLITE_AFF_NONE: @@ -90997,15 +87782,15 @@ char affinity, /* The affinity to be applied */ u8 enc /* Use this text encoding */ ){ if( affinity>=SQLITE_AFF_NUMERIC ){ assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL - || affinity==SQLITE_AFF_NUMERIC || affinity==SQLITE_AFF_FLEXNUM ); + || affinity==SQLITE_AFF_NUMERIC ); if( (pRec->flags & MEM_Int)==0 ){ /*OPTIMIZATION-IF-FALSE*/ - if( (pRec->flags & (MEM_Real|MEM_IntReal))==0 ){ + if( (pRec->flags & MEM_Real)==0 ){ if( pRec->flags & MEM_Str ) applyNumericAffinity(pRec,1); - }else if( affinity<=SQLITE_AFF_REAL ){ + }else{ sqlite3VdbeIntegerAffinity(pRec); } } }else if( affinity==SQLITE_AFF_TEXT ){ /* Only attempt the conversion to TEXT if there is an integer or real @@ -91089,22 +87874,21 @@ ** ** Unlike applyNumericAffinity(), this routine does not modify pMem->flags. ** But it does set pMem->u.r and pMem->u.i appropriately. */ static u16 numericType(Mem *pMem){ - assert( (pMem->flags & MEM_Null)==0 - || pMem->db==0 || pMem->db->mallocFailed ); - if( pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null) ){ + if( pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal) ){ testcase( pMem->flags & MEM_Int ); testcase( pMem->flags & MEM_Real ); testcase( pMem->flags & MEM_IntReal ); - return pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null); + return pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal); } - assert( pMem->flags & (MEM_Str|MEM_Blob) ); - testcase( pMem->flags & MEM_Str ); - testcase( pMem->flags & MEM_Blob ); - return computeNumericType(pMem); + if( pMem->flags & (MEM_Str|MEM_Blob) ){ + testcase( pMem->flags & MEM_Str ); + testcase( pMem->flags & MEM_Blob ); + return computeNumericType(pMem); + } return 0; } #ifdef SQLITE_DEBUG /* @@ -91229,10 +88013,21 @@ # define REGISTER_TRACE(R,M) if(db->flags&SQLITE_VdbeTrace)registerTrace(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" */ + +#endif + #ifndef NDEBUG /* ** This function is only called from within an assert() expression. It ** checks that the sqlite3.nTransaction variable is correctly set to ** the number of non-transaction savepoints currently in the @@ -91288,14 +88083,12 @@ if( p->flags & (MEM_Int|MEM_IntReal) ){ h += p->u.i; }else if( p->flags & MEM_Real ){ h += sqlite3VdbeIntValue(p); }else if( p->flags & (MEM_Str|MEM_Blob) ){ - /* All strings have the same hash and all blobs have the same hash, - ** though, at least, those hashes are different from each other and - ** from NULL. */ - h += 4093 + (p->flags & (MEM_Str|MEM_Blob)); + h += p->n; + if( p->flags & MEM_Zero ) h += p->u.nZero; } } return h; } @@ -91320,14 +88113,15 @@ SQLITE_PRIVATE int sqlite3VdbeExec( Vdbe *p /* The VDBE */ ){ Op *aOp = p->aOp; /* Copy of p->aOp */ Op *pOp = aOp; /* Current operation */ -#ifdef SQLITE_DEBUG +#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) Op *pOrigOp; /* Value of pOp at the top of the loop */ +#endif +#ifdef SQLITE_DEBUG int nExtraDelete = 0; /* Verifies FORDELETE and AUXDELETE flags */ - u8 iCompareIsInit = 0; /* iCompare is initialized */ #endif int rc = SQLITE_OK; /* Value to return */ sqlite3 *db = p->db; /* The database */ u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */ u8 encoding = ENC(db); /* The database encoding */ @@ -91339,20 +88133,17 @@ 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 */ -#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) - u64 *pnCycle = 0; - int bStmtScanStatus = IS_STMT_SCANSTATUS(db)!=0; +#ifdef VDBE_PROFILE + u64 start; /* CPU clock count at start of opcode */ #endif /*** INSERT STACK UNION HERE ***/ - assert( p->eVdbeState==VDBE_RUN_STATE ); /* sqlite3_step() verifies this */ - if( DbMaskNonZero(p->lockMask) ){ - sqlite3VdbeEnter(p); - } + assert( p->iVdbeMagic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */ + sqlite3VdbeEnter(p); #ifndef SQLITE_OMIT_PROGRESS_CALLBACK if( db->xProgress ){ u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP]; assert( 0 < db->nProgressOps ); nProgressLimit = db->nProgressOps - (iPrior % db->nProgressOps); @@ -91369,10 +88160,11 @@ testcase( p->rc!=SQLITE_OK ); p->rc = SQLITE_OK; assert( p->bIsReader || p->readOnly!=0 ); p->iCurrentTime = 0; assert( p->explain==0 ); + p->pResultSet = 0; db->busyHandler.nBusy = 0; if( AtomicLoad(&db->u1.isInterrupted) ) goto abort_due_to_interrupt; sqlite3VdbeIOTraceSql(p); #ifdef SQLITE_DEBUG sqlite3BeginBenignMalloc(); @@ -91405,22 +88197,16 @@ /* Errors are detected by individual opcodes, with an immediate ** jumps to abort_due_to_error. */ assert( rc==SQLITE_OK ); assert( pOp>=aOp && pOp<&aOp[p->nOp]); +#ifdef VDBE_PROFILE + start = sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime(); +#endif nVmStep++; - -#if defined(VDBE_PROFILE) - pOp->nExec++; - pnCycle = &pOp->nCycle; - if( sqlite3NProfileCnt==0 ) *pnCycle -= sqlite3Hwtime(); -#elif defined(SQLITE_ENABLE_STMT_SCANSTATUS) - if( bStmtScanStatus ){ - pOp->nExec++; - pnCycle = &pOp->nCycle; - *pnCycle -= sqlite3Hwtime(); - } +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + if( p->anExec ) p->anExec[(int)(pOp-aOp)]++; #endif /* Only allow tracing if SQLITE_DEBUG is defined. */ #ifdef SQLITE_DEBUG @@ -91478,11 +88264,11 @@ assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); memAboutToChange(p, &aMem[pOp->p3]); } } #endif -#ifdef SQLITE_DEBUG +#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) pOrigOp = pOp; #endif switch( pOp->opcode ){ @@ -91595,43 +88381,30 @@ assert( VdbeMemDynamic(pIn1)==0 ); memAboutToChange(p, pIn1); pIn1->flags = MEM_Int; pIn1->u.i = (int)(pOp-aOp); REGISTER_TRACE(pOp->p1, pIn1); - goto jump_to_p2_and_check_for_interrupt; -} - -/* Opcode: Return P1 P2 P3 * * -** -** Jump to the address stored in register P1. If P1 is a return address -** register, then this accomplishes a return from a subroutine. -** -** If P3 is 1, then the jump is only taken if register P1 holds an integer -** values, otherwise execution falls through to the next opcode, and the -** OP_Return becomes a no-op. If P3 is 0, then register P1 must hold an -** integer or else an assert() is raised. P3 should be set to 1 when -** this opcode is used in combination with OP_BeginSubrtn, and set to 0 -** otherwise. -** -** The value in register P1 is unchanged by this opcode. -** -** P2 is not used by the byte-code engine. However, if P2 is positive -** and also less than the current address, then the "EXPLAIN" output -** formatter in the CLI will indent all opcodes from the P2 opcode up -** to be not including the current Return. P2 should be the first opcode -** in the subroutine from which this opcode is returning. Thus the P2 -** value is a byte-code indentation hint. See tag-20220407a in -** wherecode.c and shell.c. + + /* Most jump operations do a goto to this spot in order to update + ** the pOp pointer. */ +jump_to_p2: + assert( pOp->p2>0 ); /* There are never any jumps to instruction 0 */ + assert( pOp->p2nOp ); /* Jumps must be in range */ + pOp = &aOp[pOp->p2 - 1]; + break; +} + +/* Opcode: Return P1 * * * * +** +** Jump to the next instruction after the address in register P1. After +** the jump, register P1 becomes undefined. */ case OP_Return: { /* in1 */ pIn1 = &aMem[pOp->p1]; - if( pIn1->flags & MEM_Int ){ - if( pOp->p3 ){ VdbeBranchTaken(1, 2); } - pOp = &aOp[pIn1->u.i]; - }else if( ALWAYS(pOp->p3) ){ - VdbeBranchTaken(0, 2); - } + assert( pIn1->flags==MEM_Int ); + pOp = &aOp[pIn1->u.i]; + pIn1->flags = MEM_Undefined; break; } /* Opcode: InitCoroutine P1 P2 P3 * * ** @@ -91650,18 +88423,11 @@ assert( pOp->p3>=0 && pOp->p3nOp ); pOut = &aMem[pOp->p1]; assert( !VdbeMemDynamic(pOut) ); pOut->u.i = pOp->p3 - 1; pOut->flags = MEM_Int; - if( pOp->p2==0 ) break; - - /* Most jump operations do a goto to this spot in order to update - ** the pOp pointer. */ -jump_to_p2: - assert( pOp->p2>0 ); /* There are never any jumps to instruction 0 */ - assert( pOp->p2nOp ); /* Jumps must be in range */ - pOp = &aOp[pOp->p2 - 1]; + if( pOp->p2 ) goto jump_to_p2; break; } /* Opcode: EndCoroutine P1 * * * * ** @@ -91759,20 +88525,15 @@ */ case OP_Halt: { VdbeFrame *pFrame; int pcx; + pcx = (int)(pOp - aOp); #ifdef SQLITE_DEBUG if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); } #endif - - /* A deliberately coded "OP_Halt SQLITE_INTERNAL * * * *" opcode indicates - ** something is wrong with the code generator. Raise an assertion in order - ** to bring this to the attention of fuzzers and other testing tools. */ - assert( pOp->p1!=SQLITE_INTERNAL ); - - if( p->pFrame && pOp->p1==SQLITE_OK ){ + if( pOp->p1==SQLITE_OK && p->pFrame ){ /* Halt the sub-program. Return control to the parent frame. */ pFrame = p->pFrame; p->pFrame = pFrame->pParent; p->nFrame--; sqlite3VdbeSetChanges(db, p->nChange); @@ -91790,10 +88551,11 @@ pOp = &aOp[pcx]; break; } p->rc = pOp->p1; p->errorAction = (u8)pOp->p2; + p->pc = pcx; assert( pOp->p5<=4 ); if( p->rc ){ if( pOp->p5 ){ static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK", "FOREIGN KEY" }; @@ -91806,11 +88568,10 @@ p->zErrMsg = sqlite3MPrintf(db, "%z: %s", p->zErrMsg, pOp->p4.z); } }else{ sqlite3VdbeError(p, "%s", pOp->p4.z); } - pcx = (int)(pOp - aOp); sqlite3_log(pOp->p1, "abort at %d in [%s]: %s", pcx, p->zSql, p->zErrMsg); } rc = sqlite3VdbeHalt(p); assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR ); if( rc==SQLITE_BUSY ){ @@ -91932,32 +88693,10 @@ } #endif break; } -/* Opcode: BeginSubrtn * P2 * * * -** Synopsis: r[P2]=NULL -** -** Mark the beginning of a subroutine that can be entered in-line -** or that can be called using OP_Gosub. The subroutine should -** be terminated by an OP_Return instruction that has a P1 operand that -** is the same as the P2 operand to this opcode and that has P3 set to 1. -** If the subroutine is entered in-line, then the OP_Return will simply -** fall through. But if the subroutine is entered using OP_Gosub, then -** the OP_Return will jump back to the first instruction after the OP_Gosub. -** -** This routine works by loading a NULL into the P2 register. When the -** return address register contains a NULL, the OP_Return instruction is -** a no-op that simply falls through to the next instruction (assuming that -** the OP_Return opcode has a P3 value of 1). Thus if the subroutine is -** entered in-line, then the OP_Return will cause in-line execution to -** continue. But if the subroutine is entered via OP_Gosub, then the -** OP_Return will cause a return to the address following the OP_Gosub. -** -** This opcode is identical to OP_Null. It has a different name -** only to make the byte code easier to read and verify. -*/ /* Opcode: Null P1 P2 P3 * * ** Synopsis: r[P2..P3]=NULL ** ** Write a NULL into registers P2. If P3 greater than P2, then also write ** NULL into register P3 and every register in between P2 and P3. If P3 @@ -91966,11 +88705,10 @@ ** ** If the P1 value is non-zero, then also set the MEM_Cleared flag so that ** NULL values will not compare equal even if SQLITE_NULLEQ is set on ** OP_Ne or OP_Eq. */ -case OP_BeginSubrtn: case OP_Null: { /* out2 */ int cnt; u16 nullFlag; pOut = out2Prerelease(p, pOp); cnt = pOp->p3-pOp->p2; @@ -92097,20 +88835,15 @@ pOut++; }while( --n ); break; } -/* Opcode: Copy P1 P2 P3 * P5 +/* Opcode: Copy P1 P2 P3 * * ** Synopsis: r[P2@P3+1]=r[P1@P3+1] ** ** Make a copy of registers P1..P1+P3 into registers P2..P2+P3. ** -** If the 0x0002 bit of P5 is set then also clear the MEM_Subtype flag in the -** destination. The 0x0001 bit of P5 indicates that this Copy opcode cannot -** be merged. The 0x0001 bit is used by the query planner and does not -** come into play during query execution. -** ** 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: { int n; @@ -92121,13 +88854,10 @@ assert( pOut!=pIn1 ); while( 1 ){ memAboutToChange(p, pOut); sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); Deephemeralize(pOut); - if( (pOut->flags & MEM_Subtype)!=0 && (pOp->p5 & 0x0002)!=0 ){ - pOut->flags &= ~MEM_Subtype; - } #ifdef SQLITE_DEBUG pOut->pScopyFrom = 0; #endif REGISTER_TRACE(pOp->p2+pOp->p3-n, pOut); if( (n--)==0 ) break; @@ -92204,36 +88934,49 @@ ** with an SQLITE_ROW return code and it sets up the sqlite3_stmt ** structure to provide access to the r(P1)..r(P1+P2-1) values as ** the result row. */ case OP_ResultRow: { + Mem *pMem; + int i; assert( p->nResColumn==pOp->p2 ); assert( pOp->p1>0 || CORRUPT_DB ); assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 ); + /* Invalidate all ephemeral cursor row caches */ p->cacheCtr = (p->cacheCtr + 2)|1; - p->pResultRow = &aMem[pOp->p1]; + + /* 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. + */ + pMem = p->pResultSet = &aMem[pOp->p1]; + for(i=0; ip2; i++){ + assert( memIsValid(&pMem[i]) ); + Deephemeralize(&pMem[i]); + assert( (pMem[i].flags & MEM_Ephem)==0 + || (pMem[i].flags & (MEM_Str|MEM_Blob))==0 ); + sqlite3VdbeMemNulTerminate(&pMem[i]); + REGISTER_TRACE(pOp->p1+i, &pMem[i]); #ifdef SQLITE_DEBUG - { - Mem *pMem = p->pResultRow; - int i; - for(i=0; ip2; i++){ - assert( memIsValid(&pMem[i]) ); - REGISTER_TRACE(pOp->p1+i, &pMem[i]); - /* The registers in the result will not be used again when the - ** prepared statement restarts. This is because sqlite3_column() - ** APIs might have caused type conversions of made other changes to - ** the register values. Therefore, we can go ahead and break any - ** OP_SCopy dependencies. */ - pMem[i].pScopyFrom = 0; - } - } -#endif + /* The registers in the result will not be used again when the + ** prepared statement restarts. This is because sqlite3_column() + ** APIs might have caused type conversions of made other changes to + ** the register values. Therefore, we can go ahead and break any + ** OP_SCopy dependencies. */ + pMem[i].pScopyFrom = 0; +#endif + } if( db->mallocFailed ) goto no_mem; + if( db->mTrace & SQLITE_TRACE_ROW ){ db->trace.xV2(SQLITE_TRACE_ROW, db->pTraceArg, p, 0); } + + + /* Return SQLITE_ROW + */ p->pc = (int)(pOp - aOp) + 1; rc = SQLITE_ROW; goto vdbe_return; } @@ -92284,11 +89027,11 @@ } nByte = pIn1->n + pIn2->n; if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } - if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){ + if( sqlite3VdbeMemGrow(pOut, (int)nByte+3, pOut==pIn2) ){ goto no_mem; } MemSetTypeFlag(pOut, MEM_Str); if( pOut!=pIn2 ){ memcpy(pOut->z, pIn2->z, pIn2->n); @@ -92296,13 +89039,13 @@ pIn2->flags = flags2; } memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n); assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) ); pIn1->flags = flags1; - if( encoding>SQLITE_UTF8 ) nByte &= ~1; pOut->z[nByte]=0; pOut->z[nByte+1] = 0; + pOut->z[nByte+2] = 0; pOut->flags |= MEM_Term; pOut->n = (int)nByte; pOut->enc = encoding; UPDATE_MAX_BLOBSIZE(pOut); break; @@ -92349,24 +89092,25 @@ 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 */ + u16 flags; /* Combined MEM_* flags from both inputs */ u16 type1; /* Numeric type of left operand */ u16 type2; /* Numeric type of right operand */ 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 */ pIn1 = &aMem[pOp->p1]; - type1 = pIn1->flags; + type1 = numericType(pIn1); pIn2 = &aMem[pOp->p2]; - type2 = pIn2->flags; + type2 = numericType(pIn2); pOut = &aMem[pOp->p3]; + flags = pIn1->flags | pIn2->flags; if( (type1 & type2 & MEM_Int)!=0 ){ -int_math: iA = pIn1->u.i; iB = pIn2->u.i; switch( pOp->opcode ){ case OP_Add: if( sqlite3AddInt64(&iB,iA) ) goto fp_math; break; case OP_Subtract: if( sqlite3SubInt64(&iB,iA) ) goto fp_math; break; @@ -92384,16 +89128,13 @@ break; } } pOut->u.i = iB; MemSetTypeFlag(pOut, MEM_Int); - }else if( ((type1 | type2) & MEM_Null)!=0 ){ + }else if( (flags & MEM_Null)!=0 ){ goto arithmetic_result_is_null; }else{ - type1 = numericType(pIn1); - type2 = numericType(pIn2); - if( (type1 & type2 & MEM_Int)!=0 ) goto int_math; fp_math: rA = sqlite3VdbeRealValue(pIn1); rB = sqlite3VdbeRealValue(pIn2); switch( pOp->opcode ){ case OP_Add: rB += rA; break; @@ -92742,32 +89483,30 @@ pIn1 = &aMem[pOp->p1]; pIn3 = &aMem[pOp->p3]; flags1 = pIn1->flags; flags3 = pIn3->flags; if( (flags1 & flags3 & MEM_Int)!=0 ){ + assert( (pOp->p5 & SQLITE_AFF_MASK)!=SQLITE_AFF_TEXT || CORRUPT_DB ); /* Common case of comparison of two integers */ if( pIn3->u.i > pIn1->u.i ){ + iCompare = +1; if( sqlite3aGTb[pOp->opcode] ){ VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3); goto jump_to_p2; } - iCompare = +1; - VVA_ONLY( iCompareIsInit = 1; ) }else if( pIn3->u.i < pIn1->u.i ){ + iCompare = -1; if( sqlite3aLTb[pOp->opcode] ){ VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3); goto jump_to_p2; } - iCompare = -1; - VVA_ONLY( iCompareIsInit = 1; ) }else{ + iCompare = 0; if( sqlite3aEQb[pOp->opcode] ){ VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3); goto jump_to_p2; } - iCompare = 0; - VVA_ONLY( iCompareIsInit = 1; ) } VdbeBranchTaken(0, (pOp->p5 & SQLITE_NULLEQ)?2:3); break; } if( (flags1 | flags3)&MEM_Null ){ @@ -92790,16 +89529,15 @@ }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. */ + iCompare = 1; /* Operands are not equal */ VdbeBranchTaken(2,3); if( pOp->p5 & SQLITE_JUMPIFNULL ){ goto jump_to_p2; } - iCompare = 1; /* Operands are not equal */ - VVA_ONLY( iCompareIsInit = 1; ) break; } }else{ /* Neither operand is NULL and we couldn't do the special high-speed ** integer comparison case. So do a general-case comparison. */ @@ -92806,26 +89544,26 @@ affinity = pOp->p5 & SQLITE_AFF_MASK; if( affinity>=SQLITE_AFF_NUMERIC ){ if( (flags1 | flags3)&MEM_Str ){ if( (flags1 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){ applyNumericAffinity(pIn1,0); - assert( flags3==pIn3->flags || CORRUPT_DB ); + testcase( flags3==pIn3->flags ); flags3 = pIn3->flags; } if( (flags3 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){ applyNumericAffinity(pIn3,0); } } - }else if( affinity==SQLITE_AFF_TEXT && ((flags1 | flags3) & MEM_Str)!=0 ){ + }else if( affinity==SQLITE_AFF_TEXT ){ if( (flags1 & MEM_Str)==0 && (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ testcase( pIn1->flags & MEM_Int ); testcase( pIn1->flags & MEM_Real ); testcase( pIn1->flags & MEM_IntReal ); sqlite3VdbeMemStringify(pIn1, encoding, 1); testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) ); flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask); - if( NEVER(pIn1==pIn3) ) flags3 = flags1 | MEM_Str; + if( pIn1==pIn3 ) flags3 = flags1 | MEM_Str; } if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ testcase( pIn3->flags & MEM_Int ); testcase( pIn3->flags & MEM_Real ); testcase( pIn3->flags & MEM_IntReal ); @@ -92852,11 +89590,10 @@ res2 = sqlite3aEQb[pOp->opcode]; }else{ res2 = sqlite3aGTb[pOp->opcode]; } iCompare = res; - VVA_ONLY( iCompareIsInit = 1; ) /* Undo any changes made by applyAffinity() to the input registers. */ assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) ); pIn3->flags = flags3; assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) ); @@ -92891,11 +89628,10 @@ if( aOp[iAddr].opcode==OP_ReleaseReg ) continue; assert( aOp[iAddr].opcode==OP_Lt || aOp[iAddr].opcode==OP_Gt ); break; } #endif /* SQLITE_DEBUG */ - assert( iCompareIsInit ); VdbeBranchTaken(iCompare==0, 2); if( iCompare==0 ) goto jump_to_p2; break; } @@ -92903,12 +89639,13 @@ /* Opcode: Permutation * * * P4 * ** ** Set the permutation used by the OP_Compare operator in the next ** instruction. The permutation is stored in the P4 operand. ** -** The permutation is only valid for the next opcode which must be -** an OP_Compare that has the OPFLAG_PERMUTE bit set in P5. +** The permutation is only valid until the next OP_Compare that has +** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should +** occur immediately prior to the OP_Compare. ** ** The first integer in the P4 integer array is the length of the array ** and does not become part of the permutation. */ case OP_Permutation: { @@ -92936,12 +89673,10 @@ ** 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. -** -** This opcode must be immediately followed by an OP_Jump opcode. */ case OP_Compare: { int n; int i; int p1; @@ -92986,11 +89721,10 @@ REGISTER_TRACE(p2+idx, &aMem[p2+idx]); assert( inKeyField ); pColl = pKeyInfo->aColl[i]; bRev = (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_DESC); iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl); - VVA_ONLY( iCompareIsInit = 1; ) if( iCompare ){ if( (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) && ((aMem[p1+idx].flags & MEM_Null) || (aMem[p2+idx].flags & MEM_Null)) ){ iCompare = -iCompare; @@ -92997,25 +89731,20 @@ } if( bRev ) iCompare = -iCompare; break; } } - assert( pOp[1].opcode==OP_Jump ); 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. -** -** This opcode must immediately follow an OP_Compare opcode. */ case OP_Jump: { /* jump */ - assert( pOp>aOp && pOp[-1].opcode==OP_Compare ); - assert( iCompareIsInit ); if( iCompare<0 ){ VdbeBranchTaken(0,4); pOp = &aOp[pOp->p1 - 1]; }else if( iCompare==0 ){ VdbeBranchTaken(1,4); pOp = &aOp[pOp->p2 - 1]; }else{ @@ -93211,100 +89940,23 @@ goto jump_to_p2; } break; } -/* Opcode: IsType P1 P2 P3 P4 P5 -** Synopsis: if typeof(P1.P3) in P5 goto P2 -** -** Jump to P2 if the type of a column in a btree is one of the types specified -** by the P5 bitmask. -** -** P1 is normally a cursor on a btree for which the row decode cache is -** valid through at least column P3. In other words, there should have been -** a prior OP_Column for column P3 or greater. If the cursor is not valid, -** then this opcode might give spurious results. -** The the btree row has fewer than P3 columns, then use P4 as the -** datatype. -** -** If P1 is -1, then P3 is a register number and the datatype is taken -** from the value in that register. -** -** P5 is a bitmask of data types. SQLITE_INTEGER is the least significant -** (0x01) bit. SQLITE_FLOAT is the 0x02 bit. SQLITE_TEXT is 0x04. -** SQLITE_BLOB is 0x08. SQLITE_NULL is 0x10. -** -** WARNING: This opcode does not reliably distinguish between NULL and REAL -** when P1>=0. If the database contains a NaN value, this opcode will think -** that the datatype is REAL when it should be NULL. When P1<0 and the value -** is already stored in register P3, then this opcode does reliably -** distinguish between NULL and REAL. The problem only arises then P1>=0. -** -** Take the jump to address P2 if and only if the datatype of the -** value determined by P1 and P3 corresponds to one of the bits in the -** P5 bitmask. -** -*/ -case OP_IsType: { /* jump */ - VdbeCursor *pC; - u16 typeMask; - u32 serialType; - - assert( pOp->p1>=(-1) && pOp->p1nCursor ); - assert( pOp->p1>=0 || (pOp->p3>=0 && pOp->p3<=(p->nMem+1 - p->nCursor)) ); - if( pOp->p1>=0 ){ - pC = p->apCsr[pOp->p1]; - assert( pC!=0 ); - assert( pOp->p3>=0 ); - if( pOp->p3nHdrParsed ){ - serialType = pC->aType[pOp->p3]; - if( serialType>=12 ){ - if( serialType&1 ){ - typeMask = 0x04; /* SQLITE_TEXT */ - }else{ - typeMask = 0x08; /* SQLITE_BLOB */ - } - }else{ - static const unsigned char aMask[] = { - 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x2, - 0x01, 0x01, 0x10, 0x10 - }; - testcase( serialType==0 ); - testcase( serialType==1 ); - testcase( serialType==2 ); - testcase( serialType==3 ); - testcase( serialType==4 ); - testcase( serialType==5 ); - testcase( serialType==6 ); - testcase( serialType==7 ); - testcase( serialType==8 ); - testcase( serialType==9 ); - testcase( serialType==10 ); - testcase( serialType==11 ); - typeMask = aMask[serialType]; - } - }else{ - typeMask = 1 << (pOp->p4.i - 1); - testcase( typeMask==0x01 ); - testcase( typeMask==0x02 ); - testcase( typeMask==0x04 ); - testcase( typeMask==0x08 ); - testcase( typeMask==0x10 ); - } - }else{ - assert( memIsValid(&aMem[pOp->p3]) ); - typeMask = 1 << (sqlite3_value_type((sqlite3_value*)&aMem[pOp->p3])-1); - testcase( typeMask==0x01 ); - testcase( typeMask==0x02 ); - testcase( typeMask==0x04 ); - testcase( typeMask==0x08 ); - testcase( typeMask==0x10 ); - } - VdbeBranchTaken( (typeMask & pOp->p5)!=0, 2); - if( typeMask & pOp->p5 ){ - goto jump_to_p2; - } +/* Opcode: IsNullOrType P1 P2 P3 * * +** Synopsis: if typeof(r[P1]) IN (P3,5) goto P2 +** +** Jump to P2 if the value in register P1 is NULL or has a datatype P3. +** P3 is an integer which should be one of SQLITE_INTEGER, SQLITE_FLOAT, +** SQLITE_BLOB, SQLITE_NULL, or SQLITE_TEXT. +*/ +case OP_IsNullOrType: { /* jump, in1 */ + int doTheJump; + pIn1 = &aMem[pOp->p1]; + doTheJump = (pIn1->flags & MEM_Null)!=0 || sqlite3_value_type(pIn1)==pOp->p3; + VdbeBranchTaken( doTheJump, 2); + if( doTheJump ) goto jump_to_p2; break; } /* Opcode: ZeroOrNull P1 P2 P3 * * ** Synopsis: r[P2] = 0 OR NULL @@ -93343,18 +89995,15 @@ ** ** Check the cursor P1 to see if it is currently pointing at a NULL row. ** If it is, then set register P3 to NULL and jump immediately to P2. ** If P1 is not on a NULL row, then fall through without making any ** changes. -** -** If P1 is not an open cursor, then this opcode is a no-op. */ case OP_IfNullRow: { /* jump */ - VdbeCursor *pC; assert( pOp->p1>=0 && pOp->p1nCursor ); - pC = p->apCsr[pOp->p1]; - if( ALWAYS(pC) && pC->nullRow ){ + assert( p->apCsr[pOp->p1]!=0 ); + if( p->apCsr[pOp->p1]->nullRow ){ sqlite3VdbeMemSetNull(aMem + pOp->p3); goto jump_to_p2; } break; } @@ -93396,35 +90045,33 @@ break; } #endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */ /* Opcode: Column P1 P2 P3 P4 P5 -** Synopsis: r[P3]=PX cursor P1 column P2 +** Synopsis: r[P3]=PX ** ** Interpret the data that cursor P1 points to as a structure built using ** the MakeRecord instruction. (See the MakeRecord opcode for additional ** information about the format of the data.) Extract the P2-th column -** from this record. If there are less than (P2+1) +** 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 record contains fewer than P2 fields, then extract a NULL. Or, ** if the P4 argument is a P4_MEM use the value of the P4 argument as ** the result. ** -** If the OPFLAG_LENGTHARG bit is set in P5 then the result is guaranteed -** to only be used by the length() function or the equivalent. The content -** of large blobs is not loaded, thus saving CPU cycles. If the -** OPFLAG_TYPEOFARG bit is set then the result will only be used by the -** typeof() function or the IS NULL or IS NOT NULL operators or the -** equivalent. In this case, all content loading can be omitted. +** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 then +** the result is guaranteed to only be used as the argument of a length() +** or typeof() function, respectively. The loading of large blobs can be +** skipped for length() and all content loading can be skipped for typeof(). */ -case OP_Column: { /* ncycle */ +case OP_Column: { u32 p2; /* column number to retrieve */ VdbeCursor *pC; /* The VDBE cursor */ - BtCursor *pCrsr; /* The B-Tree cursor corresponding to pC */ + BtCursor *pCrsr; /* The BTree cursor */ u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */ int len; /* The length of the serialized data for the column */ int i; /* Loop counter */ Mem *pDest; /* Where to write the extracted value */ Mem sMem; /* For storing the record being decoded */ @@ -93434,72 +90081,63 @@ u64 offset64; /* 64-bit offset */ u32 t; /* A type code from the record header */ Mem *pReg; /* PseudoTable input register */ assert( pOp->p1>=0 && pOp->p1nCursor ); - assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); p2 = (u32)pOp->p2; -op_column_restart: + /* If the cursor cache is stale (meaning it is not currently point at + ** the correct row) then bring it up-to-date by doing the necessary + ** B-Tree seek. */ + rc = sqlite3VdbeCursorMoveto(&pC, &p2); + if( rc ) goto abort_due_to_error; + + assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); + pDest = &aMem[pOp->p3]; + memAboutToChange(p, pDest); assert( pC!=0 ); - assert( p2<(u32)pC->nField - || (pC->eCurType==CURTYPE_PSEUDO && pC->seekResult==0) ); + assert( p2<(u32)pC->nField ); aOffset = pC->aOffset; assert( aOffset==pC->aType+pC->nField ); assert( pC->eCurType!=CURTYPE_VTAB ); assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow ); assert( pC->eCurType!=CURTYPE_SORTER ); if( pC->cacheStatus!=p->cacheCtr ){ /*OPTIMIZATION-IF-FALSE*/ if( pC->nullRow ){ - if( pC->eCurType==CURTYPE_PSEUDO && pC->seekResult>0 ){ + if( pC->eCurType==CURTYPE_PSEUDO ){ /* For the special case of as pseudo-cursor, the seekResult field ** identifies the register that holds the record */ + assert( pC->seekResult>0 ); pReg = &aMem[pC->seekResult]; assert( pReg->flags & MEM_Blob ); assert( memIsValid(pReg) ); pC->payloadSize = pC->szRow = pReg->n; pC->aRow = (u8*)pReg->z; }else{ - pDest = &aMem[pOp->p3]; - memAboutToChange(p, pDest); sqlite3VdbeMemSetNull(pDest); goto op_column_out; } }else{ pCrsr = pC->uc.pCursor; - if( pC->deferredMoveto ){ - u32 iMap; - assert( !pC->isEphemeral ); - if( pC->ub.aAltMap && (iMap = pC->ub.aAltMap[1+p2])>0 ){ - pC = pC->pAltCursor; - p2 = iMap - 1; - goto op_column_restart; - } - rc = sqlite3VdbeFinishMoveto(pC); - if( rc ) goto abort_due_to_error; - }else if( sqlite3BtreeCursorHasMoved(pCrsr) ){ - rc = sqlite3VdbeHandleMovedCursor(pC); - if( rc ) goto abort_due_to_error; - goto op_column_restart; - } assert( pC->eCurType==CURTYPE_BTREE ); assert( pCrsr ); assert( sqlite3BtreeCursorIsValid(pCrsr) ); pC->payloadSize = sqlite3BtreePayloadSize(pCrsr); pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &pC->szRow); assert( pC->szRow<=pC->payloadSize ); assert( pC->szRow<=65536 ); /* Maximum page size is 64KiB */ + if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ + goto too_big; + } } pC->cacheStatus = p->cacheCtr; - if( (aOffset[0] = pC->aRow[0])<0x80 ){ - pC->iHdrOffset = 1; - }else{ - pC->iHdrOffset = sqlite3GetVarint32(pC->aRow, aOffset); - } + pC->iHdrOffset = getVarint32(pC->aRow, aOffset[0]); pC->nHdrParsed = 0; + if( pC->szRowaRow does not have to hold the entire row, but it does at least ** need to cover the header of the record. If pC->aRow does not contain ** the complete header, then set it to zero, forcing the header to be @@ -93536,14 +90174,10 @@ zData = pC->aRow; assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */ testcase( aOffset[0]==0 ); goto op_column_read_header; } - }else if( sqlite3BtreeCursorHasMoved(pC->uc.pCursor) ){ - rc = sqlite3VdbeHandleMovedCursor(pC); - if( rc ) goto abort_due_to_error; - goto op_column_restart; } /* Make sure at least the first p2+1 entries of the header have been ** parsed and valid information is in aOffset[] and pC->aType[]. */ @@ -93608,12 +90242,10 @@ /* If after trying to extract new entries from the header, nHdrParsed is ** still not up to p2, that means that the record has fewer than p2 ** columns. So the result will be either the default value or a NULL. */ if( pC->nHdrParsed<=p2 ){ - pDest = &aMem[pOp->p3]; - memAboutToChange(p, pDest); if( pOp->p4type==P4_MEM ){ sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static); }else{ sqlite3VdbeMemSetNull(pDest); } @@ -93627,12 +90259,10 @@ ** reach this point if aOffset[p2], aOffset[p2+1], and pC->aType[p2] are ** all valid. */ assert( p2nHdrParsed ); assert( rc==SQLITE_OK ); - pDest = &aMem[pOp->p3]; - memAboutToChange(p, pDest); assert( sqlite3VdbeCheckMemInvariants(pDest) ); if( VdbeMemDynamic(pDest) ){ sqlite3VdbeMemSetNull(pDest); } assert( t==pC->aType[p2] ); @@ -93649,11 +90279,10 @@ */ static const u16 aFlag[] = { MEM_Blob, MEM_Str|MEM_Term }; pDest->n = len = (t-12)/2; pDest->enc = encoding; if( pDest->szMalloc < len+2 ){ - if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) goto too_big; pDest->flags = MEM_Null; if( sqlite3VdbeMemGrow(pDest, len+2, 0) ) goto no_mem; }else{ pDest->z = pDest->zMalloc; } @@ -93682,11 +90311,10 @@ ** as that array is 256 bytes long (plenty for VdbeMemPrettyPrint()) ** and it begins with a bunch of zeros. */ sqlite3VdbeSerialGet((u8*)sqlite3CtypeMap, t, pDest); }else{ - if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) goto too_big; rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest); if( rc!=SQLITE_OK ) goto abort_due_to_error; sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest); pDest->flags &= ~MEM_Ephem; } @@ -93766,11 +90394,11 @@ if( (pIn1->flags & MEM_Str)==0 ) goto vdbe_type_error; break; } case COLTYPE_REAL: { testcase( (pIn1->flags & (MEM_Real|MEM_IntReal))==MEM_Real ); - assert( (pIn1->flags & MEM_IntReal)==0 ); + testcase( (pIn1->flags & (MEM_Real|MEM_IntReal))==MEM_IntReal ); if( pIn1->flags & MEM_Int ){ /* When applying REAL affinity, if the result is still an MEM_Int ** that will fit in 6 bytes, then change the type to MEM_IntReal ** so that we keep the high-resolution integer value but know that ** the type really wants to be REAL. */ @@ -93895,10 +90523,11 @@ u32 serial_type; /* Type field */ Mem *pData0; /* First field to be combined into the record */ Mem *pLast; /* Last field of the record */ int nField; /* Number of fields in the record */ char *zAffinity; /* The affinity string for the record */ + int file_format; /* File format to use for encoding */ u32 len; /* Length of a field */ u8 *zHdr; /* Where to write next byte of the header */ u8 *zPayload; /* Where to write next byte of the payload */ /* Assuming the record contains N fields, the record format looks @@ -93923,10 +90552,11 @@ zAffinity = pOp->p4.z; assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem+1 - p->nCursor)+1 ); pData0 = &aMem[nField]; nField = pOp->p2; pLast = &pData0[nField-1]; + file_format = p->minWriteFileFormat; /* Identify the output register */ assert( pOp->p3p1 || pOp->p3>=pOp->p1+pOp->p2 ); pOut = &aMem[pOp->p3]; memAboutToChange(p, pOut); @@ -94024,11 +90654,11 @@ testcase( uu==32767 ); testcase( uu==32768 ); testcase( uu==8388607 ); testcase( uu==8388608 ); testcase( uu==2147483647 ); testcase( uu==2147483648LL ); testcase( uu==140737488355327LL ); testcase( uu==140737488355328LL ); if( uu<=127 ){ - if( (i&1)==i && p->minWriteFileFormat>=4 ){ + if( (i&1)==i && file_format>=4 ){ pRec->uTemp = 8+(u32)uu; }else{ nData++; pRec->uTemp = 1; } @@ -94129,64 +90759,22 @@ UPDATE_MAX_BLOBSIZE(pOut); zHdr = (u8 *)pOut->z; zPayload = zHdr + nHdr; /* Write the record */ - if( nHdr<0x80 ){ - *(zHdr++) = nHdr; - }else{ - zHdr += sqlite3PutVarint(zHdr,nHdr); - } + zHdr += putVarint32(zHdr, nHdr); assert( pData0<=pLast ); pRec = pData0; - while( 1 /*exit-by-break*/ ){ + do{ serial_type = pRec->uTemp; /* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more - ** additional varints, one per column. - ** EVIDENCE-OF: R-64536-51728 The values for each column in the record + ** additional varints, one per column. */ + zHdr += putVarint32(zHdr, serial_type); /* serial type */ + /* EVIDENCE-OF: R-64536-51728 The values for each column in the record ** immediately follow the header. */ - if( serial_type<=7 ){ - *(zHdr++) = serial_type; - if( serial_type==0 ){ - /* NULL value. No change in zPayload */ - }else{ - u64 v; - u32 i; - if( serial_type==7 ){ - assert( sizeof(v)==sizeof(pRec->u.r) ); - memcpy(&v, &pRec->u.r, sizeof(v)); - swapMixedEndianFloat(v); - }else{ - v = pRec->u.i; - } - len = i = sqlite3SmallTypeSizes[serial_type]; - assert( i>0 ); - while( 1 /*exit-by-break*/ ){ - zPayload[--i] = (u8)(v&0xFF); - if( i==0 ) break; - v >>= 8; - } - zPayload += len; - } - }else if( serial_type<0x80 ){ - *(zHdr++) = serial_type; - if( serial_type>=14 && pRec->n>0 ){ - assert( pRec->z!=0 ); - memcpy(zPayload, pRec->z, pRec->n); - zPayload += pRec->n; - } - }else{ - zHdr += sqlite3PutVarint(zHdr, serial_type); - if( pRec->n ){ - assert( pRec->z!=0 ); - memcpy(zPayload, pRec->z, pRec->n); - zPayload += pRec->n; - } - } - if( pRec==pLast ) break; - pRec++; - } + zPayload += sqlite3VdbeSerialPut(zPayload, pRec, serial_type); /* content */ + }while( (++pRec)<=pLast ); assert( nHdr==(int)(zHdr - (u8*)pOut->z) ); assert( nByte==(int)(zPayload - (u8*)pOut->z) ); assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); REGISTER_TRACE(pOp->p3, pOut); @@ -94401,14 +90989,11 @@ if( rc!=SQLITE_OK ) goto abort_due_to_error; } } } if( rc ) goto abort_due_to_error; - if( p->eVdbeState==VDBE_HALT_STATE ){ - rc = SQLITE_DONE; - goto vdbe_return; - } + break; } /* Opcode: AutoCommit P1 P2 * * * ** @@ -94508,11 +91093,10 @@ ** halts. The sqlite3_step() wrapper function might then reprepare the ** statement and rerun it from the beginning. */ case OP_Transaction: { Btree *pBt; - Db *pDb; int iMeta = 0; assert( p->bIsReader ); assert( p->readOnly==0 || pOp->p2==0 ); assert( pOp->p2>=0 && pOp->p2<=2 ); @@ -94528,12 +91112,11 @@ ** transaction */ rc = SQLITE_CORRUPT; } goto abort_due_to_error; } - pDb = &db->aDb[pOp->p1]; - pBt = pDb->pBt; + pBt = db->aDb[pOp->p1].pBt; if( pBt ){ rc = sqlite3BtreeBeginTrans(pBt, pOp->p2, &iMeta); testcase( rc==SQLITE_BUSY_SNAPSHOT ); testcase( rc==SQLITE_BUSY_RECOVERY ); @@ -94570,11 +91153,12 @@ } } assert( pOp->p5==0 || pOp->p4type==P4_INT32 ); if( rc==SQLITE_OK && pOp->p5 - && (iMeta!=pOp->p3 || pDb->pSchema->iGeneration!=pOp->p4.i) + && (iMeta!=pOp->p3 + || db->aDb[pOp->p1].pSchema->iGeneration!=pOp->p4.i) ){ /* ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema ** version is checked to ensure that the schema has not changed since the ** SQL statement was prepared. @@ -94597,15 +91181,10 @@ if( db->aDb[pOp->p1].pSchema->schema_cookie!=iMeta ){ sqlite3ResetOneSchema(db, pOp->p1); } p->expired = 1; rc = SQLITE_SCHEMA; - - /* Set changeCntOn to 0 to prevent the value returned by sqlite3_changes() - ** from being modified in sqlite3VdbeHalt(). If this statement is - ** reprepared, changeCntOn will be set again. */ - p->changeCntOn = 0; } if( rc ) goto abort_due_to_error; break; } @@ -94668,11 +91247,11 @@ assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); /* See note about index shifting on OP_ReadCookie */ rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, pOp->p3); if( pOp->p2==BTREE_SCHEMA_VERSION ){ /* When the schema cookie changes, record the new cookie internally */ - *(u32*)&pDb->pSchema->schema_cookie = *(u32*)&pOp->p3 - pOp->p5; + pDb->pSchema->schema_cookie = pOp->p3 - pOp->p5; db->mDbFlags |= DBFLAG_SchemaChange; sqlite3FkClearTriggerCache(db, pOp->p1); }else if( pOp->p2==BTREE_FILE_FORMAT ){ /* Record changes in the file format */ pDb->pSchema->file_format = pOp->p3; @@ -94769,11 +91348,11 @@ ** This instruction works like OpenRead except that it opens the cursor ** in read/write mode. ** ** See also: OP_OpenRead, OP_ReopenIdx */ -case OP_ReopenIdx: { /* ncycle */ +case OP_ReopenIdx: { int nField; KeyInfo *pKeyInfo; u32 p2; int iDb; int wrFlag; @@ -94790,11 +91369,11 @@ sqlite3BtreeClearCursor(pCur->uc.pCursor); goto open_cursor_set_hints; } /* If the cursor is not currently open or is open on a different ** index, then fall through into OP_OpenRead to force a reopen */ -case OP_OpenRead: /* ncycle */ +case OP_OpenRead: case OP_OpenWrite: assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ ); assert( p->bIsReader ); assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx @@ -94884,11 +91463,11 @@ ** cursor P2. The P2 cursor must have been opened by a prior OP_OpenEphemeral ** opcode. Only ephemeral cursors may be duplicated. ** ** Duplicate ephemeral cursors are used for self-joins of materialized views. */ -case OP_OpenDup: { /* ncycle */ +case OP_OpenDup: { VdbeCursor *pOrig; /* The original cursor to be duplicated */ VdbeCursor *pCx; /* The new cursor */ pOrig = p->apCsr[pOp->p2]; assert( pOrig ); @@ -94901,12 +91480,12 @@ pCx->pKeyInfo = pOrig->pKeyInfo; pCx->isTable = pOrig->isTable; pCx->pgnoRoot = pOrig->pgnoRoot; pCx->isOrdered = pOrig->isOrdered; pCx->ub.pBtx = pOrig->ub.pBtx; - pCx->noReuse = 1; - pOrig->noReuse = 1; + pCx->hasBeenDuped = 1; + pOrig->hasBeenDuped = 1; rc = sqlite3BtreeCursor(pCx->ub.pBtx, pCx->pgnoRoot, BTREE_WRCSR, pCx->pKeyInfo, pCx->uc.pCursor); /* The sqlite3BtreeCursor() routine can only fail for the first cursor ** opened for a database. Since there is already an open cursor when this ** opcode is run, the sqlite3BtreeCursor() cannot fail */ @@ -94946,12 +91525,12 @@ ** 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: /* ncycle */ -case OP_OpenEphemeral: { /* ncycle */ +case OP_OpenAutoindex: +case OP_OpenEphemeral: { VdbeCursor *pCx; KeyInfo *pKeyInfo; static const int vfsFlags = SQLITE_OPEN_READWRITE | @@ -94969,11 +91548,11 @@ assert( aMem[pOp->p3].flags & MEM_Null ); aMem[pOp->p3].n = 0; aMem[pOp->p3].z = ""; } pCx = p->apCsr[pOp->p1]; - if( pCx && !pCx->noReuse && ALWAYS(pOp->p2<=pCx->nField) ){ + if( pCx && !pCx->hasBeenDuped && ALWAYS(pOp->p2<=pCx->nField) ){ /* If the ephermeral table is already open and has no duplicates from ** OP_OpenDup, then erase all existing content so that the table is ** empty again, rather than creating a new table. */ assert( pCx->isEphemeral ); pCx->seqCount = 0; @@ -95105,11 +91684,11 @@ /* 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: { /* ncycle */ +case OP_Close: { assert( pOp->p1>=0 && pOp->p1nCursor ); sqlite3VdbeFreeCursor(p, p->apCsr[pOp->p1]); p->apCsr[pOp->p1] = 0; break; } @@ -95222,14 +91801,14 @@ ** OPFLAG_SEEKEQ flags is a hint to the btree layer to say that this ** is an equality search. ** ** See also: Found, NotFound, SeekGt, SeekGe, SeekLt */ -case OP_SeekLT: /* jump, in3, group, ncycle */ -case OP_SeekLE: /* jump, in3, group, ncycle */ -case OP_SeekGE: /* jump, in3, group, ncycle */ -case OP_SeekGT: { /* jump, in3, group, ncycle */ +case OP_SeekLT: /* jump, in3, group */ +case OP_SeekLE: /* jump, in3, group */ +case OP_SeekGE: /* jump, in3, group */ +case OP_SeekGT: { /* jump, in3, group */ int res; /* Comparison result */ int oc; /* Opcode */ VdbeCursor *pC; /* The cursor to seek */ UnpackedRecord r; /* The key to seek for */ int nField; /* Number of columns or fields in the key */ @@ -95354,17 +91933,11 @@ assert( oc!=OP_SeekGE || r.default_rc==+1 ); assert( oc!=OP_SeekLT || r.default_rc==+1 ); r.aMem = &aMem[pOp->p3]; #ifdef SQLITE_DEBUG - { - int i; - for(i=0; i0 ) REGISTER_TRACE(pOp->p3+i, &r.aMem[i]); - } - } + { int i; for(i=0; iuc.pCursor, &r, &res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; @@ -95423,105 +91996,72 @@ } break; } -/* Opcode: SeekScan P1 P2 * * P5 +/* Opcode: SeekScan P1 P2 * * * ** Synopsis: Scan-ahead up to P1 rows ** ** This opcode is a prefix opcode to OP_SeekGE. In other words, this ** opcode must be immediately followed by OP_SeekGE. This constraint is ** checked by assert() statements. ** ** This opcode uses the P1 through P4 operands of the subsequent ** OP_SeekGE. In the text that follows, the operands of the subsequent ** OP_SeekGE opcode are denoted as SeekOP.P1 through SeekOP.P4. Only -** the P1, P2 and P5 operands of this opcode are also used, and are called -** This.P1, This.P2 and This.P5. +** the P1 and P2 operands of this opcode are also used, and are called +** This.P1 and This.P2. ** ** This opcode helps to optimize IN operators on a multi-column index ** where the IN operator is on the later terms of the index by avoiding ** unnecessary seeks on the btree, substituting steps to the next row ** of the b-tree instead. A correct answer is obtained if this opcode ** is omitted or is a no-op. ** ** The SeekGE.P3 and SeekGE.P4 operands identify an unpacked key which ** is the desired entry that we want the cursor SeekGE.P1 to be pointing -** to. Call this SeekGE.P3/P4 row the "target". +** to. Call this SeekGE.P4/P5 row the "target". ** ** If the SeekGE.P1 cursor is not currently pointing to a valid row, ** then this opcode is a no-op and control passes through into the OP_SeekGE. ** ** If the SeekGE.P1 cursor is pointing to a valid row, then that row ** might be the target row, or it might be near and slightly before the -** target row, or it might be after the target row. If the cursor is -** currently before the target row, then this opcode attempts to position -** the cursor on or after the target row by invoking sqlite3BtreeStep() -** on the cursor between 1 and This.P1 times. -** -** The This.P5 parameter is a flag that indicates what to do if the -** cursor ends up pointing at a valid row that is past the target -** row. If This.P5 is false (0) then a jump is made to SeekGE.P2. If -** This.P5 is true (non-zero) then a jump is made to This.P2. The P5==0 -** case occurs when there are no inequality constraints to the right of -** the IN constraing. The jump to SeekGE.P2 ends the loop. The P5!=0 case -** occurs when there are inequality constraints to the right of the IN -** operator. In that case, the This.P2 will point either directly to or -** to setup code prior to the OP_IdxGT or OP_IdxGE opcode that checks for -** loop terminate. -** -** Possible outcomes from this opcode:
      -** -**
    1. If the cursor is initally not pointed to any valid row, then -** fall through into the subsequent OP_SeekGE opcode. -** -**
    2. If the cursor is left pointing to a row that is before the target -** row, even after making as many as This.P1 calls to -** sqlite3BtreeNext(), then also fall through into OP_SeekGE. -** -**
    3. If the cursor is left pointing at the target row, either because it -** was at the target row to begin with or because one or more -** sqlite3BtreeNext() calls moved the cursor to the target row, -** then jump to This.P2.., -** -**
    4. If the cursor started out before the target row and a call to -** to sqlite3BtreeNext() moved the cursor off the end of the index -** (indicating that the target row definitely does not exist in the -** btree) then jump to SeekGE.P2, ending the loop. -** -**
    5. If the cursor ends up on a valid row that is past the target row -** (indicating that the target row does not exist in the btree) then -** jump to SeekOP.P2 if This.P5==0 or to This.P2 if This.P5>0. +** target row. This opcode attempts to position the cursor on the target +** row by, perhaps by invoking sqlite3BtreeStep() on the cursor +** between 0 and This.P1 times. +** +** There are three possible outcomes from this opcode:
        +** +**
      1. If after This.P1 steps, the cursor is still pointing to a place that +** is earlier in the btree than the target row, then fall through +** into the subsquence OP_SeekGE opcode. +** +**
      2. If the cursor is successfully moved to the target row by 0 or more +** sqlite3BtreeNext() calls, then jump to This.P2, which will land just +** past the OP_IdxGT or OP_IdxGE opcode that follows the OP_SeekGE. +** +**
      3. If the cursor ends up past the target row (indicating the the target +** row does not exist in the btree) then jump to SeekOP.P2. **
      */ -case OP_SeekScan: { /* ncycle */ +case OP_SeekScan: { VdbeCursor *pC; int res; int nStep; UnpackedRecord r; assert( pOp[1].opcode==OP_SeekGE ); - /* If pOp->p5 is clear, then pOp->p2 points to the first instruction past the - ** OP_IdxGT that follows the OP_SeekGE. Otherwise, it points to the first - ** opcode past the OP_SeekGE itself. */ + /* pOp->p2 points to the first instruction past the OP_IdxGT that + ** follows the OP_SeekGE. */ assert( pOp->p2>=(int)(pOp-aOp)+2 ); -#ifdef SQLITE_DEBUG - if( pOp->p5==0 ){ - /* There are no inequality constraints following the IN constraint. */ - assert( pOp[1].p1==aOp[pOp->p2-1].p1 ); - assert( pOp[1].p2==aOp[pOp->p2-1].p2 ); - assert( pOp[1].p3==aOp[pOp->p2-1].p3 ); - assert( aOp[pOp->p2-1].opcode==OP_IdxGT - || aOp[pOp->p2-1].opcode==OP_IdxGE ); - testcase( aOp[pOp->p2-1].opcode==OP_IdxGE ); - }else{ - /* There are inequality constraints. */ - assert( pOp->p2==(int)(pOp-aOp)+2 ); - assert( aOp[pOp->p2-1].opcode==OP_SeekGE ); - } -#endif + assert( aOp[pOp->p2-1].opcode==OP_IdxGT || aOp[pOp->p2-1].opcode==OP_IdxGE ); + testcase( aOp[pOp->p2-1].opcode==OP_IdxGE ); + assert( pOp[1].p1==aOp[pOp->p2-1].p1 ); + assert( pOp[1].p2==aOp[pOp->p2-1].p2 ); + assert( pOp[1].p3==aOp[pOp->p2-1].p3 ); assert( pOp->p1>0 ); pC = p->apCsr[pOp[1].p1]; assert( pC!=0 ); assert( pC->eCurType==CURTYPE_BTREE ); @@ -95551,24 +92091,22 @@ #endif res = 0; /* Not needed. Only used to silence a warning. */ while(1){ rc = sqlite3VdbeIdxKeyCompare(db, pC, &r, &res); if( rc ) goto abort_due_to_error; - if( res>0 && pOp->p5==0 ){ + if( res>0 ){ seekscan_search_fail: - /* Jump to SeekGE.P2, ending the loop */ #ifdef SQLITE_DEBUG if( db->flags&SQLITE_VdbeTrace ){ printf("... %d steps and then skip\n", pOp->p1 - nStep); } #endif VdbeBranchTaken(1,3); pOp++; goto jump_to_p2; } - if( res>=0 ){ - /* Jump to This.P2, bypassing the OP_SeekGE opcode */ + if( res==0 ){ #ifdef SQLITE_DEBUG if( db->flags&SQLITE_VdbeTrace ){ printf("... %d steps and then success\n", pOp->p1 - nStep); } #endif @@ -95584,11 +92122,10 @@ #endif VdbeBranchTaken(0,3); break; } nStep--; - pC->cacheStatus = CACHE_STALE; rc = sqlite3BtreeNext(pC->uc.pCursor, 0); if( rc ){ if( rc==SQLITE_DONE ){ rc = SQLITE_OK; goto seekscan_search_fail; @@ -95614,11 +92151,11 @@ ** OP_IfNoHope opcode might run to see if the IN loop can be abandoned ** early, thus saving work. This is part of the IN-early-out optimization. ** ** P1 must be a valid b-tree cursor. */ -case OP_SeekHit: { /* ncycle */ +case OP_SeekHit: { VdbeCursor *pC; assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pOp->p3>=pOp->p2 ); @@ -95641,20 +92178,16 @@ } /* Opcode: IfNotOpen P1 P2 * * * ** Synopsis: if( !csr[P1] ) goto P2 ** -** If cursor P1 is not open or if P1 is set to a NULL row using the -** OP_NullRow opcode, then jump to instruction P2. Otherwise, fall through. +** If cursor P1 is not open, jump to instruction P2. Otherwise, fall through. */ case OP_IfNotOpen: { /* jump */ - VdbeCursor *pCur; - assert( pOp->p1>=0 && pOp->p1nCursor ); - pCur = p->apCsr[pOp->p1]; - VdbeBranchTaken(pCur==0 || pCur->nullRow, 2); - if( pCur==0 || pCur->nullRow ){ + VdbeBranchTaken(p->apCsr[pOp->p1]==0, 2); + if( !p->apCsr[pOp->p1] ){ goto jump_to_p2_and_check_for_interrupt; } break; } @@ -95746,11 +92279,11 @@ ** advanced in either direction. In other words, the Next and Prev ** opcodes do not work after this operation. ** ** See also: NotFound, Found, NotExists */ -case OP_IfNoHope: { /* jump, in3, ncycle */ +case OP_IfNoHope: { /* jump, in3 */ VdbeCursor *pC; assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); #ifdef SQLITE_DEBUG @@ -95760,16 +92293,19 @@ #endif if( pC->seekHit>=pOp->p4.i ) break; /* Fall through into OP_NotFound */ /* no break */ deliberate_fall_through } -case OP_NoConflict: /* jump, in3, ncycle */ -case OP_NotFound: /* jump, in3, ncycle */ -case OP_Found: { /* jump, in3, ncycle */ +case OP_NoConflict: /* jump, in3 */ +case OP_NotFound: /* jump, in3 */ +case OP_Found: { /* jump, in3 */ int alreadyExists; + int takeJump; int ii; VdbeCursor *pC; + int res; + UnpackedRecord *pFree; UnpackedRecord *pIdxKey; UnpackedRecord r; #ifdef SQLITE_TEST if( pOp->opcode!=OP_NoConflict ) sqlite3_found_count++; @@ -95780,71 +92316,66 @@ pC = p->apCsr[pOp->p1]; assert( pC!=0 ); #ifdef SQLITE_DEBUG pC->seekOp = pOp->opcode; #endif - r.aMem = &aMem[pOp->p3]; + pIn3 = &aMem[pOp->p3]; assert( pC->eCurType==CURTYPE_BTREE ); assert( pC->uc.pCursor!=0 ); assert( pC->isTable==0 ); - r.nField = (u16)pOp->p4.i; - if( r.nField>0 ){ - /* Key values in an array of registers */ + if( pOp->p4.i>0 ){ r.pKeyInfo = pC->pKeyInfo; - r.default_rc = 0; + r.nField = (u16)pOp->p4.i; + r.aMem = pIn3; #ifdef SQLITE_DEBUG for(ii=0; iip3+ii, &r.aMem[ii]); } #endif - rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, &r, &pC->seekResult); + pIdxKey = &r; + pFree = 0; }else{ - /* Composite key generated by OP_MakeRecord */ - assert( r.aMem->flags & MEM_Blob ); - assert( pOp->opcode!=OP_NoConflict ); - rc = ExpandBlob(r.aMem); + assert( pIn3->flags & MEM_Blob ); + rc = ExpandBlob(pIn3); assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); if( rc ) goto no_mem; - pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo); + pFree = pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo); if( pIdxKey==0 ) goto no_mem; - sqlite3VdbeRecordUnpack(pC->pKeyInfo, r.aMem->n, r.aMem->z, pIdxKey); - pIdxKey->default_rc = 0; - rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &pC->seekResult); - sqlite3DbFreeNN(db, pIdxKey); + sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey); } + pIdxKey->default_rc = 0; + takeJump = 0; + if( pOp->opcode==OP_NoConflict ){ + /* For the OP_NoConflict opcode, take the jump if any of the + ** input fields are NULL, since any key with a NULL will not + ** conflict */ + for(ii=0; iinField; ii++){ + if( pIdxKey->aMem[ii].flags & MEM_Null ){ + takeJump = 1; + break; + } + } + } + rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &res); + if( pFree ) sqlite3DbFreeNN(db, pFree); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } - alreadyExists = (pC->seekResult==0); + pC->seekResult = res; + alreadyExists = (res==0); pC->nullRow = 1-alreadyExists; pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; if( pOp->opcode==OP_Found ){ VdbeBranchTaken(alreadyExists!=0,2); if( alreadyExists ) goto jump_to_p2; }else{ - if( !alreadyExists ){ - VdbeBranchTaken(1,2); - goto jump_to_p2; - } - if( pOp->opcode==OP_NoConflict ){ - /* For the OP_NoConflict opcode, take the jump if any of the - ** input fields are NULL, since any key with a NULL will not - ** conflict */ - for(ii=0; iiopcode==OP_IfNoHope ){ - pC->seekHit = pOp->p4.i; - } + VdbeBranchTaken(takeJump||alreadyExists==0,2); + if( takeJump || !alreadyExists ) goto jump_to_p2; + if( pOp->opcode==OP_IfNoHope ) pC->seekHit = pOp->p4.i; } break; } /* Opcode: SeekRowid P1 P2 P3 * * @@ -95892,11 +92423,11 @@ ** in either direction. In other words, the Next and Prev opcodes will ** not work following this opcode. ** ** See also: Found, NotFound, NoConflict, SeekRowid */ -case OP_SeekRowid: { /* jump, in3, ncycle */ +case OP_SeekRowid: { /* jump, in3 */ VdbeCursor *pC; BtCursor *pCrsr; int res; u64 iKey; @@ -95917,11 +92448,11 @@ iKey = x.u.i; goto notExistsWithKey; } /* Fall through into OP_NotExists */ /* no break */ deliberate_fall_through -case OP_NotExists: /* jump, in3, ncycle */ +case OP_NotExists: /* jump, in3 */ pIn3 = &aMem[pOp->p3]; assert( (pIn3->flags & MEM_Int)!=0 || pOp->opcode==OP_SeekRowid ); assert( pOp->p1>=0 && pOp->p1nCursor ); iKey = pIn3->u.i; notExistsWithKey: @@ -96197,15 +92728,12 @@ } } if( pOp->p5 & OPFLAG_ISNOOP ) break; #endif - assert( (pOp->p5 & OPFLAG_LASTROWID)==0 || (pOp->p5 & OPFLAG_NCHANGE)!=0 ); - if( pOp->p5 & OPFLAG_NCHANGE ){ - p->nChange++; - if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey; - } + if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; + if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey; assert( (pData->flags & (MEM_Blob|MEM_Str))!=0 || pData->n==0 ); x.pData = pData->z; x.nData = pData->n; seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0); if( pData->flags & MEM_Zero ){ @@ -96212,11 +92740,10 @@ x.nZero = pData->u.nZero; }else{ x.nZero = 0; } x.pKey = 0; - assert( BTREE_PREFORMAT==OPFLAG_PREFORMAT ); rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)), seekResult ); pC->deferredMoveto = 0; @@ -96535,20 +93062,20 @@ REGISTER_TRACE(pOp->p2, pOut); break; } /* Opcode: Rowid P1 P2 * * * -** Synopsis: r[P2]=PX rowid of P1 +** Synopsis: r[P2]=rowid ** ** 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, ncycle */ +case OP_Rowid: { /* out2 */ VdbeCursor *pC; i64 v; sqlite3_vtab *pVtab; const sqlite3_module *pModule; @@ -96591,28 +93118,20 @@ ** ** 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. ** -** If cursor P1 is not previously opened, open it now to a special -** pseudo-cursor that always returns NULL for every column. +** Or, if P1 is a Pseudo-Cursor (a cursor opened using OP_OpenPseudo) +** just reset the cache for that cursor. This causes the row of +** content held by the pseudo-cursor to be reparsed. */ case OP_NullRow: { VdbeCursor *pC; assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; - if( pC==0 ){ - /* If the cursor is not already open, create a special kind of - ** pseudo-cursor that always gives null rows. */ - pC = allocateCursor(p, pOp->p1, 1, CURTYPE_PSEUDO); - if( pC==0 ) goto no_mem; - pC->seekResult = 0; - pC->isTable = 1; - pC->noReuse = 1; - pC->uc.pCursor = sqlite3BtreeFakeValidCursor(); - } + assert( pC!=0 ); pC->nullRow = 1; pC->cacheStatus = CACHE_STALE; if( pC->eCurType==CURTYPE_BTREE ){ assert( pC->uc.pCursor!=0 ); sqlite3BtreeClearCursor(pC->uc.pCursor); @@ -96643,12 +93162,12 @@ ** ** This opcode leaves the cursor configured to move in reverse order, ** from the end toward the beginning. In other words, the cursor is ** configured to use Prev, not Next. */ -case OP_SeekEnd: /* ncycle */ -case OP_Last: { /* jump, ncycle */ +case OP_SeekEnd: +case OP_Last: { /* jump */ VdbeCursor *pC; BtCursor *pCrsr; int res; assert( pOp->p1>=0 && pOp->p1nCursor ); @@ -96745,26 +93264,21 @@ ** will refer to the first entry in the database table or index. ** If the table or index is empty, jump immediately to P2. ** If the table or index is not empty, fall through to the following ** instruction. ** -** If P2 is zero, that is an assertion that the P1 table is never -** empty and hence the jump will never be taken. -** ** This opcode leaves the cursor configured to move in forward order, ** from the beginning toward the end. In other words, the cursor is ** configured to use Next, not Prev. */ -case OP_Rewind: { /* jump, ncycle */ +case OP_Rewind: { /* jump */ VdbeCursor *pC; BtCursor *pCrsr; int res; assert( pOp->p1>=0 && pOp->p1nCursor ); assert( pOp->p5==0 ); - assert( pOp->p2>=0 && pOp->p2nOp ); - pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) ); res = 1; #ifdef SQLITE_DEBUG @@ -96780,18 +93294,17 @@ pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; } if( rc ) goto abort_due_to_error; pC->nullRow = (u8)res; - if( pOp->p2>0 ){ - VdbeBranchTaken(res!=0,2); - if( res ) goto jump_to_p2; - } + assert( pOp->p2>0 && pOp->p2nOp ); + VdbeBranchTaken(res!=0,2); + if( res ) goto jump_to_p2; break; } -/* Opcode: Next P1 P2 P3 * P5 +/* Opcode: Next P1 P2 P3 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. @@ -96805,17 +93318,20 @@ ** ** The P3 value is a hint to the btree implementation. If P3==1, that ** means P1 is an SQL index and that this instruction could have been ** omitted if that index had been unique. P3 is usually 0. P3 is ** always either 0 or 1. +** +** P4 is always of type P4_ADVANCE. The function pointer points to +** sqlite3BtreeNext(). ** ** 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 P3 * P5 +/* Opcode: Prev P1 P2 P3 P4 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. @@ -96830,10 +93346,13 @@ ** ** The P3 value is a hint to the btree implementation. If P3==1, that ** means P1 is an SQL index and that this instruction could have been ** omitted if that index had been unique. P3 is usually 0. P3 is ** always either 0 or 1. +** +** P4 is always of type P4_ADVANCE. The function pointer points to +** sqlite3BtreePrevious(). ** ** If P5 is positive and the jump is taken, then event counter ** number P5-1 in the prepared statement is incremented. */ /* Opcode: SorterNext P1 P2 * * P5 @@ -96848,41 +93367,34 @@ pC = p->apCsr[pOp->p1]; assert( isSorter(pC) ); rc = sqlite3VdbeSorterNext(db, pC); goto next_tail; - -case OP_Prev: /* jump, ncycle */ - assert( pOp->p1>=0 && pOp->p1nCursor ); - assert( pOp->p5==0 - || pOp->p5==SQLITE_STMTSTATUS_FULLSCAN_STEP - || pOp->p5==SQLITE_STMTSTATUS_AUTOINDEX); - pC = p->apCsr[pOp->p1]; - assert( pC!=0 ); - assert( pC->deferredMoveto==0 ); - assert( pC->eCurType==CURTYPE_BTREE ); - assert( pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE - || pC->seekOp==OP_Last || pC->seekOp==OP_IfNoHope - || pC->seekOp==OP_NullRow); - rc = sqlite3BtreePrevious(pC->uc.pCursor, pOp->p3); - goto next_tail; - -case OP_Next: /* jump, ncycle */ - assert( pOp->p1>=0 && pOp->p1nCursor ); - assert( pOp->p5==0 - || pOp->p5==SQLITE_STMTSTATUS_FULLSCAN_STEP - || pOp->p5==SQLITE_STMTSTATUS_AUTOINDEX); - pC = p->apCsr[pOp->p1]; - assert( pC!=0 ); - assert( pC->deferredMoveto==0 ); - assert( pC->eCurType==CURTYPE_BTREE ); - assert( pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE - || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found - || pC->seekOp==OP_NullRow|| pC->seekOp==OP_SeekRowid - || pC->seekOp==OP_IfNoHope); - rc = sqlite3BtreeNext(pC->uc.pCursor, pOp->p3); - +case OP_Prev: /* jump */ +case OP_Next: /* jump */ + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( pOp->p5aCounter) ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->deferredMoveto==0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); + assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); + + /* The Next opcode is only used after SeekGT, SeekGE, Rewind, and Found. + ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */ + assert( pOp->opcode!=OP_Next + || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE + || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found + || pC->seekOp==OP_NullRow|| pC->seekOp==OP_SeekRowid + || pC->seekOp==OP_IfNoHope); + assert( pOp->opcode!=OP_Prev + || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE + || pC->seekOp==OP_Last || pC->seekOp==OP_IfNoHope + || pC->seekOp==OP_NullRow); + + rc = pOp->p4.xAdvance(pC->uc.pCursor, pOp->p3); next_tail: pC->cacheStatus = CACHE_STALE; VdbeBranchTaken(rc==SQLITE_OK,2); if( rc==SQLITE_OK ){ pC->nullRow = 0; @@ -97056,33 +93568,33 @@ ** 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_DeferredSeek: /* ncycle */ -case OP_IdxRowid: { /* out2, ncycle */ +case OP_DeferredSeek: +case OP_IdxRowid: { /* out2 */ VdbeCursor *pC; /* The P1 index cursor */ VdbeCursor *pTabCur; /* The P2 table cursor (OP_DeferredSeek only) */ i64 rowid; /* Rowid that P1 current points to */ assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); - assert( pC->eCurType==CURTYPE_BTREE || IsNullCursor(pC) ); + assert( pC->eCurType==CURTYPE_BTREE ); assert( pC->uc.pCursor!=0 ); - assert( pC->isTable==0 || IsNullCursor(pC) ); + assert( pC->isTable==0 ); assert( pC->deferredMoveto==0 ); assert( !pC->nullRow || pOp->opcode==OP_IdxRowid ); /* The IdxRowid and Seek opcodes are combined because of the commonality ** of sqlite3VdbeCursorRestore() and sqlite3VdbeIdxRowid(). */ rc = sqlite3VdbeCursorRestore(pC); - /* sqlite3VdbeCursorRestore() may fail if the cursor has been disturbed - ** since it was last positioned and an error (e.g. OOM or an IO error) - ** occurs while trying to reposition it. */ - if( rc!=SQLITE_OK ) goto abort_due_to_error; + /* sqlite3VbeCursorRestore() can only fail if the record has been deleted + ** out from under the cursor. That will never happens for an IdxRowid + ** or Seek opcode */ + if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; if( !pC->nullRow ){ rowid = 0; /* Not needed. Only used to silence a warning. */ rc = sqlite3VdbeIdxRowid(db, pC->uc.pCursor, &rowid); if( rc!=SQLITE_OK ){ @@ -97096,11 +93608,10 @@ assert( pTabCur->uc.pCursor!=0 ); assert( pTabCur->isTable ); pTabCur->nullRow = 0; pTabCur->movetoTarget = rowid; pTabCur->deferredMoveto = 1; - pTabCur->cacheStatus = CACHE_STALE; assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 ); assert( !pTabCur->isEphemeral ); pTabCur->ub.aAltMap = pOp->p4.ai; assert( !pC->isEphemeral ); pTabCur->pAltCursor = pC; @@ -97119,12 +93630,12 @@ ** ** If cursor P1 was previously moved via OP_DeferredSeek, complete that ** seek operation now, without further delay. If the cursor seek has ** already occurred, this instruction is a no-op. */ -case OP_FinishSeek: { /* ncycle */ - VdbeCursor *pC; /* The P1 index cursor */ +case OP_FinishSeek: { + VdbeCursor *pC; /* The P1 index cursor */ assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; if( pC->deferredMoveto ){ rc = sqlite3VdbeFinishMoveto(pC); @@ -97175,14 +93686,14 @@ ** ROWID on the P1 index. ** ** If the P1 index entry is less than or equal to the key value then jump ** to P2. Otherwise fall through to the next instruction. */ -case OP_IdxLE: /* jump, ncycle */ -case OP_IdxGT: /* jump, ncycle */ -case OP_IdxLT: /* jump, ncycle */ -case OP_IdxGE: { /* jump, ncycle */ +case OP_IdxLE: /* jump */ +case OP_IdxGT: /* jump */ +case OP_IdxLT: /* jump */ +case OP_IdxGE: { /* jump */ VdbeCursor *pC; int res; UnpackedRecord r; assert( pOp->p1>=0 && pOp->p1nCursor ); @@ -97231,11 +93742,11 @@ } sqlite3VdbeMemInit(&m, db, 0); rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m); if( rc ) goto abort_due_to_error; res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, &r, 0); - sqlite3VdbeMemReleaseMalloc(&m); + sqlite3VdbeMemRelease(&m); } /* End of inlined sqlite3VdbeIdxKeyCompare() */ assert( (OP_IdxLE&1)==(OP_IdxLT&1) && (OP_IdxGE&1)==(OP_IdxGT&1) ); if( (pOp->opcode&1)==(OP_IdxLT&1) ){ @@ -97589,18 +94100,17 @@ assert( (pnErr->flags & MEM_Int)!=0 ); assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 ); pIn1 = &aMem[pOp->p1]; assert( pOp->p5nDb ); assert( DbMaskTest(p->btreeMask, pOp->p5) ); - rc = sqlite3BtreeIntegrityCheck(db, db->aDb[pOp->p5].pBt, &aRoot[1], nRoot, - (int)pnErr->u.i+1, &nErr, &z); + z = sqlite3BtreeIntegrityCheck(db, db->aDb[pOp->p5].pBt, &aRoot[1], nRoot, + (int)pnErr->u.i+1, &nErr); sqlite3VdbeMemSetNull(pIn1); if( nErr==0 ){ assert( z==0 ); - }else if( rc ){ - sqlite3_free(z); - goto abort_due_to_error; + }else if( z==0 ){ + goto no_mem; }else{ pnErr->u.i -= nErr-1; sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free); } UPDATE_MAX_BLOBSIZE(pIn1); @@ -97800,10 +94310,13 @@ pFrame->apCsr = p->apCsr; pFrame->nCursor = p->nCursor; pFrame->aOp = p->aOp; pFrame->nOp = p->nOp; pFrame->token = pProgram->token; +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + pFrame->anExec = p->anExec; +#endif #ifdef SQLITE_DEBUG pFrame->iFrameMagic = SQLITE_FRAME_MAGIC; #endif pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem]; @@ -97836,10 +94349,13 @@ p->apCsr = (VdbeCursor **)&aMem[p->nMem]; pFrame->aOnce = (u8*)&p->apCsr[pProgram->nCsr]; memset(pFrame->aOnce, 0, (pProgram->nOp + 7)/8); p->aOp = aOp = pProgram->aOp; p->nOp = pProgram->nOp; +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + p->anExec = 0; +#endif #ifdef SQLITE_DEBUG /* Verify that second and subsequent executions of the same trigger do not ** try to reuse register values from the first use. */ { int i; @@ -97975,11 +94491,11 @@ /* Opcode: OffsetLimit P1 P2 P3 * * ** Synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) ** ** This opcode performs a commonly used computation associated with -** LIMIT and OFFSET processing. r[P1] holds the limit counter. r[P3] +** LIMIT and OFFSET process. r[P1] holds the limit counter. r[P3] ** holds the offset counter. The opcode computes the combined value ** of the LIMIT and OFFSET and stores that value in r[P2]. The r[P2] ** value computed is the total number of rows that will need to be ** visited in order to complete the query. ** @@ -98107,11 +94623,10 @@ pCtx->pFunc = pOp->p4.pFunc; pCtx->iOp = (int)(pOp - aOp); pCtx->pVdbe = p; pCtx->skipFlag = 0; pCtx->isError = 0; - pCtx->enc = encoding; pCtx->argc = n; pOp->p4type = P4_FUNCCTX; pOp->p4.pCtx = pCtx; /* OP_AggInverse must have P1==1 and OP_AggStep must have P1==0 */ @@ -98237,11 +94752,13 @@ sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem)); goto abort_due_to_error; } sqlite3VdbeChangeEncoding(pMem, encoding); UPDATE_MAX_BLOBSIZE(pMem); - REGISTER_TRACE((int)(pMem-aMem), pMem); + if( sqlite3VdbeMemTooBig(pMem) ){ + goto too_big; + } break; } #ifndef SQLITE_OMIT_WAL /* Opcode: Checkpoint P1 P2 P3 * * @@ -98593,11 +95110,11 @@ ** ** P4 is a pointer to a virtual table object, an sqlite3_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: { /* ncycle */ +case OP_VOpen: { VdbeCursor *pCur; sqlite3_vtab_cursor *pVCur; sqlite3_vtab *pVtab; const sqlite3_module *pModule; @@ -98640,11 +95157,11 @@ ** can be used as the first argument to sqlite3_vtab_in_first() and ** sqlite3_vtab_in_next() to extract all of the values stored in the P1 ** cursor. Register P3 is used to hold the values returned by ** sqlite3_vtab_in_first() and sqlite3_vtab_in_next(). */ -case OP_VInitIn: { /* out2, ncycle */ +case OP_VInitIn: { /* out2 */ VdbeCursor *pC; /* The cursor containing the RHS values */ ValueList *pRhs; /* New ValueList object to put in reg[P2] */ pC = p->apCsr[pOp->p1]; pRhs = sqlite3_malloc64( sizeof(*pRhs) ); @@ -98651,11 +95168,11 @@ if( pRhs==0 ) goto no_mem; pRhs->pCsr = pC->uc.pCursor; pRhs->pOut = &aMem[pOp->p3]; pOut = out2Prerelease(p, pOp); pOut->flags = MEM_Null; - sqlite3VdbeMemSetPointer(pOut, pRhs, "ValueList", sqlite3VdbeValueListFree); + sqlite3VdbeMemSetPointer(pOut, pRhs, "ValueList", sqlite3_free); break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -98677,11 +95194,11 @@ ** 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, ncycle */ +case OP_VFilter: { /* jump */ int nArg; int iQuery; const sqlite3_module *pModule; Mem *pQuery; Mem *pArgc; @@ -98737,32 +95254,31 @@ ** function to return true inside the xColumn method of the virtual ** table implementation. The P5 column might also contain other ** bits (OPFLAG_LENGTHARG or OPFLAG_TYPEOFARG) but those bits are ** unused by OP_VColumn. */ -case OP_VColumn: { /* ncycle */ +case OP_VColumn: { sqlite3_vtab *pVtab; const sqlite3_module *pModule; Mem *pDest; sqlite3_context sContext; VdbeCursor *pCur = p->apCsr[pOp->p1]; assert( pCur!=0 ); + assert( pCur->eCurType==CURTYPE_VTAB ); assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); pDest = &aMem[pOp->p3]; memAboutToChange(p, pDest); if( pCur->nullRow ){ sqlite3VdbeMemSetNull(pDest); break; } - assert( pCur->eCurType==CURTYPE_VTAB ); pVtab = pCur->uc.pVCur->pVtab; pModule = pVtab->pModule; assert( pModule->xColumn ); memset(&sContext, 0, sizeof(sContext)); sContext.pOut = pDest; - sContext.enc = encoding; assert( pOp->p5==OPFLAG_NOCHNG || pOp->p5==0 ); if( pOp->p5 & OPFLAG_NOCHNG ){ sqlite3VdbeMemSetNull(pDest); pDest->flags = MEM_Null|MEM_Zero; pDest->u.nZero = 0; @@ -98777,10 +95293,13 @@ } sqlite3VdbeChangeEncoding(pDest, encoding); REGISTER_TRACE(pOp->p3, pDest); UPDATE_MAX_BLOBSIZE(pDest); + if( sqlite3VdbeMemTooBig(pDest) ){ + goto too_big; + } if( rc ) goto abort_due_to_error; break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -98789,11 +95308,11 @@ ** ** 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, ncycle */ +case OP_VNext: { /* jump */ sqlite3_vtab *pVtab; const sqlite3_module *pModule; int res; VdbeCursor *pCur; @@ -99043,11 +95562,10 @@ ** reinitializes the relavant parts of the sqlite3_context object */ pOut = &aMem[pOp->p3]; if( pCtx->pOut != pOut ){ pCtx->pVdbe = p; pCtx->pOut = pOut; - pCtx->enc = encoding; for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i]; } assert( pCtx->pVdbe==p ); memAboutToChange(p, pOut); @@ -99070,31 +95588,21 @@ sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1); pCtx->isError = 0; if( rc ) goto abort_due_to_error; } - assert( (pOut->flags&MEM_Str)==0 - || pOut->enc==encoding - || db->mallocFailed ); - assert( !sqlite3VdbeMemTooBig(pOut) ); + /* Copy the result of the function into register P3 */ + if( pOut->flags & (MEM_Str|MEM_Blob) ){ + sqlite3VdbeChangeEncoding(pOut, encoding); + if( sqlite3VdbeMemTooBig(pOut) ) goto too_big; + } REGISTER_TRACE(pOp->p3, pOut); UPDATE_MAX_BLOBSIZE(pOut); break; } -/* Opcode: ClrSubtype P1 * * * * -** Synopsis: r[P1].subtype = 0 -** -** Clear the subtype from register P1. -*/ -case OP_ClrSubtype: { /* in1 */ - pIn1 = &aMem[pOp->p1]; - pIn1->flags &= ~MEM_Subtype; - break; -} - /* Opcode: FilterAdd P1 * P3 P4 * ** Synopsis: filter(P1) += key(P3@P4) ** ** Compute a hash on the P4 registers starting with r[P3] and ** add that hash to the bloom filter contained in r[P1]. @@ -99210,11 +95718,11 @@ /* OP_Init is always instruction 0 */ assert( pOp==p->aOp || pOp->opcode==OP_Trace ); #ifndef SQLITE_OMIT_TRACE if( (db->mTrace & (SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0 - && p->minWriteFileFormat!=254 /* tag-20220401a */ + && !p->doingRerun && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){ #ifndef SQLITE_OMIT_DEPRECATED if( db->mTrace & SQLITE_TRACE_LEGACY ){ char *z = sqlite3VdbeExpandSql(p, zTrace); @@ -99372,17 +95880,15 @@ ** readability. From this point on down, the normal indentation rules are ** restored. *****************************************************************************/ } -#if defined(VDBE_PROFILE) - *pnCycle += sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime(); - pnCycle = 0; -#elif defined(SQLITE_ENABLE_STMT_SCANSTATUS) - if( pnCycle ){ - *pnCycle += sqlite3Hwtime(); - pnCycle = 0; +#ifdef VDBE_PROFILE + { + u64 endTime = sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime(); + if( endTime>start ) pOrigOp->cycles += endTime - start; + pOrigOp->cnt++; } #endif /* The following code adds nothing to the actual functionality ** of the program. It is only here for testing and debugging. @@ -99441,11 +95947,11 @@ p->rc = rc; sqlite3SystemError(db, rc); testcase( sqlite3GlobalConfig.xLog!=0 ); sqlite3_log(rc, "statement aborts at %d: [%s] %s", (int)(pOp - aOp), p->zSql, p->zErrMsg); - if( p->eVdbeState==VDBE_RUN_STATE ) sqlite3VdbeHalt(p); + sqlite3VdbeHalt(p); if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db); if( rc==SQLITE_CORRUPT && db->autoCommit==0 ){ db->flags |= SQLITE_CorruptRdOnly; } rc = SQLITE_ERROR; @@ -99455,22 +95961,10 @@ /* 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: -#if defined(VDBE_PROFILE) - if( pnCycle ){ - *pnCycle += sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime(); - pnCycle = 0; - } -#elif defined(SQLITE_ENABLE_STMT_SCANSTATUS) - if( pnCycle ){ - *pnCycle += sqlite3Hwtime(); - pnCycle = 0; - } -#endif - #ifndef SQLITE_OMIT_PROGRESS_CALLBACK while( nVmStep>=nProgressLimit && db->xProgress!=0 ){ nProgressLimit += db->nProgressOps; if( db->xProgress(db->pProgressArg) ){ nProgressLimit = LARGEST_UINT64; @@ -99478,13 +95972,11 @@ goto abort_due_to_error; } } #endif p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep; - if( DbMaskNonZero(p->lockMask) ){ - sqlite3VdbeLeave(p); - } + sqlite3VdbeLeave(p); assert( rc!=SQLITE_OK || nExtraDelete==0 || sqlite3_strlike("DELETE%",p->zSql,0)!=0 ); return rc; @@ -102887,13 +99379,10 @@ "subprog TEXT," "stmt HIDDEN" ");" }; - (void)argc; - (void)argv; - (void)pzErr; rc = sqlite3_declare_vtab(db, azSchema[isTabUsed]); if( rc==SQLITE_OK ){ pNew = sqlite3_malloc( sizeof(*pNew) ); *ppVtab = (sqlite3_vtab*)pNew; if( pNew==0 ) return SQLITE_NOMEM; @@ -103125,11 +99614,10 @@ int argc, sqlite3_value **argv ){ bytecodevtab_cursor *pCur = (bytecodevtab_cursor *)pVtabCursor; bytecodevtab *pVTab = (bytecodevtab *)pVtabCursor->pVtab; int rc = SQLITE_OK; - (void)idxStr; bytecodevtabCursorClear(pCur); pCur->iRowid = 0; pCur->iAddr = 0; pCur->showSubprograms = idxNum==0; @@ -103594,12 +100082,10 @@ int flags, /* Opening flags */ int nSpill /* Bytes buffered before opening the file */ ){ MemJournal *p = (MemJournal*)pJfd; - assert( zName || nSpill<0 || (flags & SQLITE_OPEN_EXCLUSIVE) ); - /* Zero the file-handle object. If nSpill was passed zero, initialize ** it using the sqlite3OsOpen() function of the underlying VFS. In this ** case none of the code in this module is executed as a result of calls ** made on the journal file-handle. */ memset(p, 0, sizeof(MemJournal)); @@ -104023,28 +100509,57 @@ pDup = sqlite3ExprDup(db, pOrig, 0); if( db->mallocFailed ){ sqlite3ExprDelete(db, pDup); pDup = 0; }else{ - Expr temp; incrAggFunctionDepth(pDup, nSubquery); if( pExpr->op==TK_COLLATE ){ assert( !ExprHasProperty(pExpr, EP_IntValue) ); pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); } - memcpy(&temp, pDup, sizeof(Expr)); - memcpy(pDup, pExpr, sizeof(Expr)); - memcpy(pExpr, &temp, sizeof(Expr)); + + /* Before calling sqlite3ExprDelete(), 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. + ** The pExpr->u.zToken might point into memory that will be freed by the + ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to + ** make a copy of the token before doing the sqlite3DbFree(). + */ + ExprSetProperty(pExpr, EP_Static); + sqlite3ExprDelete(db, pExpr); + memcpy(pExpr, pDup, sizeof(*pExpr)); + if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){ + assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 ); + pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken); + pExpr->flags |= EP_MemToken; + } if( ExprHasProperty(pExpr, EP_WinFunc) ){ if( ALWAYS(pExpr->y.pWin!=0) ){ pExpr->y.pWin->pOwner = pExpr; } } - sqlite3ExprDeferredDelete(pParse, pDup); + sqlite3DbFree(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; knId; k++){ + if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ) return 1; + } + } + return 0; +} + /* ** Subqueries stores the original database, table and column names for their ** result sets in ExprList.a[].zSpan, in the form "DATABASE.TABLE.COLUMN". ** Check to see if the zSpan given to this routine matches the zDb, zTab, ** and zCol. If any of zDb, zTab, and zCol are NULL then those fields will @@ -104056,11 +100571,11 @@ const char *zTab, const char *zDb ){ int n; const char *zSpan; - if( pItem->fg.eEName!=ENAME_TAB ) return 0; + if( pItem->eEName!=ENAME_TAB ) return 0; zSpan = pItem->zEName; for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){} if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){ return 0; } @@ -104117,59 +100632,10 @@ if( n>=BMS ) n = BMS-1; return ((Bitmask)1)<db, TK_COLUMN, 0, 0); - if( pNew ){ - pNew->iTable = pMatch->iCursor; - pNew->iColumn = iColumn; - pNew->y.pTab = pMatch->pTab; - assert( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ); - ExprSetProperty(pNew, EP_CanBeNull); - *ppList = sqlite3ExprListAppend(pParse, *ppList, pNew); - } -} - -/* -** Return TRUE (non-zero) if zTab is a valid name for the schema table pTab. -*/ -static SQLITE_NOINLINE int isValidSchemaTableName( - const char *zTab, /* Name as it appears in the SQL */ - Table *pTab, /* The schema table we are trying to match */ - Schema *pSchema /* non-NULL if a database qualifier is present */ -){ - const char *zLegacy; - assert( pTab!=0 ); - assert( pTab->tnum==1 ); - if( sqlite3StrNICmp(zTab, "sqlite_", 7)!=0 ) return 0; - zLegacy = pTab->zName; - if( strcmp(zLegacy+7, &LEGACY_TEMP_SCHEMA_TABLE[7])==0 ){ - if( sqlite3StrICmp(zTab+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0 ){ - return 1; - } - if( pSchema==0 ) return 0; - if( sqlite3StrICmp(zTab+7, &LEGACY_SCHEMA_TABLE[7])==0 ) return 1; - if( sqlite3StrICmp(zTab+7, &PREFERRED_SCHEMA_TABLE[7])==0 ) return 1; - }else{ - if( sqlite3StrICmp(zTab+7, &PREFERRED_SCHEMA_TABLE[7])==0 ) return 1; - } - return 0; -} - /* ** 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: @@ -104211,17 +100677,15 @@ SrcItem *pItem; /* Use for looping over pSrcList items */ SrcItem *pMatch = 0; /* The matching pSrcList item */ NameContext *pTopNC = pNC; /* First namecontext in the list */ Schema *pSchema = 0; /* Schema of the expression */ int eNewExprOp = TK_COLUMN; /* New value for pExpr->op on success */ - Table *pTab = 0; /* Table holding the row */ + Table *pTab = 0; /* Table hold the row */ Column *pCol; /* A column of pTab */ - ExprList *pFJMatch = 0; /* Matches for FULL JOIN .. USING */ assert( pNC ); /* the name context cannot be NULL. */ assert( zCol ); /* The Z in X.Y.Z cannot be NULL */ - assert( zDb==0 || zTab!=0 ); assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); /* Initialize the node to no-match */ pExpr->iTable = -1; ExprSetVVAProperty(pExpr, EP_NoReduce); @@ -104266,74 +100730,33 @@ for(i=0, pItem=pSrcList->a; inSrc; i++, pItem++){ u8 hCol; pTab = pItem->pTab; assert( pTab!=0 && pTab->zName!=0 ); assert( pTab->nCol>0 || pParse->nErr ); - assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); - if( pItem->fg.isNestedFrom ){ - /* In this case, pItem is a subquery that has been formed from a - ** parenthesized subset of the FROM clause terms. Example: - ** .... FROM t1 LEFT JOIN (t2 RIGHT JOIN t3 USING(x)) USING(y) ... - ** \_________________________/ - ** This pItem -------------^ - */ + if( pItem->pSelect && (pItem->pSelect->selFlags & SF_NestedFrom)!=0 ){ int hit = 0; - assert( pItem->pSelect!=0 ); pEList = pItem->pSelect->pEList; - assert( pEList!=0 ); - assert( pEList->nExpr==pTab->nCol ); for(j=0; jnExpr; j++){ - if( !sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb) ){ - continue; - } - if( cnt>0 ){ - if( pItem->fg.isUsing==0 - || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0 - ){ - /* Two or more tables have the same column name which is - ** not joined by USING. This is an error. Signal as much - ** by clearing pFJMatch and letting cnt go above 1. */ - sqlite3ExprListDelete(db, pFJMatch); - pFJMatch = 0; - }else - if( (pItem->fg.jointype & JT_RIGHT)==0 ){ - /* An INNER or LEFT JOIN. Use the left-most table */ - continue; - }else - if( (pItem->fg.jointype & JT_LEFT)==0 ){ - /* A RIGHT JOIN. Use the right-most table */ - cnt = 0; - sqlite3ExprListDelete(db, pFJMatch); - pFJMatch = 0; - }else{ - /* For a FULL JOIN, we must construct a coalesce() func */ - extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); - } - } - cnt++; - cntTab = 2; - pMatch = pItem; - pExpr->iColumn = j; - pEList->a[j].fg.bUsed = 1; - hit = 1; - if( pEList->a[j].fg.bUsingTerm ) break; + if( sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb) ){ + cnt++; + cntTab = 2; + pMatch = pItem; + pExpr->iColumn = j; + hit = 1; + } } if( hit || zTab==0 ) continue; } - assert( zDb==0 || zTab!=0 ); + if( zDb ){ + if( pTab->pSchema!=pSchema ) continue; + if( pSchema==0 && strcmp(zDb,"*")!=0 ) continue; + } if( zTab ){ - if( zDb ){ - if( pTab->pSchema!=pSchema ) continue; - if( pSchema==0 && strcmp(zDb,"*")!=0 ) continue; - } - if( pItem->zAlias!=0 ){ - if( sqlite3StrICmp(zTab, pItem->zAlias)!=0 ){ - continue; - } - }else if( sqlite3StrICmp(zTab, pTab->zName)!=0 ){ - if( pTab->tnum!=1 ) continue; - if( !isValidSchemaTableName(zTab, pTab, pSchema) ) continue; + const char *zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName; + assert( zTabName!=0 ); + if( sqlite3StrICmp(zTabName, zTab)!=0 ){ + continue; } assert( ExprUseYTab(pExpr) ); if( IN_RENAME_OBJECT && pItem->zAlias ){ sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab); } @@ -104341,41 +100764,22 @@ hCol = sqlite3StrIHash(zCol); for(j=0, pCol=pTab->aCol; jnCol; j++, pCol++){ if( pCol->hName==hCol && sqlite3StrICmp(pCol->zCnName, zCol)==0 ){ - if( cnt>0 ){ - if( pItem->fg.isUsing==0 - || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0 - ){ - /* Two or more tables have the same column name which is - ** not joined by USING. This is an error. Signal as much - ** by clearing pFJMatch and letting cnt go above 1. */ - sqlite3ExprListDelete(db, pFJMatch); - pFJMatch = 0; - }else - if( (pItem->fg.jointype & JT_RIGHT)==0 ){ - /* An INNER or LEFT JOIN. Use the left-most table */ - continue; - }else - if( (pItem->fg.jointype & JT_LEFT)==0 ){ - /* A RIGHT JOIN. Use the right-most table */ - cnt = 0; - sqlite3ExprListDelete(db, pFJMatch); - pFJMatch = 0; - }else{ - /* For a FULL JOIN, we must construct a coalesce() func */ - extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); - } + /* 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->fg.jointype & JT_NATURAL ) continue; + if( nameInUsingClause(pItem->pUsing, zCol) ) continue; } cnt++; pMatch = pItem; /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j; - if( pItem->fg.isNestedFrom ){ - sqlite3SrcItemColumnUsed(pItem, j); - } break; } } if( 0==cnt && VisibleRowid(pTab) ){ cntTab++; @@ -104384,11 +100788,13 @@ } if( pMatch ){ pExpr->iTable = pMatch->iCursor; assert( ExprUseYTab(pExpr) ); pExpr->y.pTab = pMatch->pTab; - if( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ){ + /* RIGHT JOIN not (yet) supported */ + assert( (pMatch->fg.jointype & JT_RIGHT)==0 ); + if( (pMatch->fg.jointype & JT_LEFT)!=0 ){ ExprSetProperty(pExpr, EP_CanBeNull); } pSchema = pExpr->y.pTab->pSchema; } } /* if( pSrcList ) */ @@ -104405,12 +100811,11 @@ if( pParse->pTriggerTab!=0 ){ int op = pParse->eTriggerOp; assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT ); if( pParse->bReturning ){ if( (pNC->ncFlags & NC_UBaseReg)!=0 - && ALWAYS(zTab==0 - || sqlite3StrICmp(zTab,pParse->pTriggerTab->zName)==0) + && (zTab==0 || sqlite3StrICmp(zTab,pParse->pTriggerTab->zName)==0) ){ pExpr->iTable = op!=TK_DELETE; pTab = pParse->pTriggerTab; } }else if( op!=TK_DELETE && zTab && sqlite3StrICmp("new",zTab) == 0 ){ @@ -104473,11 +100878,10 @@ assert( ExprUseYTab(pExpr) ); pExpr->y.pTab = pTab; if( pParse->bReturning ){ eNewExprOp = TK_REGISTER; pExpr->op2 = TK_COLUMN; - pExpr->iColumn = iCol; pExpr->iTable = pNC->uNC.iBaseReg + (pTab->nCol+1)*pExpr->iTable + sqlite3TableColumnToStorage(pTab, iCol) + 1; }else{ pExpr->iColumn = (i16)iCol; eNewExprOp = TK_TRIGGER; @@ -104540,11 +100944,11 @@ ){ pEList = pNC->uNC.pEList; assert( pEList!=0 ); for(j=0; jnExpr; j++){ char *zAs = pEList->a[j].zEName; - if( pEList->a[j].fg.eEName==ENAME_NAME + if( pEList->a[j].eEName==ENAME_NAME && sqlite3_stricmp(zAs, zCol)==0 ){ Expr *pOrig; assert( pExpr->pLeft==0 && pExpr->pRight==0 ); assert( ExprUseXList(pExpr)==0 || pExpr->x.pList==0 ); @@ -104627,41 +101031,15 @@ return WRC_Prune; } } /* - ** cnt==0 means there was not match. - ** cnt>1 means there were two or more matches. - ** - ** cnt==0 is always an error. cnt>1 is often an error, but might - ** be multiple matches for a NATURAL LEFT JOIN or a LEFT JOIN USING. + ** cnt==0 means there was not match. cnt>1 means there were two or + ** more matches. Either way, we have an error. */ - assert( pFJMatch==0 || cnt>0 ); - assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) ); if( cnt!=1 ){ const char *zErr; - if( pFJMatch ){ - if( pFJMatch->nExpr==cnt-1 ){ - if( ExprHasProperty(pExpr,EP_Leaf) ){ - ExprClearProperty(pExpr,EP_Leaf); - }else{ - sqlite3ExprDelete(db, pExpr->pLeft); - pExpr->pLeft = 0; - sqlite3ExprDelete(db, pExpr->pRight); - pExpr->pRight = 0; - } - extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); - pExpr->op = TK_FUNCTION; - pExpr->u.zToken = "coalesce"; - pExpr->x.pList = pFJMatch; - cnt = 1; - goto lookupname_end; - }else{ - sqlite3ExprListDelete(db, pFJMatch); - pFJMatch = 0; - } - } zErr = cnt==0 ? "no such column" : "ambiguous column name"; if( zDb ){ sqlite3ErrorMsg(pParse, "%s: %s.%s.%s", zErr, zDb, zTab, zCol); }else if( zTab ){ sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol); @@ -104670,20 +101048,10 @@ } sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr); pParse->checkSchema = 1; pTopNC->nNcErr++; } - assert( pFJMatch==0 ); - - /* Remove all substructure from pExpr */ - if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ - sqlite3ExprDelete(db, pExpr->pLeft); - pExpr->pLeft = 0; - sqlite3ExprDelete(db, pExpr->pRight); - pExpr->pRight = 0; - ExprSetProperty(pExpr, EP_Leaf); - } /* 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. Bit 63 is ** set if the 63rd or any subsequent column is used. @@ -104699,11 +101067,20 @@ */ if( pExpr->iColumn>=0 && pMatch!=0 ){ pMatch->colUsed |= sqlite3ExprColUsed(pExpr); } + /* Clean up and return + */ + if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ + sqlite3ExprDelete(db, pExpr->pLeft); + pExpr->pLeft = 0; + sqlite3ExprDelete(db, pExpr->pRight); + pExpr->pRight = 0; + } pExpr->op = eNewExprOp; + ExprSetProperty(pExpr, EP_Leaf); lookupname_end: if( cnt==1 ){ assert( pNC!=0 ); #ifndef SQLITE_OMIT_AUTHORIZATION if( pParse->db->xAuth @@ -104884,16 +101261,20 @@ for(i=0, p=pNC; p && ipNext, i++){ anRef[i] = p->nRef; } sqlite3WalkExpr(pWalker, pExpr->pLeft); if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) && !IN_RENAME_OBJECT ){ - testcase( ExprHasProperty(pExpr, EP_OuterON) ); + testcase( ExprHasProperty(pExpr, EP_FromJoin) ); assert( !ExprHasProperty(pExpr, EP_IntValue) ); - pExpr->u.iValue = (pExpr->op==TK_NOTNULL); - pExpr->flags |= EP_IntValue; - pExpr->op = TK_INTEGER; - + if( pExpr->op==TK_NOTNULL ){ + pExpr->u.zToken = "true"; + ExprSetProperty(pExpr, EP_IsTrue); + }else{ + pExpr->u.zToken = "false"; + ExprSetProperty(pExpr, EP_IsFalse); + } + pExpr->op = TK_TRUEFALSE; for(i=0, p=pNC; p && ipNext, i++){ p->nRef = anRef[i]; } sqlite3ExprDelete(pParse->db, pExpr->pLeft); pExpr->pLeft = 0; @@ -105191,12 +101572,12 @@ sqlite3WalkSelect(pWalker, pExpr->x.pSelect); } assert( pNC->nRef>=nRef ); if( nRef!=pNC->nRef ){ ExprSetProperty(pExpr, EP_VarSelect); + pNC->ncFlags |= NC_VarSelect; } - pNC->ncFlags |= NC_Subquery; } break; } case TK_VARIABLE: { testcase( pNC->ncFlags & NC_IsCheck ); @@ -105289,11 +101670,11 @@ if( pE->op==TK_ID ){ const char *zCol; assert( !ExprHasProperty(pE, EP_IntValue) ); zCol = pE->u.zToken; for(i=0; inExpr; i++){ - if( pEList->a[i].fg.eEName==ENAME_NAME + if( pEList->a[i].eEName==ENAME_NAME && sqlite3_stricmp(pEList->a[i].zEName, zCol)==0 ){ return i+1; } } @@ -105410,11 +101791,11 @@ if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ sqlite3ErrorMsg(pParse, "too many terms in ORDER BY clause"); return 1; } for(i=0; inExpr; i++){ - pOrderBy->a[i].fg.done = 0; + pOrderBy->a[i].done = 0; } pSelect->pNext = 0; while( pSelect->pPrior ){ pSelect->pPrior->pNext = pSelect; pSelect = pSelect->pPrior; @@ -105425,11 +101806,11 @@ pEList = pSelect->pEList; assert( pEList!=0 ); for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ int iCol = -1; Expr *pE, *pDup; - if( pItem->fg.done ) continue; + if( pItem->done ) continue; pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr); if( NEVER(pE==0) ) continue; if( sqlite3ExprIsInteger(pE, &iCol) ){ if( iCol<=0 || iCol>pEList->nExpr ){ resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr, pE); @@ -105478,19 +101859,19 @@ pParent->pLeft = pNew; } sqlite3ExprDelete(db, pE); pItem->u.x.iOrderByCol = (u16)iCol; } - pItem->fg.done = 1; + pItem->done = 1; }else{ moreToDo = 1; } } pSelect = pSelect->pNext; } for(i=0; inExpr; i++){ - if( pOrderBy->a[i].fg.done==0 ){ + if( pOrderBy->a[i].done==0 ){ sqlite3ErrorMsg(pParse, "%r ORDER BY term does not match any " "column in the result set", i+1); return 1; } } @@ -105776,12 +102157,12 @@ */ assert( (sNC.ncFlags & (NC_UAggInfo|NC_UUpsert|NC_UBaseReg))==0 ); sNC.uNC.pEList = p->pEList; sNC.ncFlags |= NC_UEList; if( p->pHaving ){ - if( (p->selFlags & SF_Aggregate)==0 ){ - sqlite3ErrorMsg(pParse, "HAVING clause on a non-aggregate query"); + if( !pGroupBy ){ + sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING"); return WRC_Abort; } if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; } if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort; @@ -106146,125 +102527,53 @@ ** SELECT a AS b FROM t1 WHERE b; ** SELECT * FROM t1 WHERE (select a from t1); */ SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){ int op; + while( ExprHasProperty(pExpr, EP_Skip|EP_IfNullRow) ){ + assert( pExpr->op==TK_COLLATE + || pExpr->op==TK_IF_NULL_ROW + || (pExpr->op==TK_REGISTER && pExpr->op2==TK_IF_NULL_ROW) ); + pExpr = pExpr->pLeft; + assert( pExpr!=0 ); + } op = pExpr->op; - while( 1 /* exit-by-break */ ){ - if( op==TK_COLUMN || (op==TK_AGG_COLUMN && pExpr->y.pTab!=0) ){ - assert( ExprUseYTab(pExpr) ); - assert( pExpr->y.pTab!=0 ); + if( op==TK_REGISTER ) op = pExpr->op2; + if( op==TK_COLUMN || op==TK_AGG_COLUMN ){ + assert( ExprUseYTab(pExpr) ); + if( pExpr->y.pTab ){ return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); } - if( op==TK_SELECT ){ - assert( ExprUseXSelect(pExpr) ); - assert( pExpr->x.pSelect!=0 ); - assert( pExpr->x.pSelect->pEList!=0 ); - assert( pExpr->x.pSelect->pEList->a[0].pExpr!=0 ); - return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr); - } + } + if( op==TK_SELECT ){ + assert( ExprUseXSelect(pExpr) ); + assert( pExpr->x.pSelect!=0 ); + assert( pExpr->x.pSelect->pEList!=0 ); + assert( pExpr->x.pSelect->pEList->a[0].pExpr!=0 ); + return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr); + } #ifndef SQLITE_OMIT_CAST - if( op==TK_CAST ){ - assert( !ExprHasProperty(pExpr, EP_IntValue) ); - return sqlite3AffinityType(pExpr->u.zToken, 0); - } + if( op==TK_CAST ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + return sqlite3AffinityType(pExpr->u.zToken, 0); + } #endif - if( op==TK_SELECT_COLUMN ){ - assert( pExpr->pLeft!=0 && ExprUseXSelect(pExpr->pLeft) ); - assert( pExpr->iColumn < pExpr->iTable ); - assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr ); - return sqlite3ExprAffinity( - pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr - ); - } - if( op==TK_VECTOR ){ - assert( ExprUseXList(pExpr) ); - return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr); - } - if( ExprHasProperty(pExpr, EP_Skip|EP_IfNullRow) ){ - assert( pExpr->op==TK_COLLATE - || pExpr->op==TK_IF_NULL_ROW - || (pExpr->op==TK_REGISTER && pExpr->op2==TK_IF_NULL_ROW) ); - pExpr = pExpr->pLeft; - op = pExpr->op; - continue; - } - if( op!=TK_REGISTER || (op = pExpr->op2)==TK_REGISTER ) break; + if( op==TK_SELECT_COLUMN ){ + assert( pExpr->pLeft!=0 && ExprUseXSelect(pExpr->pLeft) ); + assert( pExpr->iColumn < pExpr->iTable ); + assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr ); + return sqlite3ExprAffinity( + pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr + ); + } + if( op==TK_VECTOR ){ + assert( ExprUseXList(pExpr) ); + return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr); } return pExpr->affExpr; } -/* -** Make a guess at all the possible datatypes of the result that could -** be returned by an expression. Return a bitmask indicating the answer: -** -** 0x01 Numeric -** 0x02 Text -** 0x04 Blob -** -** If the expression must return NULL, then 0x00 is returned. -*/ -SQLITE_PRIVATE int sqlite3ExprDataType(const Expr *pExpr){ - while( pExpr ){ - switch( pExpr->op ){ - case TK_COLLATE: - case TK_IF_NULL_ROW: - case TK_UPLUS: { - pExpr = pExpr->pLeft; - break; - } - case TK_NULL: { - pExpr = 0; - break; - } - case TK_STRING: { - return 0x02; - } - case TK_BLOB: { - return 0x04; - } - case TK_CONCAT: { - return 0x06; - } - case TK_VARIABLE: - case TK_AGG_FUNCTION: - case TK_FUNCTION: { - return 0x07; - } - case TK_COLUMN: - case TK_AGG_COLUMN: - case TK_SELECT: - case TK_CAST: - case TK_SELECT_COLUMN: - case TK_VECTOR: { - int aff = sqlite3ExprAffinity(pExpr); - if( aff>=SQLITE_AFF_NUMERIC ) return 0x05; - if( aff==SQLITE_AFF_TEXT ) return 0x06; - return 0x07; - } - case TK_CASE: { - int res = 0; - int ii; - ExprList *pList = pExpr->x.pList; - assert( ExprUseXList(pExpr) && pList!=0 ); - assert( pList->nExpr > 0); - for(ii=1; iinExpr; ii+=2){ - res |= sqlite3ExprDataType(pList->a[ii].pExpr); - } - if( pList->nExpr % 2 ){ - res |= sqlite3ExprDataType(pList->a[pList->nExpr-1].pExpr); - } - return res; - } - default: { - return 0x01; - } - } /* End of switch(op) */ - } /* End of while(pExpr) */ - return 0x00; -} - /* ** Set the collating sequence for expression pExpr to be the collating ** sequence named by pToken. Return a pointer to a new Expr node that ** implements the COLLATE operator. ** @@ -106348,21 +102657,22 @@ CollSeq *pColl = 0; const Expr *p = pExpr; while( p ){ int op = p->op; if( op==TK_REGISTER ) op = p->op2; - if( (op==TK_AGG_COLUMN && p->y.pTab!=0) - || op==TK_COLUMN || op==TK_TRIGGER - ){ - int j; + if( op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_TRIGGER ){ assert( ExprUseYTab(p) ); - assert( p->y.pTab!=0 ); - if( (j = p->iColumn)>=0 ){ - const char *zColl = sqlite3ColumnColl(&p->y.pTab->aCol[j]); - pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); + if( p->y.pTab!=0 ){ + /* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally + ** a TK_COLUMN but was previously evaluated and cached in a register */ + int j = p->iColumn; + if( j>=0 ){ + const char *zColl = sqlite3ColumnColl(&p->y.pTab->aCol[j]); + pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); + } + break; } - break; } if( op==TK_CAST || op==TK_UPLUS ){ p = p->pLeft; continue; } @@ -106380,14 +102690,15 @@ if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){ p = p->pLeft; }else{ Expr *pNext = p->pRight; /* The Expr.x union is never used at the same time as Expr.pRight */ - assert( !ExprUseXList(p) || p->x.pList==0 || p->pRight==0 ); - if( ExprUseXList(p) && p->x.pList!=0 && !db->mallocFailed ){ + assert( ExprUseXList(p) ); + assert( p->x.pList==0 || p->pRight==0 ); + if( p->x.pList!=0 && !db->mallocFailed ){ int i; - for(i=0; ix.pList->nExpr; i++){ + for(i=0; ALWAYS(ix.pList->nExpr); i++){ if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){ pNext = p->x.pList->a[i].pExpr; break; } } @@ -106942,13 +103253,11 @@ ** Also propagate EP_Propagate flags up from Expr.x.pList to Expr.flags, ** if appropriate. */ static void exprSetHeight(Expr *p){ int nHeight = p->pLeft ? p->pLeft->nHeight : 0; - if( NEVER(p->pRight) && p->pRight->nHeight>nHeight ){ - nHeight = p->pRight->nHeight; - } + if( p->pRight && p->pRight->nHeight>nHeight ) nHeight = p->pRight->nHeight; if( ExprUseXSelect(p) ){ heightOfSelect(p->x.pSelect, &nHeight); }else if( p->x.pList ){ heightOfExprList(p->x.pList, &nHeight); p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList); @@ -107087,30 +103396,19 @@ if( pRoot==0 ){ assert( db->mallocFailed ); sqlite3ExprDelete(db, pLeft); sqlite3ExprDelete(db, pRight); }else{ - assert( ExprUseXList(pRoot) ); - assert( pRoot->x.pSelect==0 ); if( pRight ){ pRoot->pRight = pRight; pRoot->flags |= EP_Propagate & pRight->flags; -#if SQLITE_MAX_EXPR_DEPTH>0 - pRoot->nHeight = pRight->nHeight+1; - }else{ - pRoot->nHeight = 1; -#endif } if( pLeft ){ pRoot->pLeft = pLeft; pRoot->flags |= EP_Propagate & pLeft->flags; -#if SQLITE_MAX_EXPR_DEPTH>0 - if( pLeft->nHeight>=pRoot->nHeight ){ - pRoot->nHeight = pLeft->nHeight+1; - } -#endif } + exprSetHeight(pRoot); } } /* ** Allocate an Expr node which joins as many as two subtrees. @@ -107254,11 +103552,10 @@ pNew = sqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1); if( pNew==0 ){ sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */ return 0; } - assert( !ExprHasProperty(pNew, EP_InnerON|EP_OuterON) ); pNew->w.iOfst = (int)(pToken->z - pParse->zTail); if( pList && pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] && !pParse->nested ){ @@ -107392,11 +103689,10 @@ /* ** Recursively delete an expression tree. */ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ assert( p!=0 ); - assert( db!=0 ); assert( !ExprUseUValue(p) || p->u.iValue>=0 ); assert( !ExprUseYWin(p) || !ExprUseYSub(p) ); assert( !ExprUseYWin(p) || p->y.pWin!=0 || db->mallocFailed ); assert( p->op!=TK_FUNCTION || !ExprUseYSub(p) ); #ifdef SQLITE_DEBUG @@ -107423,31 +103719,23 @@ if( ExprHasProperty(p, EP_WinFunc) ){ sqlite3WindowDelete(db, p->y.pWin); } #endif } + } + if( ExprHasProperty(p, EP_MemToken) ){ + assert( !ExprHasProperty(p, EP_IntValue) ); + sqlite3DbFree(db, p->u.zToken); } if( !ExprHasProperty(p, EP_Static) ){ - sqlite3DbNNFreeNN(db, p); + sqlite3DbFreeNN(db, p); } } SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){ if( p ) sqlite3ExprDeleteNN(db, p); } -/* -** Clear both elements of an OnOrUsing object -*/ -SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3 *db, OnOrUsing *p){ - if( p==0 ){ - /* Nothing to clear */ - }else if( p->pOn ){ - sqlite3ExprDeleteNN(db, p->pOn); - }else if( p->pUsing ){ - sqlite3IdListDelete(db, p->pUsing); - } -} /* ** Arrange to cause pExpr to be deleted when the pParse is deleted. ** This is similar to sqlite3ExprDelete() except that the delete is ** deferred untilthe pParse is deleted. @@ -107456,13 +103744,12 @@ ** ** The deferred delete is (currently) implemented by adding the ** pExpr to the pParse->pConstExpr list with a register number of 0. */ SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){ - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3ExprDelete, - pExpr); + pParse->pConstExpr = + sqlite3ExprListAppend(pParse, pParse->pConstExpr, pExpr); } /* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the ** expression. */ @@ -107531,11 +103818,12 @@ #endif ){ nSize = EXPR_FULLSIZE; }else{ assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); - assert( !ExprHasProperty(p, EP_OuterON) ); + assert( !ExprHasProperty(p, EP_FromJoin) ); + assert( !ExprHasProperty(p, EP_MemToken) ); assert( !ExprHasVVAProperty(p, EP_NoReduce) ); if( p->pLeft || p->x.pList ){ nSize = EXPR_REDUCEDSIZE | EP_Reduced; }else{ assert( p->pRight==0 ); @@ -107635,11 +103923,11 @@ 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 &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken); pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly); pNew->flags |= staticFlag; ExprClearVVAProperties(pNew); if( dupFlags ){ ExprSetVVAProperty(pNew, EP_Immutable); @@ -107710,11 +103998,10 @@ pRet->nCte = p->nCte; for(i=0; inCte; i++){ pRet->a[i].pSelect = sqlite3SelectDup(db, p->a[i].pSelect, 0); pRet->a[i].pCols = sqlite3ExprListDup(db, p->a[i].pCols, 0); pRet->a[i].zName = sqlite3DbStrDup(db, p->a[i].zName); - pRet->a[i].eM10d = p->a[i].eM10d; } } } return pRet; } @@ -107811,12 +104098,15 @@ } pNewExpr->pLeft = pPriorSelectColNew; } } pItem->zEName = sqlite3DbStrDup(db, pOldItem->zEName); - pItem->fg = pOldItem->fg; - pItem->fg.done = 0; + pItem->sortFlags = pOldItem->sortFlags; + pItem->eEName = pOldItem->eEName; + pItem->done = 0; + pItem->bNulls = pOldItem->bNulls; + pItem->bSorterRef = pOldItem->bSorterRef; pItem->u = pOldItem->u; } return pNew; } @@ -107864,35 +104154,37 @@ pTab = pNewItem->pTab = pOldItem->pTab; if( pTab ){ pTab->nTabRef++; } pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags); - if( pOldItem->fg.isUsing ){ - assert( pNewItem->fg.isUsing ); - pNewItem->u3.pUsing = sqlite3IdListDup(db, pOldItem->u3.pUsing); - }else{ - pNewItem->u3.pOn = sqlite3ExprDup(db, pOldItem->u3.pOn, flags); - } + pNewItem->pOn = sqlite3ExprDup(db, pOldItem->pOn, flags); + pNewItem->pUsing = sqlite3IdListDup(db, pOldItem->pUsing); pNewItem->colUsed = pOldItem->colUsed; } return pNew; } SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, const IdList *p){ IdList *pNew; int i; assert( db!=0 ); if( p==0 ) return 0; - assert( p->eU4!=EU4_EXPR ); - pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew)+(p->nId-1)*sizeof(p->a[0]) ); + pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) ); if( pNew==0 ) return 0; pNew->nId = p->nId; - pNew->eU4 = p->eU4; + pNew->a = sqlite3DbMallocRawNN(db, p->nId*sizeof(p->a[0]) ); + if( pNew->a==0 ){ + sqlite3DbFreeNN(db, pNew); + return 0; + } + /* Note that because the size of the allocation for p->a[] is not + ** necessarily a power of two, sqlite3IdListAppend() may not be called + ** on the duplicate created by this function. */ for(i=0; inId; i++){ struct IdList_item *pNewItem = &pNew->a[i]; - const struct IdList_item *pOldItem = &p->a[i]; + struct IdList_item *pOldItem = &p->a[i]; pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); - pNewItem->u4 = pOldItem->u4; + pNewItem->idx = pOldItem->idx; } return pNew; } SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int flags){ Select *pRet = 0; @@ -108112,20 +104404,20 @@ || eNulls==SQLITE_SO_ASC || eNulls==SQLITE_SO_DESC ); pItem = &p->a[p->nExpr-1]; - assert( pItem->fg.bNulls==0 ); + assert( pItem->bNulls==0 ); if( iSortOrder==SQLITE_SO_UNDEFINED ){ iSortOrder = SQLITE_SO_ASC; } - pItem->fg.sortFlags = (u8)iSortOrder; + pItem->sortFlags = (u8)iSortOrder; if( eNulls!=SQLITE_SO_UNDEFINED ){ - pItem->fg.bNulls = 1; + pItem->bNulls = 1; if( iSortOrder!=eNulls ){ - pItem->fg.sortFlags |= KEYINFO_ORDER_BIGNULL; + pItem->sortFlags |= KEYINFO_ORDER_BIGNULL; } } } /* @@ -108147,11 +104439,11 @@ if( pList ){ struct ExprList_item *pItem; assert( pList->nExpr>0 ); pItem = &pList->a[pList->nExpr-1]; assert( pItem->zEName==0 ); - assert( pItem->fg.eEName==ENAME_NAME ); + assert( pItem->eEName==ENAME_NAME ); pItem->zEName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n); if( dequote ){ /* If dequote==0, then pName->z does not point to part of a DDL ** statement handled by the parser. And so no token need be added ** to the token-map. */ @@ -108182,11 +104474,11 @@ if( pList ){ struct ExprList_item *pItem = &pList->a[pList->nExpr-1]; assert( pList->nExpr>0 ); if( pItem->zEName==0 ){ pItem->zEName = sqlite3DbSpanDup(db, zStart, zEnd); - pItem->fg.eEName = ENAME_SPAN; + pItem->eEName = ENAME_SPAN; } } } /* @@ -108211,17 +104503,16 @@ */ static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){ int i = pList->nExpr; struct ExprList_item *pItem = pList->a; assert( pList->nExpr>0 ); - assert( db!=0 ); do{ sqlite3ExprDelete(db, pItem->pExpr); - if( pItem->zEName ) sqlite3DbNNFreeNN(db, pItem->zEName); + sqlite3DbFree(db, pItem->zEName); pItem++; }while( --i>0 ); - sqlite3DbNNFreeNN(db, pList); + sqlite3DbFreeNN(db, pList); } SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){ if( pList ) exprListDeleteNN(db, pList); } @@ -108355,13 +104646,13 @@ ** malformed schema error. */ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ /* If pWalker->eCode is 2 then any term of the expression that comes from - ** the ON or USING clauses of an outer join disqualifies the expression + ** the ON or USING clauses of a left join disqualifies the expression ** from being considered constant. */ - if( pWalker->eCode==2 && ExprHasProperty(pExpr, EP_OuterON) ){ + if( pWalker->eCode==2 && ExprHasProperty(pExpr, EP_FromJoin) ){ pWalker->eCode = 0; return WRC_Abort; } switch( pExpr->op ){ @@ -108480,40 +104771,36 @@ /* ** Check pExpr to see if it is an invariant constraint on data source pSrc. ** This is an optimization. False negatives will perhaps cause slower ** queries, but false positives will yield incorrect answers. So when in -** doubt, return 0. +** double, return 0. ** ** To be an invariant constraint, the following must be true: ** ** (1) pExpr cannot refer to any table other than pSrc->iCursor. ** ** (2) pExpr cannot use subqueries or non-deterministic functions. ** -** (3) pSrc cannot be part of the left operand for a RIGHT JOIN. -** (Is there some way to relax this constraint?) +** (*) ** Not applicable to this branch ** ** ** (4) If pSrc is the right operand of a LEFT JOIN, then... ** (4a) pExpr must come from an ON clause.. - (4b) and specifically the ON clause associated with the LEFT JOIN. +** (4b) and specifically the ON clause associated with the LEFT JOIN. ** ** (5) If pSrc is not the right operand of a LEFT JOIN or the left ** operand of a RIGHT JOIN, then pExpr must be from the WHERE ** clause, not an ON clause. */ SQLITE_PRIVATE int sqlite3ExprIsTableConstraint(Expr *pExpr, const SrcItem *pSrc){ - if( pSrc->fg.jointype & JT_LTORJ ){ - return 0; /* rule (3) */ - } if( pSrc->fg.jointype & JT_LEFT ){ - if( !ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* rule (4a) */ - if( pExpr->w.iJoin!=pSrc->iCursor ) return 0; /* rule (4b) */ + if( !ExprHasProperty(pExpr, EP_FromJoin) ) return 0; /* rule (4a) */ + if( pExpr->w.iRightJoinTable!=pSrc->iCursor ) return 0; /* rule (4b) */ }else{ - if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* rule (5) */ + if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0; /* rule (5) */ } - return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor); /* rules (1), (2) */ + return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor); /* rules (1), (2) */ } /* ** sqlite3WalkExpr() callback used by sqlite3ExprIsConstantOrGroupBy(). @@ -108751,11 +105038,11 @@ /* ** pX is the RHS of an IN operator. If pX is a SELECT statement ** that can be simplified to a direct table access, then return ** a pointer to the SELECT statement. If pX is not a SELECT statement, -** or if the SELECT statement needs to be materialized into a transient +** or if the SELECT statement needs to be manifested into a transient ** table, then return NULL. */ #ifndef SQLITE_OMIT_SUBQUERY static Select *isCandidateForInOpt(const Expr *pX){ Select *p; @@ -108839,11 +105126,11 @@ ** The job of this routine is to find or create a b-tree object that can ** be used either to test for membership in the RHS set or to iterate through ** all members of the RHS set, skipping duplicates. ** ** A cursor is opened on the b-tree object that is the RHS of the IN operator -** and the *piTab parameter is set to the index of that cursor. +** and pX->iTable is set to the index of that cursor. ** ** 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_ASC - The cursor was opened on an ascending index. @@ -108859,14 +105146,11 @@ ** SELECT , ... FROM ** ** If the RHS of the IN operator is a list or a more complex subquery, then ** an ephemeral table might need to be generated from the RHS and then ** pX->iTable made to point to the ephemeral table instead of an -** existing table. In this case, the creation and initialization of the -** ephmeral table might be put inside of a subroutine, the EP_Subrtn flag -** will be set on pX and the pX->y.sub fields will be set to show where -** the subroutine is coded. +** existing table. ** ** The inFlags parameter must contain, at a minimum, one of the bits ** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP but not both. If inFlags contains ** IN_INDEX_MEMBERSHIP, then the generated table will be used for a fast ** membership test. When the IN_INDEX_LOOP bit is set, the IN index will @@ -108923,17 +105207,16 @@ int *aiMap, /* Mapping from Index fields to RHS fields */ int *piTab /* OUT: index to use */ ){ Select *p; /* SELECT to the right of IN operator */ int eType = 0; /* Type of RHS table. IN_INDEX_* */ - int iTab; /* Cursor of the RHS table */ + int iTab = pParse->nTab++; /* Cursor of the RHS table */ int mustBeUnique; /* True if RHS must be unique */ Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ assert( pX->op==TK_IN ); mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0; - iTab = pParse->nTab++; /* If the RHS of this IN(...) operator is a SELECT, and if it matters ** whether or not the SELECT result contains NULL values, check whether ** or not NULL is actually possible (it may not be, for example, due ** to NOT NULL constraints in the schema). If no NULL values are possible, @@ -109037,10 +105320,11 @@ Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i); Expr *pRhs = pEList->a[i].pExpr; CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); int j; + assert( pReq!=0 || pRhs->iColumn==XN_ROWID || pParse->nErr ); for(j=0; jaiColumn[j]!=pRhs->iColumn ) continue; assert( pIdx->azColl[j] ); if( pReq!=0 && sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ){ continue; @@ -109094,12 +105378,10 @@ if( eType==0 && (inFlags & IN_INDEX_NOOP_OK) && ExprUseXList(pX) && (!sqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2) ){ - pParse->nTab--; /* Back out the allocation of the unused cursor */ - iTab = -1; /* Cursor is not allocated */ eType = IN_INDEX_NOOP; } if( eType==0 ){ /* Could not find an existing table or index to use as the RHS b-tree. @@ -109262,11 +105544,10 @@ pExpr->x.pSelect->selId)); } assert( ExprUseYSub(pExpr) ); sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, pExpr->y.sub.iAddr); - assert( iTab!=pExpr->iTable ); sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable); sqlite3VdbeJumpHere(v, addrOnce); return; } @@ -109274,11 +105555,12 @@ assert( !ExprUseYWin(pExpr) ); ExprSetProperty(pExpr, EP_Subrtn); assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); pExpr->y.sub.regReturn = ++pParse->nMem; pExpr->y.sub.iAddr = - sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1; + sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1; + VdbeComment((v, "return address")); addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); } /* Check to see if this is a vector IN operator */ @@ -109376,11 +105658,10 @@ ** 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( addrOnce && !sqlite3ExprIsConstant(pE2) ){ - sqlite3VdbeChangeToNoop(v, addrOnce-1); sqlite3VdbeChangeToNoop(v, addrOnce); ExprClearProperty(pExpr, EP_Subrtn); addrOnce = 0; } @@ -109394,19 +105675,15 @@ } if( pKeyInfo ){ sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO); } if( addrOnce ){ - sqlite3VdbeAddOp1(v, OP_NullRow, iTab); sqlite3VdbeJumpHere(v, addrOnce); /* Subroutine return */ assert( ExprUseYSub(pExpr) ); - assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn - || pParse->nErr ); - sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, - pExpr->y.sub.iAddr, 1); - VdbeCoverage(v); + sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn); + sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1); sqlite3ClearTempRegCache(pParse); } } #endif /* SQLITE_OMIT_SUBQUERY */ @@ -109430,13 +105707,10 @@ int rReg = 0; /* Register storing resulting */ Select *pSel; /* SELECT statement to encode */ SelectDest dest; /* How to deal with SELECT result */ int nReg; /* Registers to allocate */ Expr *pLimit; /* New limit expression */ -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS - int addrExplain; /* Address of OP_Explain instruction */ -#endif Vdbe *v = pParse->pVdbe; assert( v!=0 ); if( pParse->nErr ) return 0; testcase( pExpr->op==TK_EXISTS ); @@ -109459,11 +105733,13 @@ assert( !ExprUseYWin(pExpr) ); assert( !ExprHasProperty(pExpr, EP_Reduced|EP_TokenOnly) ); ExprSetProperty(pExpr, EP_Subrtn); pExpr->y.sub.regReturn = ++pParse->nMem; pExpr->y.sub.iAddr = - sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1; + sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1; + VdbeComment((v, "return address")); + /* The evaluation of the EXISTS/SELECT must be repeated every time it ** is encountered if any of the following is true: ** ** * The right-hand side is a correlated subquery @@ -109485,13 +105761,12 @@ ** into a register and return that register number. ** ** In both cases, the query is augmented with "LIMIT 1". Any ** preexisting limit is discarded in place of the new LIMIT 1. */ - ExplainQueryPlan2(addrExplain, (pParse, 1, "%sSCALAR SUBQUERY %d", + ExplainQueryPlan((pParse, 1, "%sSCALAR SUBQUERY %d", addrOnce?"":"CORRELATED ", pSel->selId)); - sqlite3VdbeScanStatusCounters(v, addrExplain, addrExplain, -1); nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1; sqlite3SelectDestInit(&dest, 0, pParse->nMem+1); pParse->nMem += nReg; if( pExpr->op==TK_SELECT ){ dest.eDest = SRT_Mem; @@ -109512,11 +105787,11 @@ if( pLimit ){ pLimit->affExpr = SQLITE_AFF_NUMERIC; pLimit = sqlite3PExpr(pParse, TK_NE, sqlite3ExprDup(db, pSel->pLimit->pLeft, 0), pLimit); } - sqlite3ExprDeferredDelete(pParse, pSel->pLimit->pLeft); + sqlite3ExprDelete(db, pSel->pLimit->pLeft); pSel->pLimit->pLeft = pLimit; }else{ /* If there is no pre-existing limit add a limit of 1 */ pLimit = sqlite3Expr(pParse->db, TK_INTEGER, "1"); pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0); @@ -109530,19 +105805,15 @@ pExpr->iTable = rReg = dest.iSDParm; ExprSetVVAProperty(pExpr, EP_NoReduce); if( addrOnce ){ sqlite3VdbeJumpHere(v, addrOnce); } - sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1); /* Subroutine return */ assert( ExprUseYSub(pExpr) ); - assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn - || pParse->nErr ); - sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, - pExpr->y.sub.iAddr, 1); - VdbeCoverage(v); + sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn); + sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1); sqlite3ClearTempRegCache(pParse); return rReg; } #endif /* SQLITE_OMIT_SUBQUERY */ @@ -109939,11 +106210,10 @@ Column *pCol, /* The generated column */ int regOut /* Put the result in this register */ ){ int iAddr; Vdbe *v = pParse->pVdbe; - int nErr = pParse->nErr; assert( v!=0 ); assert( pParse->iSelfTab!=0 ); if( pParse->iSelfTab>0 ){ iAddr = sqlite3VdbeAddOp3(v, OP_IfNullRow, pParse->iSelfTab-1, 0, regOut); }else{ @@ -109952,11 +106222,10 @@ sqlite3ExprCodeCopy(pParse, sqlite3ColumnExpr(pTab,pCol), regOut); if( pCol->affinity>=SQLITE_AFF_TEXT ){ sqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1); } if( iAddr ) sqlite3VdbeJumpHere(v, iAddr); - if( pParse->nErr>nErr ) pParse->db->errByteOffset = -1; } #endif /* SQLITE_OMIT_GENERATED_COLUMNS */ /* ** Generate code to extract the value of the iCol-th column of a table. @@ -109968,15 +106237,16 @@ int iCol, /* Index of the column to extract */ int regOut /* Extract the value into this register */ ){ Column *pCol; assert( v!=0 ); - assert( pTab!=0 ); - assert( iCol!=XN_EXPR ); + if( pTab==0 ){ + sqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut); + return; + } if( iCol<0 || iCol==pTab->iPKey ){ sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut); - VdbeComment((v, "%s.rowid", pTab->zName)); }else{ int op; int x; if( IsVirtual(pTab) ){ op = OP_VColumn; @@ -110027,11 +106297,11 @@ u8 p5 /* P5 value for OP_Column + FLAGS */ ){ assert( pParse->pVdbe!=0 ); sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pTab, iTable, iColumn, iReg); if( p5 ){ - VdbeOp *pOp = sqlite3VdbeGetLastOp(pParse->pVdbe); + VdbeOp *pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1); if( pOp->opcode==OP_Column ) pOp->p5 = p5; } return iReg; } @@ -110096,11 +106366,11 @@ /* ** If the last opcode is a OP_Copy, then set the do-not-merge flag (p5) ** so that a subsequent copy will not be merged into this one. */ static void setDoNotMergeFlagOnCopy(Vdbe *v){ - if( sqlite3VdbeGetLastOp(v)->opcode==OP_Copy ){ + if( sqlite3VdbeGetOp(v, -1)->opcode==OP_Copy ){ sqlite3VdbeChangeP5(v, 1); /* Tag trailing OP_Copy as not mergable */ } } /* @@ -110143,21 +106413,11 @@ memset(&caseExpr, 0, sizeof(caseExpr)); caseExpr.op = TK_CASE; caseExpr.x.pList = pFarg; return sqlite3ExprCodeTarget(pParse, &caseExpr, target); } -#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC - case INLINEFUNC_sqlite_offset: { - Expr *pArg = pFarg->a[0].pExpr; - if( pArg->op==TK_COLUMN && pArg->iTable>=0 ){ - sqlite3VdbeAddOp3(v, OP_Offset, pArg->iTable, pArg->iColumn, target); - }else{ - sqlite3VdbeAddOp2(v, OP_Null, 0, target); - } - break; - } -#endif + default: { /* The UNLIKELY() function is a no-op. The result is the value ** of the first argument. */ assert( nFarg==1 || nFarg==2 ); @@ -110206,84 +106466,23 @@ case INLINEFUNC_affinity: { /* The AFFINITY() function evaluates to a string that describes ** the type affinity of the argument. This is used for testing of ** the SQLite type logic. */ - const char *azAff[] = { "blob", "text", "numeric", "integer", - "real", "flexnum" }; + const char *azAff[] = { "blob", "text", "numeric", "integer", "real" }; char aff; assert( nFarg==1 ); aff = sqlite3ExprAffinity(pFarg->a[0].pExpr); - assert( aff<=SQLITE_AFF_NONE - || (aff>=SQLITE_AFF_BLOB && aff<=SQLITE_AFF_FLEXNUM) ); sqlite3VdbeLoadString(v, target, (aff<=SQLITE_AFF_NONE) ? "none" : azAff[aff-SQLITE_AFF_BLOB]); break; } #endif /* !defined(SQLITE_UNTESTABLE) */ } return target; } -/* -** Check to see if pExpr is one of the indexed expressions on pParse->pIdxEpr. -** If it is, then resolve the expression by reading from the index and -** return the register into which the value has been read. If pExpr is -** not an indexed expression, then return negative. -*/ -static SQLITE_NOINLINE int sqlite3IndexedExprLookup( - Parse *pParse, /* The parsing context */ - Expr *pExpr, /* The expression to potentially bypass */ - int target /* Where to store the result of the expression */ -){ - IndexedExpr *p; - Vdbe *v; - for(p=pParse->pIdxEpr; p; p=p->pIENext){ - u8 exprAff; - int iDataCur = p->iDataCur; - if( iDataCur<0 ) continue; - if( pParse->iSelfTab ){ - if( p->iDataCur!=pParse->iSelfTab-1 ) continue; - iDataCur = -1; - } - if( sqlite3ExprCompare(0, pExpr, p->pExpr, iDataCur)!=0 ) continue; - assert( p->aff>=SQLITE_AFF_BLOB && p->aff<=SQLITE_AFF_NUMERIC ); - exprAff = sqlite3ExprAffinity(pExpr); - if( (exprAff<=SQLITE_AFF_BLOB && p->aff!=SQLITE_AFF_BLOB) - || (exprAff==SQLITE_AFF_TEXT && p->aff!=SQLITE_AFF_TEXT) - || (exprAff>=SQLITE_AFF_NUMERIC && p->aff!=SQLITE_AFF_NUMERIC) - ){ - /* Affinity mismatch on a generated column */ - continue; - } - - v = pParse->pVdbe; - assert( v!=0 ); - if( p->bMaybeNullRow ){ - /* If the index is on a NULL row due to an outer join, then we - ** cannot extract the value from the index. The value must be - ** computed using the original expression. */ - int addr = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp3(v, OP_IfNullRow, p->iIdxCur, addr+3, target); - VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_Column, p->iIdxCur, p->iIdxCol, target); - VdbeComment((v, "%s expr-column %d", p->zIdxName, p->iIdxCol)); - sqlite3VdbeGoto(v, 0); - p = pParse->pIdxEpr; - pParse->pIdxEpr = 0; - sqlite3ExprCode(pParse, pExpr, target); - pParse->pIdxEpr = p; - sqlite3VdbeJumpHere(v, addr+2); - }else{ - sqlite3VdbeAddOp3(v, OP_Column, p->iIdxCur, p->iIdxCol, target); - VdbeComment((v, "%s expr-column %d", p->zIdxName, p->iIdxCol)); - } - return target; - } - return -1; /* Not found */ -} - /* ** 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. @@ -110308,61 +106507,38 @@ assert( v!=0 ); expr_code_doover: if( pExpr==0 ){ op = TK_NULL; - }else if( pParse->pIdxEpr!=0 - && !ExprHasProperty(pExpr, EP_Leaf) - && (r1 = sqlite3IndexedExprLookup(pParse, pExpr, target))>=0 - ){ - return r1; }else{ assert( !ExprHasVVAProperty(pExpr,EP_Immutable) ); op = pExpr->op; } switch( op ){ case TK_AGG_COLUMN: { AggInfo *pAggInfo = pExpr->pAggInfo; struct AggInfo_col *pCol; assert( pAggInfo!=0 ); - assert( pExpr->iAgg>=0 ); - if( pExpr->iAgg>=pAggInfo->nColumn ){ - /* Happens when the left table of a RIGHT JOIN is null and - ** is using an expression index */ - sqlite3VdbeAddOp2(v, OP_Null, 0, target); -#ifdef SQLITE_VDBE_COVERAGE - /* Verify that the OP_Null above is exercised by tests - ** tag-20230325-2 */ - sqlite3VdbeAddOp2(v, OP_NotNull, target, 1); - VdbeCoverageNeverTaken(v); -#endif - break; - } + assert( pExpr->iAgg>=0 && pExpr->iAggnColumn ); pCol = &pAggInfo->aCol[pExpr->iAgg]; if( !pAggInfo->directMode ){ - return AggInfoColumnReg(pAggInfo, pExpr->iAgg); + assert( pCol->iMem>0 ); + return pCol->iMem; }else if( pAggInfo->useSortingIdx ){ Table *pTab = pCol->pTab; sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab, pCol->iSorterColumn, target); - if( pTab==0 ){ - /* No comment added */ - }else if( pCol->iColumn<0 ){ + if( pCol->iColumn<0 ){ VdbeComment((v,"%s.rowid",pTab->zName)); }else{ VdbeComment((v,"%s.%s", pTab->zName, pTab->aCol[pCol->iColumn].zCnName)); if( pTab->aCol[pCol->iColumn].affinity==SQLITE_AFF_REAL ){ sqlite3VdbeAddOp1(v, OP_RealAffinity, target); } } return target; - }else if( pExpr->y.pTab==0 ){ - /* This case happens when the argument to an aggregate function - ** is rewritten by aggregateConvertIndexedExprRefToColumn() */ - sqlite3VdbeAddOp3(v, OP_Column, pExpr->iTable, pExpr->iColumn, target); - return target; } /* Otherwise, fall thru into the TK_COLUMN case */ /* no break */ deliberate_fall_through } case TK_COLUMN: { @@ -110376,14 +106552,17 @@ ** constant. */ int aff; iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target); assert( ExprUseYTab(pExpr) ); - assert( pExpr->y.pTab!=0 ); - aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); + if( pExpr->y.pTab ){ + aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); + }else{ + aff = pExpr->affExpr; + } if( aff>SQLITE_AFF_BLOB ){ - static const char zAff[] = "B\000C\000D\000E\000F"; + static const char zAff[] = "B\000C\000D\000E"; assert( SQLITE_AFF_BLOB=='A' ); assert( SQLITE_AFF_TEXT=='B' ); sqlite3VdbeAddOp4(v, OP_Affinity, iReg, 1, 0, &zAff[(aff-'B')*2], P4_STATIC); } @@ -110439,14 +106618,16 @@ ** in the index refer to the table to which the index belongs */ iTab = pParse->iSelfTab - 1; } } assert( ExprUseYTab(pExpr) ); - assert( pExpr->y.pTab!=0 ); iReg = sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab, pExpr->iColumn, iTab, target, pExpr->op2); + if( pExpr->y.pTab==0 && pExpr->affExpr==SQLITE_AFF_REAL ){ + sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); + } return iReg; } case TK_INTEGER: { codeInteger(pParse, pExpr, 0, target); return target; @@ -110509,12 +106690,15 @@ return pExpr->iTable; } #ifndef SQLITE_OMIT_CAST case TK_CAST: { /* Expressions of the form: CAST(pLeft AS token) */ - sqlite3ExprCode(pParse, pExpr->pLeft, target); - assert( inReg==target ); + inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); + if( inReg!=target ){ + sqlite3VdbeAddOp2(v, OP_SCopy, inReg, target); + inReg = target; + } assert( !ExprHasProperty(pExpr, EP_IntValue) ); sqlite3VdbeAddOp2(v, OP_Cast, target, sqlite3AffinityType(pExpr->u.zToken, 0)); return inReg; } @@ -110653,11 +106837,11 @@ || NEVER(pExpr->iAgg>=pInfo->nFunc) ){ assert( !ExprHasProperty(pExpr, EP_IntValue) ); sqlite3ErrorMsg(pParse, "misuse of aggregate: %#T()", pExpr); }else{ - return AggInfoFuncReg(pInfo, pExpr->iAgg); + return pInfo->aFunc[pExpr->iAgg].iMem; } break; } case TK_FUNCTION: { ExprList *pFarg; /* List of function arguments */ @@ -110768,12 +106952,24 @@ #endif if( pDef->funcFlags & SQLITE_FUNC_NEEDCOLL ){ if( !pColl ) pColl = db->pDfltColl; sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ); } - sqlite3VdbeAddFunctionCall(pParse, constMask, r1, target, nFarg, - pDef, pExpr->op2); +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC + if( (pDef->funcFlags & SQLITE_FUNC_OFFSET)!=0 && ALWAYS(pFarg!=0) ){ + Expr *pArg = pFarg->a[0].pExpr; + if( pArg->op==TK_COLUMN ){ + sqlite3VdbeAddOp3(v, OP_Offset, pArg->iTable, pArg->iColumn, target); + }else{ + sqlite3VdbeAddOp2(v, OP_Null, 0, target); + } + }else +#endif + { + sqlite3VdbeAddFunctionCall(pParse, constMask, r1, target, nFarg, + pDef, pExpr->op2); + } if( nFarg ){ if( constMask==0 ){ sqlite3ReleaseTempRange(pParse, r1, nFarg); }else{ sqlite3VdbeReleaseRegisters(pParse, r1, nFarg, constMask, 1); @@ -110799,22 +106995,20 @@ } break; } case TK_SELECT_COLUMN: { int n; - Expr *pLeft = pExpr->pLeft; - if( pLeft->iTable==0 || pParse->withinRJSubrtn > pLeft->op2 ){ - pLeft->iTable = sqlite3CodeSubselect(pParse, pLeft); - pLeft->op2 = pParse->withinRJSubrtn; + if( pExpr->pLeft->iTable==0 ){ + pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft); } - assert( pLeft->op==TK_SELECT || pLeft->op==TK_ERROR ); - n = sqlite3ExprVectorSize(pLeft); + assert( pExpr->pLeft->op==TK_SELECT || pExpr->pLeft->op==TK_ERROR ); + n = sqlite3ExprVectorSize(pExpr->pLeft); if( pExpr->iTable!=n ){ sqlite3ErrorMsg(pParse, "%d columns assigned %d values", pExpr->iTable, n); } - return pLeft->iTable + pExpr->iColumn; + return pExpr->pLeft->iTable + pExpr->iColumn; } case TK_IN: { int destIfFalse = sqlite3VdbeMakeLabel(pParse); int destIfNull = sqlite3VdbeMakeLabel(pParse); sqlite3VdbeAddOp2(v, OP_Null, 0, target); @@ -110841,27 +107035,12 @@ */ case TK_BETWEEN: { exprCodeBetween(pParse, pExpr, target, 0, 0); return target; } - case TK_COLLATE: { - if( !ExprHasProperty(pExpr, EP_Collate) ){ - /* A TK_COLLATE Expr node without the EP_Collate tag is a so-called - ** "SOFT-COLLATE" that is added to constraints that are pushed down - ** from outer queries into sub-queries by the push-down optimization. - ** Clear subtypes as subtypes may not cross a subquery boundary. - */ - assert( pExpr->pLeft ); - sqlite3ExprCode(pParse, pExpr->pLeft, target); - sqlite3VdbeAddOp1(v, OP_ClrSubtype, target); - return target; - }else{ - pExpr = pExpr->pLeft; - goto expr_code_doover; /* 2018-04-28: Prevent deep recursion. */ - } - } case TK_SPAN: + case TK_COLLATE: case TK_UPLUS: { pExpr = pExpr->pLeft; goto expr_code_doover; /* 2018-04-28: Prevent deep recursion. OSSFuzz. */ } @@ -110937,38 +107116,20 @@ ** on a LEFT JOIN NULL row. */ case TK_IF_NULL_ROW: { int addrINR; u8 okConstFactor = pParse->okConstFactor; - AggInfo *pAggInfo = pExpr->pAggInfo; - if( pAggInfo ){ - assert( pExpr->iAgg>=0 && pExpr->iAggnColumn ); - if( !pAggInfo->directMode ){ - inReg = AggInfoColumnReg(pAggInfo, pExpr->iAgg); - break; - } - if( pExpr->pAggInfo->useSortingIdx ){ - sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab, - pAggInfo->aCol[pExpr->iAgg].iSorterColumn, - target); - inReg = target; - break; - } - } - addrINR = sqlite3VdbeAddOp3(v, OP_IfNullRow, pExpr->iTable, 0, target); - /* The OP_IfNullRow opcode above can overwrite the result register with - ** NULL. So we have to ensure that the result register is not a value - ** that is suppose to be a constant. Two defenses are needed: - ** (1) Temporarily disable factoring of constant expressions - ** (2) Make sure the computed value really is stored in register - ** "target" and not someplace else. - */ - pParse->okConstFactor = 0; /* note (1) above */ - sqlite3ExprCode(pParse, pExpr->pLeft, target); - assert( target==inReg ); + addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable); + /* Temporarily disable factoring of constant expressions, since + ** even though expressions may appear to be constant, they are not + ** really constant because they originate from the right-hand side + ** of a LEFT JOIN. */ + pParse->okConstFactor = 0; + inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); pParse->okConstFactor = okConstFactor; sqlite3VdbeJumpHere(v, addrINR); + sqlite3VdbeChangeP3(v, addrINR, inReg); break; } /* ** Form A: @@ -111116,13 +107277,11 @@ p = pParse->pConstExpr; if( regDest<0 && p ){ struct ExprList_item *pItem; int i; for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){ - if( pItem->fg.reusable - && sqlite3ExprCompare(0,pItem->pExpr,pExpr,-1)==0 - ){ + if( pItem->reusable && sqlite3ExprCompare(0,pItem->pExpr,pExpr,-1)==0 ){ return pItem->u.iConstExprReg; } } } pExpr = sqlite3ExprDup(pParse->db, pExpr, 0); @@ -111141,11 +107300,11 @@ sqlite3VdbeJumpHere(v, addr); }else{ p = sqlite3ExprListAppend(pParse, p, pExpr); if( p ){ struct ExprList_item *pItem = &p->a[p->nExpr-1]; - pItem->fg.reusable = regDest<0; + pItem->reusable = regDest<0; if( regDest<0 ) regDest = ++pParse->nMem; pItem->u.iConstExprReg = regDest; } pParse->pConstExpr = p; } @@ -111201,13 +107360,11 @@ assert( pParse->pVdbe!=0 || pParse->db->mallocFailed ); if( pParse->pVdbe==0 ) return; inReg = sqlite3ExprCodeTarget(pParse, pExpr, target); if( inReg!=target ){ u8 op; - if( ALWAYS(pExpr) - && (ExprHasProperty(pExpr,EP_Subquery) || pExpr->op==TK_REGISTER) - ){ + if( ALWAYS(pExpr) && ExprHasProperty(pExpr,EP_Subquery) ){ op = OP_Copy; }else{ op = OP_SCopy; } sqlite3VdbeAddOp2(pParse->pVdbe, op, inReg, target); @@ -111277,11 +107434,11 @@ n = pList->nExpr; if( !ConstFactorOk(pParse) ) flags &= ~SQLITE_ECEL_FACTOR; for(pItem=pList->a, i=0; ipExpr; #ifdef SQLITE_ENABLE_SORTER_REFERENCES - if( pItem->fg.bSorterRef ){ + if( pItem->bSorterRef ){ i--; n--; }else #endif if( (flags & SQLITE_ECEL_REF)!=0 && (j = pItem->u.x.iOrderByCol)>0 ){ @@ -111298,11 +107455,11 @@ }else{ int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i); if( inReg!=target+i ){ VdbeOp *pOp; if( copyOp==OP_Copy - && (pOp=sqlite3VdbeGetLastOp(v))->opcode==OP_Copy + && (pOp=sqlite3VdbeGetOp(v, -1))->opcode==OP_Copy && pOp->p1+pOp->p3+1==inReg && pOp->p2+pOp->p3+1==target+i && pOp->p5==0 /* The do-not-merge flag must be clear */ ){ pOp->p3++; @@ -111371,12 +107528,12 @@ }else{ /* Mark the expression is being from the ON or USING clause of a join ** so that the sqlite3ExprCodeTarget() routine will not attempt to move ** it into the Parse.pConstExpr list. We should use a new bit for this, ** for clarity, but we are out of bits in the Expr.flags field so we - ** have to reuse the EP_OuterON bit. Bummer. */ - pDel->flags |= EP_OuterON; + ** have to reuse the EP_FromJoin bit. Bummer. */ + pDel->flags |= EP_FromJoin; sqlite3ExprCodeTarget(pParse, &exprAnd, dest); } sqlite3ReleaseTempReg(pParse, regFree1); } sqlite3ExprDelete(db, pDel); @@ -111497,11 +107654,10 @@ case TK_ISNULL: case TK_NOTNULL: { assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL ); assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - sqlite3VdbeTypeofColumn(v, r1); sqlite3VdbeAddOp2(v, op, r1, dest); VdbeCoverageIf(v, op==TK_ISNULL); VdbeCoverageIf(v, op==TK_NOTNULL); testcase( regFree1==0 ); break; @@ -111672,11 +107828,10 @@ break; } case TK_ISNULL: case TK_NOTNULL: { r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - sqlite3VdbeTypeofColumn(v, r1); sqlite3VdbeAddOp2(v, op, r1, dest); testcase( op==TK_ISNULL ); VdbeCoverageIf(v, op==TK_ISNULL); testcase( op==TK_NOTNULL ); VdbeCoverageIf(v, op==TK_NOTNULL); testcase( regFree1==0 ); break; @@ -111826,17 +107981,11 @@ return 1; } if( pB->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA,pB->pLeft,iTab)<2 ){ return 1; } - if( pA->op==TK_AGG_COLUMN && pB->op==TK_COLUMN - && pB->iTable<0 && pA->iTable==iTab - ){ - /* fall through */ - }else{ - return 2; - } + return 2; } assert( !ExprHasProperty(pA, EP_IntValue) ); assert( !ExprHasProperty(pB, EP_IntValue) ); if( pA->u.zToken ){ if( pA->op==TK_FUNCTION || pA->op==TK_AGG_FUNCTION ){ @@ -111910,11 +108059,11 @@ if( pA->nExpr!=pB->nExpr ) return 1; for(i=0; inExpr; i++){ int res; Expr *pExprA = pA->a[i].pExpr; Expr *pExprB = pB->a[i].pExpr; - if( pA->a[i].fg.sortFlags!=pB->a[i].fg.sortFlags ) return 1; + if( pA->a[i].sortFlags!=pB->a[i].sortFlags ) return 1; if( (res = sqlite3ExprCompare(0, pExprA, pExprB, iTab)) ) return res; } return 0; } @@ -112065,11 +108214,11 @@ ** (never setting pWalker->eCode) is a harmless missed optimization. */ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ testcase( pExpr->op==TK_AGG_COLUMN ); testcase( pExpr->op==TK_AGG_FUNCTION ); - if( ExprHasProperty(pExpr, EP_OuterON) ) return WRC_Prune; + if( ExprHasProperty(pExpr, EP_FromJoin) ) return WRC_Prune; switch( pExpr->op ){ case TK_ISNOT: case TK_ISNULL: case TK_NOTNULL: case TK_IS: @@ -112134,14 +108283,14 @@ /* The y.pTab=0 assignment in wherecode.c always happens after the ** impliesNotNullRow() test */ assert( pLeft->op!=TK_COLUMN || ExprUseYTab(pLeft) ); assert( pRight->op!=TK_COLUMN || ExprUseYTab(pRight) ); if( (pLeft->op==TK_COLUMN - && ALWAYS(pLeft->y.pTab!=0) + && pLeft->y.pTab!=0 && IsVirtual(pLeft->y.pTab)) || (pRight->op==TK_COLUMN - && ALWAYS(pRight->y.pTab!=0) + && pRight->y.pTab!=0 && IsVirtual(pRight->y.pTab)) ){ return WRC_Prune; } /* no break */ deliberate_fall_through @@ -112162,12 +108311,12 @@ ** is NULL. A false negative is merely a missed optimization opportunity. ** ** False positives are not allowed, however. A false positive may result ** in an incorrect answer. ** -** Terms of p that are marked with EP_OuterON (and hence that come from -** the ON or USING clauses of OUTER JOINS) are excluded from the analysis. +** Terms of p that are marked with EP_FromJoin (and hence that come from +** the ON or USING clauses of LEFT JOINS) are excluded from the analysis. ** ** This routine is used to check if a LEFT JOIN can be converted into ** an ordinary JOIN. The p argument is the WHERE clause. If the WHERE ** clause requires that some column of the right table of the LEFT JOIN ** be non-NULL, then the LEFT JOIN can be safely converted into an @@ -112342,11 +108491,10 @@ ** fact is exploited for efficiency. */ SQLITE_PRIVATE int sqlite3ReferencesSrcList(Parse *pParse, Expr *pExpr, SrcList *pSrcList){ Walker w; struct RefSrcList x; - assert( pParse->db!=0 ); memset(&w, 0, sizeof(w)); memset(&x, 0, sizeof(x)); w.xExprCallback = exprRefToSrcList; w.xSelectCallback = selectRefEnter; w.xSelectCallback2 = selectRefLeave; @@ -112359,11 +108507,11 @@ #ifndef SQLITE_OMIT_WINDOWFUNC if( ExprHasProperty(pExpr, EP_WinFunc) ){ sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter); } #endif - if( x.aiExclude ) sqlite3DbNNFreeNN(pParse->db, x.aiExclude); + sqlite3DbFree(pParse->db, x.aiExclude); if( w.eCode & 0x01 ){ return 1; }else if( w.eCode ){ return 0; }else{ @@ -112377,37 +108525,36 @@ ** For Expr nodes that contain pAggInfo pointers, make sure the AggInfo ** object that is referenced does not refer directly to the Expr. If ** it does, make a copy. This is done because the pExpr argument is ** subject to change. ** -** The copy is scheduled for deletion using the sqlite3ExprDeferredDelete() -** which builds on the sqlite3ParserAddCleanup() mechanism. +** The copy is stored on pParse->pConstExpr with a register number of 0. +** This will cause the expression to be deleted automatically when the +** Parse object is destroyed, but the zero register number means that it +** will not generate any code in the preamble. */ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){ if( ALWAYS(!ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced)) && pExpr->pAggInfo!=0 ){ AggInfo *pAggInfo = pExpr->pAggInfo; int iAgg = pExpr->iAgg; Parse *pParse = pWalker->pParse; sqlite3 *db = pParse->db; - assert( iAgg>=0 ); - if( pExpr->op!=TK_AGG_FUNCTION ){ - if( iAggnColumn - && pAggInfo->aCol[iAgg].pCExpr==pExpr - ){ + assert( pExpr->op==TK_AGG_COLUMN || pExpr->op==TK_AGG_FUNCTION ); + if( pExpr->op==TK_AGG_COLUMN ){ + assert( iAgg>=0 && iAggnColumn ); + if( pAggInfo->aCol[iAgg].pCExpr==pExpr ){ pExpr = sqlite3ExprDup(db, pExpr, 0); if( pExpr ){ pAggInfo->aCol[iAgg].pCExpr = pExpr; sqlite3ExprDeferredDelete(pParse, pExpr); } } }else{ - assert( pExpr->op==TK_AGG_FUNCTION ); - if( ALWAYS(iAggnFunc) - && pAggInfo->aFunc[iAgg].pFExpr==pExpr - ){ + assert( iAgg>=0 && iAggnFunc ); + if( pAggInfo->aFunc[iAgg].pFExpr==pExpr ){ pExpr = sqlite3ExprDup(db, pExpr, 0); if( pExpr ){ pAggInfo->aFunc[iAgg].pFExpr = pExpr; sqlite3ExprDeferredDelete(pParse, pExpr); } @@ -112458,77 +108605,10 @@ &i ); return i; } -/* -** Search the AggInfo object for an aCol[] entry that has iTable and iColumn. -** Return the index in aCol[] of the entry that describes that column. -** -** If no prior entry is found, create a new one and return -1. The -** new column will have an idex of pAggInfo->nColumn-1. -*/ -static void findOrCreateAggInfoColumn( - Parse *pParse, /* Parsing context */ - AggInfo *pAggInfo, /* The AggInfo object to search and/or modify */ - Expr *pExpr /* Expr describing the column to find or insert */ -){ - struct AggInfo_col *pCol; - int k; - - assert( pAggInfo->iFirstReg==0 ); - pCol = pAggInfo->aCol; - for(k=0; knColumn; k++, pCol++){ - if( pCol->iTable==pExpr->iTable - && pCol->iColumn==pExpr->iColumn - && pExpr->op!=TK_IF_NULL_ROW - ){ - goto fix_up_expr; - } - } - k = addAggInfoColumn(pParse->db, pAggInfo); - if( k<0 ){ - /* OOM on resize */ - assert( pParse->db->mallocFailed ); - return; - } - pCol = &pAggInfo->aCol[k]; - assert( ExprUseYTab(pExpr) ); - pCol->pTab = pExpr->y.pTab; - pCol->iTable = pExpr->iTable; - pCol->iColumn = pExpr->iColumn; - pCol->iSorterColumn = -1; - pCol->pCExpr = pExpr; - if( pAggInfo->pGroupBy && pExpr->op!=TK_IF_NULL_ROW ){ - int j, n; - ExprList *pGB = pAggInfo->pGroupBy; - struct ExprList_item *pTerm = pGB->a; - n = pGB->nExpr; - for(j=0; jpExpr; - 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++; - } -fix_up_expr: - ExprSetVVAProperty(pExpr, EP_NoReduce); - assert( pExpr->pAggInfo==0 || pExpr->pAggInfo==pAggInfo ); - pExpr->pAggInfo = pAggInfo; - if( pExpr->op==TK_COLUMN ){ - pExpr->op = TK_AGG_COLUMN; - } - pExpr->iAgg = (i16)k; -} - /* ** This is the xExprCallback for a tree walker. It is used to ** implement sqlite3ExprAnalyzeAggregates(). See sqlite3ExprAnalyzeAggregates ** for additional information. */ @@ -112538,68 +108618,80 @@ Parse *pParse = pNC->pParse; SrcList *pSrcList = pNC->pSrcList; AggInfo *pAggInfo = pNC->uNC.pAggInfo; assert( pNC->ncFlags & NC_UAggInfo ); - assert( pAggInfo->iFirstReg==0 ); switch( pExpr->op ){ - default: { - IndexedExpr *pIEpr; - Expr tmp; - assert( pParse->iSelfTab==0 ); - if( (pNC->ncFlags & NC_InAggFunc)==0 ) break; - if( pParse->pIdxEpr==0 ) break; - for(pIEpr=pParse->pIdxEpr; pIEpr; pIEpr=pIEpr->pIENext){ - int iDataCur = pIEpr->iDataCur; - if( iDataCur<0 ) continue; - if( sqlite3ExprCompare(0, pExpr, pIEpr->pExpr, iDataCur)==0 ) break; - } - if( pIEpr==0 ) break; - if( NEVER(!ExprUseYTab(pExpr)) ) break; - for(i=0; inSrc; i++){ - if( pSrcList->a[0].iCursor==pIEpr->iDataCur ) break; - } - if( i>=pSrcList->nSrc ) break; - if( NEVER(pExpr->pAggInfo!=0) ) break; /* Resolved by outer context */ - if( pParse->nErr ){ return WRC_Abort; } - - /* If we reach this point, it means that expression pExpr can be - ** translated into a reference to an index column as described by - ** pIEpr. - */ - memset(&tmp, 0, sizeof(tmp)); - tmp.op = TK_AGG_COLUMN; - tmp.iTable = pIEpr->iIdxCur; - tmp.iColumn = pIEpr->iIdxCol; - findOrCreateAggInfoColumn(pParse, pAggInfo, &tmp); - if( pParse->nErr ){ return WRC_Abort; } - assert( pAggInfo->aCol!=0 ); - assert( tmp.iAggnColumn ); - pAggInfo->aCol[tmp.iAgg].pCExpr = pExpr; - pExpr->pAggInfo = pAggInfo; - pExpr->iAgg = tmp.iAgg; - return WRC_Prune; - } - case TK_IF_NULL_ROW: case TK_AGG_COLUMN: case TK_COLUMN: { testcase( pExpr->op==TK_AGG_COLUMN ); testcase( pExpr->op==TK_COLUMN ); - testcase( pExpr->op==TK_IF_NULL_ROW ); /* Check to see if the column is in one of the tables in the FROM ** clause of the aggregate query */ if( ALWAYS(pSrcList!=0) ){ SrcItem *pItem = pSrcList->a; for(i=0; inSrc; i++, pItem++){ + struct AggInfo_col *pCol; assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); if( pExpr->iTable==pItem->iCursor ){ - findOrCreateAggInfoColumn(pParse, pAggInfo, pExpr); + /* 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; knColumn; 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]; + assert( ExprUseYTab(pExpr) ); + pCol->pTab = pExpr->y.pTab; + pCol->iTable = pExpr->iTable; + pCol->iColumn = pExpr->iColumn; + pCol->iMem = ++pParse->nMem; + pCol->iSorterColumn = -1; + pCol->pCExpr = pExpr; + if( pAggInfo->pGroupBy ){ + int j, n; + ExprList *pGB = pAggInfo->pGroupBy; + struct ExprList_item *pTerm = pGB->a; + n = pGB->nExpr; + for(j=0; jpExpr; + 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. + */ + ExprSetVVAProperty(pExpr, EP_NoReduce); + pExpr->pAggInfo = pAggInfo; + pExpr->op = TK_AGG_COLUMN; + pExpr->iAgg = (i16)k; break; } /* endif pExpr->iTable==pItem->iCursor */ } /* end loop over pSrcList */ } - return WRC_Continue; + return WRC_Prune; } case TK_AGG_FUNCTION: { if( (pNC->ncFlags & NC_InAggFunc)==0 && pWalker->walkerDepth==pExpr->op2 ){ @@ -112620,10 +108712,11 @@ i = addAggInfoFunc(pParse->db, pAggInfo); if( i>=0 ){ assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); pItem = &pAggInfo->aFunc[i]; pItem->pFExpr = pExpr; + pItem->iMem = ++pParse->nMem; assert( ExprUseUToken(pExpr) ); pItem->pFunc = sqlite3FindFunction(pParse->db, pExpr->u.zToken, pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0); if( pExpr->flags & EP_Distinct ){ @@ -112748,41 +108841,10 @@ SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse *pParse){ pParse->nTempReg = 0; pParse->nRangeReg = 0; } -/* -** Make sure sufficient registers have been allocated so that -** iReg is a valid register number. -*/ -SQLITE_PRIVATE void sqlite3TouchRegister(Parse *pParse, int iReg){ - if( pParse->nMemnMem = iReg; -} - -#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_DEBUG) -/* -** Return the latest reusable register in the set of all registers. -** The value returned is no less than iMin. If any register iMin or -** greater is in permanent use, then return one more than that last -** permanent register. -*/ -SQLITE_PRIVATE int sqlite3FirstAvailableRegister(Parse *pParse, int iMin){ - const ExprList *pList = pParse->pConstExpr; - if( pList ){ - int i; - for(i=0; inExpr; i++){ - if( pList->a[i].u.iConstExprReg>=iMin ){ - iMin = pList->a[i].u.iConstExprReg + 1; - } - } - } - pParse->nTempReg = 0; - pParse->nRangeReg = 0; - return iMin; -} -#endif /* SQLITE_ENABLE_STAT4 || SQLITE_DEBUG */ - /* ** Validate that no temporary register falls within the range of ** iFirst..iLast, inclusive. This routine is only call from within assert() ** statements. */ @@ -112798,18 +108860,10 @@ for(i=0; inTempReg; i++){ if( pParse->aTempReg[i]>=iFirst && pParse->aTempReg[i]<=iLast ){ return 0; } } - if( pParse->pConstExpr ){ - ExprList *pList = pParse->pConstExpr; - for(i=0; inExpr; i++){ - int iReg = pList->a[i].u.iConstExprReg; - if( iReg==0 ) continue; - if( iReg>=iFirst && iReg<=iLast ) return 0; - } - } return 1; } #endif /* SQLITE_DEBUG */ /************** End of expr.c ************************************************/ @@ -113555,18 +109609,17 @@ static void renameTokenCheckAll(Parse *pParse, const void *pPtr){ assert( pParse==pParse->db->pParse ); assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 ); if( pParse->nErr==0 ){ const RenameToken *p; - u32 i = 1; + u8 i = 0; for(p=pParse->pRename; p; p=p->pNext){ if( p->p ){ assert( p->p!=pPtr ); - i += *(u8*)(p->p) | 1; + i += *(u8*)(p->p); } } - assert( i>0 ); } } #else # define renameTokenCheckAll(x,y) #endif @@ -113673,14 +109726,15 @@ */ static void unmapColumnIdlistNames( Parse *pParse, const IdList *pIdList ){ - int ii; - assert( pIdList!=0 ); - for(ii=0; iinId; ii++){ - sqlite3RenameTokenRemap(pParse, 0, (const void*)pIdList->a[ii].zName); + if( pIdList ){ + int ii; + for(ii=0; iinId; ii++){ + sqlite3RenameTokenRemap(pParse, 0, (const void*)pIdList->a[ii].zName); + } } } /* ** Walker callback used by sqlite3RenameExprUnmap(). @@ -113695,24 +109749,21 @@ return WRC_Prune; } if( ALWAYS(p->pEList) ){ ExprList *pList = p->pEList; for(i=0; inExpr; i++){ - if( pList->a[i].zEName && pList->a[i].fg.eEName==ENAME_NAME ){ + if( pList->a[i].zEName && pList->a[i].eEName==ENAME_NAME ){ sqlite3RenameTokenRemap(pParse, 0, (void*)pList->a[i].zEName); } } } if( ALWAYS(p->pSrc) ){ /* Every Select as a SrcList, even if it is empty */ SrcList *pSrc = p->pSrc; for(i=0; inSrc; i++){ sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName); - if( pSrc->a[i].fg.isUsing==0 ){ - sqlite3WalkExpr(pWalker, pSrc->a[i].u3.pOn); - }else{ - unmapColumnIdlistNames(pParse, pSrc->a[i].u3.pUsing); - } + sqlite3WalkExpr(pWalker, pSrc->a[i].pOn); + unmapColumnIdlistNames(pParse, pSrc->a[i].pUsing); } } renameWalkWith(pWalker, p); return WRC_Continue; @@ -113744,11 +109795,11 @@ memset(&sWalker, 0, sizeof(Walker)); sWalker.pParse = pParse; sWalker.xExprCallback = renameUnmapExprCb; sqlite3WalkExprList(&sWalker, pEList); for(i=0; inExpr; i++){ - if( ALWAYS(pEList->a[i].fg.eEName==ENAME_NAME) ){ + if( ALWAYS(pEList->a[i].eEName==ENAME_NAME) ){ sqlite3RenameTokenRemap(pParse, 0, (void*)pEList->a[i].zEName); } } } } @@ -113902,11 +109953,11 @@ ){ if( pEList ){ int i; for(i=0; inExpr; i++){ const char *zName = pEList->a[i].zEName; - if( ALWAYS(pEList->a[i].fg.eEName==ENAME_NAME) + if( ALWAYS(pEList->a[i].eEName==ENAME_NAME) && ALWAYS(zName!=0) && 0==sqlite3_stricmp(zName, zOld) ){ renameTokenFind(pParse, pCtx, (const void*)zName); } @@ -114093,23 +110144,10 @@ sqlite3_free(zQuot); return rc; } -/* -** Set all pEList->a[].fg.eEName fields in the expression-list to val. -*/ -static void renameSetENames(ExprList *pEList, int val){ - if( pEList ){ - int i; - for(i=0; inExpr; i++){ - assert( val==ENAME_NAME || pEList->a[i].fg.eEName==ENAME_NAME ); - pEList->a[i].fg.eEName = val; - } - } -} - /* ** Resolve all symbols in the trigger at pParse->pNewTrigger, assuming ** it was read from the schema of database zDb. Return SQLITE_OK if ** successful. Otherwise, return an SQLite error code and leave an error ** message in the Parse object. @@ -114145,47 +110183,31 @@ if( pParse->nErr ) rc = pParse->rc; } if( rc==SQLITE_OK && pStep->zTarget ){ SrcList *pSrc = sqlite3TriggerStepSrc(pParse, pStep); if( pSrc ){ - Select *pSel = sqlite3SelectNew( - pParse, pStep->pExprList, pSrc, 0, 0, 0, 0, 0, 0 - ); - if( pSel==0 ){ - pStep->pExprList = 0; - pSrc = 0; - rc = SQLITE_NOMEM; - }else{ - /* pStep->pExprList contains an expression-list used for an UPDATE - ** statement. So the a[].zEName values are the RHS of the - ** "= " clauses of the UPDATE statement. So, before - ** running SelectPrep(), change all the eEName values in - ** pStep->pExprList to ENAME_SPAN (from their current value of - ** ENAME_NAME). This is to prevent any ids in ON() clauses that are - ** part of pSrc from being incorrectly resolved against the - ** a[].zEName values as if they were column aliases. */ - renameSetENames(pStep->pExprList, ENAME_SPAN); - sqlite3SelectPrep(pParse, pSel, 0); - renameSetENames(pStep->pExprList, ENAME_NAME); - rc = pParse->nErr ? SQLITE_ERROR : SQLITE_OK; - assert( pStep->pExprList==0 || pStep->pExprList==pSel->pEList ); - assert( pSrc==pSel->pSrc ); - if( pStep->pExprList ) pSel->pEList = 0; - pSel->pSrc = 0; - sqlite3SelectDelete(db, pSel); - } - if( pStep->pFrom ){ - int i; - for(i=0; ipFrom->nSrc && rc==SQLITE_OK; i++){ - SrcItem *p = &pStep->pFrom->a[i]; - if( p->pSelect ){ - sqlite3SelectPrep(pParse, p->pSelect, 0); - } - } - } - - if( db->mallocFailed ){ + int i; + for(i=0; inSrc && rc==SQLITE_OK; i++){ + SrcItem *p = &pSrc->a[i]; + p->iCursor = pParse->nTab++; + if( p->pSelect ){ + sqlite3SelectPrep(pParse, p->pSelect, 0); + sqlite3ExpandSubquery(pParse, p); + assert( i>0 ); + assert( pStep->pFrom->a[i-1].pSelect ); + sqlite3SelectPrep(pParse, pStep->pFrom->a[i-1].pSelect, 0); + }else{ + p->pTab = sqlite3LocateTableItem(pParse, 0, p); + if( p->pTab==0 ){ + rc = SQLITE_ERROR; + }else{ + p->pTab->nTabRef++; + rc = sqlite3ViewGetColumnNames(pParse, p->pTab); + } + } + } + if( rc==SQLITE_OK && db->mallocFailed ){ rc = SQLITE_NOMEM; } sNC.pSrcList = pSrc; if( rc==SQLITE_OK && pStep->pWhere ){ rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere); @@ -114633,19 +110655,10 @@ renameWalkTrigger(&sWalker, pTrigger); for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){ if( pStep->zTarget && 0==sqlite3_stricmp(pStep->zTarget, zOld) ){ renameTokenFind(&sParse, &sCtx, pStep->zTarget); } - if( pStep->pFrom ){ - int i; - for(i=0; ipFrom->nSrc; i++){ - SrcItem *pItem = &pStep->pFrom->a[i]; - if( 0==sqlite3_stricmp(pItem->zName, zOld) ){ - renameTokenFind(&sParse, &sCtx, pItem->zName); - } - } - } } } } } #endif @@ -115965,18 +111978,13 @@ ** * the index contains 100 rows, ** * "WHERE a=?" matches 10 rows, and ** * "WHERE a=? AND b=?" matches 2 rows. ** ** If D is the count of distinct values and K is the total number of - ** rows, then each estimate is usually computed as: + ** rows, then each estimate is computed as: ** ** I = (K+D-1)/D - ** - ** In other words, I is K/D rounded up to the next whole integer. - ** However, if I is between 1.0 and 1.1 (in other words if I is - ** close to 1.0 but just a little larger) then do not round up but - ** instead keep the I value at 1.0. */ sqlite3_str sStat; /* Text of the constructed "stat" line */ int i; /* Loop counter */ sqlite3StrAccumInit(&sStat, 0, 0, 0, (p->nKeyCol+1)*100); @@ -115983,11 +111991,10 @@ sqlite3_str_appendf(&sStat, "%llu", p->nSkipAhead ? (u64)p->nEst : (u64)p->nRow); for(i=0; inKeyCol; i++){ u64 nDistinct = p->current.anDLt[i] + 1; u64 iVal = (p->nRow + nDistinct - 1) / nDistinct; - if( iVal==2 && p->nRow*10 <= nDistinct*11 ) iVal = 1; sqlite3_str_appendf(&sStat, " %llu", iVal); assert( p->current.anEq[i] ); } sqlite3ResultStrAccum(context, &sStat); } @@ -116071,11 +112078,10 @@ assert( k>=0 && knColumn ); i = pIdx->aiColumn[k]; if( NEVER(i==XN_ROWID) ){ VdbeComment((v,"%s.rowid",pIdx->zName)); }else if( i==XN_EXPR ){ - assert( pIdx->bHasExpr ); VdbeComment((v,"%s.expr(%d)",pIdx->zName, k)); }else{ VdbeComment((v,"%s.%s", pIdx->zName, pIdx->pTable->aCol[i].zCnName)); } } @@ -116112,19 +112118,15 @@ int regTemp2 = iMem++; /* Second temporary use register */ int regTabname = iMem++; /* Register containing table name */ int regIdxname = iMem++; /* Register containing index name */ int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */ int regPrev = iMem; /* MUST BE LAST (see below) */ -#ifdef SQLITE_ENABLE_STAT4 - int doOnce = 1; /* Flag for a one-time computation */ -#endif #ifdef SQLITE_ENABLE_PREUPDATE_HOOK Table *pStat1 = 0; #endif - sqlite3TouchRegister(pParse, iMem); - assert( sqlite3NoTempsInRange(pParse, regNewRowid, iMem) ); + pParse->nMem = MAX(pParse->nMem, iMem); v = sqlite3GetVdbe(pParse); if( v==0 || NEVER(pTab==0) ){ return; } if( !IsOrdinaryTable(pTab) ){ @@ -116152,11 +112154,11 @@ if( pStat1==0 ) return; pStat1->zName = (char*)&pStat1[1]; memcpy(pStat1->zName, "sqlite_stat1", 13); pStat1->nCol = 3; pStat1->iPKey = -1; - sqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNAMIC); + sqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNBLOB); } #endif /* Establish a read-lock on the table at the shared-cache level. ** Open a read-only cursor on the table. Also allocate a cursor number @@ -116226,11 +112228,11 @@ /* Make sure there are enough memory cells allocated to accommodate ** the regPrev array and a trailing rowid (the rowid slot is required ** when building a record to insert into the sample column of ** the sqlite_stat4 table. */ - sqlite3TouchRegister(pParse, regPrev+nColTest); + pParse->nMem = MAX(pParse->nMem, regPrev+nColTest); /* Open a read-only cursor on the index being analyzed. */ assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb); sqlite3VdbeSetP4KeyInfo(pParse, pIdx); @@ -116398,39 +112400,11 @@ int regSampleRowid = regCol + nCol; int addrNext; int addrIsNull; u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound; - if( doOnce ){ - int mxCol = nCol; - Index *pX; - - /* Compute the maximum number of columns in any index */ - for(pX=pTab->pIndex; pX; pX=pX->pNext){ - int nColX; /* Number of columns in pX */ - if( !HasRowid(pTab) && IsPrimaryKeyIndex(pX) ){ - nColX = pX->nKeyCol; - }else{ - nColX = pX->nColumn; - } - if( nColX>mxCol ) mxCol = nColX; - } - - /* Allocate space to compute results for the largest index */ - sqlite3TouchRegister(pParse, regCol+mxCol); - doOnce = 0; -#ifdef SQLITE_DEBUG - /* Verify that the call to sqlite3ClearTempRegCache() below - ** really is needed. - ** https://sqlite.org/forum/forumpost/83cb4a95a0 (2023-03-25) - */ - testcase( !sqlite3NoTempsInRange(pParse, regEq, regCol+mxCol) ); -#endif - sqlite3ClearTempRegCache(pParse); /* tag-20230325-1 */ - assert( sqlite3NoTempsInRange(pParse, regEq, regCol+mxCol) ); - } - assert( sqlite3NoTempsInRange(pParse, regEq, regCol+nCol) ); + pParse->nMem = MAX(pParse->nMem, regCol+nCol); addrNext = sqlite3VdbeCurrentAddr(v); callStatGet(pParse, regStat, STAT_GET_ROWID, regSampleRowid); addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid); VdbeCoverage(v); @@ -116507,15 +112481,10 @@ iTab = pParse->nTab; assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ Table *pTab = (Table*)sqliteHashData(k); analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab); -#ifdef SQLITE_ENABLE_STAT4 - iMem = sqlite3FirstAvailableRegister(pParse, iMem); -#else - assert( iMem==sqlite3FirstAvailableRegister(pParse,iMem) ); -#endif } loadAnalysis(pParse, iDb); } /* @@ -116752,22 +112721,20 @@ /* ** If the Index.aSample variable is not NULL, delete the aSample[] array ** and its contents. */ SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){ - assert( db!=0 ); - assert( pIdx!=0 ); #ifdef SQLITE_ENABLE_STAT4 if( pIdx->aSample ){ int j; for(j=0; jnSample; j++){ IndexSample *p = &pIdx->aSample[j]; sqlite3DbFree(db, p->p); } sqlite3DbFree(db, pIdx->aSample); } - if( db->pnBytesFreed==0 ){ + if( db && db->pnBytesFreed==0 ){ pIdx->nSample = 0; pIdx->aSample = 0; } #else UNUSED_PARAMETER(db); @@ -117182,11 +113149,11 @@ const char *zFile; char *zPath = 0; char *zErr = 0; unsigned int flags; Db *aNew; /* New array of Db pointers */ - Db *pNew = 0; /* Db object for the newly attached database */ + Db *pNew; /* Db object for the newly attached database */ char *zErrDyn = 0; sqlite3_vfs *pVfs; UNUSED_PARAMETER(NotUsed); zFile = (const char *)sqlite3_value_text(argv[0]); @@ -117202,30 +113169,17 @@ if( REOPEN_AS_MEMDB(db) ){ /* This is not a real ATTACH. Instead, this routine is being called ** from sqlite3_deserialize() to close database db->init.iDb and ** reopen it as a MemDB */ - Btree *pNewBt = 0; pVfs = sqlite3_vfs_find("memdb"); if( pVfs==0 ) return; - rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNewBt, 0, SQLITE_OPEN_MAIN_DB); - if( rc==SQLITE_OK ){ - Schema *pNewSchema = sqlite3SchemaGet(db, pNewBt); - if( pNewSchema ){ - /* Both the Btree and the new Schema were allocated successfully. - ** Close the old db and update the aDb[] slot with the new memdb - ** values. */ - pNew = &db->aDb[db->init.iDb]; - if( ALWAYS(pNew->pBt) ) sqlite3BtreeClose(pNew->pBt); - pNew->pBt = pNewBt; - pNew->pSchema = pNewSchema; - }else{ - sqlite3BtreeClose(pNewBt); - rc = SQLITE_NOMEM; - } - } - if( rc ) goto attach_error; + pNew = &db->aDb[db->init.iDb]; + if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt); + pNew->pBt = 0; + pNew->pSchema = 0; + rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB); }else{ /* This is a real ATTACH ** ** Check for the following errors: ** @@ -117334,11 +113288,11 @@ rc = SQLITE_AUTH_USER; } } #endif if( rc ){ - if( ALWAYS(!REOPEN_AS_MEMDB(db)) ){ + if( !REOPEN_AS_MEMDB(db) ){ int iDb = db->nDb - 1; assert( iDb>=2 ); if( db->aDb[iDb].pBt ){ sqlite3BtreeClose(db->aDb[iDb].pBt); db->aDb[iDb].pBt = 0; @@ -117451,12 +113405,10 @@ NameContext sName; Vdbe *v; sqlite3* db = pParse->db; int regArgs; - if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto attach_end; - if( pParse->nErr ) goto attach_end; memset(&sName, 0, sizeof(NameContext)); sName.pParse = pParse; if( @@ -117592,15 +113544,11 @@ } pItem->pSchema = pFix->pSchema; pItem->fg.fromDDL = 1; } #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) - if( pList->a[i].fg.isUsing==0 - && sqlite3WalkExpr(&pFix->w, pList->a[i].u3.pOn) - ){ - return WRC_Abort; - } + if( sqlite3WalkExpr(&pFix->w, pList->a[i].pOn) ) return WRC_Abort; #endif } if( pSelect->pWith ){ for(i=0; ipWith->nCte; i++){ if( sqlite3WalkSelect(p, pSelect->pWith->a[i].pSelect) ){ @@ -118128,11 +114076,10 @@ ** no VDBE code was generated. */ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ sqlite3 *db; Vdbe *v; - int iDb, i; assert( pParse->pToplevel==0 ); db = pParse->db; assert( db->pParse==pParse ); if( pParse->nested ) return; @@ -118158,13 +114105,16 @@ || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort)); if( v ){ if( pParse->bReturning ){ Returning *pReturning = pParse->u1.pReturning; int addrRewind; + int i; int reg; - if( pReturning->nRetCol ){ + if( NEVER(pReturning->nRetCol==0) ){ + assert( CORRUPT_DB ); + }else{ sqlite3VdbeAddOp0(v, OP_FkCheck); addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, pReturning->iRetCur); VdbeCoverage(v); reg = pReturning->iRetReg; @@ -118194,73 +114144,80 @@ ** (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. */ - assert( pParse->nErr>0 || sqlite3VdbeGetOp(v, 0)->opcode==OP_Init ); - sqlite3VdbeJumpHere(v, 0); - assert( db->nDb>0 ); - iDb = 0; - do{ - Schema *pSchema; - if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue; - sqlite3VdbeUsesBtree(v, iDb); - pSchema = db->aDb[iDb].pSchema; - sqlite3VdbeAddOp4Int(v, - OP_Transaction, /* Opcode */ - iDb, /* P1 */ - DbMaskTest(pParse->writeMask,iDb), /* P2 */ - pSchema->schema_cookie, /* P3 */ - pSchema->iGeneration /* P4 */ - ); - if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1); - VdbeComment((v, - "usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite)); - }while( ++iDbnDb ); + if( db->mallocFailed==0 + && (DbMaskNonZero(pParse->cookieMask) || pParse->pConstExpr) + ){ + int iDb, i; + assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init ); + sqlite3VdbeJumpHere(v, 0); + for(iDb=0; iDbnDb; iDb++){ + Schema *pSchema; + if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue; + sqlite3VdbeUsesBtree(v, iDb); + pSchema = db->aDb[iDb].pSchema; + sqlite3VdbeAddOp4Int(v, + OP_Transaction, /* Opcode */ + iDb, /* P1 */ + DbMaskTest(pParse->writeMask,iDb), /* P2 */ + pSchema->schema_cookie, /* P3 */ + pSchema->iGeneration /* P4 */ + ); + if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1); + VdbeComment((v, + "usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite)); + } #ifndef SQLITE_OMIT_VIRTUALTABLE - for(i=0; inVtabLock; i++){ - char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]); - sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB); - } - pParse->nVtabLock = 0; + for(i=0; inVtabLock; i++){ + char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]); + sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB); + } + pParse->nVtabLock = 0; #endif - /* Once all the cookies have been verified and transactions opened, - ** obtain the required table-locks. This is a no-op unless the - ** shared-cache feature is enabled. - */ - codeTableLocks(pParse); - - /* Initialize any AUTOINCREMENT data structures required. - */ - sqlite3AutoincrementBegin(pParse); - - /* Code constant expressions that where factored out of inner loops. - ** - ** The pConstExpr list might also contain expressions that we simply - ** want to keep around until the Parse object is deleted. Such - ** expressions have iConstExprReg==0. Do not generate code for - ** those expressions, of course. - */ - if( pParse->pConstExpr ){ - ExprList *pEL = pParse->pConstExpr; - pParse->okConstFactor = 0; - for(i=0; inExpr; i++){ - int iReg = pEL->a[i].u.iConstExprReg; - sqlite3ExprCode(pParse, pEL->a[i].pExpr, iReg); - } - } - - if( pParse->bReturning ){ - Returning *pRet = pParse->u1.pReturning; - if( pRet->nRetCol ){ - sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRet->iRetCur, pRet->nRetCol); - } - } - - /* Finally, jump back to the beginning of the executable code. */ - sqlite3VdbeGoto(v, 1); + /* Once all the cookies have been verified and transactions opened, + ** obtain the required table-locks. This is a no-op unless the + ** shared-cache feature is enabled. + */ + codeTableLocks(pParse); + + /* Initialize any AUTOINCREMENT data structures required. + */ + sqlite3AutoincrementBegin(pParse); + + /* Code constant expressions that where factored out of inner loops. + ** + ** The pConstExpr list might also contain expressions that we simply + ** want to keep around until the Parse object is deleted. Such + ** expressions have iConstExprReg==0. Do not generate code for + ** those expressions, of course. + */ + if( pParse->pConstExpr ){ + ExprList *pEL = pParse->pConstExpr; + pParse->okConstFactor = 0; + for(i=0; inExpr; i++){ + int iReg = pEL->a[i].u.iConstExprReg; + if( iReg>0 ){ + sqlite3ExprCode(pParse, pEL->a[i].pExpr, iReg); + } + } + } + + if( pParse->bReturning ){ + Returning *pRet = pParse->u1.pReturning; + if( NEVER(pRet->nRetCol==0) ){ + assert( CORRUPT_DB ); + }else{ + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRet->iRetCur, pRet->nRetCol); + } + } + + /* Finally, jump back to the beginning of the executable code. */ + sqlite3VdbeGoto(v, 1); + } } /* Get the VDBE program ready for execution */ assert( v!=0 || pParse->nErr ); @@ -118295,11 +114252,10 @@ sqlite3 *db = pParse->db; u32 savedDbFlags = db->mDbFlags; char saveBuf[PARSE_TAIL_SZ]; if( pParse->nErr ) return; - if( pParse->eParseMode ) return; assert( pParse->nested<10 ); /* Nesting should only be of limited depth */ va_start(ap, zFormat); zSql = sqlite3VMPrintf(db, zFormat, ap); va_end(ap); if( zSql==0 ){ @@ -118313,10 +114269,12 @@ pParse->nested++; memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ); memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ); db->mDbFlags |= DBFLAG_PreferBuiltin; sqlite3RunParser(pParse, zSql); + sqlite3DbFree(db, pParse->zErrMsg); + pParse->zErrMsg = 0; db->mDbFlags = savedDbFlags; sqlite3DbFree(db, zSql); memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ); pParse->nested--; } @@ -118442,11 +114400,11 @@ if( p==0 ){ #ifndef SQLITE_OMIT_VIRTUALTABLE /* If zName is the not the name of a table in the schema created using ** CREATE, then check to see if it is the name of an virtual table that ** can be an eponymous virtual table. */ - if( (pParse->prepFlags & SQLITE_PREPARE_NO_VTAB)==0 && db->init.busy==0 ){ + if( pParse->disableVtab==0 && db->init.busy==0 ){ Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName); if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){ pMod = sqlite3PragmaVtabRegister(db, zName); } if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){ @@ -118455,11 +114413,11 @@ } } #endif if( flags & LOCATE_NOERR ) return 0; pParse->checkSchema = 1; - }else if( IsVirtual(p) && (pParse->prepFlags & SQLITE_PREPARE_NO_VTAB)!=0 ){ + }else if( IsVirtual(p) && pParse->disableVtab ){ p = 0; } if( p==0 ){ const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table"; @@ -118764,21 +114722,20 @@ */ SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){ int i; Column *pCol; assert( pTable!=0 ); - assert( db!=0 ); if( (pCol = pTable->aCol)!=0 ){ for(i=0; inCol; i++, pCol++){ assert( pCol->zCnName==0 || pCol->hName==sqlite3StrIHash(pCol->zCnName) ); sqlite3DbFree(db, pCol->zCnName); } - sqlite3DbNNFreeNN(db, pTable->aCol); + sqlite3DbFree(db, pTable->aCol); if( IsOrdinaryTable(pTable) ){ sqlite3ExprListDelete(db, pTable->u.tab.pDfltList); } - if( db->pnBytesFreed==0 ){ + if( db==0 || db->pnBytesFreed==0 ){ pTable->aCol = 0; pTable->nCol = 0; if( IsOrdinaryTable(pTable) ){ pTable->u.tab.pDfltList = 0; } @@ -118811,22 +114768,21 @@ ** ** If malloc has already failed, it may be that it failed while allocating ** a Table object that was going to be marked ephemeral. So do not check ** that no lookaside memory is used in this case either. */ int nLookaside = 0; - assert( db!=0 ); - if( !db->mallocFailed && (pTable->tabFlags & TF_Ephemeral)==0 ){ + if( db && !db->mallocFailed && (pTable->tabFlags & TF_Ephemeral)==0 ){ nLookaside = sqlite3LookasideUsed(db, 0); } #endif /* Delete all indices associated with this table. */ for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){ pNext = pIndex->pNext; assert( pIndex->pSchema==pTable->pSchema || (IsVirtual(pTable) && pIndex->idxType!=SQLITE_IDXTYPE_APPDEF) ); - if( db->pnBytesFreed==0 && !IsVirtual(pTable) ){ + if( (db==0 || db->pnBytesFreed==0) && !IsVirtual(pTable) ){ char *zName = pIndex->zName; TESTONLY ( Index *pOld = ) sqlite3HashInsert( &pIndex->pSchema->idxHash, zName, 0 ); assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); @@ -118859,13 +114815,12 @@ /* Verify that no lookaside memory was used by schema tables */ assert( nLookaside==0 || nLookaside==sqlite3LookasideUsed(db,0) ); } SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ /* Do not delete the table until the reference count reaches zero. */ - assert( db!=0 ); if( !pTable ) return; - if( db->pnBytesFreed==0 && (--pTable->nTabRef)>0 ) return; + if( ((!db || db->pnBytesFreed==0) && (--pTable->nTabRef)>0) ) return; deleteTable(db, pTable); } /* @@ -119439,11 +115394,11 @@ Hash *pHash; sqlite3 *db = pParse->db; if( pParse->pNewTrigger ){ sqlite3ErrorMsg(pParse, "cannot use RETURNING in a trigger"); }else{ - assert( pParse->bReturning==0 || pParse->ifNotExists ); + assert( pParse->bReturning==0 ); } pParse->bReturning = 1; pRet = sqlite3DbMallocZero(db, sizeof(*pRet)); if( pRet==0 ){ sqlite3ExprListDelete(db, pList); @@ -119465,12 +115420,11 @@ pRet->retTrig.step_list = &pRet->retTStep; pRet->retTStep.op = TK_RETURNING; pRet->retTStep.pTrig = &pRet->retTrig; pRet->retTStep.pExprList = pList; pHash = &(db->aDb[1].pSchema->trigHash); - assert( sqlite3HashFind(pHash, RETURNING_TRIGGER_NAME)==0 - || pParse->nErr || pParse->ifNotExists ); + assert( sqlite3HashFind(pHash, RETURNING_TRIGGER_NAME)==0 || pParse->nErr ); if( sqlite3HashInsert(pHash, RETURNING_TRIGGER_NAME, &pRet->retTrig) ==&pRet->retTrig ){ sqlite3OomFault(db); } } @@ -119874,11 +115828,11 @@ } pTab->iPKey = iCol; pTab->keyConf = (u8)onError; assert( autoInc==0 || autoInc==1 ); pTab->tabFlags |= autoInc*TF_Autoincrement; - if( pList ) pParse->iPkSortOrder = pList->a[0].fg.sortFlags; + if( pList ) pParse->iPkSortOrder = pList->a[0].sortFlags; (void)sqlite3HasExplicitNulls(pParse, pList); }else if( autoInc ){ #ifndef SQLITE_OMIT_AUTOINCREMENT sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an " "INTEGER PRIMARY KEY"); @@ -119994,18 +115948,10 @@ assert( TF_HasStored==COLFLAG_STORED ); pTab->tabFlags |= eType; if( pCol->colFlags & COLFLAG_PRIMKEY ){ makeColumnPartOfPrimaryKey(pParse, pCol); /* For the error message */ } - if( ALWAYS(pExpr) && pExpr->op==TK_ID ){ - /* The value of a generated column needs to be a real expression, not - ** just a reference to another column, in order for covering index - ** optimizations to work correctly. So if the value is not an expression, - ** turn it into one by adding a unary "+" operator. */ - pExpr = sqlite3PExpr(pParse, TK_UPLUS, pExpr, 0); - } - if( pExpr && pExpr->op!=TK_RAISE ) pExpr->affExpr = pCol->affinity; sqlite3ColumnSetExpr(pParse, pTab, pCol, pExpr); pExpr = 0; goto generated_done; generated_error: @@ -120138,12 +116084,11 @@ static const char * const azType[] = { /* SQLITE_AFF_BLOB */ "", /* SQLITE_AFF_TEXT */ " TEXT", /* SQLITE_AFF_NUMERIC */ " NUM", /* SQLITE_AFF_INTEGER */ " INT", - /* SQLITE_AFF_REAL */ " REAL", - /* SQLITE_AFF_FLEXNUM */ " NUM", + /* SQLITE_AFF_REAL */ " REAL" }; int len; const char *zType; sqlite3_snprintf(n-k, &zStmt[k], zSep); @@ -120155,16 +116100,14 @@ testcase( pCol->affinity==SQLITE_AFF_BLOB ); testcase( pCol->affinity==SQLITE_AFF_TEXT ); testcase( pCol->affinity==SQLITE_AFF_NUMERIC ); testcase( pCol->affinity==SQLITE_AFF_INTEGER ); testcase( pCol->affinity==SQLITE_AFF_REAL ); - testcase( pCol->affinity==SQLITE_AFF_FLEXNUM ); zType = azType[pCol->affinity - SQLITE_AFF_BLOB]; len = sqlite3Strlen30(zType); assert( pCol->affinity==SQLITE_AFF_BLOB - || pCol->affinity==SQLITE_AFF_FLEXNUM || pCol->affinity==sqlite3AffinityType(zType, 0) ); memcpy(&zStmt[k], zType, len); k += len; assert( k<=n ); } @@ -120277,12 +116220,11 @@ } /* Recompute the colNotIdxed field of the Index. ** ** colNotIdxed is a bitmask that has a 0 bit representing each indexed -** columns that are within the first 63 columns of the table and a 1 for -** all other bits (all columns that are not in the index). The +** columns that are within the first 63 columns of the table. The ** high-order bit of colNotIdxed is always 1. All unindexed columns ** of the table have a 1. ** ** 2019-10-24: For the purpose of this computation, virtual columns are ** not considered to be covered by the index, even if they are in the @@ -120306,11 +116248,11 @@ testcase( x==BMS-2 ); if( xcolNotIdxed = ~m; - assert( (pIdx->colNotIdxed>>63)==1 ); /* See note-20221022-a */ + assert( (pIdx->colNotIdxed>>63)==1 ); } /* ** This routine runs at the end of parsing a CREATE TABLE statement that ** has a WITHOUT ROWID clause. The job of this routine is to convert both @@ -120380,11 +116322,11 @@ return; } if( IN_RENAME_OBJECT ){ sqlite3RenameTokenRemap(pParse, pList->a[0].pExpr, &pTab->iPKey); } - pList->a[0].fg.sortFlags = pParse->iPkSortOrder; + pList->a[0].sortFlags = pParse->iPkSortOrder; assert( pParse->pNewTable==pTab ); pTab->iPKey = -1; sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0, SQLITE_IDXTYPE_PRIMARYKEY); if( pParse->nErr ){ @@ -120575,11 +116517,10 @@ ** they should not be changed. Expressions attached to a table or ** index definition are tagged this way to help ensure that we do ** not pass them into code generator routines by mistake. */ static int markImmutableExprStep(Walker *pWalker, Expr *pExpr){ - (void)pWalker; ExprSetVVAProperty(pExpr, EP_Immutable); return WRC_Continue; } static void markExprListImmutable(ExprList *pList){ if( pList ){ @@ -121048,14 +116989,15 @@ /* ** 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. */ -static SQLITE_NOINLINE int viewGetColumnNames(Parse *pParse, Table *pTable){ +SQLITE_PRIVATE int sqlite3ViewGetColumnNames(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 */ sqlite3 *db = pParse->db; /* Database connection for malloc errors */ #ifndef SQLITE_OMIT_VIRTUALTABLE int rc; #endif #ifndef SQLITE_OMIT_AUTHORIZATION @@ -121073,14 +117015,13 @@ } #endif #ifndef SQLITE_OMIT_VIEW /* A positive nCol means the columns names for this view are - ** already known. This routine is not called unless either the - ** table is virtual or nCol is zero. + ** already known. */ - assert( pTable->nCol<=0 ); + 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: ** @@ -121110,13 +117051,12 @@ */ assert( IsView(pTable) ); pSel = sqlite3SelectDup(db, pTable->u.view.pSelect, 0); if( pSel ){ u8 eParseMode = pParse->eParseMode; - int nTab = pParse->nTab; - int nSelect = pParse->nSelect; pParse->eParseMode = PARSE_MODE_NORMAL; + n = pParse->nTab; sqlite3SrcListAssignCursors(pParse, pSel->pSrc); pTable->nCol = -1; DisableLookaside; #ifndef SQLITE_OMIT_AUTHORIZATION xAuth = db->xAuth; @@ -121124,12 +117064,11 @@ pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE); db->xAuth = xAuth; #else pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE); #endif - pParse->nTab = nTab; - pParse->nSelect = nSelect; + pParse->nTab = n; if( pSelTab==0 ){ pTable->nCol = 0; nErr++; }else if( pTable->pCheck ){ /* CREATE VIEW name(arglist) AS ... @@ -121142,11 +117081,12 @@ &pTable->nCol, &pTable->aCol); if( pParse->nErr==0 && pTable->nCol==pSel->pEList->nExpr ){ assert( db->mallocFailed==0 ); - sqlite3SubqueryColumnTypes(pParse, pTable, pSel, SQLITE_AFF_NONE); + sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel, + SQLITE_AFF_NONE); } }else{ /* CREATE VIEW name AS... without an argument list. Construct ** the column names from the SELECT statement that defines the view. */ @@ -121171,15 +117111,10 @@ sqlite3DeleteColumnNames(db, pTable); } #endif /* SQLITE_OMIT_VIEW */ return nErr; } -SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ - assert( pTable!=0 ); - if( !IsVirtual(pTable) && pTable->nCol>0 ) return 0; - return viewGetColumnNames(pParse, pTable); -} #endif /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */ #ifndef SQLITE_OMIT_VIEW /* ** Clear the column names from every VIEW in database idx. @@ -121874,12 +117809,12 @@ */ SQLITE_PRIVATE int sqlite3HasExplicitNulls(Parse *pParse, ExprList *pList){ if( pList ){ int i; for(i=0; inExpr; i++){ - if( pList->a[i].fg.bNulls ){ - u8 sf = pList->a[i].fg.sortFlags; + if( pList->a[i].bNulls ){ + u8 sf = pList->a[i].sortFlags; sqlite3ErrorMsg(pParse, "unsupported use of NULLS %s", (sf==0 || sf==3) ? "FIRST" : "LAST" ); return 1; } @@ -122041,11 +117976,11 @@ if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName,"index",pTab->zName) ){ goto exit_create_index; } if( !IN_RENAME_OBJECT ){ if( !db->init.busy ){ - if( sqlite3FindTable(db, zName, pDb->zDbSName)!=0 ){ + if( sqlite3FindTable(db, zName, 0)!=0 ){ sqlite3ErrorMsg(pParse, "there is already a table named %s", zName); goto exit_create_index; } } if( sqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){ @@ -122194,11 +118129,10 @@ pList = 0; } j = XN_EXPR; pIndex->aiColumn[i] = XN_EXPR; pIndex->uniqNotNull = 0; - pIndex->bHasExpr = 1; }else{ j = pCExpr->iColumn; assert( j<=0x7fff ); if( j<0 ){ j = pTab->iPKey; @@ -122206,11 +118140,10 @@ if( pTab->aCol[j].notNull==0 ){ pIndex->uniqNotNull = 0; } if( pTab->aCol[j].colFlags & COLFLAG_VIRTUAL ){ pIndex->bHasVCol = 1; - pIndex->bHasExpr = 1; } } pIndex->aiColumn[i] = (i16)j; } zColl = 0; @@ -122230,11 +118163,11 @@ if( !zColl ) zColl = sqlite3StrBINARY; if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){ goto exit_create_index; } pIndex->azColl[i] = zColl; - requestedSortOrder = pListItem->fg.sortFlags & sortOrderMask; + requestedSortOrder = pListItem->sortFlags & sortOrderMask; pIndex->aSortOrder[i] = (u8)requestedSortOrder; } /* Append the table key to the end of the index. For WITHOUT ROWID ** tables (when pPk!=0) this will be the declared PRIMARY KEY. For @@ -122673,21 +118606,22 @@ sqlite3 *db = pParse->db; int i; if( pList==0 ){ pList = sqlite3DbMallocZero(db, sizeof(IdList) ); if( pList==0 ) return 0; - }else{ - IdList *pNew; - pNew = sqlite3DbRealloc(db, pList, - sizeof(IdList) + pList->nId*sizeof(pList->a)); - if( pNew==0 ){ - sqlite3IdListDelete(db, pList); - return 0; - } - pList = pNew; - } - i = pList->nId++; + } + pList->a = sqlite3ArrayAllocate( + db, + pList->a, + sizeof(pList->a[0]), + &pList->nId, + &i + ); + if( i<0 ){ + sqlite3IdListDelete(db, pList); + return 0; + } pList->a[i].zName = sqlite3NameFromToken(db, pToken); if( IN_RENAME_OBJECT && pList->a[i].zName ){ sqlite3RenameTokenMap(pParse, (void*)pList->a[i].zName, pToken); } return pList; @@ -122696,26 +118630,25 @@ /* ** Delete an IdList. */ SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3 *db, IdList *pList){ int i; - assert( db!=0 ); if( pList==0 ) return; - assert( pList->eU4!=EU4_EXPR ); /* EU4_EXPR mode is not currently used */ for(i=0; inId; i++){ sqlite3DbFree(db, pList->a[i].zName); } - sqlite3DbNNFreeNN(db, pList); + sqlite3DbFree(db, pList->a); + sqlite3DbFreeNN(db, pList); } /* ** Return the index in pList of the identifier named zId. Return -1 ** if not found. */ SQLITE_PRIVATE int sqlite3IdListIndex(IdList *pList, const char *zName){ int i; - assert( pList!=0 ); + if( pList==0 ) return -1; for(i=0; inId; i++){ if( sqlite3StrICmp(pList->a[i].zName, zName)==0 ) return i; } return -1; } @@ -122905,27 +118838,23 @@ ** Delete an entire SrcList including all its substructure. */ SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ int i; SrcItem *pItem; - assert( db!=0 ); if( pList==0 ) return; for(pItem=pList->a, i=0; inSrc; i++, pItem++){ - if( pItem->zDatabase ) sqlite3DbNNFreeNN(db, pItem->zDatabase); - if( pItem->zName ) sqlite3DbNNFreeNN(db, pItem->zName); - if( pItem->zAlias ) sqlite3DbNNFreeNN(db, pItem->zAlias); + if( pItem->zDatabase ) sqlite3DbFreeNN(db, pItem->zDatabase); + sqlite3DbFree(db, pItem->zName); + if( pItem->zAlias ) sqlite3DbFreeNN(db, pItem->zAlias); if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy); if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg); sqlite3DeleteTable(db, pItem->pTab); if( pItem->pSelect ) sqlite3SelectDelete(db, pItem->pSelect); - if( pItem->fg.isUsing ){ - sqlite3IdListDelete(db, pItem->u3.pUsing); - }else if( pItem->u3.pOn ){ - sqlite3ExprDelete(db, pItem->u3.pOn); - } + if( pItem->pOn ) sqlite3ExprDelete(db, pItem->pOn); + if( pItem->pUsing ) sqlite3IdListDelete(db, pItem->pUsing); } - sqlite3DbNNFreeNN(db, pList); + sqlite3DbFreeNN(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 @@ -122947,17 +118876,18 @@ 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 */ - OnOrUsing *pOnUsing /* Either the ON clause or the USING clause */ + Expr *pOn, /* The ON clause of a join */ + IdList *pUsing /* The USING clause of a join */ ){ SrcItem *pItem; sqlite3 *db = pParse->db; - if( !p && pOnUsing!=0 && (pOnUsing->pOn || pOnUsing->pUsing) ){ + if( !p && (pOn || pUsing) ){ sqlite3ErrorMsg(pParse, "a JOIN clause is required before %s", - (pOnUsing->pOn ? "ON" : "USING") + (pOn ? "ON" : "USING") ); goto append_from_error; } p = sqlite3SrcListAppend(pParse, p, pTable, pDatabase); if( p==0 ){ @@ -122973,31 +118903,19 @@ } assert( pAlias!=0 ); if( pAlias->n ){ pItem->zAlias = sqlite3NameFromToken(db, pAlias); } - if( pSubquery ){ - pItem->pSelect = pSubquery; - if( pSubquery->selFlags & SF_NestedFrom ){ - pItem->fg.isNestedFrom = 1; - } - } - assert( pOnUsing==0 || pOnUsing->pOn==0 || pOnUsing->pUsing==0 ); - assert( pItem->fg.isUsing==0 ); - if( pOnUsing==0 ){ - pItem->u3.pOn = 0; - }else if( pOnUsing->pUsing ){ - pItem->fg.isUsing = 1; - pItem->u3.pUsing = pOnUsing->pUsing; - }else{ - pItem->u3.pOn = pOnUsing->pOn; - } + pItem->pSelect = pSubquery; + pItem->pOn = pOn; + pItem->pUsing = pUsing; return p; append_from_error: assert( p==0 ); - sqlite3ClearOnOrUsing(db, pOnUsing); + sqlite3ExprDelete(db, pOn); + sqlite3IdListDelete(db, pUsing); sqlite3SelectDelete(db, pSubquery); return 0; } /* @@ -123038,11 +118956,10 @@ sqlite3SrcListDelete(pParse->db, p2); }else{ p1 = pNew; memcpy(&p1->a[1], p2->a, p2->nSrc*sizeof(SrcItem)); sqlite3DbFree(pParse->db, p2); - p1->a[0].fg.jointype |= (JT_LTORJ & p1->a[1].fg.jointype); } } return p1; } @@ -123075,38 +118992,18 @@ ** 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. -** -** Additional changes: -** -** * All tables to the left of the right-most RIGHT JOIN are tagged with -** JT_LTORJ (mnemonic: Left Table Of Right Join) so that the -** code generator can easily tell that the table is part of -** the left operand of at least one RIGHT JOIN. */ -SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(Parse *pParse, SrcList *p){ - (void)pParse; - if( p && p->nSrc>1 ){ - int i = p->nSrc-1; - u8 allFlags = 0; - do{ - allFlags |= p->a[i].fg.jointype = p->a[i-1].fg.jointype; - }while( (--i)>0 ); +SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList *p){ + if( p ){ + int i; + for(i=p->nSrc-1; i>0; i--){ + p->a[i].fg.jointype = p->a[i-1].fg.jointype; + } p->a[0].fg.jointype = 0; - - /* All terms to the left of a RIGHT JOIN should be tagged with the - ** JT_LTORJ flags */ - if( allFlags & JT_RIGHT ){ - for(i=p->nSrc-1; ALWAYS(i>0) && (p->a[i].fg.jointype&JT_RIGHT)==0; i--){} - i--; - assert( i>=0 ); - do{ - p->a[i].fg.jointype |= JT_LTORJ; - }while( (--i)>=0 ); - } } } /* ** Generate VDBE code for a BEGIN statement. @@ -124173,25 +120070,23 @@ SQLITE_PRIVATE void sqlite3SchemaClear(void *p){ Hash temp1; Hash temp2; HashElem *pElem; Schema *pSchema = (Schema *)p; - sqlite3 xdb; - memset(&xdb, 0, sizeof(xdb)); temp1 = pSchema->tblHash; temp2 = pSchema->trigHash; sqlite3HashInit(&pSchema->trigHash); sqlite3HashClear(&pSchema->idxHash); for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){ - sqlite3DeleteTrigger(&xdb, (Trigger*)sqliteHashData(pElem)); + sqlite3DeleteTrigger(0, (Trigger*)sqliteHashData(pElem)); } sqlite3HashClear(&temp2); sqlite3HashInit(&pSchema->tblHash); for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){ Table *pTab = sqliteHashData(pElem); - sqlite3DeleteTable(&xdb, pTab); + sqlite3DeleteTable(0, pTab); } sqlite3HashClear(&temp1); sqlite3HashClear(&pSchema->fkeyHash); pSchema->pSeqTab = 0; if( pSchema->schemaFlags & DB_SchemaLoaded ){ @@ -124286,46 +120181,22 @@ ** A table is read-only if any of the following are true: ** ** 1) It is a virtual table and no implementation of the xUpdate method ** has been provided ** -** 2) A trigger is currently being coded and the table is a virtual table -** that is SQLITE_VTAB_DIRECTONLY or if PRAGMA trusted_schema=OFF and -** the table is not SQLITE_VTAB_INNOCUOUS. -** -** 3) It is a system table (i.e. sqlite_schema), this call is not +** 2) It is a system table (i.e. sqlite_schema), this call is not ** part of a nested parse and writable_schema pragma has not ** been specified ** -** 4) The table is a shadow table, the database connection is in +** 3) The table is a shadow table, the database connection is in ** defensive mode, and the current sqlite3_prepare() ** is for a top-level SQL statement. */ -static int vtabIsReadOnly(Parse *pParse, Table *pTab){ - if( sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 ){ - return 1; - } - - /* Within triggers: - ** * Do not allow DELETE, INSERT, or UPDATE of SQLITE_VTAB_DIRECTONLY - ** virtual tables - ** * Only allow DELETE, INSERT, or UPDATE of non-SQLITE_VTAB_INNOCUOUS - ** virtual tables if PRAGMA trusted_schema=ON. - */ - if( pParse->pToplevel!=0 - && pTab->u.vtab.p->eVtabRisk > - ((pParse->db->flags & SQLITE_TrustedSchema)!=0) - ){ - sqlite3ErrorMsg(pParse, "unsafe use of virtual table \"%s\"", - pTab->zName); - } - return 0; -} static int tabIsReadOnly(Parse *pParse, Table *pTab){ sqlite3 *db; if( IsVirtual(pTab) ){ - return vtabIsReadOnly(pParse, pTab); + return sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0; } if( (pTab->tabFlags & (TF_Readonly|TF_Shadow))==0 ) return 0; db = pParse->db; if( (pTab->tabFlags & TF_Readonly)!=0 ){ return sqlite3WritableSchema(db)==0 && pParse->nested==0; @@ -124333,25 +120204,21 @@ assert( pTab->tabFlags & TF_Shadow ); return sqlite3ReadOnlyShadowTables(db); } /* -** Check to make sure the given table is writable. -** -** If pTab is not writable -> generate an error message and return 1. -** If pTab is writable but other errors have occurred -> return 1. -** If pTab is writable and no prior errors -> return 0; +** 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 sqlite3IsReadOnly(Parse *pParse, Table *pTab, Trigger *pTrigger){ +SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){ if( tabIsReadOnly(pParse, pTab) ){ sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName); return 1; } #ifndef SQLITE_OMIT_VIEW - if( IsView(pTab) - && (pTrigger==0 || (pTrigger->bReturning && pTrigger->pNext==0)) - ){ + if( !viewOk && IsView(pTab) ){ sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName); return 1; } #endif return 0; @@ -124381,12 +120248,12 @@ pFrom = sqlite3SrcListAppend(pParse, 0, 0, 0); if( pFrom ){ assert( pFrom->nSrc==1 ); pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName); pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); - assert( pFrom->a[0].fg.isUsing==0 ); - assert( pFrom->a[0].u3.pOn==0 ); + assert( pFrom->a[0].pOn==0 ); + assert( pFrom->a[0].pUsing==0 ); } pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, pOrderBy, SF_IncludeHidden, pLimit); sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur); sqlite3Select(pParse, pSel, &dest); @@ -124552,10 +120419,11 @@ if( pParse->nErr ){ goto delete_from_cleanup; } assert( db->mallocFailed==0 ); assert( pTabList->nSrc==1 ); + /* Locate the table which we want to delete. This table has to be ** put in an SrcList structure because some of the subroutines we ** will be calling are designed to work with multiple tables and expect ** an SrcList* parameter instead of just a Table* parameter. @@ -124577,18 +120445,10 @@ #ifdef SQLITE_OMIT_VIEW # undef isView # define isView 0 #endif -#if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x10000 ){ - sqlite3TreeViewLine(0, "In sqlite3Delete() at %s:%d", __FILE__, __LINE__); - sqlite3TreeViewDelete(pParse->pWith, pTabList, pWhere, - pOrderBy, pLimit, pTrigger); - } -#endif - #ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT if( !isView ){ pWhere = sqlite3LimitWhere( pParse, pTabList, pWhere, pOrderBy, pLimit, "DELETE" ); @@ -124601,11 +120461,11 @@ */ if( sqlite3ViewGetColumnNames(pParse, pTab) ){ goto delete_from_cleanup; } - if( sqlite3IsReadOnly(pParse, pTab, pTrigger) ){ + if( sqlite3IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){ goto delete_from_cleanup; } iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iDbnDb ); rcauth = sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, @@ -124700,21 +120560,20 @@ sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt ? memCnt : -1, pTab->zName, P4_STATIC); } for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ assert( pIdx->pSchema==pTab->pSchema ); + sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb); if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ - sqlite3VdbeAddOp3(v, OP_Clear, pIdx->tnum, iDb, memCnt ? memCnt : -1); - }else{ - sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb); + sqlite3VdbeChangeP3(v, -1, memCnt ? memCnt : -1); } } }else #endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */ { u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK; - if( sNC.ncFlags & NC_Subquery ) bComplex = 1; + if( sNC.ncFlags & NC_VarSelect ) bComplex = 1; wcf |= (bComplex ? 0 : WHERE_ONEPASS_MULTIROW); if( HasRowid(pTab) ){ /* For a rowid table, initialize the RowSet to an empty set */ pPk = 0; nPk = 1; @@ -124903,11 +120762,11 @@ sqlite3ExprDelete(db, pWhere); #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) sqlite3ExprListDelete(db, pOrderBy); sqlite3ExprDelete(db, pLimit); #endif - if( aToOpen ) sqlite3DbNNFreeNN(db, aToOpen); + sqlite3DbFree(db, aToOpen); return; } /* Make sure "isView" and other macros defined above are undefined. Otherwise ** they may interfere with compilation of other functions in this file ** (or in another file, if this file becomes part of the amalgamation). */ @@ -125986,11 +121845,11 @@ ** ** For a case-insensitive search, set variable cx to be the same as ** c but in the other case and search the input string for either ** c or cx. */ - if( c<0x80 ){ + if( c<=0x80 ){ char zStop[3]; int bMatch; if( noCase ){ zStop[0] = sqlite3Toupper(c); zStop[1] = sqlite3Tolower(c); @@ -126069,31 +121928,19 @@ /* ** The sqlite3_strglob() interface. Return 0 on a match (like strcmp()) and ** non-zero if there is no match. */ SQLITE_API int sqlite3_strglob(const char *zGlobPattern, const char *zString){ - if( zString==0 ){ - return zGlobPattern!=0; - }else if( zGlobPattern==0 ){ - return 1; - }else { - return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '['); - } + return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '['); } /* ** The sqlite3_strlike() interface. Return 0 on a match and non-zero for ** a miss - like strcmp(). */ SQLITE_API int sqlite3_strlike(const char *zPattern, const char *zStr, unsigned int esc){ - if( zStr==0 ){ - return zPattern!=0; - }else if( zPattern==0 ){ - return 1; - }else{ - return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc); - } + return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc); } /* ** Count the number of times that the LIKE operator (or GLOB which is ** just a variation of LIKE) gets called. This is used for testing @@ -126328,11 +122175,11 @@ sqlite3_str_appendf(pStr, "%lld", sqlite3_value_int64(pValue)); break; } case SQLITE_BLOB: { char const *zBlob = sqlite3_value_blob(pValue); - i64 nBlob = sqlite3_value_bytes(pValue); + int nBlob = sqlite3_value_bytes(pValue); assert( zBlob==sqlite3_value_blob(pValue) ); /* No encoding change */ sqlite3StrAccumEnlarge(pStr, nBlob*2 + 4); if( pStr->accError==0 ){ char *zText = pStr->zText; int i; @@ -126468,100 +122315,10 @@ } *z = 0; sqlite3_result_text(context, zHex, n*2, sqlite3_free); } } - -/* -** Buffer zStr contains nStr bytes of utf-8 encoded text. Return 1 if zStr -** contains character ch, or 0 if it does not. -*/ -static int strContainsChar(const u8 *zStr, int nStr, u32 ch){ - const u8 *zEnd = &zStr[nStr]; - const u8 *z = zStr; - while( znCol; int regTemp = sqlite3GetTempRange(pParse, nCol); + int regRec = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb); sqlite3VdbeSetP4KeyInfo(pParse, pIdx); for(i=0; idb,pIdx), nCol); - sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regTemp, nCol); - VdbeCoverage(v); + sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0); VdbeCoverage(v); + + sqlite3ReleaseTempReg(pParse, regRec); sqlite3ReleaseTempRange(pParse, regTemp, nCol); } } if( !pFKey->isDeferred && !(pParse->db->flags & SQLITE_DeferFKs) @@ -128284,14 +124028,18 @@ ** 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". @@ -128935,13 +124683,13 @@ ** 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" then a NULL pointer is returned (these actions -** require no special handling by the triggers sub-system, code for them is -** created by fkScanChildren()). +** 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); @@ -129066,27 +124814,22 @@ zFrom = pFKey->pFrom->zName; nFrom = sqlite3Strlen30(zFrom); if( action==OE_Restrict ){ - int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - SrcList *pSrc; + Token tFrom; Expr *pRaise; + tFrom.z = zFrom; + tFrom.n = nFrom; pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed"); if( pRaise ){ pRaise->affExpr = OE_Abort; } - pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); - if( pSrc ){ - assert( pSrc->nSrc==1 ); - pSrc->a[0].zName = sqlite3DbStrDup(db, zFrom); - pSrc->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); - } pSelect = sqlite3SelectNew(pParse, sqlite3ExprListAppend(pParse, 0, pRaise), - pSrc, + sqlite3SrcListAppend(pParse, 0, &tFrom, 0), pWhere, 0, 0, 0, 0, 0 ); pWhere = 0; } @@ -129189,16 +124932,15 @@ SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *db, Table *pTab){ FKey *pFKey; /* Iterator variable */ FKey *pNext; /* Copy of pFKey->pNextFrom */ assert( IsOrdinaryTable(pTab) ); - assert( db!=0 ); for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pNext){ assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) ); /* Remove the FK from the fkeyHash hash table. */ - if( db->pnBytesFreed==0 ){ + 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); @@ -129298,72 +125040,47 @@ ** ** 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 sqlite3DeleteIndex() is called. */ -static SQLITE_NOINLINE const char *computeIndexAffStr(sqlite3 *db, 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. - */ - int n; - Table *pTab = pIdx->pTable; - pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1); +SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){ if( !pIdx->zColAff ){ - sqlite3OomFault(db); - return 0; - } - for(n=0; nnColumn; n++){ - i16 x = pIdx->aiColumn[n]; - char aff; - if( x>=0 ){ - aff = pTab->aCol[x].affinity; - }else if( x==XN_ROWID ){ - aff = SQLITE_AFF_INTEGER; - }else{ - assert( x==XN_EXPR ); - assert( pIdx->bHasExpr ); - assert( pIdx->aColExpr!=0 ); - aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr); - } - if( affSQLITE_AFF_NUMERIC) aff = SQLITE_AFF_NUMERIC; - pIdx->zColAff[n] = aff; - } - pIdx->zColAff[n] = 0; - return pIdx->zColAff; -} -SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){ - if( !pIdx->zColAff ) return computeIndexAffStr(db, pIdx); - return pIdx->zColAff; -} - - -/* -** Compute an affinity string for a table. Space is obtained -** from sqlite3DbMalloc(). The caller is responsible for freeing -** the space when done. -*/ -SQLITE_PRIVATE char *sqlite3TableAffinityStr(sqlite3 *db, const Table *pTab){ - char *zColAff; - zColAff = (char *)sqlite3DbMallocRaw(db, pTab->nCol+1); - if( zColAff ){ - int i, j; - for(i=j=0; inCol; i++){ - if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){ - zColAff[j++] = pTab->aCol[i].affinity; - } - } - do{ - zColAff[j--] = 0; - }while( j>=0 && zColAff[j]<=SQLITE_AFF_BLOB ); - } - return zColAff; + /* The first time a column affinity string for a particular index is + ** required, it is allocated and populated here. It is then stored as + ** 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. + */ + int n; + Table *pTab = pIdx->pTable; + pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1); + if( !pIdx->zColAff ){ + sqlite3OomFault(db); + return 0; + } + for(n=0; nnColumn; n++){ + i16 x = pIdx->aiColumn[n]; + char aff; + if( x>=0 ){ + aff = pTab->aCol[x].affinity; + }else if( x==XN_ROWID ){ + aff = SQLITE_AFF_INTEGER; + }else{ + assert( x==XN_EXPR ); + assert( pIdx->aColExpr!=0 ); + aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr); + } + if( affSQLITE_AFF_NUMERIC) aff = SQLITE_AFF_NUMERIC; + pIdx->zColAff[n] = aff; + } + pIdx->zColAff[n] = 0; + } + + return pIdx->zColAff; } /* ** Make changes to the evolving bytecode to do affinity transformations ** of values that are about to be gathered into a row for table pTab. @@ -129403,20 +125120,20 @@ ** register set as the OP_MakeRecord. If iReg>0 then register iReg is ** the first of a series of registers that will form the new record. ** Apply the type checking to that array of registers. */ SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ - int i; + int i, j; char *zColAff; if( pTab->tabFlags & TF_Strict ){ if( iReg==0 ){ /* Move the previous opcode (which should be OP_MakeRecord) forward ** by one slot and insert a new OP_TypeCheck where the current ** OP_MakeRecord is found */ VdbeOp *pPrev; sqlite3VdbeAppendP4(v, pTab, P4_TABLE); - pPrev = sqlite3VdbeGetLastOp(v); + pPrev = sqlite3VdbeGetOp(v, -1); assert( pPrev!=0 ); assert( pPrev->opcode==OP_MakeRecord || sqlite3VdbeDb(v)->mallocFailed ); pPrev->opcode = OP_TypeCheck; sqlite3VdbeAddOp3(v, OP_MakeRecord, pPrev->p1, pPrev->p2, pPrev->p3); }else{ @@ -129426,24 +125143,35 @@ } return; } zColAff = pTab->zColAff; if( zColAff==0 ){ - zColAff = sqlite3TableAffinityStr(0, pTab); + sqlite3 *db = sqlite3VdbeDb(v); + zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1); if( !zColAff ){ - sqlite3OomFault(sqlite3VdbeDb(v)); + sqlite3OomFault(db); return; } + + for(i=j=0; inCol; i++){ + assert( pTab->aCol[i].affinity!=0 || sqlite3VdbeParser(v)->nErr>0 ); + if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){ + zColAff[j++] = pTab->aCol[i].affinity; + } + } + do{ + zColAff[j--] = 0; + }while( j>=0 && zColAff[j]<=SQLITE_AFF_BLOB ); pTab->zColAff = zColAff; } assert( zColAff!=0 ); i = sqlite3Strlen30NN(zColAff); if( i ){ if( iReg ){ sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i); }else{ - assert( sqlite3VdbeGetLastOp(v)->opcode==OP_MakeRecord + assert( sqlite3VdbeGetOp(v, -1)->opcode==OP_MakeRecord || sqlite3VdbeDb(v)->mallocFailed ); sqlite3VdbeChangeP4(v, -1, zColAff, i); } } } @@ -129525,11 +125253,11 @@ /* Before computing generated columns, first go through and make sure ** that appropriate affinity has been applied to the regular columns */ sqlite3TableAffinity(pParse->pVdbe, pTab, iRegStore); if( (pTab->tabFlags & TF_HasStored)!=0 ){ - pOp = sqlite3VdbeGetLastOp(pParse->pVdbe); + pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1); if( pOp->opcode==OP_Affinity ){ /* Change the OP_Affinity argument to '@' (NONE) for all stored ** columns. '@' is the no-op affinity and those columns have not ** yet been computed. */ int ii, jj; @@ -130007,28 +125735,20 @@ # undef isView # define isView 0 #endif assert( (pTrigger && tmask) || (pTrigger==0 && tmask==0) ); -#if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x10000 ){ - sqlite3TreeViewLine(0, "In sqlite3Insert() at %s:%d", __FILE__, __LINE__); - sqlite3TreeViewInsert(pParse->pWith, pTabList, pColumn, pSelect, pList, - onError, pUpsert, pTrigger); - } -#endif - /* If pTab is really a view, make sure it has been initialized. ** ViewGetColumnNames() is a no-op if pTab is not a view. */ if( sqlite3ViewGetColumnNames(pParse, pTab) ){ goto insert_cleanup; } /* Cannot insert into a read-only table. */ - if( sqlite3IsReadOnly(pParse, pTab, pTrigger) ){ + if( sqlite3IsReadOnly(pParse, pTab, tmask) ){ goto insert_cleanup; } /* Allocate a VDBE */ @@ -130093,19 +125813,17 @@ ** columns into storage order. False negatives are harmless, ** but false positives will cause database corruption. */ bIdListInOrder = (pTab->tabFlags & (TF_OOOHidden|TF_HasStored))==0; if( pColumn ){ - assert( pColumn->eU4!=EU4_EXPR ); - pColumn->eU4 = EU4_IDX; for(i=0; inId; i++){ - pColumn->a[i].u4.idx = -1; + pColumn->a[i].idx = -1; } for(i=0; inId; i++){ for(j=0; jnCol; j++){ if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zCnName)==0 ){ - pColumn->a[i].u4.idx = j; + pColumn->a[i].idx = j; if( i!=j ) bIdListInOrder = 0; if( j==pTab->iPKey ){ ipkColumn = i; assert( !withoutRowid ); } #ifndef SQLITE_OMIT_GENERATED_COLUMNS @@ -130403,12 +126121,11 @@ iRegStore); continue; } } if( pColumn ){ - assert( pColumn->eU4==EU4_IDX ); - for(j=0; jnId && pColumn->a[j].u4.idx!=i; j++){} + for(j=0; jnId && pColumn->a[j].idx!=i; j++){} if( j>=pColumn->nId ){ /* A column not named in the insert column list gets its ** default value */ sqlite3ExprCodeFactorable(pParse, sqlite3ColumnExpr(pTab, &pTab->aCol[i]), @@ -130431,16 +126148,11 @@ }else if( pSelect ){ if( regFromSelect!=regData ){ sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+k, iRegStore); } }else{ - Expr *pX = pList->a[k].pExpr; - int y = sqlite3ExprCodeTarget(pParse, pX, iRegStore); - if( y!=iRegStore ){ - sqlite3VdbeAddOp2(v, - ExprHasProperty(pX, EP_Subquery) ? OP_Copy : OP_SCopy, y, iRegStore); - } + sqlite3ExprCode(pParse, pList->a[k].pExpr, iRegStore); } } /* Run the BEFORE and INSTEAD OF triggers, if there are any @@ -130471,11 +126183,11 @@ sqlite3VdbeJumpHere(v, addr1); sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols); VdbeCoverage(v); } /* Copy the new data already generated. */ - assert( pTab->nNVCol>0 || pParse->nErr>0 ); + assert( pTab->nNVCol>0 ); sqlite3VdbeAddOp3(v, OP_Copy, regRowid+1, regCols+1, pTab->nNVCol-1); #ifndef SQLITE_OMIT_GENERATED_COLUMNS /* Compute the new value for generated columns after all other ** columns have already been computed. This must be done after @@ -130573,13 +126285,11 @@ int isReplace = 0;/* Set to true if constraints may cause a replace */ int bUseSeek; /* True to use OPFLAG_SEEKRESULT */ sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur, regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0, pUpsert ); - if( db->flags & SQLITE_ForeignKeys ){ - sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0); - } + sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0); /* Set the OPFLAG_USESEEKRESULT flag if either (a) there are no REPLACE ** constraints or (b) there are no triggers and this table is not a ** parent table in a foreign key constraint. It is safe to set the ** flag in the second case as if any REPLACE constraint is hit, an @@ -130659,11 +126369,11 @@ sqlite3SrcListDelete(db, pTabList); sqlite3ExprListDelete(db, pList); sqlite3UpsertDelete(db, pUpsert); sqlite3SelectDelete(db, pSelect); sqlite3IdListDelete(db, pColumn); - if( aRegIdx ) sqlite3DbNNFreeNN(db, aRegIdx); + sqlite3DbFree(db, aRegIdx); } /* Make sure "isView" and other macros defined above are undefined. Otherwise ** they may interfere with compilation of other functions in this file ** (or in another file, if this file becomes part of the amalgamation). */ @@ -131023,11 +126733,10 @@ /* no break */ deliberate_fall_through case OE_Rollback: case OE_Fail: { char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName, pCol->zCnName); - testcase( zMsg==0 && db->mallocFailed==0 ); sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError, iReg); sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC); sqlite3VdbeChangeP5(v, P5_ConstraintNotNull); VdbeCoverage(v); @@ -131543,11 +127252,11 @@ } } if( isUpdate ){ /* If currently processing the PRIMARY KEY of a WITHOUT ROWID ** table, only conflict if the new PRIMARY KEY values are actually - ** different from the old. See TH3 withoutrowid04.test. + ** different from the old. ** ** For a UNIQUE index, only conflict if the PRIMARY KEY values ** of the matched index row are different from the original PRIMARY ** KEY values of this row before the update. */ int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol; @@ -132887,13 +128596,13 @@ const char *(*uri_key)(const char*,int); const char *(*filename_database)(const char*); const char *(*filename_journal)(const char*); const char *(*filename_wal)(const char*); /* Version 3.32.0 and later */ - const char *(*create_filename)(const char*,const char*,const char*, + char *(*create_filename)(const char*,const char*,const char*, int,const char**); - void (*free_filename)(const char*); + void (*free_filename)(char*); sqlite3_file *(*database_file_object)(const char*); /* Version 3.34.0 and later */ int (*txn_state)(sqlite3*,const char*); /* Version 3.36.1 and later */ sqlite3_int64 (*changes64)(sqlite3*); @@ -132907,20 +128616,10 @@ int (*vtab_rhs_value)(sqlite3_index_info*,int,sqlite3_value**); int (*vtab_distinct)(sqlite3_index_info*); int (*vtab_in)(sqlite3_index_info*,int,int); int (*vtab_in_first)(sqlite3_value*,sqlite3_value**); int (*vtab_in_next)(sqlite3_value*,sqlite3_value**); - /* Version 3.39.0 and later */ - int (*deserialize)(sqlite3*,const char*,unsigned char*, - sqlite3_int64,sqlite3_int64,unsigned); - unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*, - unsigned int); - const char *(*db_name)(sqlite3*,int); - /* Version 3.40.0 and later */ - int (*value_encoding)(sqlite3_value*); - /* Version 3.41.0 and later */ - int (*is_interrupted)(sqlite3*); }; /* ** This is the function signature used for all extension entry points. It ** is also defined in the file "loadext.c". @@ -133235,20 +128934,10 @@ #define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value #define sqlite3_vtab_distinct sqlite3_api->vtab_distinct #define sqlite3_vtab_in sqlite3_api->vtab_in #define sqlite3_vtab_in_first sqlite3_api->vtab_in_first #define sqlite3_vtab_in_next sqlite3_api->vtab_in_next -/* Version 3.39.0 and later */ -#ifndef SQLITE_OMIT_DESERIALIZE -#define sqlite3_deserialize sqlite3_api->deserialize -#define sqlite3_serialize sqlite3_api->serialize -#endif -#define sqlite3_db_name sqlite3_api->db_name -/* Version 3.40.0 and later */ -#define sqlite3_value_encoding sqlite3_api->value_encoding -/* Version 3.41.0 and later */ -#define sqlite3_is_interrupted sqlite3_api->is_interrupted #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) /* This case when the file really is being compiled as a loadable ** extension */ @@ -133736,36 +129425,15 @@ sqlite3_total_changes64, /* Version 3.37.0 and later */ sqlite3_autovacuum_pages, /* Version 3.38.0 and later */ sqlite3_error_offset, -#ifndef SQLITE_OMIT_VIRTUALTABLE sqlite3_vtab_rhs_value, sqlite3_vtab_distinct, sqlite3_vtab_in, sqlite3_vtab_in_first, - sqlite3_vtab_in_next, -#else - 0, - 0, - 0, - 0, - 0, -#endif - /* Version 3.39.0 and later */ -#ifndef SQLITE_OMIT_DESERIALIZE - sqlite3_deserialize, - sqlite3_serialize, -#else - 0, - 0, -#endif - sqlite3_db_name, - /* Version 3.40.0 and later */ - sqlite3_value_encoding, - /* Version 3.41.0 and later */ - sqlite3_is_interrupted + sqlite3_vtab_in_next }; /* True if x is the directory separator character */ #if SQLITE_OS_WIN @@ -133834,25 +129502,19 @@ zEntry = zProc ? zProc : "sqlite3_extension_init"; /* tag-20210611-1. Some dlopen() implementations will segfault if given ** an oversize filename. Most filesystems have a pathname limit of 4K, ** so limit the extension filename length to about twice that. - ** https://sqlite.org/forum/forumpost/08a0d6d9bf - ** - ** Later (2023-03-25): Save an extra 6 bytes for the filename suffix. - ** See https://sqlite.org/forum/forumpost/24083b579d. - */ + ** https://sqlite.org/forum/forumpost/08a0d6d9bf */ if( nMsg>SQLITE_MAX_PATHLEN ) goto extension_not_found; handle = sqlite3OsDlOpen(pVfs, zFile); #if SQLITE_OS_UNIX || SQLITE_OS_WIN for(ii=0; iipNext){ const char *zType; + static const u32 mask = + SQLITE_DETERMINISTIC | + SQLITE_DIRECTONLY | + SQLITE_SUBTYPE | + SQLITE_INNOCUOUS | + SQLITE_FUNC_INTERNAL + ; static const char *azEnc[] = { 0, "utf8", "utf16le", "utf16be" }; assert( SQLITE_FUNC_ENCMASK==0x3 ); assert( strcmp(azEnc[SQLITE_UTF8],"utf8")==0 ); assert( strcmp(azEnc[SQLITE_UTF16LE],"utf16le")==0 ); @@ -135627,11 +131288,11 @@ ** ** Do N steps of incremental vacuuming on a database. */ #ifndef SQLITE_OMIT_AUTOVACUUM case PragTyp_INCREMENTAL_VACUUM: { - int iLimit = 0, addr; + int iLimit, addr; if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){ iLimit = 0x7fffffff; } sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1); @@ -135784,21 +131445,19 @@ ** Setting to a null string reverts to the default temporary directory search. ** If temporary directory is changed, then invalidateTempStorage. ** */ case PragTyp_TEMP_STORE_DIRECTORY: { - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); if( !zRight ){ returnSingleText(v, sqlite3_temp_directory); }else{ #ifndef SQLITE_OMIT_WSD if( zRight[0] ){ int res; rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res); if( rc!=SQLITE_OK || res==0 ){ sqlite3ErrorMsg(pParse, "not a writable directory"); - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); goto pragma_out; } } if( SQLITE_TEMP_STORE==0 || (SQLITE_TEMP_STORE==1 && db->temp_store<=1) @@ -135812,11 +131471,10 @@ }else{ sqlite3_temp_directory = 0; } #endif /* SQLITE_OMIT_WSD */ } - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); break; } #if SQLITE_OS_WIN /* @@ -135831,21 +131489,19 @@ ** process. Database file specified with an absolute path are not impacted ** by this setting, regardless of its value. ** */ case PragTyp_DATA_STORE_DIRECTORY: { - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); if( !zRight ){ returnSingleText(v, sqlite3_data_directory); }else{ #ifndef SQLITE_OMIT_WSD if( zRight[0] ){ int res; rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res); if( rc!=SQLITE_OK || res==0 ){ sqlite3ErrorMsg(pParse, "not a writable directory"); - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); goto pragma_out; } } sqlite3_free(sqlite3_data_directory); if( zRight[0] ){ @@ -135853,11 +131509,10 @@ }else{ sqlite3_data_directory = 0; } #endif /* SQLITE_OMIT_WSD */ } - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); break; } #endif #if SQLITE_ENABLE_LOCKING_STYLE @@ -136321,17 +131976,19 @@ int i; /* Loop counter: Foreign key number for pTab */ int j; /* Loop counter: Field of the foreign key */ HashElem *k; /* Loop counter: Next table in schema */ int x; /* result variable */ int regResult; /* 3 registers to hold a result row */ + int regKey; /* Register to hold key for checking the FK */ int regRow; /* Registers to hold a row from pTab */ int addrTop; /* Top of a loop checking foreign keys */ int addrOk; /* Jump here if the key is OK */ int *aiCols; /* child to parent column mapping */ regResult = pParse->nMem+1; pParse->nMem += 4; + regKey = ++pParse->nMem; regRow = ++pParse->nMem; k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash); while( k ){ if( zRight ){ pTab = sqlite3LocateTable(pParse, 0, zRight, zDb); @@ -136343,11 +132000,11 @@ if( pTab==0 || !IsOrdinaryTable(pTab) || pTab->u.tab.pFKey==0 ) continue; iDb = sqlite3SchemaToIndex(db, pTab->pSchema); zDb = db->aDb[iDb].zDbSName; sqlite3CodeVerifySchema(pParse, iDb); sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); - sqlite3TouchRegister(pParse, pTab->nCol+regRow); + if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow; sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead); sqlite3VdbeLoadString(v, regResult, pTab->zName); assert( IsOrdinaryTable(pTab) ); for(i=1, pFK=pTab->u.tab.pFKey; pFK; i++, pFK=pFK->pNextFrom){ pParent = sqlite3FindTable(db, pFK->zTo, zDb); @@ -136384,23 +132041,23 @@ /* Generate code to read the child key values into registers ** regRow..regRow+n. If any of the child key values are NULL, this ** row cannot cause an FK violation. Jump directly to addrOk in ** this case. */ - sqlite3TouchRegister(pParse, regRow + pFK->nCol); + if( regRow+pFK->nCol>pParse->nMem ) pParse->nMem = regRow+pFK->nCol; for(j=0; jnCol; j++){ int iCol = aiCols ? aiCols[j] : pFK->aCol[j].iFrom; sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, iCol, regRow+j); sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v); } /* Generate code to query the parent index for a matching parent ** key. If a match is found, jump to addrOk. */ if( pIdx ){ - sqlite3VdbeAddOp4(v, OP_Affinity, regRow, pFK->nCol, 0, + sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey, sqlite3IndexAffinityStr(db,pIdx), pFK->nCol); - sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regRow, pFK->nCol); + sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0); VdbeCoverage(v); }else if( pParent ){ int jmp = sqlite3VdbeCurrentAddr(v)+2; sqlite3VdbeAddOp3(v, OP_SeekRowid, i, jmp, regRow); VdbeCoverage(v); sqlite3VdbeGoto(v, addrOk); @@ -136513,11 +132170,10 @@ if( OMIT_TEMPDB && i==1 ) continue; if( iDb>=0 && i!=iDb ) continue; sqlite3CodeVerifySchema(pParse, i); - pParse->okConstFactor = 0; /* tag-20230327-1 */ /* Do an integrity check of the B-Tree ** ** Begin by finding the root pages numbers ** for all tables and indices in the database. @@ -136549,11 +132205,11 @@ } } aRoot[0] = cnt; /* Make sure sufficient number of registers have been allocated */ - sqlite3TouchRegister(pParse, 8+mxIdx); + pParse->nMem = MAX( pParse->nMem, 8+mxIdx ); sqlite3ClearTempRegCache(pParse); /* Do the b-tree integrity checks */ sqlite3VdbeAddOp4(v, OP_IntegrityCk, 2, cnt, 1, (char*)aRoot,P4_INTARRAY); sqlite3VdbeChangeP5(v, (u8)i); @@ -136568,28 +132224,19 @@ /* Make sure all the indices are constructed correctly. */ for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); Index *pIdx, *pPk; - Index *pPrior = 0; /* Previous index */ + Index *pPrior = 0; int loopTop; int iDataCur, iIdxCur; int r1 = -1; - int bStrict; /* True for a STRICT table */ - int r2; /* Previous key for WITHOUT ROWID tables */ - int mxCol; /* Maximum non-virtual column number */ + int bStrict; if( !IsOrdinaryTable(pTab) ) continue; if( pObjTab && pObjTab!=pTab ) continue; - if( isQuick || HasRowid(pTab) ){ - pPk = 0; - r2 = 0; - }else{ - pPk = sqlite3PrimaryKeyIndex(pTab); - r2 = sqlite3GetTempRange(pParse, pPk->nKeyCol); - sqlite3VdbeAddOp3(v, OP_Null, 1, r2, r2+pPk->nKeyCol-1); - } + pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0, 1, 0, &iDataCur, &iIdxCur); /* reg[7] counts the number of entries in the table. ** reg[8+i] counts the number of entries in the i-th index */ @@ -136599,184 +132246,56 @@ } assert( pParse->nMem>=8+j ); assert( sqlite3NoTempsInRange(pParse,1,7+j) ); sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v); loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1); - - /* Fetch the right-most column from the table. This will cause - ** the entire record header to be parsed and sanity checked. It - ** will also prepopulate the cursor column cache that is used - ** by the OP_IsType code, so it is a required step. - */ - assert( !IsVirtual(pTab) ); - if( HasRowid(pTab) ){ - mxCol = -1; - for(j=0; jnCol; j++){ - if( (pTab->aCol[j].colFlags & COLFLAG_VIRTUAL)==0 ) mxCol++; - } - if( mxCol==pTab->iPKey ) mxCol--; - }else{ - /* COLFLAG_VIRTUAL columns are not included in the WITHOUT ROWID - ** PK index column-count, so there is no need to account for them - ** in this case. */ - mxCol = sqlite3PrimaryKeyIndex(pTab)->nColumn-1; - } - if( mxCol>=0 ){ - sqlite3VdbeAddOp3(v, OP_Column, iDataCur, mxCol, 3); - sqlite3VdbeTypeofColumn(v, 3); - } - if( !isQuick ){ - if( pPk ){ - /* Verify WITHOUT ROWID keys are in ascending order */ - int a1; - char *zErr; - a1 = sqlite3VdbeAddOp4Int(v, OP_IdxGT, iDataCur, 0,r2,pPk->nKeyCol); - VdbeCoverage(v); - sqlite3VdbeAddOp1(v, OP_IsNull, r2); VdbeCoverage(v); - zErr = sqlite3MPrintf(db, - "row not in PRIMARY KEY order for %s", - pTab->zName); - sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); - integrityCheckResultRow(v); - sqlite3VdbeJumpHere(v, a1); - sqlite3VdbeJumpHere(v, a1+1); - for(j=0; jnKeyCol; j++){ - sqlite3ExprCodeLoadIndexColumn(pParse, pPk, iDataCur, j, r2+j); - } - } - } - /* Verify datatypes for all columns: - ** - ** (1) NOT NULL columns may not contain a NULL - ** (2) Datatype must be exact for non-ANY columns in STRICT tables - ** (3) Datatype for TEXT columns in non-STRICT tables must be - ** NULL, TEXT, or BLOB. - ** (4) Datatype for numeric columns in non-STRICT tables must not - ** be a TEXT value that can be losslessly converted to numeric. - */ + /* Sanity check on record header decoding */ + sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nNVCol-1,3); + sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); + VdbeComment((v, "(right-most column)")); + } + /* Verify that all NOT NULL columns really are NOT NULL. At the + ** same time verify the type of the content of STRICT tables */ bStrict = (pTab->tabFlags & TF_Strict)!=0; for(j=0; jnCol; j++){ char *zErr; - Column *pCol = pTab->aCol + j; /* The column to be checked */ - int labelError; /* Jump here to report an error */ - int labelOk; /* Jump here if all looks ok */ - int p1, p3, p4; /* Operands to the OP_IsType opcode */ - int doTypeCheck; /* Check datatypes (besides NOT NULL) */ - + Column *pCol = pTab->aCol + j; + int doError, jmp2; if( j==pTab->iPKey ) continue; - if( bStrict ){ - doTypeCheck = pCol->eCType>COLTYPE_ANY; - }else{ - doTypeCheck = pCol->affinity>SQLITE_AFF_BLOB; - } - if( pCol->notNull==0 && !doTypeCheck ) continue; - - /* Compute the operands that will be needed for OP_IsType */ - p4 = SQLITE_NULL; - if( pCol->colFlags & COLFLAG_VIRTUAL ){ - sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); - p1 = -1; - p3 = 3; - }else{ - if( pCol->iDflt ){ - sqlite3_value *pDfltValue = 0; - sqlite3ValueFromExpr(db, sqlite3ColumnExpr(pTab,pCol), ENC(db), - pCol->affinity, &pDfltValue); - if( pDfltValue ){ - p4 = sqlite3_value_type(pDfltValue); - sqlite3ValueFree(pDfltValue); - } - } - p1 = iDataCur; - if( !HasRowid(pTab) ){ - testcase( j!=sqlite3TableColumnToStorage(pTab, j) ); - p3 = sqlite3TableColumnToIndex(sqlite3PrimaryKeyIndex(pTab), j); - }else{ - p3 = sqlite3TableColumnToStorage(pTab,j); - testcase( p3!=j); - } - } - - labelError = sqlite3VdbeMakeLabel(pParse); - labelOk = sqlite3VdbeMakeLabel(pParse); + if( pCol->notNull==0 && !bStrict ) continue; + doError = bStrict ? sqlite3VdbeMakeLabel(pParse) : 0; + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); + if( sqlite3VdbeGetOp(v,-1)->opcode==OP_Column ){ + sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); + } if( pCol->notNull ){ - /* (1) NOT NULL columns may not contain a NULL */ - int jmp3; - int jmp2 = sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4); - VdbeCoverage(v); - if( p1<0 ){ - sqlite3VdbeChangeP5(v, 0x0f); /* INT, REAL, TEXT, or BLOB */ - jmp3 = jmp2; - }else{ - sqlite3VdbeChangeP5(v, 0x0d); /* INT, TEXT, or BLOB */ - /* OP_IsType does not detect NaN values in the database file - ** which should be treated as a NULL. So if the header type - ** is REAL, we have to load the actual data using OP_Column - ** to reliably determine if the value is a NULL. */ - sqlite3VdbeAddOp3(v, OP_Column, p1, p3, 3); - jmp3 = sqlite3VdbeAddOp2(v, OP_NotNull, 3, labelOk); - VdbeCoverage(v); - } + jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v); zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName, pCol->zCnName); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); - if( doTypeCheck ){ - sqlite3VdbeGoto(v, labelError); - sqlite3VdbeJumpHere(v, jmp2); - sqlite3VdbeJumpHere(v, jmp3); + if( bStrict && pCol->eCType!=COLTYPE_ANY ){ + sqlite3VdbeGoto(v, doError); }else{ - /* VDBE byte code will fall thru */ - } - } - if( bStrict && doTypeCheck ){ - /* (2) Datatype must be exact for non-ANY columns in STRICT tables*/ - static unsigned char aStdTypeMask[] = { - 0x1f, /* ANY */ - 0x18, /* BLOB */ - 0x11, /* INT */ - 0x11, /* INTEGER */ - 0x13, /* REAL */ - 0x14 /* TEXT */ - }; - sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4); - assert( pCol->eCType>=1 && pCol->eCType<=sizeof(aStdTypeMask) ); - sqlite3VdbeChangeP5(v, aStdTypeMask[pCol->eCType-1]); + integrityCheckResultRow(v); + } + sqlite3VdbeJumpHere(v, jmp2); + } + if( (pTab->tabFlags & TF_Strict)!=0 + && pCol->eCType!=COLTYPE_ANY + ){ + jmp2 = sqlite3VdbeAddOp3(v, OP_IsNullOrType, 3, 0, + sqlite3StdTypeMap[pCol->eCType-1]); VdbeCoverage(v); zErr = sqlite3MPrintf(db, "non-%s value in %s.%s", sqlite3StdType[pCol->eCType-1], pTab->zName, pTab->aCol[j].zCnName); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); - }else if( !bStrict && pCol->affinity==SQLITE_AFF_TEXT ){ - /* (3) Datatype for TEXT columns in non-STRICT tables must be - ** NULL, TEXT, or BLOB. */ - sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4); - sqlite3VdbeChangeP5(v, 0x1c); /* NULL, TEXT, or BLOB */ - VdbeCoverage(v); - zErr = sqlite3MPrintf(db, "NUMERIC value in %s.%s", - pTab->zName, pTab->aCol[j].zCnName); - sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); - }else if( !bStrict && pCol->affinity>=SQLITE_AFF_NUMERIC ){ - /* (4) Datatype for numeric columns in non-STRICT tables must not - ** be a TEXT value that can be converted to numeric. */ - sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4); - sqlite3VdbeChangeP5(v, 0x1b); /* NULL, INT, FLOAT, or BLOB */ - VdbeCoverage(v); - if( p1>=0 ){ - sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); - } - sqlite3VdbeAddOp4(v, OP_Affinity, 3, 1, 0, "C", P4_STATIC); - sqlite3VdbeAddOp4Int(v, OP_IsType, -1, labelOk, 3, p4); - sqlite3VdbeChangeP5(v, 0x1c); /* NULL, TEXT, or BLOB */ - VdbeCoverage(v); - zErr = sqlite3MPrintf(db, "TEXT value in %s.%s", - pTab->zName, pTab->aCol[j].zCnName); - sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); - } - sqlite3VdbeResolveLabel(v, labelError); - integrityCheckResultRow(v); - sqlite3VdbeResolveLabel(v, labelOk); + sqlite3VdbeResolveLabel(v, doError); + integrityCheckResultRow(v); + sqlite3VdbeJumpHere(v, jmp2); + } } /* Verify CHECK constraints */ if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){ ExprList *pCheck = sqlite3ExprListDup(db, pTab->pCheck, 0); if( db->mallocFailed==0 ){ @@ -136801,12 +132320,11 @@ sqlite3ExprListDelete(db, pCheck); } if( !isQuick ){ /* Omit the remaining tests for quick_check */ /* Validate index entries for the current row */ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ - int jmp2, jmp3, jmp4, jmp5, label6; - int kk; + int jmp2, jmp3, jmp4, jmp5; int ckUniq = sqlite3VdbeMakeLabel(pParse); if( pPk==pIdx ) continue; r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3, pPrior, r1); pPrior = pIdx; @@ -136820,53 +132338,17 @@ sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName); sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); jmp4 = integrityCheckResultRow(v); sqlite3VdbeJumpHere(v, jmp2); - - /* The OP_IdxRowid opcode is an optimized version of OP_Column - ** that extracts the rowid off the end of the index record. - ** But it only works correctly if index record does not have - ** any extra bytes at the end. Verify that this is the case. */ - if( HasRowid(pTab) ){ - int jmp7; - sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur+j, 3); - jmp7 = sqlite3VdbeAddOp3(v, OP_Eq, 3, 0, r1+pIdx->nColumn-1); - VdbeCoverageNeverNull(v); - sqlite3VdbeLoadString(v, 3, - "rowid not at end-of-record for row "); - sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); - sqlite3VdbeLoadString(v, 4, " of index "); - sqlite3VdbeGoto(v, jmp5-1); - sqlite3VdbeJumpHere(v, jmp7); - } - - /* Any indexed columns with non-BINARY collations must still hold - ** the exact same text value as the table. */ - label6 = 0; - for(kk=0; kknKeyCol; kk++){ - if( pIdx->azColl[kk]==sqlite3StrBINARY ) continue; - if( label6==0 ) label6 = sqlite3VdbeMakeLabel(pParse); - sqlite3VdbeAddOp3(v, OP_Column, iIdxCur+j, kk, 3); - sqlite3VdbeAddOp3(v, OP_Ne, 3, label6, r1+kk); VdbeCoverage(v); - } - if( label6 ){ - int jmp6 = sqlite3VdbeAddOp0(v, OP_Goto); - sqlite3VdbeResolveLabel(v, label6); - sqlite3VdbeLoadString(v, 3, "row "); - sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); - sqlite3VdbeLoadString(v, 4, " values differ from index "); - sqlite3VdbeGoto(v, jmp5-1); - sqlite3VdbeJumpHere(v, jmp6); - } - /* For UNIQUE indexes, verify that only one entry exists with the ** current key. The entry is unique if (1) any column is NULL ** or (2) the next entry has a different key */ if( IsUniqueIndex(pIdx) ){ int uniqOk = sqlite3VdbeMakeLabel(pParse); int jmp6; + int kk; for(kk=0; kknKeyCol; kk++){ int iCol = pIdx->aiColumn[kk]; assert( iCol!=XN_ROWID && iColnCol ); if( iCol>=0 && pTab->aCol[iCol].notNull ) continue; sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk); @@ -136897,13 +132379,10 @@ sqlite3VdbeLoadString(v, 4, pIdx->zName); sqlite3VdbeAddOp3(v, OP_Concat, 4, 2, 3); integrityCheckResultRow(v); sqlite3VdbeJumpHere(v, addr); } - if( pPk ){ - sqlite3ReleaseTempRange(pParse, r2, pPk->nKeyCol); - } } } } { static const int iLn = VDBE_OFFSET_LINENO(2); @@ -137050,15 +132529,10 @@ aOp[0].p1 = iDb; aOp[1].p1 = iDb; aOp[1].p2 = iCookie; aOp[1].p3 = sqlite3Atoi(zRight); aOp[1].p5 = 1; - if( iCookie==BTREE_SCHEMA_VERSION && (db->flags & SQLITE_Defensive)!=0 ){ - /* Do not allow the use of PRAGMA schema_version=VALUE in defensive - ** mode. Change the OP_SetCookie opcode into a no-op. */ - aOp[1].opcode = OP_Noop; - } }else{ /* Read the specified cookie value */ static const VdbeOpList readCookie[] = { { OP_Transaction, 0, 0, 0}, /* 0 */ { OP_ReadCookie, 0, 1, 0}, /* 1 */ @@ -138035,18 +133509,11 @@ encoding = (u8)meta[BTREE_TEXT_ENCODING-1] & 3; if( encoding==0 ) encoding = SQLITE_UTF8; #else encoding = SQLITE_UTF8; #endif - if( db->nVdbeActive>0 && encoding!=ENC(db) - && (db->mDbFlags & DBFLAG_Vacuum)==0 - ){ - rc = SQLITE_LOCKED; - goto initone_error_out; - }else{ - sqlite3SetTextEncoding(db, encoding); - } + sqlite3SetTextEncoding(db, encoding); }else{ /* If opening an attached database, the encoding much match ENC(db) */ if( (meta[BTREE_TEXT_ENCODING-1] & 3)!=ENC(db) ){ sqlite3SetString(pzErrMsg, db, "attached databases must use the same" " text encoding as main database"); @@ -138256,12 +133723,12 @@ ** value stored as part of the in-memory schema representation, ** set Parse.rc to SQLITE_SCHEMA. */ sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie); assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( cookie!=db->aDb[iDb].pSchema->schema_cookie ){ - if( DbHasProperty(db, iDb, DB_SchemaLoaded) ) pParse->rc = SQLITE_SCHEMA; sqlite3ResetOneSchema(db, iDb); + pParse->rc = SQLITE_SCHEMA; } /* Close the transaction, if one was opened. */ if( openedTransaction ){ sqlite3BtreeCommit(pBt); @@ -138310,19 +133777,19 @@ sqlite3 *db = pParse->db; assert( db!=0 ); assert( db->pParse==pParse ); assert( pParse->nested==0 ); #ifndef SQLITE_OMIT_SHARED_CACHE - if( pParse->aTableLock ) sqlite3DbNNFreeNN(db, pParse->aTableLock); + sqlite3DbFree(db, pParse->aTableLock); #endif while( pParse->pCleanup ){ ParseCleanup *pCleanup = pParse->pCleanup; pParse->pCleanup = pCleanup->pNext; pCleanup->xCleanup(db, pCleanup->pPtr); - sqlite3DbNNFreeNN(db, pCleanup); + sqlite3DbFreeNN(db, pCleanup); } - if( pParse->aLabel ) sqlite3DbNNFreeNN(db, pParse->aLabel); + sqlite3DbFree(db, pParse->aLabel); if( pParse->pConstExpr ){ sqlite3ExprListDelete(db, pParse->pConstExpr); } assert( db->lookaside.bDisable >= pParse->disableLookaside ); db->lookaside.bDisable -= pParse->disableLookaside; @@ -138441,11 +133908,11 @@ */ if( prepFlags & SQLITE_PREPARE_PERSISTENT ){ sParse.disableLookaside++; DisableLookaside; } - sParse.prepFlags = prepFlags & 0xff; + sParse.disableVtab = (prepFlags & SQLITE_PREPARE_NO_VTAB)!=0; /* Check to verify that it is possible to get a read lock on all ** database schemas. The inability to get a read lock indicates that ** some other database connection is holding a write-lock, which in ** turn means that the other connection has made uncommitted changes @@ -138482,13 +133949,11 @@ } } } } -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( db->pDisconnect ) sqlite3VtabUnlockList(db); -#endif + sqlite3VtabUnlockList(db); if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){ char *zSqlCopy; int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; testcase( nBytes==mxLen ); @@ -138824,11 +134289,11 @@ ** how to process the DISTINCT keyword, to simplify passing that information ** into the selectInnerLoop() routine. */ typedef struct DistinctCtx DistinctCtx; struct DistinctCtx { - u8 isTnct; /* 0: Not distinct. 1: DISTICT 2: DISTINCT and ORDER BY */ + u8 isTnct; /* True if the DISTINCT keyword is present */ u8 eTnctType; /* One of the WHERE_DISTINCT_* operators */ int tabTnct; /* Ephemeral table used for DISTINCT processing */ int addrTnct; /* Address of OP_OpenEphemeral opcode for tabTnct */ }; @@ -138868,14 +134333,10 @@ int iCsr; /* Cursor number for table */ int nKey; /* Number of PK columns for table pTab (>=1) */ } aDefer[4]; #endif struct RowLoadInfo *pDeferredRowLoad; /* Deferred row loading info or NULL */ -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS - int addrPush; /* First instruction to push data into sorter */ - int addrPushEnd; /* Last instruction that pushes data into sorter */ -#endif }; #define SORTFLAG_UseSorter 0x01 /* Use SorterOpen instead of OpenEphemeral */ /* ** Delete all the content of a Select structure. Deallocate the structure @@ -138883,11 +134344,10 @@ ** ** If bFree==1, call sqlite3DbFree() on the p object. ** If bFree==0, Leave the first Select object unfreed */ static void clearSelect(sqlite3 *db, Select *p, int bFree){ - assert( db!=0 ); while( p ){ Select *pPrior = p->pPrior; sqlite3ExprListDelete(db, p->pEList); sqlite3SrcListDelete(db, p->pSrc); sqlite3ExprDelete(db, p->pWhere); @@ -138903,11 +134363,11 @@ while( p->pWin ){ assert( p->pWin->ppThis==&p->pWin ); sqlite3WindowUnlinkFromSelect(p->pWin); } #endif - if( bFree ) sqlite3DbNNFreeNN(db, p); + if( bFree ) sqlite3DbFreeNN(db, p); p = pPrior; bFree = 1; } } @@ -139012,56 +134472,10 @@ ** ** 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. -** -** These are the valid join types: -** -** -** pA pB pC Return Value -** ------- ----- ----- ------------ -** CROSS - - JT_CROSS -** INNER - - JT_INNER -** LEFT - - JT_LEFT|JT_OUTER -** LEFT OUTER - JT_LEFT|JT_OUTER -** RIGHT - - JT_RIGHT|JT_OUTER -** RIGHT OUTER - JT_RIGHT|JT_OUTER -** FULL - - JT_LEFT|JT_RIGHT|JT_OUTER -** FULL OUTER - JT_LEFT|JT_RIGHT|JT_OUTER -** NATURAL INNER - JT_NATURAL|JT_INNER -** NATURAL LEFT - JT_NATURAL|JT_LEFT|JT_OUTER -** NATURAL LEFT OUTER JT_NATURAL|JT_LEFT|JT_OUTER -** NATURAL RIGHT - JT_NATURAL|JT_RIGHT|JT_OUTER -** NATURAL RIGHT OUTER JT_NATURAL|JT_RIGHT|JT_OUTER -** NATURAL FULL - JT_NATURAL|JT_LEFT|JT_RIGHT -** NATURAL FULL OUTER JT_NATRUAL|JT_LEFT|JT_RIGHT -** -** To preserve historical compatibly, SQLite also accepts a variety -** of other non-standard and in many cases non-sensical join types. -** This routine makes as much sense at it can from the nonsense join -** type and returns a result. Examples of accepted nonsense join types -** include but are not limited to: -** -** INNER CROSS JOIN -> same as JOIN -** NATURAL CROSS JOIN -> same as NATURAL JOIN -** OUTER LEFT JOIN -> same as LEFT JOIN -** LEFT NATURAL JOIN -> same as NATURAL LEFT JOIN -** LEFT RIGHT JOIN -> same as FULL JOIN -** RIGHT OUTER FULL JOIN -> same as FULL JOIN -** CROSS CROSS CROSS JOIN -> same as JOIN -** -** The only restrictions on the join type name are: -** -** * "INNER" cannot appear together with "OUTER", "LEFT", "RIGHT", -** or "FULL". -** -** * "CROSS" cannot appear together with "OUTER", "LEFT", "RIGHT, -** or "FULL". -** -** * If "OUTER" is present then there must also be one of -** "LEFT", "RIGHT", or "FULL" */ SQLITE_PRIVATE int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){ int jointype = 0; Token *apAll[3]; Token *p; @@ -139070,17 +134484,17 @@ 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[] = { - /* (0) natural */ { 0, 7, JT_NATURAL }, - /* (1) left */ { 6, 4, JT_LEFT|JT_OUTER }, - /* (2) outer */ { 10, 5, JT_OUTER }, - /* (3) right */ { 14, 5, JT_RIGHT|JT_OUTER }, - /* (4) full */ { 19, 4, JT_LEFT|JT_RIGHT|JT_OUTER }, - /* (5) inner */ { 23, 5, JT_INNER }, - /* (6) cross */ { 28, 5, JT_INNER|JT_CROSS }, + /* 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; @@ -139099,19 +134513,22 @@ break; } } if( (jointype & (JT_INNER|JT_OUTER))==(JT_INNER|JT_OUTER) || - (jointype & JT_ERROR)!=0 || - (jointype & (JT_OUTER|JT_LEFT|JT_RIGHT))==JT_OUTER + (jointype & JT_ERROR)!=0 ){ - const char *zSp1 = " "; - const char *zSp2 = " "; - if( pB==0 ){ zSp1++; } - if( pC==0 ){ zSp2++; } - sqlite3ErrorMsg(pParse, "unknown join type: " - "%T%s%T%s%T", pA, zSp1, pB, zSp2, pC); + const char *zSp = " "; + assert( pB!=0 ); + if( pC==0 ){ zSp++; } + sqlite3ErrorMsg(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 ){ + sqlite3ErrorMsg(pParse, + "RIGHT and FULL OUTER JOINs are not currently supported"); jointype = JT_INNER; } return jointype; } @@ -139128,58 +134545,36 @@ } return -1; } /* -** Mark a subquery result column as having been used. -*/ -SQLITE_PRIVATE void sqlite3SrcItemColumnUsed(SrcItem *pItem, int iCol){ - assert( pItem!=0 ); - assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); - if( pItem->fg.isNestedFrom ){ - ExprList *pResults; - assert( pItem->pSelect!=0 ); - pResults = pItem->pSelect->pEList; - assert( pResults!=0 ); - assert( iCol>=0 && iColnExpr ); - pResults->a[iCol].fg.bUsed = 1; - } -} - -/* -** Search the tables iStart..iEnd (inclusive) in pSrc, looking for a -** table that has a column named zCol. The search is left-to-right. -** The first match found is returned. +** 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 iStart, /* First member of pSrc->a[] to check */ - int iEnd, /* Last member of pSrc->a[] to check */ + 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 bIgnoreHidden /* Ignore hidden columns */ + int bIgnoreHidden /* True to ignore hidden columns */ ){ int i; /* For looping over tables in pSrc */ int iCol; /* Index of column matching zCol */ - assert( iEndnSrc ); - assert( iStart>=0 ); assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */ - - for(i=iStart; i<=iEnd; i++){ + for(i=0; ia[i].pTab, zCol); if( iCol>=0 && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0) ){ if( piTab ){ - sqlite3SrcItemColumnUsed(&pSrc->a[i], iCol); *piTab = i; *piCol = iCol; } return 1; } @@ -139186,23 +134581,70 @@ } return 0; } /* -** Set the EP_OuterON property on all terms of the given expression. -** And set the Expr.w.iJoin to iTable for every term in the +** 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 */ +){ + sqlite3 *db = pParse->db; + Expr *pE1; + Expr *pE2; + Expr *pEq; + + assert( iLeftnSrc>iRight ); + assert( pSrc->a[iLeft].pTab ); + assert( pSrc->a[iRight].pTab ); + + pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iColLeft); + pE2 = sqlite3CreateColumnExpr(db, pSrc, iRight, iColRight); + + pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2); + assert( pE2!=0 || pEq==0 ); /* Due to db->mallocFailed test + ** in sqlite3DbMallocRawNN() called from + ** sqlite3PExpr(). */ + if( pEq && isOuterJoin ){ + ExprSetProperty(pEq, EP_FromJoin); + assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) ); + ExprSetVVAProperty(pEq, EP_NoReduce); + pEq->w.iRightJoinTable = pE2->iTable; + } + *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq); +} + +/* +** Set the EP_FromJoin property on all terms of the given expression. +** And set the Expr.w.iRightJoinTable to iTable for every term in the ** expression. ** -** The EP_OuterON property is used on terms of an expression to tell -** the OUTER JOIN processing logic that this term is part of the +** 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.w.iJoin tells the WHERE clause processing that the -** expression depends on table w.iJoin even if that table is not +** The Expr.w.iRightJoinTable tells the WHERE clause processing that the +** expression depends on table w.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 ** @@ -139211,90 +134653,74 @@ ** 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. */ -SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable, u32 joinFlag){ - assert( joinFlag==EP_OuterON || joinFlag==EP_InnerON ); +SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable){ while( p ){ - ExprSetProperty(p, joinFlag); + ExprSetProperty(p, EP_FromJoin); assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); ExprSetVVAProperty(p, EP_NoReduce); - p->w.iJoin = iTable; + p->w.iRightJoinTable = iTable; if( p->op==TK_FUNCTION ){ assert( ExprUseXList(p) ); if( p->x.pList ){ int i; for(i=0; ix.pList->nExpr; i++){ - sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable, joinFlag); + sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable); } } } - sqlite3SetJoinExpr(p->pLeft, iTable, joinFlag); + sqlite3SetJoinExpr(p->pLeft, iTable); p = p->pRight; } } -/* Undo the work of sqlite3SetJoinExpr(). This is used when a LEFT JOIN -** is simplified into an ordinary JOIN, and when an ON expression is -** "pushed down" into the WHERE clause of a subquery. -** -** Convert every term that is marked with EP_OuterON and w.iJoin==iTable into -** an ordinary term that omits the EP_OuterON mark. Or if iTable<0, then -** just clear every EP_OuterON and EP_InnerON mark from the expression tree. -** -** If nullable is true, that means that Expr p might evaluate to NULL even -** if it is a reference to a NOT NULL column. This can happen, for example, -** if the table that p references is on the left side of a RIGHT JOIN. -** If nullable is true, then take care to not remove the EP_CanBeNull bit. -** See forum thread https://sqlite.org/forum/forumpost/b40696f50145d21c -*/ -static void unsetJoinExpr(Expr *p, int iTable, int nullable){ +/* Undo the work of sqlite3SetJoinExpr(). In the expression p, convert every +** term that is marked with EP_FromJoin and w.iRightJoinTable==iTable into +** an ordinary term that omits the EP_FromJoin mark. +** +** This happens when a LEFT JOIN is simplified into an ordinary JOIN. +*/ +static void unsetJoinExpr(Expr *p, int iTable){ while( p ){ - if( iTable<0 || (ExprHasProperty(p, EP_OuterON) && p->w.iJoin==iTable) ){ - ExprClearProperty(p, EP_OuterON|EP_InnerON); - if( iTable>=0 ) ExprSetProperty(p, EP_InnerON); + if( ExprHasProperty(p, EP_FromJoin) + && (iTable<0 || p->w.iRightJoinTable==iTable) ){ + ExprClearProperty(p, EP_FromJoin); } - if( p->op==TK_COLUMN && p->iTable==iTable && !nullable ){ + if( p->op==TK_COLUMN && p->iTable==iTable ){ ExprClearProperty(p, EP_CanBeNull); } if( p->op==TK_FUNCTION ){ assert( ExprUseXList(p) ); if( p->x.pList ){ int i; for(i=0; ix.pList->nExpr; i++){ - unsetJoinExpr(p->x.pList->a[i].pExpr, iTable, nullable); + unsetJoinExpr(p->x.pList->a[i].pExpr, iTable); } } } - unsetJoinExpr(p->pLeft, iTable, nullable); + unsetJoinExpr(p->pLeft, iTable); p = p->pRight; } } /* ** This routine processes the join information for a SELECT statement. -** -** * A NATURAL join is converted into a USING join. After that, we -** do not need to be concerned with NATURAL joins and we only have -** think about USING joins. -** -** * ON and USING clauses result in extra terms being added to the -** WHERE clause to enforce the specified constraints. The extra -** WHERE clause terms will be tagged with EP_OuterON or -** EP_InnerON so that we know that they originated in ON/USING. +** 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 right. Thus entry 1 contains the join operator for the join between +** 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 right entry. +** also attached to the left entry. ** ** This routine returns the number of errors encountered. */ -static int sqlite3ProcessJoin(Parse *pParse, Select *p){ +static int sqliteProcessJoin(Parse *pParse, Select *p){ SrcList *pSrc; /* All tables in the FROM clause */ int i, j; /* Loop counters */ SrcItem *pLeft; /* Left table being joined */ SrcItem *pRight; /* Right table being joined */ @@ -139301,135 +134727,82 @@ pSrc = p->pSrc; pLeft = &pSrc->a[0]; pRight = &pLeft[1]; for(i=0; inSrc-1; i++, pRight++, pLeft++){ Table *pRightTab = pRight->pTab; - u32 joinType; + int isOuter; if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue; - joinType = (pRight->fg.jointype & JT_OUTER)!=0 ? EP_OuterON : EP_InnerON; + isOuter = (pRight->fg.jointype & JT_OUTER)!=0; - /* If this is a NATURAL join, synthesize an approprate USING clause - ** to specify which columns should be joined. + /* When the NATURAL keyword is present, add WHERE clause terms for + ** every column that the two tables have in common. */ if( pRight->fg.jointype & JT_NATURAL ){ - IdList *pUsing = 0; - if( pRight->fg.isUsing || pRight->u3.pOn ){ + if( pRight->pOn || pRight->pUsing ){ sqlite3ErrorMsg(pParse, "a NATURAL join may not have " "an ON or USING clause", 0); return 1; } for(j=0; jnCol; j++){ char *zName; /* Name of column in the right table */ + int iLeft; /* Matching left table */ + int iLeftCol; /* Matching column in the left table */ if( IsHiddenColumn(&pRightTab->aCol[j]) ) continue; zName = pRightTab->aCol[j].zCnName; - if( tableAndColumnIndex(pSrc, 0, i, zName, 0, 0, 1) ){ - pUsing = sqlite3IdListAppend(pParse, pUsing, 0); - if( pUsing ){ - assert( pUsing->nId>0 ); - assert( pUsing->a[pUsing->nId-1].zName==0 ); - pUsing->a[pUsing->nId-1].zName = sqlite3DbStrDup(pParse->db, zName); - } - } - } - if( pUsing ){ - pRight->fg.isUsing = 1; - pRight->fg.isSynthUsing = 1; - pRight->u3.pUsing = pUsing; - } - if( pParse->nErr ) return 1; + if( tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 1) ){ + 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 ){ + sqlite3ErrorMsg(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 ) sqlite3SetJoinExpr(pRight->pOn, pRight->iCursor); + p->pWhere = sqlite3ExprAnd(pParse, 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->fg.isUsing ){ - IdList *pList = pRight->u3.pUsing; - sqlite3 *db = pParse->db; - assert( pList!=0 ); + if( pRight->pUsing ){ + IdList *pList = pRight->pUsing; for(j=0; jnId; 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 */ - Expr *pE1; /* Reference to the column on the LEFT of the join */ - Expr *pE2; /* Reference to the column on the RIGHT of the join */ - Expr *pEq; /* Equality constraint. pE1 == pE2 */ zName = pList->a[j].zName; iRightCol = sqlite3ColumnIndex(pRightTab, zName); if( iRightCol<0 - || tableAndColumnIndex(pSrc, 0, i, zName, &iLeft, &iLeftCol, - pRight->fg.isSynthUsing)==0 + || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 0) ){ sqlite3ErrorMsg(pParse, "cannot join using column %s - column " "not present in both tables", zName); return 1; } - pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol); - sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol); - if( (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ - /* This branch runs if the query contains one or more RIGHT or FULL - ** JOINs. If only a single table on the left side of this join - ** contains the zName column, then this branch is a no-op. - ** But if there are two or more tables on the left side - ** of the join, construct a coalesce() function that gathers all - ** such tables. Raise an error if more than one of those references - ** to zName is not also within a prior USING clause. - ** - ** We really ought to raise an error if there are two or more - ** non-USING references to zName on the left of an INNER or LEFT - ** JOIN. But older versions of SQLite do not do that, so we avoid - ** adding a new error so as to not break legacy applications. - */ - ExprList *pFuncArgs = 0; /* Arguments to the coalesce() */ - static const Token tkCoalesce = { "coalesce", 8 }; - while( tableAndColumnIndex(pSrc, iLeft+1, i, zName, &iLeft, &iLeftCol, - pRight->fg.isSynthUsing)!=0 ){ - if( pSrc->a[iLeft].fg.isUsing==0 - || sqlite3IdListIndex(pSrc->a[iLeft].u3.pUsing, zName)<0 - ){ - sqlite3ErrorMsg(pParse, "ambiguous reference to %s in USING()", - zName); - break; - } - pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1); - pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol); - sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol); - } - if( pFuncArgs ){ - pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1); - pE1 = sqlite3ExprFunction(pParse, pFuncArgs, &tkCoalesce, 0); - } - } - pE2 = sqlite3CreateColumnExpr(db, pSrc, i+1, iRightCol); - sqlite3SrcItemColumnUsed(pRight, iRightCol); - pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2); - assert( pE2!=0 || pEq==0 ); - if( pEq ){ - ExprSetProperty(pEq, joinType); - assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) ); - ExprSetVVAProperty(pEq, EP_NoReduce); - pEq->w.iJoin = pE2->iTable; - } - p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pEq); - } - } - - /* Add the ON clause to the end of the WHERE clause, connected by - ** an AND operator. - */ - else if( pRight->u3.pOn ){ - sqlite3SetJoinExpr(pRight->u3.pOn, pRight->iCursor, joinType); - p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->u3.pOn); - pRight->u3.pOn = 0; - pRight->fg.isOn = 1; + addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, iRightCol, + isOuter, &p->pWhere); + } } } return 0; } @@ -139528,14 +134901,10 @@ ** regOrigData is 0 to prevent this routine from trying to copy ** values that might not yet exist. */ assert( nData==1 || regData==regOrigData || regOrigData==0 ); -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS - pSort->addrPush = sqlite3VdbeCurrentAddr(v); -#endif - if( nPrefixReg ){ assert( nPrefixReg==nExpr+bSeq ); regBase = regData - nPrefixReg; }else{ regBase = pParse->nMem + 1; @@ -139632,13 +135001,10 @@ regBase+nOBSat, nBase-nOBSat); if( iSkip ){ sqlite3VdbeChangeP2(v, iSkip, pSort->labelOBLopt ? pSort->labelOBLopt : sqlite3VdbeCurrentAddr(v)); } -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS - pSort->addrPushEnd = sqlite3VdbeCurrentAddr(v)-1; -#endif } /* ** Add code to implement the OFFSET */ @@ -139822,11 +135188,11 @@ ** the row from table t1 is stored instead. Then, as records are extracted from ** the sorter to return to the user, the required value of bigblob is ** retrieved directly from table t1. If the values are very large, this ** can be more efficient than storing them directly in the sorter records. ** -** The ExprList_item.fg.bSorterRef flag is set for each expression in pEList +** The ExprList_item.bSorterRef flag is set for each expression in pEList ** for which the sorter-reference optimization should be enabled. ** Additionally, the pSort->aDefer[] array is populated with entries ** for all cursors required to evaluate all selected expressions. Finally. ** output variable (*ppExtra) is set to an expression list containing ** expressions for all extra PK values that should be stored in the @@ -139882,11 +135248,11 @@ pSort->aDefer[nDefer].iCsr = pExpr->iTable; pSort->aDefer[nDefer].nKey = nKey; nDefer++; } } - pItem->fg.bSorterRef = 1; + pItem->bSorterRef = 1; } } } pSort->nDefer = (u8)nDefer; *ppExtra = pExtra; @@ -140013,11 +135379,11 @@ ** from the sorter by the optimizations in this branch */ pEList = p->pEList; for(i=0; inExpr; i++){ if( pEList->a[i].u.x.iOrderByCol>0 #ifdef SQLITE_ENABLE_SORTER_REFERENCES - || pEList->a[i].fg.bSorterRef + || pEList->a[i].bSorterRef #endif ){ nResultCol--; regOrig = 0; } @@ -140316,14 +135682,13 @@ /* ** Deallocate a KeyInfo object */ SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo *p){ if( p ){ - assert( p->db!=0 ); assert( p->nRef>0 ); p->nRef--; - if( p->nRef==0 ) sqlite3DbNNFreeNN(p->db, p); + if( p->nRef==0 ) sqlite3DbFreeNN(p->db, p); } } /* ** Make a new pointer to a KeyInfo object @@ -140376,11 +135741,11 @@ pInfo = sqlite3KeyInfoAlloc(db, nExpr-iStart, nExtra+1); if( pInfo ){ assert( sqlite3KeyInfoIsWriteable(pInfo) ); for(i=iStart, pItem=pList->a+iStart; iaColl[i-iStart] = sqlite3ExprNNCollSeq(pParse, pItem->pExpr); - pInfo->aSortFlags[i-iStart] = pItem->fg.sortFlags; + pInfo->aSortFlags[i-iStart] = pItem->sortFlags; } } return pInfo; } @@ -140458,20 +135823,10 @@ int iSortTab; /* Sorter cursor to read from */ int i; int bSeq; /* True if sorter record includes seq. no. */ int nRefKey = 0; struct ExprList_item *aOutEx = p->pEList->a; -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS - int addrExplain; /* Address of OP_Explain instruction */ -#endif - - ExplainQueryPlan2(addrExplain, (pParse, 0, - "USE TEMP B-TREE FOR %sORDER BY", pSort->nOBSat>0?"RIGHT PART OF ":"") - ); - sqlite3VdbeScanStatusRange(v, addrExplain,pSort->addrPush,pSort->addrPushEnd); - sqlite3VdbeScanStatusCounters(v, addrExplain, addrExplain, pSort->addrPush); - assert( addrBreak<0 ); if( pSort->labelBkOut ){ sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut); sqlite3VdbeGoto(v, addrBreak); @@ -140514,25 +135869,22 @@ sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nColumn+nRefKey); if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak); VdbeCoverage(v); - assert( p->iLimit==0 && p->iOffset==0 ); + codeOffset(v, p->iOffset, addrContinue); sqlite3VdbeAddOp3(v, OP_SorterData, iTab, regSortOut, iSortTab); bSeq = 0; }else{ addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v); codeOffset(v, p->iOffset, addrContinue); iSortTab = iTab; bSeq = 1; - if( p->iOffset>0 ){ - sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1); - } } for(i=0, iCol=nKey+bSeq-1; inDefer ){ @@ -140565,11 +135917,11 @@ sqlite3ReleaseTempRange(pParse, regKey, nRefKey); } #endif for(i=nColumn-1; i>=0; i--){ #ifdef SQLITE_ENABLE_SORTER_REFERENCES - if( aOutEx[i].fg.bSorterRef ){ + if( aOutEx[i].bSorterRef ){ sqlite3ExprCode(pParse, aOutEx[i].pExpr, regRow+i); }else #endif { int iRead; @@ -140580,11 +135932,10 @@ } sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iRead, regRow+i); VdbeComment((v, "%s", aOutEx[i].zEName)); } } - sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1); switch( eDest ){ case SRT_Table: case SRT_EphemTab: { sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq, regRow); sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid); @@ -140642,18 +135993,20 @@ if( pSort->sortFlags & SORTFLAG_UseSorter ){ sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr); VdbeCoverage(v); }else{ sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); VdbeCoverage(v); } - sqlite3VdbeScanStatusRange(v, addrExplain, sqlite3VdbeCurrentAddr(v)-1, -1); if( pSort->regReturn ) sqlite3VdbeAddOp1(v, OP_Return, pSort->regReturn); sqlite3VdbeResolveLabel(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. +** +** Also try to estimate the size of the returned value and return that +** result in *pEstWidth. ** ** 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 @@ -140914,11 +136267,11 @@ #endif if( pParse->colNamesSet ) return; /* Column names are determined by the left-most term of a compound select */ while( pSelect->pPrior ) pSelect = pSelect->pPrior; - TREETRACE(0x80,pParse,pSelect,("generating column names\n")); + SELECTTRACE(1,pParse,pSelect,("generating column names\n")); pTabList = pSelect->pSrc; pEList = pSelect->pEList; assert( v!=0 ); assert( pTabList!=0 ); pParse->colNamesSet = 1; @@ -140930,11 +136283,11 @@ assert( p!=0 ); assert( p->op!=TK_AGG_COLUMN ); /* Agg processing has not run yet */ assert( p->op!=TK_COLUMN || (ExprUseYTab(p) && p->y.pTab!=0) ); /* Covering idx not yet coded */ - if( pEList->a[i].zEName && pEList->a[i].fg.eEName==ENAME_NAME ){ + if( pEList->a[i].zEName && pEList->a[i].eEName==ENAME_NAME ){ /* An AS clause always takes first priority */ char *zName = pEList->a[i].zEName; sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT); }else if( srcName && p->op==TK_COLUMN ){ char *zCol; @@ -141014,38 +136367,35 @@ } assert( nCol==(i16)nCol ); *pnCol = nCol; *paCol = aCol; - for(i=0, pCol=aCol; inErr; i++, pCol++){ - struct ExprList_item *pX = &pEList->a[i]; - struct ExprList_item *pCollide; + for(i=0, pCol=aCol; imallocFailed; i++, pCol++){ /* Get an appropriate name for the column */ - if( (zName = pX->zEName)!=0 && pX->fg.eEName==ENAME_NAME ){ + if( (zName = pEList->a[i].zEName)!=0 && pEList->a[i].eEName==ENAME_NAME ){ /* If the column contains an "AS " phrase, use as the name */ }else{ - Expr *pColExpr = sqlite3ExprSkipCollateAndLikely(pX->pExpr); + Expr *pColExpr = sqlite3ExprSkipCollateAndLikely(pEList->a[i].pExpr); while( ALWAYS(pColExpr!=0) && pColExpr->op==TK_DOT ){ pColExpr = pColExpr->pRight; assert( pColExpr!=0 ); } if( pColExpr->op==TK_COLUMN && ALWAYS( ExprUseYTab(pColExpr) ) - && ALWAYS( pColExpr->y.pTab!=0 ) + && (pTab = pColExpr->y.pTab)!=0 ){ /* For columns use the column name name */ int iCol = pColExpr->iColumn; - pTab = pColExpr->y.pTab; if( iCol<0 ) iCol = pTab->iPKey; zName = iCol>=0 ? pTab->aCol[iCol].zCnName : "rowid"; }else if( pColExpr->op==TK_ID ){ assert( !ExprHasProperty(pColExpr, EP_IntValue) ); zName = pColExpr->u.zToken; }else{ /* Use the original text of the column expression as its name */ - assert( zName==pX->zEName ); /* pointer comparison intended */ + zName = pEList->a[i].zEName; } } if( zName && !sqlite3IsTrueOrFalse(zName) ){ zName = sqlite3DbStrDup(db, zName); }else{ @@ -141054,136 +136404,92 @@ /* Make sure the column name is unique. If the name is not unique, ** append an integer to the name so that it becomes unique. */ cnt = 0; - while( zName && (pCollide = sqlite3HashFind(&ht, zName))!=0 ){ - if( pCollide->fg.bUsingTerm ){ - pCol->colFlags |= COLFLAG_NOEXPAND; - } + while( zName && sqlite3HashFind(&ht, zName)!=0 ){ nName = sqlite3Strlen30(zName); if( nName>0 ){ for(j=nName-1; j>0 && sqlite3Isdigit(zName[j]); j--){} if( zName[j]==':' ) nName = j; } zName = sqlite3MPrintf(db, "%.*z:%u", nName, zName, ++cnt); - sqlite3ProgressCheck(pParse); - if( cnt>3 ){ - sqlite3_randomness(sizeof(cnt), &cnt); - } + if( cnt>3 ) sqlite3_randomness(sizeof(cnt), &cnt); } pCol->zCnName = zName; pCol->hName = sqlite3StrIHash(zName); - if( pX->fg.bNoExpand ){ - pCol->colFlags |= COLFLAG_NOEXPAND; - } sqlite3ColumnPropertiesFromName(0, pCol); - if( zName && sqlite3HashInsert(&ht, zName, pX)==pX ){ + if( zName && sqlite3HashInsert(&ht, zName, pCol)==pCol ){ sqlite3OomFault(db); } } sqlite3HashClear(&ht); - if( pParse->nErr ){ + if( db->mallocFailed ){ for(j=0; jrc; + return SQLITE_NOMEM_BKPT; } return SQLITE_OK; } /* -** pTab is a transient Table object that represents a subquery of some -** kind (maybe a parenthesized subquery in the FROM clause of a larger -** query, or a VIEW, or a CTE). This routine computes type information -** for that Table object based on the Select object that implements the -** subquery. For the purposes of this routine, "type infomation" means: +** Add type and collation information to a column list based on +** a SELECT statement. ** -** * The datatype name, as it might appear in a CREATE TABLE statement -** * Which collating sequence to use for the column -** * The affinity of the column +** 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. */ -SQLITE_PRIVATE void sqlite3SubqueryColumnTypes( - Parse *pParse, /* Parsing contexts */ - Table *pTab, /* Add column type information to this table */ - Select *pSelect, /* SELECT used to determine types and collations */ - char aff /* Default affinity. */ +SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation( + Parse *pParse, /* Parsing contexts */ + Table *pTab, /* Add column type information to this table */ + Select *pSelect, /* SELECT used to determine types and collations */ + char aff /* Default affinity for columns */ ){ sqlite3 *db = pParse->db; + NameContext sNC; Column *pCol; CollSeq *pColl; - int i,j; + int i; Expr *p; struct ExprList_item *a; - NameContext sNC; assert( pSelect!=0 ); assert( (pSelect->selFlags & SF_Resolved)!=0 ); - assert( pTab->nCol==pSelect->pEList->nExpr || pParse->nErr>0 ); - assert( aff==SQLITE_AFF_NONE || aff==SQLITE_AFF_BLOB ); - if( db->mallocFailed || IN_RENAME_OBJECT ) return; - while( pSelect->pPrior ) pSelect = pSelect->pPrior; - a = pSelect->pEList->a; + assert( pTab->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=pTab->aCol; inCol; i++, pCol++){ const char *zType; - i64 n; + i64 n, m; pTab->tabFlags |= (pCol->colFlags & COLFLAG_NOINSERT); p = a[i].pExpr; + zType = columnType(&sNC, p, 0, 0, 0); /* pCol->szEst = ... // Column size est for SELECT tables never used */ pCol->affinity = sqlite3ExprAffinity(p); - if( pCol->affinity<=SQLITE_AFF_NONE ){ - pCol->affinity = aff; - } - if( pCol->affinity>=SQLITE_AFF_TEXT && pSelect->pNext ){ - int m = 0; - Select *pS2; - for(m=0, pS2=pSelect->pNext; pS2; pS2=pS2->pNext){ - m |= sqlite3ExprDataType(pS2->pEList->a[i].pExpr); - } - if( pCol->affinity==SQLITE_AFF_TEXT && (m&0x01)!=0 ){ - pCol->affinity = SQLITE_AFF_BLOB; - }else - if( pCol->affinity>=SQLITE_AFF_NUMERIC && (m&0x02)!=0 ){ - pCol->affinity = SQLITE_AFF_BLOB; - } - if( pCol->affinity>=SQLITE_AFF_NUMERIC && p->op==TK_CAST ){ - pCol->affinity = SQLITE_AFF_FLEXNUM; - } - } - zType = columnType(&sNC, p, 0, 0, 0); - if( zType==0 || pCol->affinity!=sqlite3AffinityType(zType, 0) ){ - if( pCol->affinity==SQLITE_AFF_NUMERIC - || pCol->affinity==SQLITE_AFF_FLEXNUM - ){ - zType = "NUM"; - }else{ - zType = 0; - for(j=1; jaffinity ){ - zType = sqlite3StdType[j]; - break; - } - } - } - } if( zType ){ - i64 m = sqlite3Strlen30(zType); + m = sqlite3Strlen30(zType); n = sqlite3Strlen30(pCol->zCnName); pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+m+2); - pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL); if( pCol->zCnName ){ memcpy(&pCol->zCnName[n+1], zType, m+1); pCol->colFlags |= COLFLAG_HASTYPE; }else{ testcase( pCol->colFlags & COLFLAG_HASTYPE ); + pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL); } } + if( pCol->affinity<=SQLITE_AFF_NONE ) pCol->affinity = aff; pColl = sqlite3ExprCollSeq(pParse, p); if( pColl ){ assert( pTab->pIndex==0 ); sqlite3ColumnSetColl(db, pCol, pColl->zName); } @@ -141213,11 +136519,11 @@ } pTab->nTabRef = 1; pTab->zName = 0; pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); - sqlite3SubqueryColumnTypes(pParse, pTab, pSelect, aff); + sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSelect, aff); pTab->iPKey = -1; if( db->mallocFailed ){ sqlite3DeleteTable(db, pTab); return 0; } @@ -141367,11 +136673,11 @@ pOrderBy->a[i].pExpr = sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName); } assert( sqlite3KeyInfoIsWriteable(pRet) ); pRet->aColl[i] = pColl; - pRet->aSortFlags[i] = pOrderBy->a[i].fg.sortFlags; + pRet->aSortFlags[i] = pOrderBy->a[i].sortFlags; } } return pRet; } @@ -141585,11 +136891,11 @@ ** (3) There is no ORDER BY clause ** ** The "LIMIT of exactly 1" case of condition (1) comes about when a VALUES ** clause occurs within scalar expression (ex: "SELECT (VALUES(1),(2),(3))"). ** The sqlite3CodeSubselect will have added the LIMIT 1 clause in tht case. -** Since the limit is exactly 1, we only need to evaluate the left-most VALUES. +** Since the limit is exactly 1, we only need to evalutes the left-most VALUES. */ static int multiSelectValues( Parse *pParse, /* Parsing context */ Select *p, /* The right-most of SELECTs to be coded */ SelectDest *pDest /* What to do with query results */ @@ -141738,11 +137044,11 @@ int nLimit = 0; /* Initialize to suppress harmless compiler warning */ assert( !pPrior->pLimit ); pPrior->iLimit = p->iLimit; pPrior->iOffset = p->iOffset; pPrior->pLimit = p->pLimit; - TREETRACE(0x200, pParse, p, ("multiSelect UNION ALL left...\n")); + SELECTTRACE(1, pParse, p, ("multiSelect UNION ALL left...\n")); rc = sqlite3Select(pParse, pPrior, &dest); pPrior->pLimit = 0; if( rc ){ goto multi_select_end; } @@ -141756,11 +137062,11 @@ sqlite3VdbeAddOp3(v, OP_OffsetLimit, p->iLimit, p->iOffset+1, p->iOffset); } } ExplainQueryPlan((pParse, 1, "UNION ALL")); - TREETRACE(0x200, pParse, p, ("multiSelect UNION ALL right...\n")); + SELECTTRACE(1, pParse, p, ("multiSelect UNION ALL right...\n")); rc = sqlite3Select(pParse, p, &dest); testcase( rc!=SQLITE_OK ); pDelete = p->pPrior; p->pPrior = pPrior; p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); @@ -141809,11 +137115,11 @@ /* Code the SELECT statements to our left */ assert( !pPrior->pOrderBy ); sqlite3SelectDestInit(&uniondest, priorOp, unionTab); - TREETRACE(0x200, pParse, p, ("multiSelect EXCEPT/UNION left...\n")); + SELECTTRACE(1, pParse, p, ("multiSelect EXCEPT/UNION left...\n")); rc = sqlite3Select(pParse, pPrior, &uniondest); if( rc ){ goto multi_select_end; } @@ -141829,11 +137135,11 @@ pLimit = p->pLimit; p->pLimit = 0; uniondest.eDest = op; ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", sqlite3SelectOpName(p->op))); - TREETRACE(0x200, pParse, p, ("multiSelect EXCEPT/UNION right...\n")); + SELECTTRACE(1, pParse, p, ("multiSelect EXCEPT/UNION right...\n")); rc = sqlite3Select(pParse, p, &uniondest); testcase( rc!=SQLITE_OK ); assert( p->pOrderBy==0 ); pDelete = p->pPrior; p->pPrior = pPrior; @@ -141890,11 +137196,11 @@ assert( p->pEList ); /* Code the SELECTs to our left into temporary table "tab1". */ sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1); - TREETRACE(0x400, pParse, p, ("multiSelect INTERSECT left...\n")); + SELECTTRACE(1, pParse, p, ("multiSelect INTERSECT left...\n")); rc = sqlite3Select(pParse, pPrior, &intersectdest); if( rc ){ goto multi_select_end; } @@ -141907,11 +137213,11 @@ pLimit = p->pLimit; p->pLimit = 0; intersectdest.iSDParm = tab2; ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", sqlite3SelectOpName(p->op))); - TREETRACE(0x400, pParse, p, ("multiSelect INTERSECT right...\n")); + SELECTTRACE(1, pParse, p, ("multiSelect INTERSECT right...\n")); rc = sqlite3Select(pParse, p, &intersectdest); testcase( rc!=SQLITE_OK ); pDelete = p->pPrior; p->pPrior = pPrior; if( p->nSelectRow>pPrior->nSelectRow ){ @@ -142554,15 +137860,14 @@ /* Jump to the this point in order to terminate the query. */ sqlite3VdbeResolveLabel(v, labelEnd); - /* Make arrangements to free the 2nd and subsequent arms of the compound - ** after the parse has finished */ + /* Reassembly the compound query so that it will be freed correctly + ** by the calling function */ if( pSplit->pPrior ){ - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3SelectDelete, pSplit->pPrior); + sqlite3SelectDelete(db, pSplit->pPrior); } pSplit->pPrior = pPrior; pPrior->pNext = pSplit; sqlite3ExprListDelete(db, pPrior->pOrderBy); pPrior->pOrderBy = 0; @@ -142579,46 +137884,17 @@ /* An instance of the SubstContext object describes an substitution edit ** to be performed on a parse tree. ** ** All references to columns in table iTable are to be replaced by corresponding ** expressions in pEList. -** -** ## About "isOuterJoin": -** -** The isOuterJoin column indicates that the replacement will occur into a -** position in the parent that NULL-able due to an OUTER JOIN. Either the -** target slot in the parent is the right operand of a LEFT JOIN, or one of -** the left operands of a RIGHT JOIN. In either case, we need to potentially -** bypass the substituted expression with OP_IfNullRow. -** -** Suppose the original expression is an integer constant. Even though the table -** has the nullRow flag set, because the expression is an integer constant, -** it will not be NULLed out. So instead, we insert an OP_IfNullRow opcode -** that checks to see if the nullRow flag is set on the table. If the nullRow -** flag is set, then the value in the register is set to NULL and the original -** expression is bypassed. If the nullRow flag is not set, then the original -** expression runs to populate the register. -** -** Example where this is needed: -** -** CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT); -** CREATE TABLE t2(x INT UNIQUE); -** -** SELECT a,b,m,x FROM t1 LEFT JOIN (SELECT 59 AS m,x FROM t2) ON b=x; -** -** When the subquery on the right side of the LEFT JOIN is flattened, we -** have to add OP_IfNullRow in front of the OP_Integer that implements the -** "m" value of the subquery so that a NULL will be loaded instead of 59 -** when processing a non-matched row of the left. */ typedef struct SubstContext { Parse *pParse; /* The parsing context */ int iTable; /* Replace references to this table */ int iNewTable; /* New table number */ - int isOuterJoin; /* Add TK_IF_NULL_ROW opcodes on each replacement */ + int isLeftJoin; /* Add TK_IF_NULL_ROW opcodes on each replacement */ ExprList *pEList; /* Replacement expressions */ - ExprList *pCList; /* Collation sequences for replacement expr */ } SubstContext; /* Forward Declarations */ static void substExprList(SubstContext*, ExprList*); static void substSelect(SubstContext*, Select*, int); @@ -142639,15 +137915,14 @@ static Expr *substExpr( SubstContext *pSubst, /* Description of the substitution */ Expr *pExpr /* Expr in which substitution occurs */ ){ if( pExpr==0 ) return 0; - if( ExprHasProperty(pExpr, EP_OuterON|EP_InnerON) - && pExpr->w.iJoin==pSubst->iTable + if( ExprHasProperty(pExpr, EP_FromJoin) + && pExpr->w.iRightJoinTable==pSubst->iTable ){ - testcase( ExprHasProperty(pExpr, EP_InnerON) ); - pExpr->w.iJoin = pSubst->iNewTable; + pExpr->w.iRightJoinTable = pSubst->iNewTable; } if( pExpr->op==TK_COLUMN && pExpr->iTable==pSubst->iTable && !ExprHasProperty(pExpr, EP_FixedCol) ){ @@ -142656,63 +137931,48 @@ pExpr->op = TK_NULL; }else #endif { Expr *pNew; - int iColumn = pExpr->iColumn; - Expr *pCopy = pSubst->pEList->a[iColumn].pExpr; + Expr *pCopy = pSubst->pEList->a[pExpr->iColumn].pExpr; Expr ifNullRow; - assert( pSubst->pEList!=0 && iColumnpEList->nExpr ); + assert( pSubst->pEList!=0 && pExpr->iColumnpEList->nExpr ); assert( pExpr->pRight==0 ); if( sqlite3ExprIsVector(pCopy) ){ sqlite3VectorErrorMsg(pSubst->pParse, pCopy); }else{ sqlite3 *db = pSubst->pParse->db; - if( pSubst->isOuterJoin - && (pCopy->op!=TK_COLUMN || pCopy->iTable!=pSubst->iNewTable) - ){ + if( pSubst->isLeftJoin && pCopy->op!=TK_COLUMN ){ memset(&ifNullRow, 0, sizeof(ifNullRow)); ifNullRow.op = TK_IF_NULL_ROW; ifNullRow.pLeft = pCopy; ifNullRow.iTable = pSubst->iNewTable; - ifNullRow.iColumn = -99; ifNullRow.flags = EP_IfNullRow; pCopy = &ifNullRow; } testcase( ExprHasProperty(pCopy, EP_Subquery) ); pNew = sqlite3ExprDup(db, pCopy, 0); if( db->mallocFailed ){ sqlite3ExprDelete(db, pNew); return pExpr; } - if( pSubst->isOuterJoin ){ + if( pSubst->isLeftJoin ){ ExprSetProperty(pNew, EP_CanBeNull); } - if( ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) ){ - sqlite3SetJoinExpr(pNew, pExpr->w.iJoin, - pExpr->flags & (EP_OuterON|EP_InnerON)); + if( ExprHasProperty(pExpr,EP_FromJoin) ){ + sqlite3SetJoinExpr(pNew, pExpr->w.iRightJoinTable); } sqlite3ExprDelete(db, pExpr); pExpr = pNew; - if( pExpr->op==TK_TRUEFALSE ){ - pExpr->u.iValue = sqlite3ExprTruthValue(pExpr); - pExpr->op = TK_INTEGER; - ExprSetProperty(pExpr, EP_IntValue); - } /* Ensure that the expression now has an implicit collation sequence, ** just as it did when it was a column of a view or sub-query. */ - { - CollSeq *pNat = sqlite3ExprCollSeq(pSubst->pParse, pExpr); - CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, - pSubst->pCList->a[iColumn].pExpr - ); - if( pNat!=pColl || (pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE) ){ - pExpr = sqlite3ExprAddCollateString(pSubst->pParse, pExpr, - (pColl ? pColl->zName : "BINARY") - ); - } + if( pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE ){ + CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, pExpr); + pExpr = sqlite3ExprAddCollateString(pSubst->pParse, pExpr, + (pColl ? pColl->zName : "BINARY") + ); } ExprClearProperty(pExpr, EP_Collate); } } }else{ @@ -142861,12 +138121,12 @@ static int renumberCursorsCb(Walker *pWalker, Expr *pExpr){ int op = pExpr->op; if( op==TK_COLUMN || op==TK_IF_NULL_ROW ){ renumberCursorDoMapping(pWalker, &pExpr->iTable); } - if( ExprHasProperty(pExpr, EP_OuterON) ){ - renumberCursorDoMapping(pWalker, &pExpr->w.iJoin); + if( ExprHasProperty(pExpr, EP_FromJoin) ){ + renumberCursorDoMapping(pWalker, &pExpr->w.iRightJoinTable); } return WRC_Continue; } /* @@ -142901,50 +138161,10 @@ w.xSelectCallback = sqlite3SelectWalkNoop; sqlite3WalkSelect(&w, p); } #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ -/* -** If pSel is not part of a compound SELECT, return a pointer to its -** expression list. Otherwise, return a pointer to the expression list -** of the leftmost SELECT in the compound. -*/ -static ExprList *findLeftmostExprlist(Select *pSel){ - while( pSel->pPrior ){ - pSel = pSel->pPrior; - } - return pSel->pEList; -} - -/* -** Return true if any of the result-set columns in the compound query -** have incompatible affinities on one or more arms of the compound. -*/ -static int compoundHasDifferentAffinities(Select *p){ - int ii; - ExprList *pList; - assert( p!=0 ); - assert( p->pEList!=0 ); - assert( p->pPrior!=0 ); - pList = p->pEList; - for(ii=0; iinExpr; ii++){ - char aff; - Select *pSub1; - assert( pList->a[ii].pExpr!=0 ); - aff = sqlite3ExprAffinity(pList->a[ii].pExpr); - for(pSub1=p->pPrior; pSub1; pSub1=pSub1->pPrior){ - assert( pSub1->pEList!=0 ); - assert( pSub1->pEList->nExpr>ii ); - assert( pSub1->pEList->a[ii].pExpr!=0 ); - if( sqlite3ExprAffinity(pSub1->pEList->a[ii].pExpr)!=aff ){ - return 1; - } - } - } - return 0; -} - #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. ** @@ -142985,14 +138205,12 @@ ** ** (3) If the subquery is the right operand of a LEFT JOIN then ** (3a) the subquery may not be a join and ** (3b) the FROM clause of the subquery may not contain a virtual ** table and -** (**) Was: "The outer query may not have a GROUP BY." This case -** is now managed correctly +** (3c) the outer query may not be an aggregate. ** (3d) the outer query may not be DISTINCT. -** See also (26) for restrictions on RIGHT JOIN. ** ** (4) The subquery can not be DISTINCT. ** ** (**) At one point restrictions (4) and (5) defined a subset of DISTINCT ** sub-queries that were excluded from this optimization. Restriction @@ -143040,15 +138258,10 @@ ** (17d) the outer query may not be ** (17d1) aggregate, or ** (17d2) DISTINCT ** (17e) the subquery may not contain window functions, and ** (17f) the subquery must not be the RHS of a LEFT JOIN. -** (17g) either the subquery is the first element of the outer -** query or there are no RIGHT or FULL JOINs in any arm -** of the subquery. (This is a duplicate of condition (27b).) -** (17h) The corresponding result set expressions in all arms of the -** compound must have the same affinity. ** ** 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 @@ -143092,21 +138305,10 @@ ** ** (25) If either the subquery or the parent query contains a window ** function in the select list or ORDER BY clause, flattening ** is not attempted. ** -** (26) The subquery may not be the right operand of a RIGHT JOIN. -** See also (3) for restrictions on LEFT JOIN. -** -** (27) The subquery may not contain a FULL or RIGHT JOIN unless it -** is the first element of the parent query. Two subcases: -** (27a) the subquery is not a compound query. -** (27b) the subquery is a compound query and the RIGHT JOIN occurs -** in any arm of the compound query. (See also (17g).) -** -** (28) The subquery is not a MATERIALIZED CTE. -** ** ** 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. ** @@ -143128,11 +138330,11 @@ Select *pSub1; /* Pointer to the rightmost select in sub-query */ SrcList *pSrc; /* The FROM clause of the outer query */ SrcList *pSubSrc; /* The FROM clause of the subquery */ int iParent; /* VDBE cursor number of the pSub result set temp table */ int iNewParent = -1;/* Replacement table for iParent */ - int isOuterJoin = 0; /* True if pSub is the right side of a LEFT JOIN */ + int isLeftJoin = 0; /* True if pSub is the right side of a LEFT JOIN */ int i; /* Loop counter */ Expr *pWhere; /* The WHERE clause */ SrcItem *pSubitem; /* The subquery */ sqlite3 *db = pParse->db; Walker w; /* Walker to persist agginfo data */ @@ -143194,42 +138396,47 @@ ** ** (t1 LEFT OUTER JOIN t2) JOIN t3 ** ** which is not at all the same thing. ** + ** If the subquery is the right operand of a LEFT JOIN, then the outer + ** query cannot be an aggregate. (3c) This is an artifact of the way + ** aggregates are processed - there is no mechanism to determine if + ** the LEFT JOIN table should be all-NULL. + ** ** See also tickets #306, #350, and #3300. */ - if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){ - if( pSubSrc->nSrc>1 /* (3a) */ - || IsVirtual(pSubSrc->a[0].pTab) /* (3b) */ - || (p->selFlags & SF_Distinct)!=0 /* (3d) */ - || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */ + if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){ + isLeftJoin = 1; + if( pSubSrc->nSrc>1 /* (3a) */ + || isAgg /* (3b) */ + || IsVirtual(pSubSrc->a[0].pTab) /* (3c) */ + || (p->selFlags & SF_Distinct)!=0 /* (3d) */ ){ return 0; } - isOuterJoin = 1; - } - - assert( pSubSrc->nSrc>0 ); /* True by restriction (7) */ - if( iFrom>0 && (pSubSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ - return 0; /* Restriction (27a) */ - } - if( pSubitem->fg.isCte && pSubitem->u2.pCteUse->eM10d==M10d_Yes ){ - return 0; /* (28) */ - } + } +#ifdef SQLITE_EXTRA_IFNULLROW + else if( iFrom>0 && !isAgg ){ + /* Setting isLeftJoin to -1 causes OP_IfNullRow opcodes to be generated for + ** every reference to any result column from subquery in a join, even + ** though they are not necessary. This will stress-test the OP_IfNullRow + ** opcode. */ + isLeftJoin = -1; + } +#endif /* 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 ){ - int ii; if( pSub->pOrderBy ){ return 0; /* Restriction (20) */ } - if( isAgg || (p->selFlags & SF_Distinct)!=0 || isOuterJoin>0 ){ + if( isAgg || (p->selFlags & SF_Distinct)!=0 || isLeftJoin>0 ){ return 0; /* (17d1), (17d2), or (17f) */ } 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 ); @@ -143243,42 +138450,33 @@ || pSub1->pWin /* (17e) */ #endif ){ return 0; } - if( iFrom>0 && (pSub1->pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ - /* Without this restriction, the JT_LTORJ flag would end up being - ** omitted on left-hand tables of the right join that is being - ** flattened. */ - return 0; /* Restrictions (17g), (27b) */ - } testcase( pSub1->pSrc->nSrc>1 ); } /* Restriction (18). */ if( p->pOrderBy ){ + int ii; for(ii=0; iipOrderBy->nExpr; ii++){ if( p->pOrderBy->a[ii].u.x.iOrderByCol==0 ) return 0; } } /* Restriction (23) */ if( (p->selFlags & SF_Recursive) ) return 0; - /* Restriction (17h) */ - if( compoundHasDifferentAffinities(pSub) ) return 0; - if( pSrc->nSrc>1 ){ if( pParse->nSelect>500 ) return 0; - if( OptimizationDisabled(db, SQLITE_FlttnUnionAll) ) return 0; aCsrMap = sqlite3DbMallocZero(db, ((i64)pParse->nTab+1)*sizeof(int)); if( aCsrMap ) aCsrMap[0] = pParse->nTab; } } /***** If we reach this point, flattening is permitted. *****/ - TREETRACE(0x4,pParse,p,("flatten %u.%p from term %d\n", + SELECTTRACE(1,pParse,p,("flatten %u.%p from term %d\n", pSub->selId, pSub, iFrom)); /* Authorize the subquery */ pParse->zAuthContext = pSubitem->zName; TESTONLY(i =) sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0); @@ -143292,11 +138490,11 @@ sqlite3DbFree(db, pSubitem->zAlias); pSubitem->zDatabase = 0; pSubitem->zName = 0; pSubitem->zAlias = 0; pSubitem->pSelect = 0; - assert( pSubitem->fg.isUsing!=0 || pSubitem->u3.pOn==0 ); + assert( pSubitem->pOn==0 ); /* 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: ** @@ -143353,11 +138551,11 @@ } pNew->pPrior = pPrior; if( pPrior ) pPrior->pNext = pNew; pNew->pNext = p; p->pPrior = pNew; - TREETRACE(0x4,pParse,p,("compound-subquery flattener" + SELECTTRACE(2,pParse,p,("compound-subquery flattener" " creates %u as peer\n",pNew->selId)); } assert( pSubitem->pSelect==0 ); } sqlite3DbFree(db, aCsrMap); @@ -143402,11 +138600,10 @@ */ pSub = pSub1; for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){ int nSubSrc; u8 jointype = 0; - u8 ltorj = pSrc->a[iFrom].fg.jointype & JT_LTORJ; assert( pSub!=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 */ @@ -143437,20 +138634,17 @@ /* Transfer the FROM clause terms from the subquery into the ** outer query. */ for(i=0; ia[i+iFrom]; - if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing); - assert( pItem->fg.isTabFunc==0 ); - *pItem = pSubSrc->a[i]; - pItem->fg.jointype |= ltorj; + sqlite3IdListDelete(db, pSrc->a[i+iFrom].pUsing); + assert( pSrc->a[i+iFrom].fg.isTabFunc==0 ); + pSrc->a[i+iFrom] = pSubSrc->a[i]; iNewParent = pSubSrc->a[i].iCursor; memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i])); } - pSrc->a[iFrom].fg.jointype &= JT_LTORJ; - pSrc->a[iFrom].fg.jointype |= jointype | ltorj; + pSrc->a[iFrom].fg.jointype = jointype; /* Now begin substituting subquery result set expressions for ** references to the iParent in the outer query. ** ** Example: @@ -143481,12 +138675,12 @@ pParent->pOrderBy = pOrderBy; pSub->pOrderBy = 0; } pWhere = pSub->pWhere; pSub->pWhere = 0; - if( isOuterJoin>0 ){ - sqlite3SetJoinExpr(pWhere, iNewParent, EP_OuterON); + if( isLeftJoin>0 ){ + sqlite3SetJoinExpr(pWhere, iNewParent); } if( pWhere ){ if( pParent->pWhere ){ pParent->pWhere = sqlite3PExpr(pParse, TK_AND, pWhere, pParent->pWhere); }else{ @@ -143496,13 +138690,12 @@ if( db->mallocFailed==0 ){ SubstContext x; x.pParse = pParse; x.iTable = iParent; x.iNewTable = iNewParent; - x.isOuterJoin = isOuterJoin; + x.isLeftJoin = isLeftJoin; x.pEList = pSub->pEList; - x.pCList = findLeftmostExprlist(pSub); substSelect(&x, pParent, 0); } /* The flattened query is a compound if either the inner or the ** outer query is a compound. */ @@ -143518,11 +138711,11 @@ if( pSub->pLimit ){ pParent->pLimit = pSub->pLimit; pSub->pLimit = 0; } - /* Recompute the SrcItem.colUsed masks for the flattened + /* Recompute the SrcList_item.colUsed masks for the flattened ** tables. */ for(i=0; ia[i+iFrom]); } } @@ -143532,13 +138725,13 @@ */ sqlite3AggInfoPersistWalkerInit(&w, pParse); sqlite3WalkSelect(&w,pSub1); sqlite3SelectDelete(db, pSub1); -#if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x4 ){ - TREETRACE(0x4,pParse,p,("After flattening:\n")); +#if SELECTTRACE_ENABLED + if( sqlite3SelectTrace & 0x100 ){ + SELECTTRACE(0x100,pParse,p,("After flattening:\n")); sqlite3TreeViewSelect(0, p, 0); } #endif return 1; @@ -143554,12 +138747,10 @@ Parse *pParse; /* Parsing context */ u8 *pOomFault; /* Pointer to pParse->db->mallocFailed */ int nConst; /* Number for COLUMN=CONSTANT terms */ int nChng; /* Number of times a constant is propagated */ int bHasAffBlob; /* At least one column in apExpr[] as affinity BLOB */ - u32 mExcludeOn; /* Which ON expressions to exclude from considertion. - ** Either EP_OuterON or EP_InnerON|EP_OuterON */ Expr **apExpr; /* [i*2] is COLUMN and [i*2+1] is VALUE */ }; /* ** Add a new entry to the pConst object. Except, do not add duplicate @@ -143618,15 +138809,11 @@ ** found, add it to the pConst structure. */ static void findConstInWhere(WhereConst *pConst, Expr *pExpr){ Expr *pRight, *pLeft; if( NEVER(pExpr==0) ) return; - if( ExprHasProperty(pExpr, pConst->mExcludeOn) ){ - testcase( ExprHasProperty(pExpr, EP_OuterON) ); - testcase( ExprHasProperty(pExpr, EP_InnerON) ); - return; - } + if( ExprHasProperty(pExpr, EP_FromJoin) ) return; if( pExpr->op==TK_AND ){ findConstInWhere(pConst, pExpr->pRight); findConstInWhere(pConst, pExpr->pLeft); return; } @@ -143658,14 +138845,13 @@ int bIgnoreAffBlob ){ int i; if( pConst->pOomFault[0] ) return WRC_Prune; if( pExpr->op!=TK_COLUMN ) return WRC_Continue; - if( ExprHasProperty(pExpr, EP_FixedCol|pConst->mExcludeOn) ){ + if( ExprHasProperty(pExpr, EP_FixedCol|EP_FromJoin) ){ testcase( ExprHasProperty(pExpr, EP_FixedCol) ); - testcase( ExprHasProperty(pExpr, EP_OuterON) ); - testcase( ExprHasProperty(pExpr, EP_InnerON) ); + testcase( ExprHasProperty(pExpr, EP_FromJoin) ); return WRC_Continue; } for(i=0; inConst; i++){ Expr *pColumn = pConst->apExpr[i*2]; if( pColumn==pExpr ) continue; @@ -143785,21 +138971,10 @@ do{ x.nConst = 0; x.nChng = 0; x.apExpr = 0; x.bHasAffBlob = 0; - if( ALWAYS(p->pSrc!=0) - && p->pSrc->nSrc>0 - && (p->pSrc->a[0].fg.jointype & JT_LTORJ)!=0 - ){ - /* Do not propagate constants on any ON clause if there is a - ** RIGHT JOIN anywhere in the query */ - x.mExcludeOn = EP_InnerON | EP_OuterON; - }else{ - /* Do not propagate constants through the ON clause of a LEFT JOIN */ - x.mExcludeOn = EP_OuterON; - } findConstInWhere(&x, p->pWhere); if( x.nConst ){ memset(&w, 0, sizeof(w)); w.pParse = pParse; w.xExprCallback = propagateConstantExprRewrite; @@ -143907,15 +139082,10 @@ ** window over which any window-function is calculated. ** ** (7) The inner query is a Common Table Expression (CTE) that should ** be materialized. (This restriction is implemented in the calling ** routine.) -** -** (8) If the subquery is a compound that uses UNION, INTERSECT, -** or EXCEPT, then all of the result set columns for all arms of -** the compound must use the BINARY collating sequence. -** ** ** Return 0 if no changes are made and non-zero if one or more WHERE clause ** terms are duplicated into the subquery. */ static int pushDownWhereTerms( @@ -143926,47 +139096,21 @@ ){ Expr *pNew; int nChng = 0; if( pWhere==0 ) return 0; if( pSubq->selFlags & (SF_Recursive|SF_MultiPart) ) return 0; - if( pSrc->fg.jointype & (JT_LTORJ|JT_RIGHT) ) return 0; +#ifndef SQLITE_OMIT_WINDOWFUNC if( pSubq->pPrior ){ Select *pSel; - int notUnionAll = 0; for(pSel=pSubq; pSel; pSel=pSel->pPrior){ - u8 op = pSel->op; - assert( op==TK_ALL || op==TK_SELECT - || op==TK_UNION || op==TK_INTERSECT || op==TK_EXCEPT ); - if( op!=TK_ALL && op!=TK_SELECT ){ - notUnionAll = 1; - } -#ifndef SQLITE_OMIT_WINDOWFUNC if( pSel->pWin ) return 0; /* restriction (6b) */ -#endif - } - if( notUnionAll ){ - /* If any of the compound arms are connected using UNION, INTERSECT, - ** or EXCEPT, then we must ensure that none of the columns use a - ** non-BINARY collating sequence. */ - for(pSel=pSubq; pSel; pSel=pSel->pPrior){ - int ii; - const ExprList *pList = pSel->pEList; - assert( pList!=0 ); - for(ii=0; iinExpr; ii++){ - CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[ii].pExpr); - if( !sqlite3IsBinary(pColl) ){ - return 0; /* Restriction (8) */ - } - } - } } }else{ -#ifndef SQLITE_OMIT_WINDOWFUNC if( pSubq->pWin && pSubq->pWin->pPartition==0 ) return 0; + } #endif - } #ifdef SQLITE_DEBUG /* Only the first term of a compound can have a WITH clause. But make ** sure no other terms are marked SF_Recursive in case something changes ** in the future. @@ -143987,17 +139131,17 @@ pWhere = pWhere->pLeft; } #if 0 /* Legacy code. Checks now done by sqlite3ExprIsTableConstraint() */ if( isLeftJoin - && (ExprHasProperty(pWhere,EP_OuterON)==0 - || pWhere->w.iJoin!=iCursor) + && (ExprHasProperty(pWhere,EP_FromJoin)==0 + || pWhere->w.iRightJoinTable!=iCursor) ){ return 0; /* restriction (4) */ } - if( ExprHasProperty(pWhere,EP_OuterON) - && pWhere->w.iJoin!=iCursor + if( ExprHasProperty(pWhere,EP_FromJoin) + && pWhere->w.iRightJoinTable!=iCursor ){ return 0; /* restriction (5) */ } #endif @@ -144005,17 +139149,16 @@ nChng++; pSubq->selFlags |= SF_PushDown; while( pSubq ){ SubstContext x; pNew = sqlite3ExprDup(pParse->db, pWhere, 0); - unsetJoinExpr(pNew, -1, 1); + unsetJoinExpr(pNew, -1); x.pParse = pParse; x.iTable = pSrc->iCursor; x.iNewTable = pSrc->iCursor; - x.isOuterJoin = 0; + x.isLeftJoin = 0; x.pEList = pSubq->pEList; - x.pCList = findLeftmostExprlist(pSubq); pNew = substExpr(&x, pNew); #ifndef SQLITE_OMIT_WINDOWFUNC if( pSubq->pWin && 0==pushDownWindowCheck(pParse, pSubq, pNew) ){ /* Restriction 6c has prevented push-down in this case */ sqlite3ExprDelete(pParse->db, pNew); @@ -144032,82 +139175,10 @@ } } return nChng; } #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ - -/* -** Check to see if a subquery contains result-set columns that are -** never used. If it does, change the value of those result-set columns -** to NULL so that they do not cause unnecessary work to compute. -** -** Return the number of column that were changed to NULL. -*/ -static int disableUnusedSubqueryResultColumns(SrcItem *pItem){ - int nCol; - Select *pSub; /* The subquery to be simplified */ - Select *pX; /* For looping over compound elements of pSub */ - Table *pTab; /* The table that describes the subquery */ - int j; /* Column number */ - int nChng = 0; /* Number of columns converted to NULL */ - Bitmask colUsed; /* Columns that may not be NULLed out */ - - assert( pItem!=0 ); - if( pItem->fg.isCorrelated || pItem->fg.isCte ){ - return 0; - } - assert( pItem->pTab!=0 ); - pTab = pItem->pTab; - assert( pItem->pSelect!=0 ); - pSub = pItem->pSelect; - assert( pSub->pEList->nExpr==pTab->nCol ); - if( (pSub->selFlags & (SF_Distinct|SF_Aggregate))!=0 ){ - testcase( pSub->selFlags & SF_Distinct ); - testcase( pSub->selFlags & SF_Aggregate ); - return 0; - } - for(pX=pSub; pX; pX=pX->pPrior){ - if( pX->pPrior && pX->op!=TK_ALL ){ - /* This optimization does not work for compound subqueries that - ** use UNION, INTERSECT, or EXCEPT. Only UNION ALL is allowed. */ - return 0; - } -#ifndef SQLITE_OMIT_WINDOWFUNC - if( pX->pWin ){ - /* This optimization does not work for subqueries that use window - ** functions. */ - return 0; - } -#endif - } - colUsed = pItem->colUsed; - if( pSub->pOrderBy ){ - ExprList *pList = pSub->pOrderBy; - for(j=0; jnExpr; j++){ - u16 iCol = pList->a[j].u.x.iOrderByCol; - if( iCol>0 ){ - iCol--; - colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol); - } - } - } - nCol = pTab->nCol; - for(j=0; jpPrior) { - Expr *pY = pX->pEList->a[j].pExpr; - if( pY->op==TK_NULL ) continue; - pY->op = TK_NULL; - ExprClearProperty(pY, EP_Skip|EP_Unlikely); - pX->selFlags |= SF_PushDown; - nChng++; - } - } - return nChng; -} - /* ** The pFunc is the only aggregate function in the query. Check to see ** if the query is a candidate for the min/max optimization. ** @@ -144155,11 +139226,11 @@ }else{ return eRet; } *ppMinMax = pOrderBy = sqlite3ExprListDup(db, pEList, 0); assert( pOrderBy!=0 || db->mallocFailed ); - if( pOrderBy ) pOrderBy->a[0].fg.sortFlags = sortFlags; + if( pOrderBy ) pOrderBy->a[0].sortFlags = sortFlags; return eRet; } /* ** The select statement passed as the first argument is an aggregate query. @@ -144187,11 +139258,10 @@ if( p->pWhere || p->pEList->nExpr!=1 || p->pSrc->nSrc!=1 || p->pSrc->a[0].pSelect || pAggInfo->nFunc!=1 - || p->pHaving ){ return 0; } pTab = p->pSrc->a[0].pTab; assert( pTab!=0 ); @@ -144292,11 +139362,11 @@ pParse = pWalker->pParse; db = pParse->db; pNew = sqlite3DbMallocZero(db, sizeof(*pNew) ); if( pNew==0 ) return WRC_Abort; memset(&dummy, 0, sizeof(dummy)); - pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0); + pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0,0); if( pNewSrc==0 ) return WRC_Abort; *pNew = *p; p->pSrc = pNewSrc; p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ASTERISK, 0)); p->op = TK_SELECT; @@ -144496,10 +139566,13 @@ return 2; } pFrom->fg.isCte = 1; pFrom->u2.pCteUse = pCteUse; pCteUse->nUse++; + if( pCteUse->nUse>=2 && pCteUse->eM10d==M10d_Any ){ + pCteUse->eM10d = M10d_Yes; + } /* Check if this is a recursive CTE. */ pRecTerm = pSel = pFrom->pSelect; bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION ); while( bMayRecursive && pRecTerm->op==pSel->op ){ @@ -144605,13 +139678,13 @@ } } #endif /* -** The SrcItem structure passed as the second argument represents a +** The SrcList_item structure passed as the second argument represents a ** sub-query in the FROM clause of a SELECT statement. This function -** allocates and populates the SrcItem.pTab object. If successful, +** allocates and populates the SrcList_item.pTab object. If successful, ** SQLITE_OK is returned. Otherwise, if an OOM error is encountered, ** SQLITE_NOMEM. */ SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){ Select *pSel = pFrom->pSelect; @@ -144622,11 +139695,11 @@ if( pTab==0 ) return SQLITE_NOMEM; pTab->nTabRef = 1; if( pFrom->zAlias ){ pTab->zName = sqlite3DbStrDup(pParse->db, pFrom->zAlias); }else{ - pTab->zName = sqlite3MPrintf(pParse->db, "%!S", pFrom); + pTab->zName = sqlite3MPrintf(pParse->db, "subquery_%u", pSel->selId); } while( pSel->pPrior ){ pSel = pSel->pPrior; } sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol); pTab->iPKey = -1; pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); @@ -144634,38 +139707,14 @@ /* The usual case - do not allow ROWID on a subquery */ pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid; #else pTab->tabFlags |= TF_Ephemeral; /* Legacy compatibility mode */ #endif + + return pParse->nErr ? SQLITE_ERROR : SQLITE_OK; } - - -/* -** Check the N SrcItem objects to the right of pBase. (N might be zero!) -** If any of those SrcItem objects have a USING clause containing zName -** then return true. -** -** If N is zero, or none of the N SrcItem objects to the right of pBase -** contains a USING clause, or if none of the USING clauses contain zName, -** then return false. -*/ -static int inAnyUsingClause( - const char *zName, /* Name we are looking for */ - SrcItem *pBase, /* The base SrcItem. Looking at pBase[1] and following */ - int N /* How many SrcItems to check */ -){ - while( N>0 ){ - N--; - pBase++; - if( pBase->fg.isUsing==0 ) continue; - if( NEVER(pBase->u3.pUsing==0) ) continue; - if( sqlite3IdListIndex(pBase->u3.pUsing, zName)>=0 ) return 1; - } - return 0; -} - /* ** This routine is a Walker callback for "expanding" a SELECT statement. ** "Expanding" means to do the following: ** @@ -144812,11 +139861,11 @@ } /* Process NATURAL keywords, and ON and USING clauses of joins. */ assert( db->mallocFailed==0 || pParse->nErr!=0 ); - if( pParse->nErr || sqlite3ProcessJoin(pParse, p) ){ + if( pParse->nErr || 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 @@ -144860,11 +139909,11 @@ /* This particular expression does not need to be expanded. */ pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr); if( pNew ){ pNew->a[pNew->nExpr-1].zEName = a[k].zEName; - pNew->a[pNew->nExpr-1].fg.eEName = a[k].fg.eEName; + pNew->a[pNew->nExpr-1].eEName = a[k].eEName; a[k].zEName = 0; } a[k].pExpr = 0; }else{ /* This expression is a "*" or a "TABLE.*" and needs to be @@ -144875,64 +139924,36 @@ assert( pE->pLeft!=0 ); assert( !ExprHasProperty(pE->pLeft, EP_IntValue) ); zTName = pE->pLeft->u.zToken; } for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ - Table *pTab = pFrom->pTab; /* Table for this data source */ - ExprList *pNestedFrom; /* Result-set of a nested FROM clause */ - char *zTabName; /* AS name for this data source */ - const char *zSchemaName = 0; /* Schema name for this data source */ - int iDb; /* Schema index for this data src */ - IdList *pUsing; /* USING clause for pFrom[1] */ - - if( (zTabName = pFrom->zAlias)==0 ){ + Table *pTab = pFrom->pTab; + Select *pSub = pFrom->pSelect; + char *zTabName = pFrom->zAlias; + const char *zSchemaName = 0; + int iDb; + if( zTabName==0 ){ zTabName = pTab->zName; } if( db->mallocFailed ) break; - assert( (int)pFrom->fg.isNestedFrom == IsNestedFrom(pFrom->pSelect) ); - if( pFrom->fg.isNestedFrom ){ - assert( pFrom->pSelect!=0 ); - pNestedFrom = pFrom->pSelect->pEList; - assert( pNestedFrom!=0 ); - assert( pNestedFrom->nExpr==pTab->nCol ); - }else{ + if( pSub==0 || (pSub->selFlags & SF_NestedFrom)==0 ){ + pSub = 0; if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){ continue; } - pNestedFrom = 0; iDb = sqlite3SchemaToIndex(db, pTab->pSchema); zSchemaName = iDb>=0 ? db->aDb[iDb].zDbSName : "*"; } - if( i+1nSrc - && pFrom[1].fg.isUsing - && (selFlags & SF_NestedFrom)!=0 - ){ - int ii; - pUsing = pFrom[1].u3.pUsing; - for(ii=0; iinId; ii++){ - const char *zUName = pUsing->a[ii].zName; - pRight = sqlite3Expr(db, TK_ID, zUName); - pNew = sqlite3ExprListAppend(pParse, pNew, pRight); - if( pNew ){ - struct ExprList_item *pX = &pNew->a[pNew->nExpr-1]; - assert( pX->zEName==0 ); - pX->zEName = sqlite3MPrintf(db,"..%s", zUName); - pX->fg.eEName = ENAME_TAB; - pX->fg.bUsingTerm = 1; - } - } - }else{ - pUsing = 0; - } for(j=0; jnCol; j++){ char *zName = pTab->aCol[j].zCnName; - struct ExprList_item *pX; /* Newly added ExprList term */ + char *zColname; /* The computed column name */ + char *zToFree; /* Malloced string that needs to be freed */ + Token sColname; /* Computed column name as a token */ assert( zName ); - if( zTName - && pNestedFrom - && sqlite3MatchEName(&pNestedFrom->a[j], 0, zTName, 0)==0 + if( zTName && pSub + && sqlite3MatchEName(&pSub->pEList->a[j], 0, zTName, 0)==0 ){ continue; } /* If a column is marked as 'hidden', omit it from the expanded @@ -144942,79 +139963,61 @@ if( (p->selFlags & SF_IncludeHidden)==0 && IsHiddenColumn(&pTab->aCol[j]) ){ continue; } - if( (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0 - && zTName==0 - && (selFlags & (SF_NestedFrom))==0 - ){ - continue; - } tableSeen = 1; - if( i>0 && zTName==0 && (selFlags & SF_NestedFrom)==0 ){ - if( pFrom->fg.isUsing - && sqlite3IdListIndex(pFrom->u3.pUsing, zName)>=0 + if( i>0 && zTName==0 ){ + if( (pFrom->fg.jointype & JT_NATURAL)!=0 + && tableAndColumnIndex(pTabList, i, zName, 0, 0, 1) ){ + /* In a NATURAL join, omit the join columns from the + ** table to the right of the join */ + continue; + } + if( sqlite3IdListIndex(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 = sqlite3Expr(db, TK_ID, zName); - if( (pTabList->nSrc>1 - && ( (pFrom->fg.jointype & JT_LTORJ)==0 - || (selFlags & SF_NestedFrom)!=0 - || !inAnyUsingClause(zName,pFrom,pTabList->nSrc-i-1) - ) - ) - || IN_RENAME_OBJECT - ){ + zColname = zName; + zToFree = 0; + if( longNames || pTabList->nSrc>1 ){ Expr *pLeft; pLeft = sqlite3Expr(db, TK_ID, zTabName); pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); - if( IN_RENAME_OBJECT && pE->pLeft ){ - sqlite3RenameTokenRemap(pParse, pLeft, pE->pLeft); - } if( zSchemaName ){ pLeft = sqlite3Expr(db, TK_ID, zSchemaName); pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pExpr); } + if( longNames ){ + zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName); + zToFree = zColname; + } }else{ pExpr = pRight; } pNew = sqlite3ExprListAppend(pParse, pNew, pExpr); - if( pNew==0 ){ - break; /* OOM */ - } - pX = &pNew->a[pNew->nExpr-1]; - assert( pX->zEName==0 ); - if( (selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){ - if( pNestedFrom ){ - pX->zEName = sqlite3DbStrDup(db, pNestedFrom->a[j].zEName); + sqlite3TokenInit(&sColname, zColname); + sqlite3ExprListSetName(pParse, pNew, &sColname, 0); + if( pNew && (p->selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){ + struct ExprList_item *pX = &pNew->a[pNew->nExpr-1]; + sqlite3DbFree(db, pX->zEName); + if( pSub ){ + pX->zEName = sqlite3DbStrDup(db, pSub->pEList->a[j].zEName); testcase( pX->zEName==0 ); }else{ pX->zEName = sqlite3MPrintf(db, "%s.%s.%s", - zSchemaName, zTabName, zName); + zSchemaName, zTabName, zColname); testcase( pX->zEName==0 ); } - pX->fg.eEName = ENAME_TAB; - if( (pFrom->fg.isUsing - && sqlite3IdListIndex(pFrom->u3.pUsing, zName)>=0) - || (pUsing && sqlite3IdListIndex(pUsing, zName)>=0) - || (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0 - ){ - pX->fg.bNoExpand = 1; - } - }else if( longNames ){ - pX->zEName = sqlite3MPrintf(db, "%s.%s", zTabName, zName); - pX->fg.eEName = ENAME_NAME; - }else{ - pX->zEName = sqlite3DbStrDup(db, zName); - pX->fg.eEName = ENAME_NAME; - } + pX->eEName = ENAME_TAB; + } + sqlite3DbFree(db, zToFree); } } if( !tableSeen ){ if( zTName ){ sqlite3ErrorMsg(pParse, "no such table: %s", zTName); @@ -145034,16 +140037,10 @@ } if( (elistFlags & (EP_HasFunc|EP_Subquery))!=0 ){ p->selFlags |= SF_ComplexResult; } } -#if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x8 ){ - TREETRACE(0x8,pParse,p,("After result-set wildcard expansion:\n")); - sqlite3TreeViewSelect(0, p, 0); - } -#endif return WRC_Continue; } #if SQLITE_DEBUG /* @@ -145087,18 +140084,18 @@ #ifndef SQLITE_OMIT_SUBQUERY /* ** This is a Walker.xSelectCallback callback for the sqlite3SelectTypeInfo() ** interface. ** -** For each FROM-clause subquery, add Column.zType, Column.zColl, and -** Column.affinity information to the Table structure that represents -** the result set of that subquery. +** 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 and affinity information -** was omitted at that point because identifiers had not yet been resolved. -** This routine is called after identifier resolution. +** 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 void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ Parse *pParse; int i; SrcList *pTabList; @@ -145114,11 +140111,13 @@ assert( pTab!=0 ); if( (pTab->tabFlags & TF_Ephemeral)!=0 ){ /* A sub-query in the FROM clause of a SELECT */ Select *pSel = pFrom->pSelect; if( pSel ){ - sqlite3SubqueryColumnTypes(pParse, pTab, pSel, SQLITE_AFF_NONE); + while( pSel->pPrior ) pSel = pSel->pPrior; + sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSel, + SQLITE_AFF_NONE); } } } } #endif @@ -145169,182 +140168,10 @@ sqlite3ResolveSelectNames(pParse, p, pOuterNC); if( pParse->nErr ) return; sqlite3SelectAddTypeInfo(pParse, p); } -#if TREETRACE_ENABLED -/* -** Display all information about an AggInfo object -*/ -static void printAggInfo(AggInfo *pAggInfo){ - int ii; - for(ii=0; iinColumn; ii++){ - struct AggInfo_col *pCol = &pAggInfo->aCol[ii]; - sqlite3DebugPrintf( - "agg-column[%d] pTab=%s iTable=%d iColumn=%d iMem=%d" - " iSorterColumn=%d %s\n", - ii, pCol->pTab ? pCol->pTab->zName : "NULL", - pCol->iTable, pCol->iColumn, pAggInfo->iFirstReg+ii, - pCol->iSorterColumn, - ii>=pAggInfo->nAccumulator ? "" : " Accumulator"); - sqlite3TreeViewExpr(0, pAggInfo->aCol[ii].pCExpr, 0); - } - for(ii=0; iinFunc; ii++){ - sqlite3DebugPrintf("agg-func[%d]: iMem=%d\n", - ii, pAggInfo->iFirstReg+pAggInfo->nColumn+ii); - sqlite3TreeViewExpr(0, pAggInfo->aFunc[ii].pFExpr, 0); - } -} -#endif /* TREETRACE_ENABLED */ - -/* -** Analyze the arguments to aggregate functions. Create new pAggInfo->aCol[] -** entries for columns that are arguments to aggregate functions but which -** are not otherwise used. -** -** The aCol[] entries in AggInfo prior to nAccumulator are columns that -** are referenced outside of aggregate functions. These might be columns -** that are part of the GROUP by clause, for example. Other database engines -** would throw an error if there is a column reference that is not in the -** GROUP BY clause and that is not part of an aggregate function argument. -** But SQLite allows this. -** -** The aCol[] entries beginning with the aCol[nAccumulator] and following -** are column references that are used exclusively as arguments to -** aggregate functions. This routine is responsible for computing -** (or recomputing) those aCol[] entries. -*/ -static void analyzeAggFuncArgs( - AggInfo *pAggInfo, - NameContext *pNC -){ - int i; - assert( pAggInfo!=0 ); - assert( pAggInfo->iFirstReg==0 ); - pNC->ncFlags |= NC_InAggFunc; - for(i=0; inFunc; i++){ - Expr *pExpr = pAggInfo->aFunc[i].pFExpr; - assert( ExprUseXList(pExpr) ); - sqlite3ExprAnalyzeAggList(pNC, pExpr->x.pList); -#ifndef SQLITE_OMIT_WINDOWFUNC - assert( !IsWindowFunc(pExpr) ); - if( ExprHasProperty(pExpr, EP_WinFunc) ){ - sqlite3ExprAnalyzeAggregates(pNC, pExpr->y.pWin->pFilter); - } -#endif - } - pNC->ncFlags &= ~NC_InAggFunc; -} - -/* -** An index on expressions is being used in the inner loop of an -** aggregate query with a GROUP BY clause. This routine attempts -** to adjust the AggInfo object to take advantage of index and to -** perhaps use the index as a covering index. -** -*/ -static void optimizeAggregateUseOfIndexedExpr( - Parse *pParse, /* Parsing context */ - Select *pSelect, /* The SELECT statement being processed */ - AggInfo *pAggInfo, /* The aggregate info */ - NameContext *pNC /* Name context used to resolve agg-func args */ -){ - assert( pAggInfo->iFirstReg==0 ); - assert( pSelect!=0 ); - assert( pSelect->pGroupBy!=0 ); - pAggInfo->nColumn = pAggInfo->nAccumulator; - if( ALWAYS(pAggInfo->nSortingColumn>0) ){ - int mx = pSelect->pGroupBy->nExpr - 1; - int j, k; - for(j=0; jnColumn; j++){ - k = pAggInfo->aCol[j].iSorterColumn; - if( k>mx ) mx = k; - } - pAggInfo->nSortingColumn = mx+1; - } - analyzeAggFuncArgs(pAggInfo, pNC); -#if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x20 ){ - IndexedExpr *pIEpr; - TREETRACE(0x20, pParse, pSelect, - ("AggInfo (possibly) adjusted for Indexed Exprs\n")); - sqlite3TreeViewSelect(0, pSelect, 0); - for(pIEpr=pParse->pIdxEpr; pIEpr; pIEpr=pIEpr->pIENext){ - printf("data-cursor=%d index={%d,%d}\n", - pIEpr->iDataCur, pIEpr->iIdxCur, pIEpr->iIdxCol); - sqlite3TreeViewExpr(0, pIEpr->pExpr, 0); - } - printAggInfo(pAggInfo); - } -#else - UNUSED_PARAMETER(pSelect); - UNUSED_PARAMETER(pParse); -#endif -} - -/* -** Walker callback for aggregateConvertIndexedExprRefToColumn(). -*/ -static int aggregateIdxEprRefToColCallback(Walker *pWalker, Expr *pExpr){ - AggInfo *pAggInfo; - struct AggInfo_col *pCol; - UNUSED_PARAMETER(pWalker); - if( pExpr->pAggInfo==0 ) return WRC_Continue; - if( pExpr->op==TK_AGG_COLUMN ) return WRC_Continue; - if( pExpr->op==TK_AGG_FUNCTION ) return WRC_Continue; - if( pExpr->op==TK_IF_NULL_ROW ) return WRC_Continue; - pAggInfo = pExpr->pAggInfo; - if( NEVER(pExpr->iAgg>=pAggInfo->nColumn) ) return WRC_Continue; - assert( pExpr->iAgg>=0 ); - pCol = &pAggInfo->aCol[pExpr->iAgg]; - pExpr->op = TK_AGG_COLUMN; - pExpr->iTable = pCol->iTable; - pExpr->iColumn = pCol->iColumn; - ExprClearProperty(pExpr, EP_Skip|EP_Collate); - return WRC_Prune; -} - -/* -** Convert every pAggInfo->aFunc[].pExpr such that any node within -** those expressions that has pAppInfo set is changed into a TK_AGG_COLUMN -** opcode. -*/ -static void aggregateConvertIndexedExprRefToColumn(AggInfo *pAggInfo){ - int i; - Walker w; - memset(&w, 0, sizeof(w)); - w.xExprCallback = aggregateIdxEprRefToColCallback; - for(i=0; inFunc; i++){ - sqlite3WalkExpr(&w, pAggInfo->aFunc[i].pFExpr); - } -} - - -/* -** Allocate a block of registers so that there is one register for each -** pAggInfo->aCol[] and pAggInfo->aFunc[] entry in pAggInfo. The first -** register in this block is stored in pAggInfo->iFirstReg. -** -** This routine may only be called once for each AggInfo object. Prior -** to calling this routine: -** -** * The aCol[] and aFunc[] arrays may be modified -** * The AggInfoColumnReg() and AggInfoFuncReg() macros may not be used -** -** After clling this routine: -** -** * The aCol[] and aFunc[] arrays are fixed -** * The AggInfoColumnReg() and AggInfoFuncReg() macros may be used -** -*/ -static void assignAggregateRegisters(Parse *pParse, AggInfo *pAggInfo){ - assert( pAggInfo!=0 ); - assert( pAggInfo->iFirstReg==0 ); - pAggInfo->iFirstReg = pParse->nMem + 1; - pParse->nMem += pAggInfo->nColumn + pAggInfo->nFunc; -} - /* ** Reset the aggregate accumulator. ** ** The aggregate accumulator is a set of memory cells that hold ** intermediate results while calculating an aggregate. This @@ -145354,17 +140181,28 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ Vdbe *v = pParse->pVdbe; int i; struct AggInfo_func *pFunc; int nReg = pAggInfo->nFunc + pAggInfo->nColumn; - assert( pAggInfo->iFirstReg>0 ); assert( pParse->db->pParse==pParse ); assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 ); if( nReg==0 ) return; if( pParse->nErr ) return; - sqlite3VdbeAddOp3(v, OP_Null, 0, pAggInfo->iFirstReg, - pAggInfo->iFirstReg+nReg-1); +#ifdef SQLITE_DEBUG + /* Verify that all AggInfo registers are within the range specified by + ** AggInfo.mnReg..AggInfo.mxReg */ + assert( nReg==pAggInfo->mxReg-pAggInfo->mnReg+1 ); + for(i=0; inColumn; i++){ + assert( pAggInfo->aCol[i].iMem>=pAggInfo->mnReg + && pAggInfo->aCol[i].iMem<=pAggInfo->mxReg ); + } + for(i=0; inFunc; i++){ + assert( pAggInfo->aFunc[i].iMem>=pAggInfo->mnReg + && pAggInfo->aFunc[i].iMem<=pAggInfo->mxReg ); + } +#endif + sqlite3VdbeAddOp3(v, OP_Null, 0, pAggInfo->mnReg, pAggInfo->mxReg); for(pFunc=pAggInfo->aFunc, i=0; inFunc; i++, pFunc++){ if( pFunc->iDistinct>=0 ){ Expr *pE = pFunc->pFExpr; assert( ExprUseXList(pE) ); if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){ @@ -145392,20 +140230,19 @@ struct AggInfo_func *pF; for(i=0, pF=pAggInfo->aFunc; inFunc; i++, pF++){ ExprList *pList; assert( ExprUseXList(pF->pFExpr) ); pList = pF->pFExpr->x.pList; - sqlite3VdbeAddOp2(v, OP_AggFinal, AggInfoFuncReg(pAggInfo,i), - pList ? pList->nExpr : 0); + sqlite3VdbeAddOp2(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0); sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); } } /* -** Generate code that will update the accumulator memory cells for an -** aggregate based on the current cursor position. +** Update the accumulator memory cells for an aggregate based on +** the current cursor position. ** ** If regAcc is non-zero and there are no min() or max() aggregates ** in pAggInfo, then only populate the pAggInfo->nAccumulator accumulator ** registers if register regAcc contains 0. The caller will take care ** of setting and clearing regAcc. @@ -145421,12 +140258,10 @@ int regHit = 0; int addrHitTest = 0; struct AggInfo_func *pF; struct AggInfo_col *pC; - assert( pAggInfo->iFirstReg>0 ); - if( pParse->nErr ) return; pAggInfo->directMode = 1; for(i=0, pF=pAggInfo->aFunc; inFunc; i++, pF++){ int nArg; int addrNext = 0; int regAgg; @@ -145483,11 +140318,11 @@ pColl = pParse->db->pDfltColl; } if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem; sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ); } - sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); + sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, pF->iMem); sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); sqlite3VdbeChangeP5(v, (u8)nArg); sqlite3ReleaseTempRange(pParse, regAgg, nArg); if( addrNext ){ sqlite3VdbeResolveLabel(v, addrNext); @@ -145498,11 +140333,11 @@ } if( regHit ){ addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v); } for(i=0, pC=pAggInfo->aCol; inAccumulator; i++, pC++){ - sqlite3ExprCode(pParse, pC->pCExpr, AggInfoColumnReg(pAggInfo,i)); + sqlite3ExprCode(pParse, pC->pCExpr, pC->iMem); } pAggInfo->directMode = 0; if( addrHitTest ){ sqlite3VdbeJumpHereOrPopInst(v, addrHitTest); @@ -145592,37 +140427,32 @@ memset(&sWalker, 0, sizeof(sWalker)); sWalker.pParse = pParse; sWalker.xExprCallback = havingToWhereExprCb; sWalker.u.pSelect = p; sqlite3WalkExpr(&sWalker, p->pHaving); -#if TREETRACE_ENABLED - if( sWalker.eCode && (sqlite3TreeTrace & 0x100)!=0 ){ - TREETRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n")); +#if SELECTTRACE_ENABLED + if( sWalker.eCode && (sqlite3SelectTrace & 0x100)!=0 ){ + SELECTTRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n")); sqlite3TreeViewSelect(0, p, 0); } #endif } /* -** Check to see if the pThis entry of pTabList is a self-join of another view. -** Search FROM-clause entries in the range of iFirst..iEnd, including iFirst -** but stopping before iEnd. -** -** If pThis is a self-join, then return the SrcItem for the first other -** instance of that view found. If pThis is not a self-join then return 0. +** Check to see if the pThis entry of pTabList is a self-join of a prior view. +** If it is, then return the SrcList_item for the prior view. If it is not, +** then return 0. */ static SrcItem *isSelfJoinView( SrcList *pTabList, /* Search for self-joins in this FROM clause */ - SrcItem *pThis, /* Search for prior reference to this subquery */ - int iFirst, int iEnd /* Range of FROM-clause entries to search. */ + SrcItem *pThis /* Search for prior reference to this subquery */ ){ SrcItem *pItem; assert( pThis->pSelect!=0 ); if( pThis->pSelect->selFlags & SF_PushDown ) return 0; - while( iFirsta; pItema[iFirst++]; if( pItem->pSelect==0 ) continue; if( pItem->fg.viaCoroutine ) continue; if( pItem->zName==0 ) continue; assert( pItem->pTab!=0 ); assert( pThis->pTab!=0 ); @@ -145651,10 +140481,11 @@ sqlite3DbFree(db, p->aCol); sqlite3DbFree(db, p->aFunc); sqlite3DbFreeNN(db, p); } +#ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION /* ** Attempt to transform a query of the form ** ** SELECT count(*) FROM (SELECT x FROM t1 UNION ALL SELECT y FROM t2) ** @@ -145678,32 +140509,27 @@ Expr *pCount; sqlite3 *db; if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate */ if( p->pEList->nExpr!=1 ) return 0; /* Single result column */ if( p->pWhere ) return 0; - if( p->pHaving ) return 0; if( p->pGroupBy ) return 0; - if( p->pOrderBy ) return 0; pExpr = p->pEList->a[0].pExpr; if( pExpr->op!=TK_AGG_FUNCTION ) return 0; /* Result is an aggregate */ assert( ExprUseUToken(pExpr) ); if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0; /* Is count() */ assert( ExprUseXList(pExpr) ); if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */ if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */ - if( ExprHasProperty(pExpr, EP_WinFunc) ) return 0;/* Not a window function */ pSub = p->pSrc->a[0].pSelect; if( pSub==0 ) return 0; /* The FROM is a subquery */ - if( pSub->pPrior==0 ) return 0; /* Must be a compound */ - if( pSub->selFlags & SF_CopyCte ) return 0; /* Not a CTE */ + if( pSub->pPrior==0 ) return 0; /* Must be a compound ry */ do{ if( pSub->op!=TK_ALL && pSub->pPrior ) return 0; /* Must be UNION ALL */ if( pSub->pWhere ) return 0; /* No WHERE clause */ if( pSub->pLimit ) return 0; /* No LIMIT clause */ if( pSub->selFlags & SF_Aggregate ) return 0; /* Not an aggregate */ - assert( pSub->pHaving==0 ); /* Due to the previous */ - pSub = pSub->pPrior; /* Repeat over compound */ + pSub = pSub->pPrior; /* Repeat over compound */ }while( pSub ); /* If we reach this point then it is OK to perform the transformation */ db = pParse->db; @@ -145734,103 +140560,19 @@ pSub = pPrior; } p->pEList->a[0].pExpr = pExpr; p->selFlags &= ~SF_Aggregate; -#if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x200 ){ - TREETRACE(0x200,pParse,p,("After count-of-view optimization:\n")); +#if SELECTTRACE_ENABLED + if( sqlite3SelectTrace & 0x400 ){ + SELECTTRACE(0x400,pParse,p,("After count-of-view optimization:\n")); sqlite3TreeViewSelect(0, p, 0); } #endif return 1; } - -/* -** If any term of pSrc, or any SF_NestedFrom sub-query, is not the same -** as pSrcItem but has the same alias as p0, then return true. -** Otherwise return false. -*/ -static int sameSrcAlias(SrcItem *p0, SrcList *pSrc){ - int i; - for(i=0; inSrc; i++){ - SrcItem *p1 = &pSrc->a[i]; - if( p1==p0 ) continue; - if( p0->pTab==p1->pTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){ - return 1; - } - if( p1->pSelect - && (p1->pSelect->selFlags & SF_NestedFrom)!=0 - && sameSrcAlias(p0, p1->pSelect->pSrc) - ){ - return 1; - } - } - return 0; -} - -/* -** Return TRUE (non-zero) if the i-th entry in the pTabList SrcList can -** be implemented as a co-routine. The i-th entry is guaranteed to be -** a subquery. -** -** The subquery is implemented as a co-routine if all of the following are -** true: -** -** (1) The subquery will likely be implemented in the outer loop of -** the query. This will be the case if any one of the following -** conditions hold: -** (a) The subquery is the only term in the FROM clause -** (b) The subquery is the left-most term and a CROSS JOIN or similar -** requires it to be the outer loop -** (c) All of the following are true: -** (i) The subquery is the left-most subquery in the FROM clause -** (ii) There is nothing that would prevent the subquery from -** being used as the outer loop if the sqlite3WhereBegin() -** routine nominates it to that position. -** (iii) The query is not a UPDATE ... FROM -** (2) The subquery is not a CTE that should be materialized because -** (a) the AS MATERIALIZED keyword is used, or -** (b) the CTE is used multiple times and does not have the -** NOT MATERIALIZED keyword -** (3) The subquery is not part of a left operand for a RIGHT JOIN -** (4) The SQLITE_Coroutine optimization disable flag is not set -** (5) The subquery is not self-joined -*/ -static int fromClauseTermCanBeCoroutine( - Parse *pParse, /* Parsing context */ - SrcList *pTabList, /* FROM clause */ - int i, /* Which term of the FROM clause holds the subquery */ - int selFlags /* Flags on the SELECT statement */ -){ - SrcItem *pItem = &pTabList->a[i]; - if( pItem->fg.isCte ){ - const CteUse *pCteUse = pItem->u2.pCteUse; - if( pCteUse->eM10d==M10d_Yes ) return 0; /* (2a) */ - if( pCteUse->nUse>=2 && pCteUse->eM10d!=M10d_No ) return 0; /* (2b) */ - } - if( pTabList->a[0].fg.jointype & JT_LTORJ ) return 0; /* (3) */ - if( OptimizationDisabled(pParse->db, SQLITE_Coroutines) ) return 0; /* (4) */ - if( isSelfJoinView(pTabList, pItem, i+1, pTabList->nSrc)!=0 ){ - return 0; /* (5) */ - } - if( i==0 ){ - if( pTabList->nSrc==1 ) return 1; /* (1a) */ - if( pTabList->a[1].fg.jointype & JT_CROSS ) return 1; /* (1b) */ - if( selFlags & SF_UpdateFrom ) return 0; /* (1c-iii) */ - return 1; - } - if( selFlags & SF_UpdateFrom ) return 0; /* (1c-iii) */ - while( 1 /*exit-by-break*/ ){ - if( pItem->fg.jointype & (JT_OUTER|JT_CROSS) ) return 0; /* (1c-ii) */ - if( i==0 ) break; - i--; - pItem--; - if( pItem->pSelect!=0 ) return 0; /* (1c-i) */ - } - return 1; -} +#endif /* SQLITE_COUNTOFVIEW_OPTIMIZATION */ /* ** Generate code for the SELECT statement given in the p argument. ** ** The results are returned according to the SelectDest structure. @@ -145872,18 +140614,14 @@ if( p==0 || pParse->nErr ){ return 1; } assert( db->mallocFailed==0 ); if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; -#if TREETRACE_ENABLED - TREETRACE(0x1,pParse,p, ("begin processing:\n", pParse->addrExplain)); - if( sqlite3TreeTrace & 0x10000 ){ - if( (sqlite3TreeTrace & 0x10001)==0x10000 ){ - sqlite3TreeViewLine(0, "In sqlite3Select() at %s:%d", - __FILE__, __LINE__); - } - sqlite3ShowSelect(p); +#if SELECTTRACE_ENABLED + SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain)); + if( sqlite3SelectTrace & 0x100 ){ + sqlite3TreeViewSelect(0, p, 0); } #endif assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo ); assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo ); @@ -145893,13 +140631,13 @@ assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union || pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard || pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_DistFifo ); /* All of these destinations are also able to ignore the ORDER BY clause */ if( p->pOrderBy ){ -#if TREETRACE_ENABLED - TREETRACE(0x800,pParse,p, ("dropping superfluous ORDER BY:\n")); - if( sqlite3TreeTrace & 0x800 ){ +#if SELECTTRACE_ENABLED + SELECTTRACE(1,pParse,p, ("dropping superfluous ORDER BY:\n")); + if( sqlite3SelectTrace & 0x100 ){ sqlite3TreeViewExprList(0, p->pOrderBy, 0, "ORDERBY"); } #endif sqlite3ParserAddCleanup(pParse, (void(*)(sqlite3*,void*))sqlite3ExprListDelete, @@ -145914,13 +140652,13 @@ if( pParse->nErr ){ goto select_end; } assert( db->mallocFailed==0 ); assert( p->pEList!=0 ); -#if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x10 ){ - TREETRACE(0x10,pParse,p, ("after name resolution:\n")); +#if SELECTTRACE_ENABLED + if( sqlite3SelectTrace & 0x104 ){ + SELECTTRACE(0x104,pParse,p, ("after name resolution:\n")); sqlite3TreeViewSelect(0, p, 0); } #endif /* If the SF_UFSrcCheck flag is set, then this function is being called @@ -145932,16 +140670,19 @@ ** systems handle this case differently, and not all the same way, ** which is just confusing. To avoid this, we follow PG's lead and ** disallow it altogether. */ if( p->selFlags & SF_UFSrcCheck ){ SrcItem *p0 = &p->pSrc->a[0]; - if( sameSrcAlias(p0, p->pSrc) ){ - sqlite3ErrorMsg(pParse, - "target object/alias may not appear in FROM clause: %s", - p0->zAlias ? p0->zAlias : p0->pTab->zName - ); - goto select_end; + for(i=1; ipSrc->nSrc; i++){ + SrcItem *p1 = &p->pSrc->a[i]; + if( p0->pTab==p1->pTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){ + sqlite3ErrorMsg(pParse, + "target object/alias may not appear in FROM clause: %s", + p0->zAlias ? p0->zAlias : p0->pTab->zName + ); + goto select_end; + } } /* Clear the SF_UFSrcCheck flag. The check has already been performed, ** and leaving this flag set can cause errors if a compound sub-query ** in p->pSrc is flattened into this query and this function called @@ -145956,13 +140697,13 @@ #ifndef SQLITE_OMIT_WINDOWFUNC if( sqlite3WindowRewrite(pParse, p) ){ assert( pParse->nErr ); goto select_end; } -#if TREETRACE_ENABLED - if( p->pWin && (sqlite3TreeTrace & 0x40)!=0 ){ - TREETRACE(0x40,pParse,p, ("after window rewrite:\n")); +#if SELECTTRACE_ENABLED + if( p->pWin && (sqlite3SelectTrace & 0x108)!=0 ){ + SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n")); sqlite3TreeViewSelect(0, p, 0); } #endif #endif /* SQLITE_OMIT_WINDOWFUNC */ pTabList = p->pSrc; @@ -145985,20 +140726,18 @@ assert( pTab!=0 ); /* Convert LEFT JOIN into JOIN if there are terms of the right table ** of the LEFT JOIN used in the WHERE clause. */ - if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==JT_LEFT + if( (pItem->fg.jointype & JT_LEFT)!=0 && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor) && OptimizationEnabled(db, SQLITE_SimplifyJoin) ){ - TREETRACE(0x1000,pParse,p, + SELECTTRACE(0x100,pParse,p, ("LEFT-JOIN simplifies to JOIN on term %d\n",i)); pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER); - assert( pItem->iCursor>=0 ); - unsetJoinExpr(p->pWhere, pItem->iCursor, - pTabList->a[0].fg.jointype & JT_LTORJ); + unsetJoinExpr(p->pWhere, pItem->iCursor); } /* No futher action if this term of the FROM clause is no a subquery */ if( pSub==0 ) continue; @@ -146045,15 +140784,13 @@ && pSub->pLimit==0 /* Condition (1) */ && (pSub->selFlags & SF_OrderByReqd)==0 /* Condition (2) */ && (p->selFlags & SF_OrderByReqd)==0 /* Condition (3) and (4) */ && OptimizationEnabled(db, SQLITE_OmitOrderBy) ){ - TREETRACE(0x800,pParse,p, + SELECTTRACE(0x100,pParse,p, ("omit superfluous ORDER BY on %r FROM-clause subquery\n",i+1)); - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3ExprListDelete, - pSub->pOrderBy); + sqlite3ExprListDelete(db, pSub->pOrderBy); pSub->pOrderBy = 0; } /* If the outer query contains a "complex" result set (that is, ** if the result set of the outer query uses functions or subqueries) @@ -146075,11 +140812,11 @@ */ if( pSub->pOrderBy!=0 && i==0 && (p->selFlags & SF_ComplexResult)!=0 && (pTabList->nSrc==1 - || (pTabList->a[1].fg.jointype&(JT_OUTER|JT_CROSS))!=0) + || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0) ){ continue; } if( flattenSubquery(pParse, p, i, isAgg) ){ @@ -146099,13 +140836,13 @@ /* Handle compound SELECT statements using the separate multiSelect() ** procedure. */ if( p->pPrior ){ rc = multiSelect(pParse, p, pDest); -#if TREETRACE_ENABLED - TREETRACE(0x400,pParse,p,("end compound-select processing\n")); - if( (sqlite3TreeTrace & 0x400)!=0 && ExplainQueryPlanParent(pParse)==0 ){ +#if SELECTTRACE_ENABLED + SELECTTRACE(0x1,pParse,p,("end compound-select processing\n")); + if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ sqlite3TreeViewSelect(0, p, 0); } #endif if( p->pNext==0 ) ExplainQueryPlanPop(pParse); return rc; @@ -146120,26 +140857,29 @@ if( p->pWhere!=0 && p->pWhere->op==TK_AND && OptimizationEnabled(db, SQLITE_PropagateConst) && propagateConstants(pParse, p) ){ -#if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x2000 ){ - TREETRACE(0x2000,pParse,p,("After constant propagation:\n")); +#if SELECTTRACE_ENABLED + if( sqlite3SelectTrace & 0x100 ){ + SELECTTRACE(0x100,pParse,p,("After constant propagation:\n")); sqlite3TreeViewSelect(0, p, 0); } #endif }else{ - TREETRACE(0x2000,pParse,p,("Constant propagation not helpful\n")); + SELECTTRACE(0x100,pParse,p,("Constant propagation not helpful\n")); } +#ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView) && countOfViewOptimization(pParse, p) ){ if( db->mallocFailed ) goto select_end; + pEList = p->pEList; pTabList = p->pSrc; } +#endif /* For each term in the FROM clause, do two things: ** (1) Authorized unreferenced tables ** (2) Generate code for all sub-queries */ @@ -146196,44 +140936,40 @@ if( OptimizationEnabled(db, SQLITE_PushDown) && (pItem->fg.isCte==0 || (pItem->u2.pCteUse->eM10d!=M10d_Yes && pItem->u2.pCteUse->nUse<2)) && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem) ){ -#if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x4000 ){ - TREETRACE(0x4000,pParse,p, +#if SELECTTRACE_ENABLED + if( sqlite3SelectTrace & 0x100 ){ + SELECTTRACE(0x100,pParse,p, ("After WHERE-clause push-down into subquery %d:\n", pSub->selId)); sqlite3TreeViewSelect(0, p, 0); } #endif assert( pItem->pSelect && (pItem->pSelect->selFlags & SF_PushDown)!=0 ); }else{ - TREETRACE(0x4000,pParse,p,("Push-down not possible\n")); - } - - /* Convert unused result columns of the subquery into simple NULL - ** expressions, to avoid unneeded searching and computation. - */ - if( OptimizationEnabled(db, SQLITE_NullUnusedCols) - && disableUnusedSubqueryResultColumns(pItem) - ){ -#if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x4000 ){ - TREETRACE(0x4000,pParse,p, - ("Change unused result columns to NULL for subquery %d:\n", - pSub->selId)); - sqlite3TreeViewSelect(0, p, 0); - } -#endif + SELECTTRACE(0x100,pParse,p,("Push-down not possible\n")); } zSavedAuthContext = pParse->zAuthContext; pParse->zAuthContext = pItem->zName; /* Generate code to implement the subquery + ** + ** The subquery is implemented as a co-routine if: + ** (1) the subquery is guaranteed to be the outer loop (so that + ** it does not need to be computed more than once), and + ** (2) the subquery is not a CTE that should be materialized + ** + ** TODO: Are there other reasons beside (1) and (2) to use a co-routine + ** implementation? */ - if( fromClauseTermCanBeCoroutine(pParse, pTabList, i, p->selFlags) ){ + if( i==0 + && (pTabList->nSrc==1 + || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0) /* (1) */ + && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes) /* (2) */ + ){ /* Implement a co-routine that will return a single row of the result ** set on each invocation. */ int addrTop = sqlite3VdbeCurrentAddr(v)+1; @@ -146260,11 +140996,11 @@ if( pItem->iCursor!=pCteUse->iCur ){ sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pCteUse->iCur); VdbeComment((v, "%!S", pItem)); } pSub->nSelectRow = pCteUse->nRowEst; - }else if( (pPrior = isSelfJoinView(pTabList, pItem, 0, i))!=0 ){ + }else if( (pPrior = isSelfJoinView(pTabList, pItem))!=0 ){ /* This view has already been materialized by a prior entry in ** this same FROM clause. Reuse it. */ if( pPrior->addrFillSub ){ sqlite3VdbeAddOp2(v, OP_Gosub, pPrior->regReturn, pPrior->addrFillSub); } @@ -146274,18 +141010,15 @@ /* Materialize the view. If the view is not correlated, generate a ** subroutine to do the materialization so that subsequent uses of ** the same view can reuse the materialization. */ int topAddr; int onceAddr = 0; -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS - int addrExplain; -#endif + int retAddr; pItem->regReturn = ++pParse->nMem; - topAddr = sqlite3VdbeAddOp0(v, OP_Goto); + topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn); pItem->addrFillSub = topAddr+1; - pItem->fg.isMaterialized = 1; if( pItem->fg.isCorrelated==0 ){ /* If the subquery is not correlated and if we are not inside of ** a trigger, then we only need to compute the value of the subquery ** once. */ onceAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); @@ -146292,19 +141025,17 @@ VdbeComment((v, "materialize %!S", pItem)); }else{ VdbeNoopComment((v, "materialize %!S", pItem)); } sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); - - ExplainQueryPlan2(addrExplain, (pParse, 1, "MATERIALIZE %!S", pItem)); + ExplainQueryPlan((pParse, 1, "MATERIALIZE %!S", pItem)); sqlite3Select(pParse, pSub, &dest); pItem->pTab->nRowLogEst = pSub->nSelectRow; if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); - sqlite3VdbeAddOp2(v, OP_Return, pItem->regReturn, topAddr+1); + retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn); VdbeComment((v, "end %!S", pItem)); - sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1); - sqlite3VdbeJumpHere(v, topAddr); + sqlite3VdbeChangeP1(v, topAddr, retAddr); sqlite3ClearTempRegCache(pParse); if( pItem->fg.isCte && pItem->fg.isCorrelated==0 ){ CteUse *pCteUse = pItem->u2.pCteUse; pCteUse->addrM9e = pItem->addrFillSub; pCteUse->regRtn = pItem->regReturn; @@ -146324,13 +141055,13 @@ pWhere = p->pWhere; pGroupBy = p->pGroupBy; pHaving = p->pHaving; sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0; -#if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x8000 ){ - TREETRACE(0x8000,pParse,p,("After all FROM-clause analysis:\n")); +#if SELECTTRACE_ENABLED + if( sqlite3SelectTrace & 0x400 ){ + SELECTTRACE(0x400,pParse,p,("After all FROM-clause analysis:\n")); sqlite3TreeViewSelect(0, p, 0); } #endif /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and @@ -146359,15 +141090,14 @@ p->selFlags |= SF_Aggregate; /* Notice that even thought SF_Distinct has been cleared from p->selFlags, ** the sDistinct.isTnct is still set. Hence, isTnct represents the ** original setting of the SF_Distinct flag, not the current setting */ assert( sDistinct.isTnct ); - sDistinct.isTnct = 2; -#if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x20000 ){ - TREETRACE(0x20000,pParse,p,("Transform DISTINCT into GROUP BY:\n")); +#if SELECTTRACE_ENABLED + if( sqlite3SelectTrace & 0x400 ){ + SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n")); sqlite3TreeViewSelect(0, p, 0); } #endif } @@ -146395,31 +141125,19 @@ /* If the output is destined for a temporary table, open that table. */ if( pDest->eDest==SRT_EphemTab ){ sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr); - if( p->selFlags & SF_NestedFrom ){ - /* Delete or NULL-out result columns that will never be used */ - int ii; - for(ii=pEList->nExpr-1; ii>0 && pEList->a[ii].fg.bUsed==0; ii--){ - sqlite3ExprDelete(db, pEList->a[ii].pExpr); - sqlite3DbFree(db, pEList->a[ii].zEName); - pEList->nExpr--; - } - for(ii=0; iinExpr; ii++){ - if( pEList->a[ii].fg.bUsed==0 ) pEList->a[ii].pExpr->op = TK_NULL; - } - } } /* Set the limiter. */ iEnd = sqlite3VdbeMakeLabel(pParse); if( (p->selFlags & SF_FixedLimit)==0 ){ p->nSelectRow = 320; /* 4 billion rows */ } - if( p->pLimit ) computeLimitRegisters(pParse, p, iEnd); + computeLimitRegisters(pParse, p, iEnd); if( p->iLimit==0 && sSort.addrSortIndex>=0 ){ sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen); sSort.sortFlags |= SORTFLAG_UseSorter; } @@ -146449,11 +141167,11 @@ #endif assert( WHERE_USE_LIMIT==SF_FixedLimit ); /* Begin the database scan. */ - TREETRACE(0x2,pParse,p,("WhereBegin\n")); + SELECTTRACE(1,pParse,p,("WhereBegin\n")); pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy, p->pEList, p, wctrlFlags, p->nSelectRow); if( pWInfo==0 ) goto select_end; if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){ p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo); @@ -146466,11 +141184,11 @@ sSort.labelOBLopt = sqlite3WhereOrderByLimitOptLabel(pWInfo); if( sSort.nOBSat==sSort.pOrderBy->nExpr ){ sSort.pOrderBy = 0; } } - TREETRACE(0x2,pParse,p,("WhereBegin returns\n")); + SELECTTRACE(1,pParse,p,("WhereBegin returns\n")); /* 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. */ @@ -146505,11 +141223,11 @@ sqlite3WhereContinueLabel(pWInfo), sqlite3WhereBreakLabel(pWInfo)); /* End the database scan loop. */ - TREETRACE(0x2,pParse,p,("WhereEnd\n")); + SELECTTRACE(1,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); } }else{ /* This case when there exist aggregate functions or a GROUP BY clause ** or both */ @@ -146556,13 +141274,12 @@ ** ASC or DESC order - only that each group is returned contiguously. ** So set the ASC/DESC flags in the GROUP BY to match those in the ** ORDER BY to maximize the chances of rows being delivered in an ** order that makes the ORDER BY redundant. */ for(ii=0; iinExpr; ii++){ - u8 sortFlags; - sortFlags = sSort.pOrderBy->a[ii].fg.sortFlags & KEYINFO_ORDER_DESC; - pGroupBy->a[ii].fg.sortFlags = sortFlags; + u8 sortFlags = sSort.pOrderBy->a[ii].sortFlags & KEYINFO_ORDER_DESC; + pGroupBy->a[ii].sortFlags = sortFlags; } if( sqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 ){ orderByGrp = 1; } } @@ -146586,18 +141303,16 @@ } if( db->mallocFailed ){ goto select_end; } pAggInfo->selId = p->selId; -#ifdef SQLITE_DEBUG - pAggInfo->pSelect = p; -#endif memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; sNC.pSrcList = pTabList; sNC.uNC.pAggInfo = pAggInfo; VVA_ONLY( sNC.ncFlags = NC_UAggInfo; ) + pAggInfo->mnReg = pParse->nMem+1; pAggInfo->nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0; pAggInfo->pGroupBy = pGroupBy; sqlite3ExprAnalyzeAggList(&sNC, pEList); sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy); if( pHaving ){ @@ -146614,21 +141329,44 @@ if( p->pGroupBy==0 && p->pHaving==0 && pAggInfo->nFunc==1 ){ minMaxFlag = minMaxQuery(db, pAggInfo->aFunc[0].pFExpr, &pMinMaxOrderBy); }else{ minMaxFlag = WHERE_ORDERBY_NORMAL; } - analyzeAggFuncArgs(pAggInfo, &sNC); + for(i=0; inFunc; i++){ + Expr *pExpr = pAggInfo->aFunc[i].pFExpr; + assert( ExprUseXList(pExpr) ); + sNC.ncFlags |= NC_InAggFunc; + sqlite3ExprAnalyzeAggList(&sNC, pExpr->x.pList); +#ifndef SQLITE_OMIT_WINDOWFUNC + assert( !IsWindowFunc(pExpr) ); + if( ExprHasProperty(pExpr, EP_WinFunc) ){ + sqlite3ExprAnalyzeAggregates(&sNC, pExpr->y.pWin->pFilter); + } +#endif + sNC.ncFlags &= ~NC_InAggFunc; + } + pAggInfo->mxReg = pParse->nMem; if( db->mallocFailed ) goto select_end; -#if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x20 ){ - TREETRACE(0x20,pParse,p,("After aggregate analysis %p:\n", pAggInfo)); +#if SELECTTRACE_ENABLED + if( sqlite3SelectTrace & 0x400 ){ + int ii; + SELECTTRACE(0x400,pParse,p,("After aggregate analysis %p:\n", pAggInfo)); sqlite3TreeViewSelect(0, p, 0); if( minMaxFlag ){ sqlite3DebugPrintf("MIN/MAX Optimization (0x%02x) adds:\n", minMaxFlag); sqlite3TreeViewExprList(0, pMinMaxOrderBy, 0, "ORDERBY"); } - printAggInfo(pAggInfo); + for(ii=0; iinColumn; ii++){ + sqlite3DebugPrintf("agg-column[%d] iMem=%d\n", + ii, pAggInfo->aCol[ii].iMem); + sqlite3TreeViewExpr(0, pAggInfo->aCol[ii].pCExpr, 0); + } + for(ii=0; iinFunc; ii++){ + sqlite3DebugPrintf("agg-func[%d]: iMem=%d\n", + ii, pAggInfo->aFunc[ii].iMem); + sqlite3TreeViewExpr(0, pAggInfo->aFunc[ii].pFExpr, 0); + } } #endif /* Processing for aggregates with GROUP BY is very different and @@ -146693,25 +141431,20 @@ ** 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. */ sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); - TREETRACE(0x2,pParse,p,("WhereBegin\n")); + SELECTTRACE(1,pParse,p,("WhereBegin\n")); pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, pDistinct, - p, (sDistinct.isTnct==2 ? WHERE_DISTINCTBY : WHERE_GROUPBY) - | (orderByGrp ? WHERE_SORTBYGROUP : 0) | distFlag, 0 + 0, (WHERE_GROUPBY|(orderByGrp ? WHERE_SORTBYGROUP : 0)|distFlag), 0 ); if( pWInfo==0 ){ sqlite3ExprListDelete(db, pDistinct); goto select_end; } - if( pParse->pIdxEpr ){ - optimizeAggregateUseOfIndexedExpr(pParse, p, pAggInfo, &sNC); - } - assignAggregateRegisters(pParse, pAggInfo); eDist = sqlite3WhereIsDistinct(pWInfo); - TREETRACE(0x2,pParse,p,("WhereBegin returns\n")); + SELECTTRACE(1,pParse,p,("WhereBegin returns\n")); if( sqlite3WhereIsOrdered(pWInfo)==pGroupBy->nExpr ){ /* 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 */ @@ -146742,49 +141475,32 @@ } } regBase = sqlite3GetTempRange(pParse, nCol); sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0); j = nGroupBy; - pAggInfo->directMode = 1; for(i=0; inColumn; i++){ struct AggInfo_col *pCol = &pAggInfo->aCol[i]; if( pCol->iSorterColumn>=j ){ - sqlite3ExprCode(pParse, pCol->pCExpr, j + regBase); + int r1 = j + regBase; + sqlite3ExprCodeGetColumnOfTable(v, + pCol->pTab, pCol->iTable, pCol->iColumn, r1); j++; } } - pAggInfo->directMode = 0; regRecord = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord); sqlite3VdbeAddOp2(v, OP_SorterInsert, pAggInfo->sortingIdx, regRecord); sqlite3ReleaseTempReg(pParse, regRecord); sqlite3ReleaseTempRange(pParse, regBase, nCol); - TREETRACE(0x2,pParse,p,("WhereEnd\n")); + SELECTTRACE(1,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); pAggInfo->sortingIdxPTab = sortPTab = pParse->nTab++; sortOut = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol); sqlite3VdbeAddOp2(v, OP_SorterSort, pAggInfo->sortingIdx, addrEnd); VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v); pAggInfo->useSortingIdx = 1; - } - - /* If there are entries in pAgggInfo->aFunc[] that contain subexpressions - ** that are indexed (and that were previously identified and tagged - ** in optimizeAggregateUseOfIndexedExpr()) then those subexpressions - ** must now be converted into a TK_AGG_COLUMN node so that the value - ** is correctly pulled from the index rather than being recomputed. */ - if( pParse->pIdxEpr ){ - aggregateConvertIndexedExprRefToColumn(pAggInfo); -#if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x20 ){ - TREETRACE(0x20, pParse, p, - ("AggInfo function expressions converted to reference index\n")); - sqlite3TreeViewSelect(0, p, 0); - printAggInfo(pAggInfo); - } -#endif } /* If the index or temporary table used by the GROUP BY sort ** will naturally deliver rows in the order required by the ORDER BY ** clause, cancel the ephemeral table open coded earlier. @@ -146851,11 +141567,11 @@ */ if( groupBySort ){ sqlite3VdbeAddOp2(v, OP_SorterNext, pAggInfo->sortingIdx,addrTopOfLoop); VdbeCoverage(v); }else{ - TREETRACE(0x2,pParse,p,("WhereEnd\n")); + SELECTTRACE(1,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); sqlite3VdbeChangeToNoop(v, addrSortingIdx); } sqlite3ExprListDelete(db, pDistinct); @@ -146899,11 +141615,11 @@ resetAccumulator(pParse, pAggInfo); sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag); VdbeComment((v, "indicate accumulator empty")); sqlite3VdbeAddOp1(v, OP_Return, regReset); - if( distFlag!=0 && eDist!=WHERE_DISTINCT_NOOP ){ + if( eDist!=WHERE_DISTINCT_NOOP ){ struct AggInfo_func *pF = &pAggInfo->aFunc[0]; fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr); } } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */ else { @@ -146961,12 +141677,11 @@ /* Open a read-only cursor, execute the OP_Count, close the cursor. */ sqlite3VdbeAddOp4Int(v, OP_OpenRead, iCsr, (int)iRoot, iDb, 1); if( pKeyInfo ){ sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO); } - assignAggregateRegisters(pParse, pAggInfo); - sqlite3VdbeAddOp2(v, OP_Count, iCsr, AggInfoFuncReg(pAggInfo,0)); + sqlite3VdbeAddOp2(v, OP_Count, iCsr, pAggInfo->aFunc[0].iMem); sqlite3VdbeAddOp1(v, OP_Close, iCsr); explainSimpleCount(pParse, pTab, pBest); }else{ int regAcc = 0; /* "populate accumulators" flag */ ExprList *pDistinct = 0; @@ -146998,11 +141713,10 @@ }else if( pAggInfo->nFunc==1 && pAggInfo->aFunc[0].iDistinct>=0 ){ assert( ExprUseXList(pAggInfo->aFunc[0].pFExpr) ); pDistinct = pAggInfo->aFunc[0].pFExpr->x.pList; distFlag = pDistinct ? (WHERE_WANT_DISTINCT|WHERE_AGG_DISTINCT) : 0; } - assignAggregateRegisters(pParse, pAggInfo); /* 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. */ @@ -147015,31 +141729,29 @@ ** be an appropriate ORDER BY expression for the optimization. */ assert( minMaxFlag==WHERE_ORDERBY_NORMAL || pMinMaxOrderBy!=0 ); assert( pMinMaxOrderBy==0 || pMinMaxOrderBy->nExpr==1 ); - TREETRACE(0x2,pParse,p,("WhereBegin\n")); + SELECTTRACE(1,pParse,p,("WhereBegin\n")); pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy, - pDistinct, p, minMaxFlag|distFlag, 0); + pDistinct, 0, minMaxFlag|distFlag, 0); if( pWInfo==0 ){ goto select_end; } - TREETRACE(0x2,pParse,p,("WhereBegin returns\n")); + SELECTTRACE(1,pParse,p,("WhereBegin returns\n")); eDist = sqlite3WhereIsDistinct(pWInfo); updateAccumulator(pParse, regAcc, pAggInfo, eDist); if( eDist!=WHERE_DISTINCT_NOOP ){ - struct AggInfo_func *pF = pAggInfo->aFunc; - if( pF ){ - fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr); - } + struct AggInfo_func *pF = &pAggInfo->aFunc[0]; + fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr); } if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc); if( minMaxFlag ){ sqlite3WhereMinMaxOptEarlyOut(v, pWInfo); } - TREETRACE(0x2,pParse,p,("WhereEnd\n")); + SELECTTRACE(1,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); finalizeAggFunctions(pParse, pAggInfo); } sSort.pOrderBy = 0; @@ -147057,10 +141769,12 @@ /* If there is an ORDER BY clause, then we need to sort the results ** and send them to the callback one by one. */ if( sSort.pOrderBy ){ + explainTempTable(pParse, + sSort.nOBSat>0 ? "RIGHT PART OF ORDER BY":"ORDER BY"); assert( p->pEList==pEList ); generateSortTail(pParse, p, &sSort, pEList->nExpr, pDest); } /* Jump here to skip this query @@ -147080,11 +141794,11 @@ sqlite3ExprListDelete(db, pMinMaxOrderBy); #ifdef SQLITE_DEBUG if( pAggInfo && !db->mallocFailed ){ for(i=0; inColumn; i++){ Expr *pExpr = pAggInfo->aCol[i].pCExpr; - if( pExpr==0 ) continue; + assert( pExpr!=0 ); assert( pExpr->pAggInfo==pAggInfo ); assert( pExpr->iAgg==i ); } for(i=0; inFunc; i++){ Expr *pExpr = pAggInfo->aFunc[i].pFExpr; @@ -147093,13 +141807,13 @@ assert( pExpr->iAgg==i ); } } #endif -#if TREETRACE_ENABLED - TREETRACE(0x1,pParse,p,("end processing\n")); - if( (sqlite3TreeTrace & 0x40000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ +#if SELECTTRACE_ENABLED + SELECTTRACE(0x1,pParse,p,("end processing\n")); + if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ sqlite3TreeViewSelect(0, p, 0); } #endif ExplainQueryPlanPop(pParse); return rc; @@ -147360,27 +142074,30 @@ SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){ Schema *pTmpSchema; /* Schema of the pTab table */ Trigger *pList; /* List of triggers to return */ HashElem *p; /* Loop variable for TEMP triggers */ - assert( pParse->disableTriggers==0 ); + if( pParse->disableTriggers ){ + return 0; + } pTmpSchema = pParse->db->aDb[1].pSchema; p = sqliteHashFirst(&pTmpSchema->trigHash); pList = pTab->pTrigger; while( p ){ Trigger *pTrig = (Trigger *)sqliteHashData(p); if( pTrig->pTabSchema==pTab->pSchema && pTrig->table && 0==sqlite3StrICmp(pTrig->table, pTab->zName) - && (pTrig->pTabSchema!=pTmpSchema || pTrig->bReturning) + && pTrig->pTabSchema!=pTmpSchema ){ pTrig->pNext = pList; pList = pTrig; - }else if( pTrig->op==TK_RETURNING ){ + }else if( pTrig->op==TK_RETURNING #ifndef SQLITE_OMIT_VIRTUALTABLE - assert( pParse->db->pVtabCtx==0 ); + && pParse->db->pVtabCtx==0 #endif + ){ assert( pParse->bReturning ); assert( &(pParse->u1.pReturning->retTrig) == pTrig ); pTrig->table = pTab->zName; pTrig->pTabSchema = pTab->pSchema; pTrig->pNext = pList; @@ -147510,11 +142227,10 @@ if( !noErr ){ sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); }else{ assert( !db->init.busy ); sqlite3CodeVerifySchema(pParse, iDb); - VVA_ONLY( pParse->ifNotExists = 1; ) } goto trigger_cleanup; } } @@ -147660,27 +142376,10 @@ */ if( !db->init.busy ){ Vdbe *v; char *z; - /* If this is a new CREATE TABLE statement, and if shadow tables - ** are read-only, and the trigger makes a change to a shadow table, - ** then raise an error - do not allow the trigger to be created. */ - if( sqlite3ReadOnlyShadowTables(db) ){ - TriggerStep *pStep; - for(pStep=pTrig->step_list; pStep; pStep=pStep->pNext){ - if( pStep->zTarget!=0 - && sqlite3ShadowTableName(db, pStep->zTarget) - ){ - sqlite3ErrorMsg(pParse, - "trigger \"%s\" may not write to shadow table \"%s\"", - pTrig->zName, pStep->zTarget); - goto triggerfinish_cleanup; - } - } - } - /* Make an entry in the sqlite_schema table */ v = sqlite3GetVdbe(pParse); if( v==0 ) goto triggerfinish_cleanup; sqlite3BeginWriteOperation(pParse, 0, iDb); z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n); @@ -147840,11 +142539,11 @@ ** sees an UPDATE statement inside the body of a CREATE TRIGGER. */ SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep( Parse *pParse, /* Parser */ Token *pTableName, /* Name of the table to be updated */ - SrcList *pFrom, /* FROM clause for an UPDATE-FROM, or NULL */ + SrcList *pFrom, ExprList *pEList, /* The SET clause: list of column and new values */ Expr *pWhere, /* The WHERE clause */ u8 orconf, /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */ const char *zStart, /* Start of SQL text */ const char *zEnd /* End of SQL text */ @@ -148053,26 +142752,17 @@ if( sqlite3IdListIndex(pIdList, pEList->a[e].zEName)>=0 ) return 1; } return 0; } -/* -** Return true if any TEMP triggers exist -*/ -static int tempTriggersExist(sqlite3 *db){ - if( NEVER(db->aDb[1].pSchema==0) ) return 0; - if( sqliteHashFirst(&db->aDb[1].pSchema->trigHash)==0 ) return 0; - return 1; -} - /* ** 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. */ -static SQLITE_NOINLINE Trigger *triggersReallyExist( +SQLITE_PRIVATE Trigger *sqlite3TriggersExist( Parse *pParse, /* Parse context */ Table *pTab, /* The table the contains the triggers */ int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */ ExprList *pChanges, /* Columns that change in an UPDATE statement */ int *pMask /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */ @@ -148131,26 +142821,10 @@ if( pMask ){ *pMask = mask; } return (mask ? pList : 0); } -SQLITE_PRIVATE Trigger *sqlite3TriggersExist( - Parse *pParse, /* Parse context */ - Table *pTab, /* The table the contains the triggers */ - int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */ - ExprList *pChanges, /* Columns that change in an UPDATE statement */ - int *pMask /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */ -){ - assert( pTab!=0 ); - if( (pTab->pTrigger==0 && !tempTriggersExist(pParse->db)) - || pParse->disableTriggers - ){ - if( pMask ) *pMask = 0; - return 0; - } - return triggersReallyExist(pParse,pTab,op,pChanges,pMask); -} /* ** Convert the pStep->zTarget string into a SrcList and return a pointer ** to that SrcList. ** @@ -148176,18 +142850,10 @@ if( pSchema!=db->aDb[1].pSchema ){ pSrc->a[0].pSchema = pSchema; } if( pStep->pFrom ){ SrcList *pDup = sqlite3SrcListDup(db, pStep->pFrom, 0); - if( pDup && pDup->nSrc>1 && !IN_RENAME_OBJECT ){ - Select *pSubquery; - Token as; - pSubquery = sqlite3SelectNew(pParse,0,pDup,0,0,0,0,SF_NestedFrom,0); - as.n = 0; - as.z = 0; - pDup = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&as,pSubquery,0); - } pSrc = sqlite3SrcListAppendList(pParse, pSrc, pDup); } }else{ sqlite3DbFree(db, zName); } @@ -148239,20 +142905,20 @@ pNewExpr = sqlite3Expr(db, TK_ID, pTab->aCol[jj].zCnName); pNew = sqlite3ExprListAppend(pParse, pNew, pNewExpr); if( !db->mallocFailed ){ struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1]; pItem->zEName = sqlite3DbStrDup(db, pTab->aCol[jj].zCnName); - pItem->fg.eEName = ENAME_NAME; + pItem->eEName = ENAME_NAME; } } }else{ Expr *pNewExpr = sqlite3ExprDup(db, pOldExpr, 0); pNew = sqlite3ExprListAppend(pParse, pNew, pNewExpr); if( !db->mallocFailed && ALWAYS(pList->a[i].zEName!=0) ){ struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1]; pItem->zEName = sqlite3DbStrDup(db, pList->a[i].zEName); - pItem->fg.eEName = pList->a[i].fg.eEName; + pItem->eEName = pList->a[i].eEName; } } } return pNew; } @@ -148292,11 +142958,11 @@ assert( db->mallocFailed==0 ); sqlite3GenerateColumnNames(pParse, &sSelect); } sqlite3ExprListDelete(db, sSelect.pEList); pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab); - if( pParse->nErr==0 ){ + if( !db->mallocFailed ){ NameContext sNC; memset(&sNC, 0, sizeof(sNC)); if( pReturning->nRetCol==0 ){ pReturning->nRetCol = pNew->nExpr; pReturning->iRetCur = pParse->nTab++; @@ -148500,11 +143166,11 @@ sSubParse.pTriggerTab = pTab; sSubParse.pToplevel = pTop; sSubParse.zAuthContext = pTrigger->zName; sSubParse.eTriggerOp = pTrigger->op; sSubParse.nQueryLoop = pParse->nQueryLoop; - sSubParse.prepFlags = pParse->prepFlags; + sSubParse.disableVtab = pParse->disableVtab; v = sqlite3GetVdbe(&sSubParse); if( v ){ VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)", pTrigger->zName, onErrorText(orconf), @@ -148761,13 +143427,10 @@ const int op = pChanges ? TK_UPDATE : TK_DELETE; u32 mask = 0; Trigger *p; assert( isNew==1 || isNew==0 ); - if( IsView(pTab) ){ - return 0xffffffff; - } for(p=pTrigger; p; p=p->pNext){ if( p->op==op && (tr_tm&p->tr_tm) && checkColumnOverlap(p->pColumns,pChanges) ){ @@ -148849,18 +143512,15 @@ ** (not a virtual table) then the value might have been stored as an ** integer. In that case, add an OP_RealAffinity opcode to make sure ** it has been converted into REAL. */ SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ - Column *pCol; assert( pTab!=0 ); - assert( pTab->nCol>i ); - pCol = &pTab->aCol[i]; - if( pCol->iDflt ){ + if( !IsView(pTab) ){ sqlite3_value *pValue = 0; u8 enc = ENC(sqlite3VdbeDb(v)); - assert( !IsView(pTab) ); + Column *pCol = &pTab->aCol[i]; VdbeComment((v, "%s.%s", pTab->zName, pCol->zCnName)); assert( inCol ); sqlite3ValueFromExpr(sqlite3VdbeDb(v), sqlite3ColumnExpr(pTab,pCol), enc, pCol->affinity, &pValue); @@ -148867,11 +143527,11 @@ if( pValue ){ sqlite3VdbeAppendP4(v, pValue, P4_MEM); } } #ifndef SQLITE_OMIT_FLOATING_POINT - if( pCol->affinity==SQLITE_AFF_REAL && !IsVirtual(pTab) ){ + if( pTab->aCol[i].affinity==SQLITE_AFF_REAL && !IsVirtual(pTab) ){ sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); } #endif } @@ -149053,12 +143713,11 @@ sqlite3ExprDup(db, pChanges->a[i].pExpr, 0) ); } } pSelect = sqlite3SelectNew(pParse, pList, - pSrc, pWhere2, pGrp, 0, pOrderBy2, - SF_UFSrcCheck|SF_IncludeHidden|SF_UpdateFrom, pLimit2 + pSrc, pWhere2, pGrp, 0, pOrderBy2, SF_UFSrcCheck|SF_IncludeHidden, pLimit2 ); if( pSelect ) pSelect->selFlags |= SF_OrderByReqd; sqlite3SelectDestInit(&dest, eDest, iEph); dest.iSDParm2 = (pPk ? pPk->nKeyCol : -1); sqlite3Select(pParse, pSelect, &dest); @@ -149170,18 +143829,10 @@ #ifdef SQLITE_OMIT_VIEW # undef isView # define isView 0 #endif -#if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x10000 ){ - sqlite3TreeViewLine(0, "In sqlite3Update() at %s:%d", __FILE__, __LINE__); - sqlite3TreeViewUpdate(pParse->pWith, pTabList, pChanges, pWhere, - onError, pOrderBy, pLimit, pUpsert, pTrigger); - } -#endif - /* If there was a FROM clause, set nChangeFrom to the number of expressions ** in the change-list. Otherwise, set it to 0. There cannot be a FROM ** clause if this function is being called to generate code for part of ** an UPSERT statement. */ nChangeFrom = (pTabList->nSrc>1) ? pChanges->nExpr : 0; @@ -149198,11 +143849,11 @@ #endif if( sqlite3ViewGetColumnNames(pParse, pTab) ){ goto update_cleanup; } - if( sqlite3IsReadOnly(pParse, pTab, pTrigger) ){ + if( sqlite3IsReadOnly(pParse, pTab, tmask) ){ goto update_cleanup; } /* 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 @@ -149517,26 +144168,16 @@ bFinishSeek = 0; }else{ /* Begin the database scan. ** ** Do not consider a single-pass strategy for a multi-row update if - ** there is anything that might disrupt the cursor being used to do - ** the UPDATE: - ** (1) This is a nested UPDATE - ** (2) There are triggers - ** (3) There are FOREIGN KEY constraints - ** (4) There are REPLACE conflict handlers - ** (5) There are subqueries in the WHERE clause - */ + ** there are any triggers or foreign keys to process, or rows may + ** be deleted as a result of REPLACE conflict handling. Any of these + ** things might disturb a cursor being used to scan through the table + ** or index, causing a single-pass approach to malfunction. */ flags = WHERE_ONEPASS_DESIRED; - if( !pParse->nested - && !pTrigger - && !hasFK - && !chngKey - && !bReplace - && (sNC.ncFlags & NC_Subquery)==0 - ){ + if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){ flags |= WHERE_ONEPASS_MULTIROW; } pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0,0,0,flags,iIdxCur); if( pWInfo==0 ) goto update_cleanup; @@ -149832,11 +144473,11 @@ if( pPk ){ sqlite3VdbeAddOp4Int(v, OP_NotFound,iDataCur,labelContinue,regKey,nKey); }else{ sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue,regOldRowid); } - VdbeCoverage(v); + VdbeCoverageNeverTaken(v); } /* Do FK constraint checks. */ if( hasFK ){ sqlite3FkCheck(pParse, pTab, regOldRowid, 0, aXRef, chngKey); @@ -150318,11 +144959,10 @@ Expr *pExpr; sCol[0].u.zToken = (char*)pIdx->azColl[ii]; if( pIdx->aiColumn[ii]==XN_EXPR ){ assert( pIdx->aColExpr!=0 ); assert( pIdx->aColExpr->nExpr>ii ); - assert( pIdx->bHasExpr ); pExpr = pIdx->aColExpr->a[ii].pExpr; if( pExpr->op!=TK_COLLATE ){ sCol[0].pLeft = pExpr; pExpr = &sCol[0]; } @@ -150632,11 +145272,10 @@ int isMemDb; /* True if vacuuming a :memory: database */ int nRes; /* Bytes of reserved space at the end of each page */ int nDb; /* Number of attached databases */ const char *zDbMain; /* Schema name of database to vacuum */ const char *zOut; /* Name of output file */ - u32 pgflags = PAGER_SYNCHRONOUS_OFF; /* sync flags for output db */ if( !db->autoCommit ){ sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction"); return SQLITE_ERROR; /* IMP: R-12218-18073 */ } @@ -150704,21 +145343,16 @@ rc = SQLITE_ERROR; sqlite3SetString(pzErrMsg, db, "output file already exists"); goto end_of_vacuum; } db->mDbFlags |= DBFLAG_VacuumInto; - - /* For a VACUUM INTO, the pager-flags are set to the same values as - ** they are for the database being vacuumed, except that PAGER_CACHESPILL - ** is always set. */ - pgflags = db->aDb[iDb].safety_level | (db->flags & PAGER_FLAGS_MASK); } nRes = sqlite3BtreeGetRequestedReserve(pMain); sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size); sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0)); - sqlite3BtreeSetPagerFlags(pTemp, pgflags|PAGER_CACHESPILL); + sqlite3BtreeSetPagerFlags(pTemp, PAGER_SYNCHRONOUS_OFF|PAGER_CACHESPILL); /* Begin a transaction and take an exclusive lock on the main database ** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below, ** to ensure that we do not try to change the page-size on a WAL database. */ @@ -150845,11 +145479,10 @@ #endif } assert( rc==SQLITE_OK ); if( pOut==0 ){ - nRes = sqlite3BtreeGetRequestedReserve(pTemp); rc = sqlite3BtreeSetPageSize(pMain, sqlite3BtreeGetPageSize(pTemp), nRes,1); } end_of_vacuum: /* Restore the original value of db->flags */ @@ -151098,14 +145731,14 @@ || db->eOpenState==SQLITE_STATE_ZOMBIE ); pVTab->nRef--; if( pVTab->nRef==0 ){ sqlite3_vtab *p = pVTab->pVtab; + sqlite3VtabModuleUnref(pVTab->db, pVTab->pMod); if( p ){ p->pModule->xDisconnect(p); } - sqlite3VtabModuleUnref(pVTab->db, pVTab->pMod); sqlite3DbFree(db, pVTab); } } /* @@ -151227,12 +145860,11 @@ ** in the list are moved to the sqlite3.pDisconnect list of the associated ** database connection. */ SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table *p){ assert( IsVirtual(p) ); - assert( db!=0 ); - if( db->pnBytesFreed==0 ) vtabDisconnectAll(0, p); + if( !db || db->pnBytesFreed==0 ) vtabDisconnectAll(0, p); if( p->u.vtab.azArg ){ int i; for(i=0; iu.vtab.nArg; i++){ if( i!=1 ) sqlite3DbFree(db, p->u.vtab.azArg[i]); } @@ -151497,13 +146129,11 @@ sCtx.pTab = pTab; sCtx.pVTable = pVTable; sCtx.pPrior = db->pVtabCtx; sCtx.bDeclared = 0; db->pVtabCtx = &sCtx; - pTab->nTabRef++; rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); - sqlite3DeleteTable(db, pTab); db->pVtabCtx = sCtx.pPrior; if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); assert( sCtx.pTab==pTab ); if( SQLITE_OK!=rc ){ @@ -152030,11 +146660,11 @@ /* Check to see the left operand is a column in a virtual table */ if( NEVER(pExpr==0) ) return pDef; if( pExpr->op!=TK_COLUMN ) return pDef; assert( ExprUseYTab(pExpr) ); pTab = pExpr->y.pTab; - if( NEVER(pTab==0) ) return pDef; + if( pTab==0 ) return pDef; if( !IsVirtual(pTab) ) return pDef; pVtab = sqlite3GetVTable(db, pTab)->pVtab; assert( pVtab!=0 ); assert( pVtab->pModule!=0 ); pMod = (sqlite3_module *)pVtab->pModule; @@ -152218,14 +146848,10 @@ } case SQLITE_VTAB_DIRECTONLY: { p->pVTable->eVtabRisk = SQLITE_VTABRISK_High; break; } - case SQLITE_VTAB_USES_ALL_SCHEMAS: { - p->pVTable->bAllSchemas = 1; - break; - } default: { rc = SQLITE_MISUSE_BKPT; break; } } @@ -152295,32 +146921,10 @@ typedef struct WhereTerm WhereTerm; typedef struct WhereLoopBuilder WhereLoopBuilder; typedef struct WhereScan WhereScan; typedef struct WhereOrCost WhereOrCost; typedef struct WhereOrSet WhereOrSet; -typedef struct WhereMemBlock WhereMemBlock; -typedef struct WhereRightJoin WhereRightJoin; - -/* -** This object is a header on a block of allocated memory that will be -** automatically freed when its WInfo oject is destructed. -*/ -struct WhereMemBlock { - WhereMemBlock *pNext; /* Next block in the chain */ - u64 sz; /* Bytes of space */ -}; - -/* -** Extra information attached to a WhereLevel that is a RIGHT JOIN. -*/ -struct WhereRightJoin { - int iMatch; /* Cursor used to determine prior matched rows */ - int regBloom; /* Bloom filter for iRJMatch */ - int regReturn; /* Return register for the interior subroutine */ - int addrSubrtn; /* Starting address for the interior subroutine */ - int endSubrtn; /* The last opcode in the interior subroutine */ -}; /* ** This object contains information needed to implement a single nested ** loop in WHERE clause. ** @@ -152350,11 +146954,10 @@ #ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS u32 iLikeRepCntr; /* LIKE range processing counter register (times 2) */ int addrLikeRep; /* LIKE range processing address */ #endif int regFilter; /* Bloom filter */ - WhereRightJoin *pRJ; /* Extra information for RIGHT JOIN */ u8 iFrom; /* Which entry in the FROM clause */ u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */ int p1, p2; /* Operands of the opcode used to end the loop */ union { /* Information that depends on pWLoop->wsFlags */ struct { @@ -152641,11 +147244,11 @@ /* ** 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 -** SrcItem.iCursor and Expr.iTable fields. For any given WHERE +** 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. @@ -152712,10 +147315,24 @@ #endif #ifndef SQLITE_QUERY_PLANNER_LIMIT_INCR # define SQLITE_QUERY_PLANNER_LIMIT_INCR 1000 #endif +/* +** Each instance of this object records a change to a single node +** in an expression tree to cause that node to point to a column +** of an index rather than an expression or a virtual column. All +** such transformations need to be undone at the end of WHERE clause +** processing. +*/ +typedef struct WhereExprMod WhereExprMod; +struct WhereExprMod { + WhereExprMod *pNext; /* Next translation on a list of them all */ + Expr *pExpr; /* The Expr node that was transformed */ + Expr orig; /* Original value of the Expr node */ +}; + /* ** 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 @@ -152727,14 +147344,14 @@ struct WhereInfo { Parse *pParse; /* Parsing and code generating context */ SrcList *pTabList; /* List of tables in the join */ ExprList *pOrderBy; /* The ORDER BY clause or NULL */ ExprList *pResultSet; /* Result set of the query */ -#if WHERETRACE_ENABLED Expr *pWhere; /* The complete WHERE clause */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + Select *pLimit; /* Used to access LIMIT expr/registers for vtabs */ #endif - Select *pSelect; /* The entire SELECT statement containing WHERE */ int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */ int iContinue; /* Jump here to continue with next record */ int iBreak; /* Jump here to break out of the loop */ int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */ u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */ @@ -152749,11 +147366,11 @@ unsigned sorted :1; /* True if really sorted (not just grouped) */ LogEst nRowOut; /* Estimated number of output rows */ int iTop; /* The very beginning of the WHERE loop */ int iEndWhere; /* End of the WHERE clause itself */ WhereLoop *pLoops; /* List of all WhereLoop objects */ - WhereMemBlock *pMemToFree;/* Memory to free when this object destroyed */ + WhereExprMod *pExprMods; /* Expression modifications */ Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ WhereClause sWC; /* Decomposition of the WHERE clause */ WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */ WhereLevel a[1]; /* Information about each nest loop in WHERE */ }; @@ -152775,12 +147392,10 @@ 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 */ ); -SQLITE_PRIVATE void *sqlite3WhereMalloc(WhereInfo *pWInfo, u64 nByte); -SQLITE_PRIVATE void *sqlite3WhereRealloc(WhereInfo *pWInfo, void *pOld, u64 nByte); /* wherecode.c: */ #ifndef SQLITE_OMIT_EXPLAIN SQLITE_PRIVATE int sqlite3WhereExplainOneScan( Parse *pParse, /* Parse context */ @@ -152813,15 +147428,10 @@ WhereInfo *pWInfo, /* Complete information about the WHERE clause */ int iLevel, /* Which level of pWInfo->a[] should be coded */ WhereLevel *pLevel, /* The current level pointer */ Bitmask notReady /* Which tables are currently available */ ); -SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( - WhereInfo *pWInfo, - int iLevel, - WhereLevel *pLevel -); /* whereexpr.c: */ SQLITE_PRIVATE void sqlite3WhereClauseInit(WhereClause*,WhereInfo*); SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause*); SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause*,Expr*,u8); @@ -152860,13 +147470,12 @@ #define WO_ISNULL 0x0100 #define WO_OR 0x0200 /* Two or more OR-connected terms */ #define WO_AND 0x0400 /* Two or more AND-connected terms */ #define WO_EQUIV 0x0800 /* Of the form A==B, both columns */ #define WO_NOOP 0x1000 /* This term does not restrict search space */ -#define WO_ROWVAL 0x2000 /* A row-value term */ -#define WO_ALL 0x3fff /* Mask of all possible WO_* values */ +#define WO_ALL 0x1fff /* Mask of all possible WO_* values */ #define WO_SINGLE 0x01ff /* Mask of all non-compound WO_* values */ /* ** These are definitions of bits in the WhereLoop.wsFlags field. ** The particular combination of bits in each WhereLoop help to @@ -152896,12 +147505,10 @@ #define WHERE_IN_SEEKSCAN 0x00100000 /* Seek-scan optimization for IN */ #define WHERE_TRANSCONS 0x00200000 /* Uses a transitive constraint */ #define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */ #define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */ #define WHERE_OMIT_OFFSET 0x01000000 /* Set offset counter to zero */ -#define WHERE_VIEWSCAN 0x02000000 /* A full-scan of a VIEW or subquery */ -#define WHERE_EXPRIDX 0x04000000 /* Uses an index-on-expressions */ #endif /* !defined(SQLITE_WHEREINT_H) */ /************** End of whereInt.h ********************************************/ /************** Continuing where we left off in wherecode.c ******************/ @@ -152995,13 +147602,13 @@ sqlite3_str_append(pStr, ")", 1); } /* ** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN -** command, or if stmt_scanstatus_v2() stats are enabled, or if SQLITE_DEBUG -** was defined at compile-time. If it is not a no-op, a single OP_Explain -** opcode is added to the output to describe the table scan strategy in pLevel. +** command, or if either SQLITE_DEBUG or SQLITE_ENABLE_STMT_SCANSTATUS was +** defined at compile-time. If it is not a no-op, a single OP_Explain opcode +** is added to the output to describe the table scan strategy in pLevel. ** ** If an OP_Explain opcode is added to the VM, its address is returned. ** Otherwise, if no OP_Explain is coded, zero is returned. */ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( @@ -153009,12 +147616,12 @@ SrcList *pTabList, /* Table list this loop refers to */ WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ ){ int ret = 0; -#if !defined(SQLITE_DEBUG) - if( sqlite3ParseToplevel(pParse)->explain==2 || IS_STMT_SCANSTATUS(pParse->db) ) +#if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS) + if( sqlite3ParseToplevel(pParse)->explain==2 ) #endif { SrcItem *pItem = &pTabList->a[pLevel->iFrom]; Vdbe *v = pParse->pVdbe; /* VM being constructed */ sqlite3 *db = pParse->db; /* Database handle */ @@ -153088,13 +147695,10 @@ else if( (flags & WHERE_VIRTUALTABLE)!=0 ){ sqlite3_str_appendf(&str, " VIRTUAL TABLE INDEX %d:%s", pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr); } #endif - if( pItem->fg.jointype & JT_LEFT ){ - sqlite3_str_appendf(&str, " LEFT-JOIN"); - } #ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS if( pLoop->nOut>=10 ){ sqlite3_str_appendf(&str, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut)); }else{ @@ -153154,12 +147758,10 @@ } sqlite3_str_append(&str, ")", 1); zMsg = sqlite3StrAccumFinish(&str); ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v), pParse->addrExplain, 0, zMsg,P4_DYNAMIC); - - sqlite3VdbeScanStatus(v, sqlite3VdbeCurrentAddr(v)-1, 0, 0, 0, 0); return ret; } #endif /* SQLITE_OMIT_EXPLAIN */ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS @@ -153176,35 +147778,20 @@ Vdbe *v, /* Vdbe to add scanstatus entry to */ SrcList *pSrclist, /* FROM clause pLvl reads data from */ WhereLevel *pLvl, /* Level to add scanstatus() entry for */ int addrExplain /* Address of OP_Explain (or 0) */ ){ - if( IS_STMT_SCANSTATUS( sqlite3VdbeDb(v) ) ){ - const char *zObj = 0; - WhereLoop *pLoop = pLvl->pWLoop; - int wsFlags = pLoop->wsFlags; - int viaCoroutine = 0; - - if( (wsFlags & WHERE_VIRTUALTABLE)==0 && pLoop->u.btree.pIndex!=0 ){ - zObj = pLoop->u.btree.pIndex->zName; - }else{ - zObj = pSrclist->a[pLvl->iFrom].zName; - viaCoroutine = pSrclist->a[pLvl->iFrom].fg.viaCoroutine; - } - sqlite3VdbeScanStatus( - v, addrExplain, pLvl->addrBody, pLvl->addrVisit, pLoop->nOut, zObj - ); - - if( viaCoroutine==0 ){ - if( (wsFlags & (WHERE_MULTI_OR|WHERE_AUTO_INDEX))==0 ){ - sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iTabCur); - } - if( wsFlags & WHERE_INDEXED ){ - sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iIdxCur); - } - } - } + const char *zObj = 0; + WhereLoop *pLoop = pLvl->pWLoop; + if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 && pLoop->u.btree.pIndex!=0 ){ + zObj = pLoop->u.btree.pIndex->zName; + }else{ + zObj = pSrclist->a[pLvl->iFrom].zName; + } + sqlite3VdbeScanStatus( + v, addrExplain, pLvl->addrBody, pLvl->addrVisit, pLoop->nOut, zObj + ); } #endif /* @@ -153251,20 +147838,20 @@ */ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){ int nLoop = 0; assert( pTerm!=0 ); while( (pTerm->wtFlags & TERM_CODED)==0 - && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_OuterON)) + && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin)) && (pLevel->notReady & pTerm->prereqAll)==0 ){ if( nLoop && (pTerm->wtFlags & TERM_LIKE)!=0 ){ pTerm->wtFlags |= TERM_LIKECOND; }else{ pTerm->wtFlags |= TERM_CODED; } #ifdef WHERETRACE_ENABLED - if( (sqlite3WhereTrace & 0x4001)==0x4001 ){ + if( sqlite3WhereTrace & 0x20000 ){ sqlite3DebugPrintf("DISABLE-"); sqlite3WhereTermPrint(pTerm, (int)(pTerm - (pTerm->pWC->a))); } #endif if( pTerm->iParent<0 ) break; @@ -153375,79 +147962,72 @@ int iEq, /* Look at loop terms starting here */ WhereLoop *pLoop, /* The current loop */ Expr *pX /* The IN expression to be reduced */ ){ sqlite3 *db = pParse->db; - Select *pSelect; /* Pointer to the SELECT on the RHS */ Expr *pNew; pNew = sqlite3ExprDup(db, pX, 0); if( db->mallocFailed==0 ){ - for(pSelect=pNew->x.pSelect; pSelect; pSelect=pSelect->pPrior){ - ExprList *pOrigRhs; /* Original unmodified RHS */ - ExprList *pOrigLhs = 0; /* Original unmodified LHS */ - ExprList *pRhs = 0; /* New RHS after modifications */ - ExprList *pLhs = 0; /* New LHS after mods */ - int i; /* Loop counter */ - - assert( ExprUseXSelect(pNew) ); - pOrigRhs = pSelect->pEList; - assert( pNew->pLeft!=0 ); - assert( ExprUseXList(pNew->pLeft) ); - if( pSelect==pNew->x.pSelect ){ - pOrigLhs = pNew->pLeft->x.pList; - } - for(i=iEq; inLTerm; i++){ - if( pLoop->aLTerm[i]->pExpr==pX ){ - int iField; - assert( (pLoop->aLTerm[i]->eOperator & (WO_OR|WO_AND))==0 ); - iField = pLoop->aLTerm[i]->u.x.iField - 1; - if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */ - pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr); - pOrigRhs->a[iField].pExpr = 0; - if( pOrigLhs ){ - assert( pOrigLhs->a[iField].pExpr!=0 ); - pLhs = sqlite3ExprListAppend(pParse,pLhs,pOrigLhs->a[iField].pExpr); - pOrigLhs->a[iField].pExpr = 0; - } - } - } - sqlite3ExprListDelete(db, pOrigRhs); - if( pOrigLhs ){ - sqlite3ExprListDelete(db, pOrigLhs); - pNew->pLeft->x.pList = pLhs; - } - pSelect->pEList = pRhs; - if( pLhs && pLhs->nExpr==1 ){ - /* Take care here not to generate a TK_VECTOR containing only a - ** single value. Since the parser never creates such a vector, some - ** of the subroutines do not handle this case. */ - Expr *p = pLhs->a[0].pExpr; - pLhs->a[0].pExpr = 0; - sqlite3ExprDelete(db, pNew->pLeft); - pNew->pLeft = p; - } - if( pSelect->pOrderBy ){ - /* If the SELECT statement has an ORDER BY clause, zero the - ** iOrderByCol variables. These are set to non-zero when an - ** ORDER BY term exactly matches one of the terms of the - ** result-set. Since the result-set of the SELECT statement may - ** have been modified or reordered, these variables are no longer - ** set correctly. Since setting them is just an optimization, - ** it's easiest just to zero them here. */ - ExprList *pOrderBy = pSelect->pOrderBy; - for(i=0; inExpr; i++){ - pOrderBy->a[i].u.x.iOrderByCol = 0; - } - } + ExprList *pOrigRhs; /* Original unmodified RHS */ + ExprList *pOrigLhs; /* Original unmodified LHS */ + ExprList *pRhs = 0; /* New RHS after modifications */ + ExprList *pLhs = 0; /* New LHS after mods */ + int i; /* Loop counter */ + Select *pSelect; /* Pointer to the SELECT on the RHS */ + + assert( ExprUseXSelect(pNew) ); + pOrigRhs = pNew->x.pSelect->pEList; + assert( pNew->pLeft!=0 ); + assert( ExprUseXList(pNew->pLeft) ); + pOrigLhs = pNew->pLeft->x.pList; + for(i=iEq; inLTerm; i++){ + if( pLoop->aLTerm[i]->pExpr==pX ){ + int iField; + assert( (pLoop->aLTerm[i]->eOperator & (WO_OR|WO_AND))==0 ); + iField = pLoop->aLTerm[i]->u.x.iField - 1; + if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */ + pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr); + pOrigRhs->a[iField].pExpr = 0; + assert( pOrigLhs->a[iField].pExpr!=0 ); + pLhs = sqlite3ExprListAppend(pParse, pLhs, pOrigLhs->a[iField].pExpr); + pOrigLhs->a[iField].pExpr = 0; + } + } + sqlite3ExprListDelete(db, pOrigRhs); + sqlite3ExprListDelete(db, pOrigLhs); + pNew->pLeft->x.pList = pLhs; + pNew->x.pSelect->pEList = pRhs; + if( pLhs && pLhs->nExpr==1 ){ + /* Take care here not to generate a TK_VECTOR containing only a + ** single value. Since the parser never creates such a vector, some + ** of the subroutines do not handle this case. */ + Expr *p = pLhs->a[0].pExpr; + pLhs->a[0].pExpr = 0; + sqlite3ExprDelete(db, pNew->pLeft); + pNew->pLeft = p; + } + pSelect = pNew->x.pSelect; + if( pSelect->pOrderBy ){ + /* If the SELECT statement has an ORDER BY clause, zero the + ** iOrderByCol variables. These are set to non-zero when an + ** ORDER BY term exactly matches one of the terms of the + ** result-set. Since the result-set of the SELECT statement may + ** have been modified or reordered, these variables are no longer + ** set correctly. Since setting them is just an optimization, + ** it's easiest just to zero them here. */ + ExprList *pOrderBy = pSelect->pOrderBy; + for(i=0; inExpr; i++){ + pOrderBy->a[i].u.x.iOrderByCol = 0; + } + } #if 0 - printf("For indexing, change the IN expr:\n"); - sqlite3TreeViewExpr(0, pX, 0); - printf("Into:\n"); - sqlite3TreeViewExpr(0, pNew, 0); + printf("For indexing, change the IN expr:\n"); + sqlite3TreeViewExpr(0, pX, 0); + printf("Into:\n"); + sqlite3TreeViewExpr(0, pNew, 0); #endif - } } return pNew; } @@ -153519,26 +148099,20 @@ iTab = 0; if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){ eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); }else{ - Expr *pExpr = pTerm->pExpr; - if( pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){ - sqlite3 *db = pParse->db; - pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); - if( !db->mallocFailed ){ - aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab); - pExpr->iTable = iTab; - } - sqlite3ExprDelete(db, pX); - }else{ - int n = sqlite3ExprVectorSize(pX->pLeft); - aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*MAX(nEq,n)); + sqlite3 *db = pParse->db; + pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); + + if( !db->mallocFailed ){ + aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab); + pTerm->pExpr->iTable = iTab; } - pX = pExpr; + sqlite3ExprDelete(db, pX); + pX = pTerm->pExpr; } if( eType==IN_INDEX_INDEX_DESC ){ testcase( bRev ); bRev = !bRev; @@ -153557,13 +148131,12 @@ } i = pLevel->u.in.nIn; pLevel->u.in.nIn += nEq; pLevel->u.in.aInLoop = - sqlite3WhereRealloc(pTerm->pWC->pWInfo, - pLevel->u.in.aInLoop, - sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn); + sqlite3DbReallocOrFree(pParse->db, pLevel->u.in.aInLoop, + sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn); pIn = pLevel->u.in.aInLoop; if( pIn ){ int iMap = 0; /* Index in aiMap[] */ pIn += i; for(i=iEq;inLTerm; i++){ @@ -153801,11 +148374,11 @@ WhereTerm *pTerm /* The upper or lower bound just coded */ ){ if( pTerm->wtFlags & TERM_LIKEOPT ){ VdbeOp *pOp; assert( pLevel->iLikeRepCntr>0 ); - pOp = sqlite3VdbeGetLastOp(v); + pOp = sqlite3VdbeGetOp(v, -1); assert( pOp!=0 ); assert( pOp->opcode==OP_String8 || pTerm->pWC->pWInfo->pParse->db->mallocFailed ); pOp->p3 = (int)(pLevel->iLikeRepCntr>>1); /* Register holding counter */ pOp->p5 = (u8)(pLevel->iLikeRepCntr&1); /* ASC or DESC */ @@ -153895,29 +148468,31 @@ ** know because CCurHint.pIdx!=0) then transform the TK_COLUMN into ** an access of the index rather than the original table. */ static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){ int rc = WRC_Continue; - int reg; struct CCurHint *pHint = pWalker->u.pCCurHint; if( pExpr->op==TK_COLUMN ){ if( pExpr->iTable!=pHint->iTabCur ){ - reg = ++pWalker->pParse->nMem; /* Register for column value */ - reg = sqlite3ExprCodeTarget(pWalker->pParse, pExpr, reg); + int reg = ++pWalker->pParse->nMem; /* Register for column value */ + sqlite3ExprCode(pWalker->pParse, pExpr, reg); pExpr->op = TK_REGISTER; pExpr->iTable = reg; }else if( pHint->pIdx!=0 ){ pExpr->iTable = pHint->iIdxCur; pExpr->iColumn = sqlite3TableColumnToIndex(pHint->pIdx, pExpr->iColumn); assert( pExpr->iColumn>=0 ); } - }else if( pExpr->pAggInfo ){ + }else if( pExpr->op==TK_AGG_FUNCTION ){ + /* An aggregate function in the WHERE clause of a query means this must + ** be a correlated sub-query, and expression pExpr is an aggregate from + ** the parent context. Do not walk the function arguments in this case. + ** + ** todo: It should be possible to replace this node with a TK_REGISTER + ** expression, as the result of the expression must be stored in a + ** register at this point. The same holds for TK_AGG_COLUMN nodes. */ rc = WRC_Prune; - reg = ++pWalker->pParse->nMem; /* Register for column value */ - reg = sqlite3ExprCodeTarget(pWalker->pParse, pExpr, reg); - pExpr->op = TK_REGISTER; - pExpr->iTable = reg; } return rc; } /* @@ -153978,20 +148553,20 @@ ** ** are also excluded. See codeCursorHintIsOrFunction() for details. */ if( pTabItem->fg.jointype & JT_LEFT ){ Expr *pExpr = pTerm->pExpr; - if( !ExprHasProperty(pExpr, EP_OuterON) - || pExpr->w.iJoin!=pTabItem->iCursor + if( !ExprHasProperty(pExpr, EP_FromJoin) + || pExpr->w.iRightJoinTable!=pTabItem->iCursor ){ sWalker.eCode = 0; sWalker.xExprCallback = codeCursorHintIsOrFunction; sqlite3WalkExpr(&sWalker, pTerm->pExpr); if( sWalker.eCode ) continue; } }else{ - if( ExprHasProperty(pTerm->pExpr, EP_OuterON) ) continue; + if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue; } /* All terms in pWLoop->aLTerm[] except pEndRange are used to initialize ** the cursor. These terms are not needed as hints for a pure range ** scan (that has no == terms) so omit them. */ @@ -154015,11 +148590,11 @@ /* If we survive all prior tests, that means this term is worth hinting */ pExpr = sqlite3ExprAnd(pParse, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0)); } if( pExpr!=0 ){ sWalker.xExprCallback = codeCursorHintFixExpr; - if( pParse->nErr==0 ) sqlite3WalkExpr(&sWalker, pExpr); + sqlite3WalkExpr(&sWalker, pExpr); sqlite3VdbeAddOp4(v, OP_CursorHint, (sHint.pIdx ? sHint.iIdxCur : sHint.iTabCur), 0, 0, (const char*)pExpr, P4_EXPR); } } @@ -154035,25 +148610,17 @@ ** ** Normally, this is just: ** ** OP_DeferredSeek $iCur $iRowid ** -** Which causes a seek on $iCur to the row with rowid $iRowid. -** ** However, if the scan currently being coded is a branch of an OR-loop and -** the statement currently being coded is a SELECT, then additional information -** is added that might allow OP_Column to omit the seek and instead do its -** lookup on the index, thus avoiding an expensive seek operation. To -** enable this optimization, the P3 of OP_DeferredSeek is set to iIdxCur -** and P4 is set to an array of integers containing one entry for each column -** in the table. For each table column, if the column is the i'th -** column of the index, then the corresponding array entry is set to (i+1). -** If the column does not appear in the index at all, the array entry is set -** to 0. The OP_Column opcode can check this array to see if the column it -** wants is in the index and if it is, it will substitute the index cursor -** and column number and continue with those new values, rather than seeking -** the table cursor. +** the statement currently being coded is a SELECT, then P3 of OP_DeferredSeek +** is set to iIdxCur and P4 is set to point to an array of integers +** containing one entry for each column of the table cursor iCur is open +** on. For each table column, if the column is the i'th column of the +** index, then the corresponding array entry is set to (i+1). If the column +** does not appear in the index at all, the array entry is set to 0. */ static void codeDeferredSeek( WhereInfo *pWInfo, /* Where clause context */ Index *pIdx, /* Index scan is using */ int iCur, /* Cursor for IPK b-tree */ @@ -154065,11 +148632,11 @@ assert( iIdxCur>0 ); assert( pIdx->aiColumn[pIdx->nColumn-1]==-1 ); pWInfo->bDeferredSeek = 1; sqlite3VdbeAddOp3(v, OP_DeferredSeek, iIdxCur, 0, iCur); - if( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN)) + if( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE) && DbMaskAllZero(sqlite3ParseToplevel(pParse)->writeMask) ){ int i; Table *pTab = pIdx->pTable; u32 *ai = (u32*)sqlite3DbMallocZero(pParse->db, sizeof(u32)*(pTab->nCol+1)); @@ -154122,10 +148689,148 @@ }else{ assert( nReg==1 || pParse->nErr ); sqlite3ExprCode(pParse, p, iReg); } } + +/* An instance of the IdxExprTrans object carries information about a +** mapping from an expression on table columns into a column in an index +** down through the Walker. +*/ +typedef struct IdxExprTrans { + Expr *pIdxExpr; /* The index expression */ + int iTabCur; /* The cursor of the corresponding table */ + int iIdxCur; /* The cursor for the index */ + int iIdxCol; /* The column for the index */ + int iTabCol; /* The column for the table */ + WhereInfo *pWInfo; /* Complete WHERE clause information */ + sqlite3 *db; /* Database connection (for malloc()) */ +} IdxExprTrans; + +/* +** Preserve pExpr on the WhereETrans list of the WhereInfo. +*/ +static void preserveExpr(IdxExprTrans *pTrans, Expr *pExpr){ + WhereExprMod *pNew; + pNew = sqlite3DbMallocRaw(pTrans->db, sizeof(*pNew)); + if( pNew==0 ) return; + pNew->pNext = pTrans->pWInfo->pExprMods; + pTrans->pWInfo->pExprMods = pNew; + pNew->pExpr = pExpr; + memcpy(&pNew->orig, pExpr, sizeof(*pExpr)); +} + +/* The walker node callback used to transform matching expressions into +** a reference to an index column for an index on an expression. +** +** If pExpr matches, then transform it into a reference to the index column +** that contains the value of pExpr. +*/ +static int whereIndexExprTransNode(Walker *p, Expr *pExpr){ + IdxExprTrans *pX = p->u.pIdxTrans; + if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){ + pExpr = sqlite3ExprSkipCollate(pExpr); + preserveExpr(pX, pExpr); + pExpr->affExpr = sqlite3ExprAffinity(pExpr); + pExpr->op = TK_COLUMN; + pExpr->iTable = pX->iIdxCur; + pExpr->iColumn = pX->iIdxCol; + testcase( ExprHasProperty(pExpr, EP_Skip) ); + testcase( ExprHasProperty(pExpr, EP_Unlikely) ); + ExprClearProperty(pExpr, EP_Skip|EP_Unlikely|EP_WinFunc|EP_Subrtn); + pExpr->y.pTab = 0; + return WRC_Prune; + }else{ + return WRC_Continue; + } +} + +#ifndef SQLITE_OMIT_GENERATED_COLUMNS +/* A walker node callback that translates a column reference to a table +** into a corresponding column reference of an index. +*/ +static int whereIndexExprTransColumn(Walker *p, Expr *pExpr){ + if( pExpr->op==TK_COLUMN ){ + IdxExprTrans *pX = p->u.pIdxTrans; + if( pExpr->iTable==pX->iTabCur && pExpr->iColumn==pX->iTabCol ){ + assert( ExprUseYTab(pExpr) && pExpr->y.pTab!=0 ); + preserveExpr(pX, pExpr); + pExpr->affExpr = sqlite3TableColumnAffinity(pExpr->y.pTab,pExpr->iColumn); + pExpr->iTable = pX->iIdxCur; + pExpr->iColumn = pX->iIdxCol; + pExpr->y.pTab = 0; + } + } + return WRC_Continue; +} +#endif /* SQLITE_OMIT_GENERATED_COLUMNS */ + +/* +** For an indexes on expression X, locate every instance of expression X +** in pExpr and change that subexpression into a reference to the appropriate +** column of the index. +** +** 2019-10-24: Updated to also translate references to a VIRTUAL column in +** the table into references to the corresponding (stored) column of the +** index. +*/ +static void whereIndexExprTrans( + Index *pIdx, /* The Index */ + int iTabCur, /* Cursor of the table that is being indexed */ + int iIdxCur, /* Cursor of the index itself */ + WhereInfo *pWInfo /* Transform expressions in this WHERE clause */ +){ + int iIdxCol; /* Column number of the index */ + ExprList *aColExpr; /* Expressions that are indexed */ + Table *pTab; + Walker w; + IdxExprTrans x; + aColExpr = pIdx->aColExpr; + if( aColExpr==0 && !pIdx->bHasVCol ){ + /* The index does not reference any expressions or virtual columns + ** so no translations are needed. */ + return; + } + pTab = pIdx->pTable; + memset(&w, 0, sizeof(w)); + w.u.pIdxTrans = &x; + x.iTabCur = iTabCur; + x.iIdxCur = iIdxCur; + x.pWInfo = pWInfo; + x.db = pWInfo->pParse->db; + for(iIdxCol=0; iIdxColnColumn; iIdxCol++){ + i16 iRef = pIdx->aiColumn[iIdxCol]; + if( iRef==XN_EXPR ){ + assert( aColExpr!=0 && aColExpr->a[iIdxCol].pExpr!=0 ); + x.pIdxExpr = aColExpr->a[iIdxCol].pExpr; + if( sqlite3ExprIsConstant(x.pIdxExpr) ) continue; + w.xExprCallback = whereIndexExprTransNode; +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + }else if( iRef>=0 + && (pTab->aCol[iRef].colFlags & COLFLAG_VIRTUAL)!=0 + && ((pTab->aCol[iRef].colFlags & COLFLAG_HASCOLL)==0 + || sqlite3StrICmp(sqlite3ColumnColl(&pTab->aCol[iRef]), + sqlite3StrBINARY)==0) + ){ + /* Check to see if there are direct references to generated columns + ** that are contained in the index. Pulling the generated column + ** out of the index is an optimization only - the main table is always + ** available if the index cannot be used. To avoid unnecessary + ** complication, omit this optimization if the collating sequence for + ** the column is non-standard */ + x.iTabCol = iRef; + w.xExprCallback = whereIndexExprTransColumn; +#endif /* SQLITE_OMIT_GENERATED_COLUMNS */ + }else{ + continue; + } + x.iIdxCol = iIdxCol; + sqlite3WalkExpr(&w, pWInfo->pWhere); + sqlite3WalkExprList(&w, pWInfo->pOrderBy); + sqlite3WalkExprList(&w, pWInfo->pResultSet); + } +} /* ** The pTruth expression is always true because it is the WHERE clause ** a partial index that is driving a query loop. Look through all of the ** WHERE clause terms on the query, and if any of those terms must be @@ -154191,12 +148896,10 @@ assert( pTerm!=0 ); assert( pTerm->pExpr!=0 ); testcase( pTerm->wtFlags & TERM_VIRTUAL ); regRowid = sqlite3GetTempReg(pParse); regRowid = codeEqualityTerm(pParse, pTerm, pLevel, 0, 0, regRowid); - sqlite3VdbeAddOp2(pParse->pVdbe, OP_MustBeInt, regRowid, addrNxt); - VdbeCoverage(pParse->pVdbe); sqlite3VdbeAddOp4Int(pParse->pVdbe, OP_Filter, pLevel->regFilter, addrNxt, regRowid, 1); VdbeCoverage(pParse->pVdbe); }else{ u16 nEq = pLoop->u.btree.nEq; @@ -154252,19 +148955,17 @@ pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; iCur = pTabItem->iCursor; pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); bRev = (pWInfo->revMask>>iLevel)&1; VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName)); -#if WHERETRACE_ENABLED /* 0x4001 */ - if( sqlite3WhereTrace & 0x1 ){ +#if WHERETRACE_ENABLED /* 0x20800 */ + if( sqlite3WhereTrace & 0x800 ){ sqlite3DebugPrintf("Coding level %d of %d: notReady=%llx iFrom=%d\n", iLevel, pWInfo->nLevel, (u64)notReady, pLevel->iFrom); - if( sqlite3WhereTrace & 0x1000 ){ - sqlite3WhereLoopPrint(pLoop, pWC); - } + sqlite3WhereLoopPrint(pLoop, pWC); } - if( (sqlite3WhereTrace & 0x4001)==0x4001 ){ + if( sqlite3WhereTrace & 0x20000 ){ if( iLevel==0 ){ sqlite3DebugPrintf("WHERE clause being coded:\n"); sqlite3TreeViewExpr(0, pWInfo->pWhere, 0); } sqlite3DebugPrintf("All WHERE-clause terms before coding:\n"); @@ -154287,11 +148988,11 @@ /* 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. */ - assert( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN)) + assert( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE) || pLevel->iFrom>0 || (pTabItem[0].fg.jointype & JT_LEFT)==0 ); if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){ pLevel->iLeftJoin = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin); @@ -154298,14 +148999,11 @@ VdbeComment((v, "init LEFT JOIN no-match flag")); } /* Compute a safe address to jump to if we discover that the table for ** this loop is empty and can never contribute content. */ - for(j=iLevel; j>0; j--){ - if( pWInfo->a[j].iLeftJoin ) break; - if( pWInfo->a[j].pRJ ) break; - } + for(j=iLevel; j>0 && pWInfo->a[j].iLeftJoin==0; j--){} addrHalt = pWInfo->a[j].addrBrk; /* Special case of a FROM clause subquery implemented as a co-routine */ if( pTabItem->fg.viaCoroutine ){ int regYield = pTabItem->regReturn; @@ -154346,13 +149044,13 @@ codeExprOrVector(pParse, pRight, iTarget, 1); if( pTerm->eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET && pLoop->u.vtab.bOmitOffset ){ assert( pTerm->eOperator==WO_AUX ); - assert( pWInfo->pSelect!=0 ); - assert( pWInfo->pSelect->iOffset>0 ); - sqlite3VdbeAddOp2(v, OP_Integer, 0, pWInfo->pSelect->iOffset); + assert( pWInfo->pLimit!=0 ); + assert( pWInfo->pLimit->iOffset>0 ); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pWInfo->pLimit->iOffset); VdbeComment((v,"Zero OFFSET counter")); } } } sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg); @@ -154456,12 +149154,10 @@ iReleaseReg = ++pParse->nMem; iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg); if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg); addrNxt = pLevel->addrNxt; if( pLevel->regFilter ){ - sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt); - VdbeCoverage(v); sqlite3VdbeAddOp4Int(v, OP_Filter, pLevel->regFilter, addrNxt, iRowidReg, 1); VdbeCoverage(v); filterPullDown(pParse, pWInfo, iLevel, addrNxt, notReady); } @@ -154809,15 +149505,10 @@ ** of entries in the tree, so basing the number of steps to try ** on the estimated number of rows in the btree seems like a good ** guess. */ addrSeekScan = sqlite3VdbeAddOp1(v, OP_SeekScan, (pIdx->aiRowLogEst[0]+9)/10); - if( pRangeStart || pRangeEnd ){ - sqlite3VdbeChangeP5(v, 1); - sqlite3VdbeChangeP2(v, addrSeekScan, sqlite3VdbeCurrentAddr(v)+1); - addrSeekScan = 0; - } VdbeCoverage(v); } sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); VdbeCoverage(v); VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind ); @@ -154850,11 +149541,20 @@ */ nConstraint = nEq; assert( pLevel->p2==0 ); if( pRangeEnd ){ Expr *pRight = pRangeEnd->pExpr->pRight; - assert( addrSeekScan==0 ); + if( addrSeekScan ){ + /* For a seek-scan that has a range on the lowest term of the index, + ** we have to make the top of the loop be code that sets the end + ** condition of the range. Otherwise, the OP_SeekScan might jump + ** over that initialization, leaving the range-end value set to the + ** range-start value, resulting in a wrong answer. + ** See ticket 5981a8c041a3c2f3 (2021-11-02). + */ + pLevel->p2 = sqlite3VdbeCurrentAddr(v); + } codeExprOrVector(pParse, pRight, regBase+nEq, nTop); whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd); if( (pRangeEnd->wtFlags & TERM_VNULL)==0 && sqlite3ExprCanBeNull(pRight) ){ @@ -154880,15 +149580,15 @@ sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); endEq = 0; } nConstraint++; } - if( zStartAff ) sqlite3DbNNFreeNN(db, zStartAff); - if( zEndAff ) sqlite3DbNNFreeNN(db, zEndAff); + sqlite3DbFree(db, zStartAff); + sqlite3DbFree(db, zEndAff); /* Top of the loop body */ - pLevel->p2 = sqlite3VdbeCurrentAddr(v); + if( pLevel->p2==0 ) pLevel->p2 = sqlite3VdbeCurrentAddr(v); /* Check if the index cursor is past the end of the range. */ if( nConstraint ){ if( regBignull ){ /* Except, skip the end-of-range check while doing the NULL-scan */ @@ -154926,11 +149626,11 @@ sqlite3VdbeAddOp3(v, OP_SeekHit, iIdxCur, nEq, nEq); } /* Seek the table cursor, if required */ omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0 - && (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))==0; + && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0; if( omitTable ){ /* pIdx is a covering index. No need to access the main table. */ }else if( HasRowid(pIdx->pTable) ){ codeDeferredSeek(pWInfo, pIdx, iCur, iIdxCur); }else if( iCur!=iIdxCur ){ @@ -154943,10 +149643,31 @@ sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont, iRowidReg, pPk->nKeyCol); VdbeCoverage(v); } if( pLevel->iLeftJoin==0 ){ + /* If pIdx is an index on one or more expressions, then look through + ** all the expressions in pWInfo and try to transform matching expressions + ** into reference to index columns. Also attempt to translate references + ** to virtual columns in the table into references to (stored) columns + ** of the index. + ** + ** Do not do this for the RHS of a LEFT JOIN. This is because the + ** expression may be evaluated after OP_NullRow has been executed on + ** the cursor. In this case it is important to do the full evaluation, + ** as the result of the expression may not be NULL, even if all table + ** column values are. https://www.sqlite.org/src/info/7fa8049685b50b5a + ** + ** Also, do not do this when processing one index an a multi-index + ** OR clause, since the transformation will become invalid once we + ** move forward to the next index. + ** https://sqlite.org/src/info/4e8e4857d32d401f + */ + if( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){ + whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo); + } + /* If a partial index is driving the loop, try to eliminate WHERE clause ** terms from the query that must be true due to the WHERE clause of ** the partial index. ** ** 2019-11-02 ticket 623eff57e76d45f6: This optimization does not work @@ -154958,11 +149679,11 @@ }else{ testcase( pIdx->pPartIdxWhere ); /* The following assert() is not a requirement, merely an observation: ** The OR-optimization doesn't work for the right hand table of ** a LEFT JOIN: */ - assert( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))==0 ); + assert( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ); } /* Record the instruction used to terminate the loop. */ if( pLoop->wsFlags & WHERE_ONEROW ){ pLevel->op = OP_Noop; @@ -155055,11 +149776,11 @@ */ if( pWInfo->nLevel>1 ){ int nNotReady; /* The number of notReady tables */ SrcItem *origSrc; /* Original list of tables */ nNotReady = pWInfo->nLevel - iLevel - 1; - pOrTab = sqlite3DbMallocRawNN(db, + pOrTab = sqlite3StackAllocRaw(db, sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0])); if( pOrTab==0 ) return notReady; pOrTab->nAlloc = (u8)(nNotReady + 1); pOrTab->nSrc = pOrTab->nAlloc; memcpy(pOrTab->a, pTabItem, sizeof(*pTabItem)); @@ -155162,11 +149883,11 @@ WhereInfo *pSubWInfo; /* Info for single OR-term scan */ Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */ Expr *pDelete; /* Local copy of OR clause term */ int jmp1 = 0; /* Address of jump operation */ testcase( (pTabItem[0].fg.jointype & JT_LEFT)!=0 - && !ExprHasProperty(pOrExpr, EP_OuterON) + && !ExprHasProperty(pOrExpr, EP_FromJoin) ); /* See TH3 vtab25.400 and ticket 614b25314c766238 */ pDelete = pOrExpr = sqlite3ExprDup(db, pOrExpr, 0); if( db->mallocFailed ){ sqlite3ExprDelete(db, pDelete); continue; @@ -155175,11 +149896,11 @@ pAndExpr->pLeft = pOrExpr; pOrExpr = pAndExpr; } /* Loop through table entries that match term pOrTerm. */ ExplainQueryPlan((pParse, 1, "INDEX %d", ii+1)); - WHERETRACE(0xffffffff, ("Subplan for OR-clause:\n")); + WHERETRACE(0xffff, ("Subplan for OR-clause:\n")); pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, 0, WHERE_OR_SUBCLAUSE, iCovCur); assert( pSubWInfo || pParse->nErr ); if( pSubWInfo ){ WhereLoop *pSubLoop; @@ -155300,19 +150021,11 @@ } sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v)); sqlite3VdbeGoto(v, pLevel->addrBrk); sqlite3VdbeResolveLabel(v, iLoopBody); - /* Set the P2 operand of the OP_Return opcode that will end the current - ** loop to point to this spot, which is the top of the next containing - ** loop. The byte-code formatter will use that P2 value as a hint to - ** indent everything in between the this point and the final OP_Return. - ** See tag-20220407a in vdbe.c and shell.c */ - assert( pLevel->op==OP_Return ); - pLevel->p2 = sqlite3VdbeCurrentAddr(v); - - if( pWInfo->nLevel>1 ){ sqlite3DbFreeNN(db, pOrTab); } + if( pWInfo->nLevel>1 ){ sqlite3StackFree(db, pOrTab); } if( !untestedTerms ) disableTerm(pLevel, pTerm); }else #endif /* SQLITE_OMIT_OR_OPTIMIZATION */ { @@ -155370,26 +150083,14 @@ pWInfo->untestedTerms = 1; continue; } pE = pTerm->pExpr; assert( pE!=0 ); - if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT) ){ - if( !ExprHasProperty(pE,EP_OuterON|EP_InnerON) ){ - /* Defer processing WHERE clause constraints until after outer - ** join processing. tag-20220513a */ - continue; - }else if( (pTabItem->fg.jointype & JT_LEFT)==JT_LEFT - && !ExprHasProperty(pE,EP_OuterON) ){ - continue; - }else{ - Bitmask m = sqlite3WhereGetMask(&pWInfo->sMaskSet, pE->w.iJoin); - if( m & pLevel->notReady ){ - /* An ON clause that is not ripe */ - continue; - } - } - } + if( (pTabItem->fg.jointype&JT_LEFT) && !ExprHasProperty(pE,EP_FromJoin) ){ + continue; + } + if( iLoop==1 && !sqlite3ExprCoveredByIndex(pE, pLevel->iTabCur, pIdx) ){ iNext = 2; continue; } if( iLoop<3 && (pTerm->wtFlags & TERM_VARSELECT) ){ @@ -155412,16 +150113,16 @@ VdbeCoverageIf(v, (x&1)==1); VdbeCoverageIf(v, (x&1)==0); } #endif } -#ifdef WHERETRACE_ENABLED /* 0xffffffff */ +#ifdef WHERETRACE_ENABLED /* 0xffff */ if( sqlite3WhereTrace ){ VdbeNoopComment((v, "WhereTerm[%d] (%p) priority=%d", pWC->nTerm-j, pTerm, iLoop)); } - if( sqlite3WhereTrace & 0x4000 ){ + if( sqlite3WhereTrace & 0x800 ){ sqlite3DebugPrintf("Coding auxiliary constraint:\n"); sqlite3WhereTermPrint(pTerm, pWC->nTerm-j); } #endif sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL); @@ -155444,19 +150145,19 @@ WhereTerm *pAlt; if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue; if( (pTerm->eOperator & WO_EQUIV)==0 ) continue; if( pTerm->leftCursor!=iCur ) continue; - if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT) ) continue; + if( pTabItem->fg.jointype & JT_LEFT ) continue; pE = pTerm->pExpr; -#ifdef WHERETRACE_ENABLED /* 0x4001 */ - if( (sqlite3WhereTrace & 0x4001)==0x4001 ){ +#ifdef WHERETRACE_ENABLED /* 0x800 */ + if( sqlite3WhereTrace & 0x800 ){ sqlite3DebugPrintf("Coding transitive constraint:\n"); sqlite3WhereTermPrint(pTerm, pWC->nTerm-j); } #endif - assert( !ExprHasProperty(pE, EP_OuterON) ); + assert( !ExprHasProperty(pE, EP_FromJoin) ); assert( (pTerm->prereqRight & pLevel->notReady)!=0 ); assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); pAlt = sqlite3WhereFindTerm(pWC, iCur, pTerm->u.x.leftColumn, notReady, WO_EQ|WO_IN|WO_IS, 0); if( pAlt==0 ) continue; @@ -155475,201 +150176,45 @@ sEAlt.pLeft = pE->pLeft; sqlite3ExprIfFalse(pParse, &sEAlt, addrCont, SQLITE_JUMPIFNULL); pAlt->wtFlags |= TERM_CODED; } - /* For a RIGHT OUTER JOIN, record the fact that the current row has - ** been matched at least once. - */ - if( pLevel->pRJ ){ - Table *pTab; - int nPk; - int r; - int jmp1 = 0; - WhereRightJoin *pRJ = pLevel->pRJ; - - /* pTab is the right-hand table of the RIGHT JOIN. Generate code that - ** will record that the current row of that table has been matched at - ** least once. This is accomplished by storing the PK for the row in - ** both the iMatch index and the regBloom Bloom filter. - */ - pTab = pWInfo->pTabList->a[pLevel->iFrom].pTab; - if( HasRowid(pTab) ){ - r = sqlite3GetTempRange(pParse, 2); - sqlite3ExprCodeGetColumnOfTable(v, pTab, pLevel->iTabCur, -1, r+1); - nPk = 1; - }else{ - int iPk; - Index *pPk = sqlite3PrimaryKeyIndex(pTab); - nPk = pPk->nKeyCol; - r = sqlite3GetTempRange(pParse, nPk+1); - for(iPk=0; iPkaiColumn[iPk]; - sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+1+iPk); - } - } - jmp1 = sqlite3VdbeAddOp4Int(v, OP_Found, pRJ->iMatch, 0, r+1, nPk); - VdbeCoverage(v); - VdbeComment((v, "match against %s", pTab->zName)); - sqlite3VdbeAddOp3(v, OP_MakeRecord, r+1, nPk, r); - sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pRJ->iMatch, r, r+1, nPk); - sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pRJ->regBloom, 0, r+1, nPk); - sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); - sqlite3VdbeJumpHere(v, jmp1); - sqlite3ReleaseTempRange(pParse, r, nPk+1); - } - /* 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 = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin); VdbeComment((v, "record LEFT JOIN hit")); - if( pLevel->pRJ==0 ){ - goto code_outer_join_constraints; /* WHERE clause constraints */ - } - } - - if( pLevel->pRJ ){ - /* Create a subroutine used to process all interior loops and code - ** of the RIGHT JOIN. During normal operation, the subroutine will - ** be in-line with the rest of the code. But at the end, a separate - ** loop will run that invokes this subroutine for unmatched rows - ** of pTab, with all tables to left begin set to NULL. - */ - WhereRightJoin *pRJ = pLevel->pRJ; - sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pRJ->regReturn); - pRJ->addrSubrtn = sqlite3VdbeCurrentAddr(v); - assert( pParse->withinRJSubrtn < 255 ); - pParse->withinRJSubrtn++; - - /* WHERE clause constraints must be deferred until after outer join - ** row elimination has completed, since WHERE clause constraints apply - ** to the results of the OUTER JOIN. The following loop generates the - ** appropriate WHERE clause constraint checks. tag-20220513a. - */ - code_outer_join_constraints: for(pTerm=pWC->a, j=0; jnBase; j++, pTerm++){ testcase( pTerm->wtFlags & TERM_VIRTUAL ); testcase( pTerm->wtFlags & TERM_CODED ); if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; if( (pTerm->prereqAll & pLevel->notReady)!=0 ){ assert( pWInfo->untestedTerms ); continue; } - if( pTabItem->fg.jointype & JT_LTORJ ) continue; assert( pTerm->pExpr ); sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); pTerm->wtFlags |= TERM_CODED; } } -#if WHERETRACE_ENABLED /* 0x4001 */ - if( sqlite3WhereTrace & 0x4000 ){ +#if WHERETRACE_ENABLED /* 0x20800 */ + if( sqlite3WhereTrace & 0x20000 ){ sqlite3DebugPrintf("All WHERE-clause terms after coding level %d:\n", iLevel); sqlite3WhereClausePrint(pWC); } - if( sqlite3WhereTrace & 0x1 ){ + if( sqlite3WhereTrace & 0x800 ){ sqlite3DebugPrintf("End Coding level %d: notReady=%llx\n", iLevel, (u64)pLevel->notReady); } #endif return pLevel->notReady; } -/* -** Generate the code for the loop that finds all non-matched terms -** for a RIGHT JOIN. -*/ -SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( - WhereInfo *pWInfo, - int iLevel, - WhereLevel *pLevel -){ - Parse *pParse = pWInfo->pParse; - Vdbe *v = pParse->pVdbe; - WhereRightJoin *pRJ = pLevel->pRJ; - Expr *pSubWhere = 0; - WhereClause *pWC = &pWInfo->sWC; - WhereInfo *pSubWInfo; - WhereLoop *pLoop = pLevel->pWLoop; - SrcItem *pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; - SrcList sFrom; - Bitmask mAll = 0; - int k; - - ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pTab->zName)); - sqlite3VdbeNoJumpsOutsideSubrtn(v, pRJ->addrSubrtn, pRJ->endSubrtn, - pRJ->regReturn); - for(k=0; ka[k].pWLoop->maskSelf; - sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur); - iIdxCur = pWInfo->a[k].iIdxCur; - if( iIdxCur ){ - sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur); - } - } - if( (pTabItem->fg.jointype & JT_LTORJ)==0 ){ - mAll |= pLoop->maskSelf; - for(k=0; knTerm; k++){ - WhereTerm *pTerm = &pWC->a[k]; - if( (pTerm->wtFlags & (TERM_VIRTUAL|TERM_SLICE))!=0 - && pTerm->eOperator!=WO_ROWVAL - ){ - break; - } - if( pTerm->prereqAll & ~mAll ) continue; - if( ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON) ) continue; - pSubWhere = sqlite3ExprAnd(pParse, pSubWhere, - sqlite3ExprDup(pParse->db, pTerm->pExpr, 0)); - } - } - sFrom.nSrc = 1; - sFrom.nAlloc = 1; - memcpy(&sFrom.a[0], pTabItem, sizeof(SrcItem)); - sFrom.a[0].fg.jointype = 0; - assert( pParse->withinRJSubrtn < 100 ); - pParse->withinRJSubrtn++; - pSubWInfo = sqlite3WhereBegin(pParse, &sFrom, pSubWhere, 0, 0, 0, - WHERE_RIGHT_JOIN, 0); - if( pSubWInfo ){ - int iCur = pLevel->iTabCur; - int r = ++pParse->nMem; - int nPk; - int jmp; - int addrCont = sqlite3WhereContinueLabel(pSubWInfo); - Table *pTab = pTabItem->pTab; - if( HasRowid(pTab) ){ - sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, r); - nPk = 1; - }else{ - int iPk; - Index *pPk = sqlite3PrimaryKeyIndex(pTab); - nPk = pPk->nKeyCol; - pParse->nMem += nPk - 1; - for(iPk=0; iPkaiColumn[iPk]; - sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+iPk); - } - } - jmp = sqlite3VdbeAddOp4Int(v, OP_Filter, pRJ->regBloom, 0, r, nPk); - VdbeCoverage(v); - sqlite3VdbeAddOp4Int(v, OP_Found, pRJ->iMatch, addrCont, r, nPk); - VdbeCoverage(v); - sqlite3VdbeJumpHere(v, jmp); - sqlite3VdbeAddOp2(v, OP_Gosub, pRJ->regReturn, pRJ->addrSubrtn); - sqlite3WhereEnd(pSubWInfo); - } - sqlite3ExprDelete(pParse->db, pSubWhere); - ExplainQueryPlanPop(pParse); - assert( pParse->withinRJSubrtn>0 ); - pParse->withinRJSubrtn--; -} - /************** End of wherecode.c *******************************************/ /************** Begin file whereexpr.c ***************************************/ /* ** 2015-06-08 ** @@ -155734,20 +150279,23 @@ int idx; testcase( wtFlags & TERM_VIRTUAL ); if( pWC->nTerm>=pWC->nSlot ){ WhereTerm *pOld = pWC->a; sqlite3 *db = pWC->pWInfo->pParse->db; - pWC->a = sqlite3WhereMalloc(pWC->pWInfo, sizeof(pWC->a[0])*pWC->nSlot*2 ); + pWC->a = sqlite3DbMallocRawNN(db, sizeof(pWC->a[0])*pWC->nSlot*2 ); if( pWC->a==0 ){ if( wtFlags & TERM_DYNAMIC ){ sqlite3ExprDelete(db, p); } pWC->a = pOld; return 0; } memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm); - pWC->nSlot = pWC->nSlot*2; + if( pOld!=pWC->aStatic ){ + sqlite3DbFree(db, pOld); + } + pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]); } pTerm = &pWC->a[idx = pWC->nTerm++]; if( (wtFlags & TERM_VIRTUAL)==0 ) pWC->nBase = pWC->nTerm; if( p && ExprHasProperty(p, EP_Unlikely) ){ pTerm->truthProb = sqlite3LogEst(p->iTable) - 270; @@ -155936,11 +150484,11 @@ ** 2019-09-03 https://sqlite.org/src/info/0f0428096f17252a */ if( pLeft->op!=TK_COLUMN || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT || (ALWAYS( ExprUseYTab(pLeft) ) - && ALWAYS(pLeft->y.pTab) + && pLeft->y.pTab && IsVirtual(pLeft->y.pTab)) /* Might be numeric */ ){ int isNum; double rDummy; isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8); @@ -156053,11 +150601,12 @@ ** ** vtab_column MATCH expression ** MATCH(expression,vtab_column) */ pCol = pList->a[1].pExpr; - assert( pCol->op!=TK_COLUMN || (ExprUseYTab(pCol) && pCol->y.pTab!=0) ); + assert( pCol->op!=TK_COLUMN || ExprUseYTab(pCol) ); + testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 ); if( ExprIsVtab(pCol) ){ for(i=0; iu.zToken, aOp[i].zOp)==0 ){ *peOp2 = aOp[i].eOp2; @@ -156078,11 +150627,11 @@ ** names. But for this use case, xFindFunction is expected to deal ** with function names in an arbitrary case. */ pCol = pList->a[0].pExpr; assert( pCol->op!=TK_COLUMN || ExprUseYTab(pCol) ); - assert( pCol->op!=TK_COLUMN || (ExprUseYTab(pCol) && pCol->y.pTab!=0) ); + testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 ); if( ExprIsVtab(pCol) ){ sqlite3_vtab *pVtab; sqlite3_module *pMod; void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**); void *pNotUsed; @@ -156103,16 +150652,17 @@ } }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){ int res = 0; Expr *pLeft = pExpr->pLeft; Expr *pRight = pExpr->pRight; - assert( pLeft->op!=TK_COLUMN || (ExprUseYTab(pLeft) && pLeft->y.pTab!=0) ); + assert( pLeft->op!=TK_COLUMN || ExprUseYTab(pLeft) ); + testcase( pLeft->op==TK_COLUMN && pLeft->y.pTab==0 ); if( ExprIsVtab(pLeft) ){ res++; } - assert( pRight==0 || pRight->op!=TK_COLUMN - || (ExprUseYTab(pRight) && pRight->y.pTab!=0) ); + assert( pRight==0 || pRight->op!=TK_COLUMN || ExprUseYTab(pRight) ); + testcase( pRight && pRight->op==TK_COLUMN && pRight->y.pTab==0 ); if( pRight && ExprIsVtab(pRight) ){ res++; SWAP(Expr*, pLeft, pRight); } *ppLeft = pLeft; @@ -156129,13 +150679,13 @@ /* ** 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){ - if( pDerived && ExprHasProperty(pBase, EP_OuterON|EP_InnerON) ){ - pDerived->flags |= pBase->flags & (EP_OuterON|EP_InnerON); - pDerived->w.iJoin = pBase->w.iJoin; + if( pDerived ){ + pDerived->flags |= pBase->flags & EP_FromJoin; + pDerived->w.iRightJoinTable = pBase->w.iRightJoinTable; } } /* ** Mark term iChild as being a child of term iParent @@ -156585,11 +151135,11 @@ static int termIsEquivalence(Parse *pParse, Expr *pExpr){ char aff1, aff2; CollSeq *pColl; if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; - if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; + if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0; aff1 = sqlite3ExprAffinity(pExpr->pLeft); aff2 = sqlite3ExprAffinity(pExpr->pRight); if( aff1!=aff2 && (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2)) ){ @@ -156616,13 +151166,11 @@ mask |= sqlite3WhereExprUsage(pMaskSet, pS->pHaving); if( ALWAYS(pSrc!=0) ){ int i; for(i=0; inSrc; i++){ mask |= exprSelectUsage(pMaskSet, pSrc->a[i].pSelect); - if( pSrc->a[i].fg.isUsing==0 ){ - mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].u3.pOn); - } + mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].pOn); if( pSrc->a[i].fg.isTabFunc ){ mask |= sqlite3WhereExprListUsage(pMaskSet, pSrc->a[i].u1.pFuncArg); } } } @@ -156644,70 +151192,59 @@ ** true even if that particular column is not indexed, because the column ** might be added to an automatic index later. */ static SQLITE_NOINLINE int exprMightBeIndexed2( SrcList *pFrom, /* The FROM clause */ + Bitmask mPrereq, /* Bitmask of FROM clause terms referenced by pExpr */ int *aiCurCol, /* Write the referenced table cursor and column here */ - Expr *pExpr, /* An operand of a comparison operator */ - int j /* Start looking with the j-th pFrom entry */ + Expr *pExpr /* An operand of a comparison operator */ ){ Index *pIdx; int i; int iCur; - do{ - iCur = pFrom->a[j].iCursor; - for(pIdx=pFrom->a[j].pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - if( pIdx->aColExpr==0 ) continue; - for(i=0; inKeyCol; i++){ - if( pIdx->aiColumn[i]!=XN_EXPR ) continue; - assert( pIdx->bHasExpr ); - if( sqlite3ExprCompareSkip(pExpr,pIdx->aColExpr->a[i].pExpr,iCur)==0 - && pExpr->op!=TK_STRING - ){ - aiCurCol[0] = iCur; - aiCurCol[1] = XN_EXPR; - return 1; - } - } - } - }while( ++j < pFrom->nSrc ); + for(i=0; mPrereq>1; i++, mPrereq>>=1){} + iCur = pFrom->a[i].iCursor; + for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( pIdx->aColExpr==0 ) continue; + for(i=0; inKeyCol; i++){ + if( pIdx->aiColumn[i]!=XN_EXPR ) continue; + if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){ + aiCurCol[0] = iCur; + aiCurCol[1] = XN_EXPR; + return 1; + } + } + } return 0; } static int exprMightBeIndexed( SrcList *pFrom, /* The FROM clause */ + Bitmask mPrereq, /* Bitmask of FROM clause terms referenced by pExpr */ int *aiCurCol, /* Write the referenced table cursor & column here */ Expr *pExpr, /* An operand of a comparison operator */ int op /* The specific comparison operator */ ){ - int i; - /* If this expression is a vector to the left or right of a ** inequality constraint (>, <, >= or <=), perform the processing ** on the first element of the vector. */ assert( TK_GT+1==TK_LE && TK_GT+2==TK_LT && TK_GT+3==TK_GE ); assert( TK_ISop==TK_VECTOR && (op>=TK_GT && ALWAYS(op<=TK_GE)) ){ assert( ExprUseXList(pExpr) ); pExpr = pExpr->x.pList->a[0].pExpr; + } if( pExpr->op==TK_COLUMN ){ aiCurCol[0] = pExpr->iTable; aiCurCol[1] = pExpr->iColumn; return 1; } - - for(i=0; inSrc; i++){ - Index *pIdx; - for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - if( pIdx->aColExpr ){ - return exprMightBeIndexed2(pFrom,aiCurCol,pExpr,i); - } - } - } - return 0; + if( mPrereq==0 ) return 0; /* No table references */ + if( (mPrereq&(mPrereq-1))!=0 ) return 0; /* Refs more than one table */ + return exprMightBeIndexed2(pFrom,mPrereq,aiCurCol,pExpr); } /* ** The input to this routine is an WhereTerm structure with only the @@ -156784,36 +151321,22 @@ #ifdef SQLITE_DEBUG if( prereqAll!=sqlite3WhereExprUsageNN(pMaskSet, pExpr) ){ printf("\n*** Incorrect prereqAll computed for:\n"); sqlite3TreeViewExpr(0,pExpr,0); - assert( 0 ); + abort(); } #endif - if( ExprHasProperty(pExpr, EP_OuterON|EP_InnerON) ){ - Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->w.iJoin); - if( ExprHasProperty(pExpr, EP_OuterON) ){ - prereqAll |= x; - extraRight = x-1; /* ON clause terms may not be used with an index - ** on left table of a LEFT JOIN. Ticket #3015 */ - if( (prereqAll>>1)>=x ){ - sqlite3ErrorMsg(pParse, "ON clause references tables to its right"); - return; - } - }else if( (prereqAll>>1)>=x ){ - /* The ON clause of an INNER JOIN references a table to its right. - ** Most other SQL database engines raise an error. But SQLite versions - ** 3.0 through 3.38 just put the ON clause constraint into the WHERE - ** clause and carried on. Beginning with 3.39, raise an error only - ** if there is a RIGHT or FULL JOIN in the query. This makes SQLite - ** more like other systems, and also preserves legacy. */ - if( ALWAYS(pSrc->nSrc>0) && (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ - sqlite3ErrorMsg(pParse, "ON clause references tables to its right"); - return; - } - ExprClearProperty(pExpr, EP_InnerON); + if( ExprHasProperty(pExpr, EP_FromJoin) ){ + Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->w.iRightJoinTable); + prereqAll |= x; + extraRight = x-1; /* ON clause terms may not be used with an index + ** on left table of a LEFT JOIN. Ticket #3015 */ + if( (prereqAll>>1)>=x ){ + sqlite3ErrorMsg(pParse, "ON clause references tables to its right"); + return; } } pTerm->prereqAll = prereqAll; pTerm->leftCursor = -1; pTerm->iParent = -1; @@ -156829,19 +151352,19 @@ assert( pLeft->op==TK_VECTOR ); assert( ExprUseXList(pLeft) ); pLeft = pLeft->x.pList->a[pTerm->u.x.iField-1].pExpr; } - if( exprMightBeIndexed(pSrc, aiCurCol, pLeft, op) ){ + if( exprMightBeIndexed(pSrc, prereqLeft, aiCurCol, pLeft, op) ){ pTerm->leftCursor = aiCurCol[0]; assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); pTerm->u.x.leftColumn = aiCurCol[1]; pTerm->eOperator = operatorMask(op) & opMask; } if( op==TK_IS ) pTerm->wtFlags |= TERM_IS; if( pRight - && exprMightBeIndexed(pSrc, aiCurCol, pRight, op) + && exprMightBeIndexed(pSrc, pTerm->prereqRight, aiCurCol, pRight, op) && !ExprHasProperty(pRight, EP_FixedCol) ){ WhereTerm *pNew; Expr *pDup; u16 eExtraOp = 0; /* Extra bits for pNew->eOperator */ @@ -156877,11 +151400,11 @@ pNew->prereqRight = prereqLeft | extraRight; pNew->prereqAll = prereqAll; pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask; }else if( op==TK_ISNULL - && !ExprHasProperty(pExpr,EP_OuterON) + && !ExprHasProperty(pExpr,EP_FromJoin) && 0==sqlite3ExprCanBeNull(pLeft) ){ assert( !ExprHasProperty(pExpr, EP_IntValue) ); pExpr->op = TK_TRUEFALSE; pExpr->u.zToken = "false"; @@ -156948,11 +151471,11 @@ ** The virtual term must be tagged with TERM_VNULL. */ else if( pExpr->op==TK_NOTNULL ){ if( pExpr->pLeft->op==TK_COLUMN && pExpr->pLeft->iColumn>=0 - && !ExprHasProperty(pExpr, EP_OuterON) + && !ExprHasProperty(pExpr, EP_FromJoin) ){ Expr *pNewExpr; Expr *pLeft = pExpr->pLeft; int idxNew; WhereTerm *pNewTerm; @@ -157048,18 +151571,18 @@ sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName), pStr1); transferJoinMarkings(pNewExpr1, pExpr); idxNew1 = whereClauseInsert(pWC, pNewExpr1, wtFlags); testcase( idxNew1==0 ); + exprAnalyze(pSrc, pWC, idxNew1); pNewExpr2 = sqlite3ExprDup(db, pLeft, 0); pNewExpr2 = sqlite3PExpr(pParse, TK_LT, sqlite3ExprAddCollateString(pParse,pNewExpr2,zCollSeqName), pStr2); transferJoinMarkings(pNewExpr2, pExpr); idxNew2 = whereClauseInsert(pWC, pNewExpr2, wtFlags); testcase( idxNew2==0 ); - exprAnalyze(pSrc, pWC, idxNew1); exprAnalyze(pSrc, pWC, idxNew2); pTerm = &pWC->a[idxTerm]; if( isComplete ){ markTermAsChild(pWC, idxNew1, idxTerm); markTermAsChild(pWC, idxNew2, idxTerm); @@ -157096,11 +151619,11 @@ idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC|TERM_SLICE); exprAnalyze(pSrc, pWC, idxNew); } pTerm = &pWC->a[idxTerm]; pTerm->wtFlags |= TERM_CODED|TERM_VIRTUAL; /* Disable the original */ - pTerm->eOperator = WO_ROWVAL; + pTerm->eOperator = 0; } /* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create ** a virtual term for each vector component. The expression object ** used by each such virtual term is pExpr (the full vector IN(...) @@ -157112,11 +151635,11 @@ */ else if( pExpr->op==TK_IN && pTerm->u.x.iField==0 && pExpr->pLeft->op==TK_VECTOR && ALWAYS( ExprUseXSelect(pExpr) ) - && (pExpr->x.pSelect->pPrior==0 || (pExpr->x.pSelect->selFlags & SF_Values)) + && pExpr->x.pSelect->pPrior==0 #ifndef SQLITE_OMIT_WINDOWFUNC && pExpr->x.pSelect->pWin==0 #endif && pWC->op==TK_AND ){ @@ -157152,13 +151675,13 @@ prereqColumn = sqlite3WhereExprUsage(pMaskSet, pLeft); if( (prereqExpr & prereqColumn)==0 ){ Expr *pNewExpr; pNewExpr = sqlite3PExpr(pParse, TK_MATCH, 0, sqlite3ExprDup(db, pRight, 0)); - if( ExprHasProperty(pExpr, EP_OuterON) && pNewExpr ){ - ExprSetProperty(pNewExpr, EP_OuterON); - pNewExpr->w.iJoin = pExpr->w.iJoin; + if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){ + ExprSetProperty(pNewExpr, EP_FromJoin); + pNewExpr->w.iRightJoinTable = pExpr->w.iRightJoinTable; } idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); testcase( idxNew==0 ); pNewTerm = &pWC->a[idxNew]; pNewTerm->prereqRight = prereqExpr; @@ -157281,13 +151804,13 @@ ** ** LIMIT and OFFSET terms are ignored by most of the planner code. They ** exist only so that they may be passed to the xBestIndex method of the ** single virtual table in the FROM clause of the SELECT. */ -SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3WhereAddLimit(WhereClause *pWC, Select *p){ - assert( p!=0 && p->pLimit!=0 ); /* 1 -- checked by caller */ - if( p->pGroupBy==0 +SQLITE_PRIVATE void sqlite3WhereAddLimit(WhereClause *pWC, Select *p){ + assert( p==0 || (p->pGroupBy==0 && (p->selFlags & SF_Aggregate)==0) ); + if( (p && p->pLimit) /* 1 */ && (p->selFlags & (SF_Distinct|SF_Aggregate))==0 /* 2 */ && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pTab)) /* 3 */ ){ ExprList *pOrderBy = p->pOrderBy; int iCsr = p->pSrc->a[0].iCursor; @@ -157297,18 +151820,11 @@ for(ii=0; iinTerm; ii++){ if( pWC->a[ii].wtFlags & TERM_CODED ){ /* This term is a vector operation that has been decomposed into ** other, subsequent terms. It can be ignored. See tag-20220128a */ assert( pWC->a[ii].wtFlags & TERM_VIRTUAL ); - assert( pWC->a[ii].eOperator==WO_ROWVAL ); - continue; - } - if( pWC->a[ii].nChild ){ - /* If this term has child terms, then they are also part of the - ** pWC->a[] array. So this term can be ignored, as a LIMIT clause - ** will only be added if each of the child terms passes the - ** (leftCursor==iCsr) test below. */ + assert( pWC->a[ii].eOperator==0 ); continue; } if( pWC->a[ii].leftCursor!=iCsr ) return; } @@ -157316,11 +151832,11 @@ if( pOrderBy ){ for(ii=0; iinExpr; ii++){ Expr *pExpr = pOrderBy->a[ii].pExpr; if( pExpr->op!=TK_COLUMN ) return; if( pExpr->iTable!=iCsr ) return; - if( pOrderBy->a[ii].fg.sortFlags & KEYINFO_ORDER_BIGNULL ) return; + if( pOrderBy->a[ii].sortFlags & KEYINFO_ORDER_BIGNULL ) return; } } /* All conditions are met. Add the terms to the where-clause object. */ assert( p->pLimit->op==TK_LIMIT ); @@ -157383,10 +151899,13 @@ } if( a==aLast ) break; a++; } } + if( pWC->a!=pWC->aStatic ){ + sqlite3DbFree(db, pWC->a); + } } /* ** These routines walk (recursively) an expression tree and generate @@ -157509,11 +152028,10 @@ assert( pTab!=0 ); pArgs = pItem->u1.pFuncArg; if( pArgs==0 ) return; for(j=k=0; jnExpr; j++){ Expr *pRhs; - u32 joinType; while( knCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;} if( k>=pTab->nCol ){ sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d", pTab->zName, j); return; @@ -157526,19 +152044,13 @@ pColRef->y.pTab = pTab; pItem->colUsed |= sqlite3ExprColUsed(pColRef); pRhs = sqlite3PExpr(pParse, TK_UPLUS, sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0); pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs); - if( pItem->fg.jointype & (JT_LEFT|JT_RIGHT) ){ - testcase( pItem->fg.jointype & JT_LEFT ); /* testtag-20230227a */ - testcase( pItem->fg.jointype & JT_RIGHT ); /* testtag-20230227b */ - joinType = EP_OuterON; - }else{ - testcase( pItem->fg.jointype & JT_LTORJ ); /* testtag-20230227c */ - joinType = EP_InnerON; - } - sqlite3SetJoinExpr(pTerm, pItem->iCursor, joinType); + if( pItem->fg.jointype & JT_LEFT ){ + sqlite3SetJoinExpr(pTerm, pItem->iCursor); + } whereClauseInsert(pWC, pTerm, TERM_DYNAMIC); } } /************** End of whereexpr.c *******************************************/ @@ -157610,11 +152122,11 @@ ** terms means that no sorting is needed at all. A return that ** is positive but less than the number of ORDER BY terms means that ** block sorting is required. */ SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo *pWInfo){ - return pWInfo->nOBSat<0 ? 0 : pWInfo->nOBSat; + return pWInfo->nOBSat; } /* ** In the ORDER BY LIMIT optimization, if the inner-most loop is known ** to emit rows in increasing order, and if the last row emitted by the @@ -157645,11 +152157,11 @@ ** continuation of the inner-most loop. */ return pWInfo->iContinue; } pInner = &pWInfo->a[pWInfo->nLevel-1]; assert( pInner->addrNxt!=0 ); - return pInner->pRJ ? pWInfo->iContinue : pInner->addrNxt; + return pInner->addrNxt; } /* ** While generating code for the min/max optimization, after handling ** the aggregate-step call to min() or max(), check to see if any @@ -157796,34 +152308,10 @@ } } return 0; } -/* Allocate memory that is automatically freed when pWInfo is freed. -*/ -SQLITE_PRIVATE void *sqlite3WhereMalloc(WhereInfo *pWInfo, u64 nByte){ - WhereMemBlock *pBlock; - pBlock = sqlite3DbMallocRawNN(pWInfo->pParse->db, nByte+sizeof(*pBlock)); - if( pBlock ){ - pBlock->pNext = pWInfo->pMemToFree; - pBlock->sz = nByte; - pWInfo->pMemToFree = pBlock; - pBlock++; - } - return (void*)pBlock; -} -SQLITE_PRIVATE void *sqlite3WhereRealloc(WhereInfo *pWInfo, void *pOld, u64 nByte){ - void *pNew = sqlite3WhereMalloc(pWInfo, nByte); - if( pNew && pOld ){ - WhereMemBlock *pOldBlk = (WhereMemBlock*)pOld; - pOldBlk--; - assert( pOldBlk->szsz); - } - return pNew; -} - /* ** 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 @@ -157873,11 +152361,11 @@ if( pTerm->leftCursor==iCur && pTerm->u.x.leftColumn==iColumn && (iColumn!=XN_EXPR || sqlite3ExprCompareSkip(pTerm->pExpr->pLeft, pScan->pIdxExpr,iCur)==0) - && (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_OuterON)) + && (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin)) ){ if( (pTerm->eOperator & WO_EQUIV)!=0 && pScan->nEquivaiCur) && (pX = whereRightSubexprIsColumn(pTerm->pExpr))!=0 ){ @@ -158225,11 +152713,10 @@ if( pOp->opcode==OP_Column ){ pOp->opcode = OP_Copy; pOp->p1 = pOp->p2 + iRegister; pOp->p2 = pOp->p3; pOp->p3 = 0; - pOp->p5 = 2; /* Cause the MEM_Subtype flag to be cleared */ }else if( pOp->opcode==OP_Rowid ){ pOp->opcode = OP_Sequence; pOp->p1 = iAutoidxCur; #ifdef SQLITE_ALLOW_ROWID_IN_VIEW if( iAutoidxCur==0 ){ @@ -158248,11 +152735,11 @@ ** are no-ops. */ #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(WHERETRACE_ENABLED) static void whereTraceIndexInfoInputs(sqlite3_index_info *p){ int i; - if( (sqlite3WhereTrace & 0x10)==0 ) return; + if( !sqlite3WhereTrace ) return; for(i=0; inConstraint; i++){ sqlite3DebugPrintf( " constraint[%d]: col=%d termid=%d op=%d usabled=%d collseq=%s\n", i, p->aConstraint[i].iColumn, @@ -158268,11 +152755,11 @@ p->aOrderBy[i].desc); } } static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){ int i; - if( (sqlite3WhereTrace & 0x10)==0 ) return; + if( !sqlite3WhereTrace ) return; for(i=0; inConstraint; i++){ sqlite3DebugPrintf(" usage[%d]: argvIdx=%d omit=%d\n", i, p->aConstraintUsage[i].argvIndex, p->aConstraintUsage[i].omit); @@ -158285,47 +152772,10 @@ } #else #define whereTraceIndexInfoInputs(A) #define whereTraceIndexInfoOutputs(A) #endif - -/* -** We know that pSrc is an operand of an outer join. Return true if -** pTerm is a constraint that is compatible with that join. -** -** pTerm must be EP_OuterON if pSrc is the right operand of an -** outer join. pTerm can be either EP_OuterON or EP_InnerON if pSrc -** is the left operand of a RIGHT join. -** -** See https://sqlite.org/forum/forumpost/206d99a16dd9212f -** for an example of a WHERE clause constraints that may not be used on -** the right table of a RIGHT JOIN because the constraint implies a -** not-NULL condition on the left table of the RIGHT JOIN. -*/ -static int constraintCompatibleWithOuterJoin( - const WhereTerm *pTerm, /* WHERE clause term to check */ - const SrcItem *pSrc /* Table we are trying to access */ -){ - assert( (pSrc->fg.jointype&(JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ); /* By caller */ - testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT ); - testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ ); - testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) ) - testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) ); - if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON) - || pTerm->pExpr->w.iJoin != pSrc->iCursor - ){ - return 0; - } - if( (pSrc->fg.jointype & (JT_LEFT|JT_RIGHT))!=0 - && ExprHasProperty(pTerm->pExpr, EP_InnerON) - ){ - return 0; - } - return 1; -} - - #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 @@ -158337,15 +152787,18 @@ const Bitmask notReady /* Tables in outer loops of the join */ ){ char aff; if( pTerm->leftCursor!=pSrc->iCursor ) return 0; if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0; - assert( (pSrc->fg.jointype & JT_RIGHT)==0 ); - if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 - && !constraintCompatibleWithOuterJoin(pTerm,pSrc) + if( (pSrc->fg.jointype & JT_LEFT) + && !ExprHasProperty(pTerm->pExpr, EP_FromJoin) + && (pTerm->eOperator & WO_IS) ){ - return 0; /* See https://sqlite.org/forum/forumpost/51e6959f61 */ + /* Cannot use an IS term from the WHERE clause as an index driver for + ** the RHS of a LEFT JOIN. Such a term can only be used if it is from + ** the ON clause. */ + return 0; } if( (pTerm->prereqRight & notReady)!=0 ) return 0; assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); if( pTerm->u.x.leftColumn<0 ) return 0; aff = pSrc->pTab->aCol[pTerm->u.x.leftColumn].affinity; @@ -158355,61 +152808,10 @@ } #endif #ifndef SQLITE_OMIT_AUTOMATIC_INDEX - -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS -/* -** Argument pIdx represents an automatic index that the current statement -** will create and populate. Add an OP_Explain with text of the form: -** -** CREATE AUTOMATIC INDEX ON
      () [WHERE ] -** -** This is only required if sqlite3_stmt_scanstatus() is enabled, to -** associate an SQLITE_SCANSTAT_NCYCLE and SQLITE_SCANSTAT_NLOOP -** values with. In order to avoid breaking legacy code and test cases, -** the OP_Explain is not added if this is an EXPLAIN QUERY PLAN command. -*/ -static void explainAutomaticIndex( - Parse *pParse, - Index *pIdx, /* Automatic index to explain */ - int bPartial, /* True if pIdx is a partial index */ - int *pAddrExplain /* OUT: Address of OP_Explain */ -){ - if( IS_STMT_SCANSTATUS(pParse->db) && pParse->explain!=2 ){ - Table *pTab = pIdx->pTable; - const char *zSep = ""; - char *zText = 0; - int ii = 0; - sqlite3_str *pStr = sqlite3_str_new(pParse->db); - sqlite3_str_appendf(pStr,"CREATE AUTOMATIC INDEX ON %s(", pTab->zName); - assert( pIdx->nColumn>1 ); - assert( pIdx->aiColumn[pIdx->nColumn-1]==XN_ROWID ); - for(ii=0; ii<(pIdx->nColumn-1); ii++){ - const char *zName = 0; - int iCol = pIdx->aiColumn[ii]; - - zName = pTab->aCol[iCol].zCnName; - sqlite3_str_appendf(pStr, "%s%s", zSep, zName); - zSep = ", "; - } - zText = sqlite3_str_finish(pStr); - if( zText==0 ){ - sqlite3OomFault(pParse->db); - }else{ - *pAddrExplain = sqlite3VdbeExplain( - pParse, 0, "%s)%s", zText, (bPartial ? " WHERE " : "") - ); - sqlite3_free(zText); - } - } -} -#else -# define explainAutomaticIndex(a,b,c,d) -#endif - /* ** 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. */ @@ -158435,20 +152837,16 @@ CollSeq *pColl; /* Collating sequence to on a column */ WhereLoop *pLoop; /* The Loop object */ char *zNotUsed; /* Extra space on the end of pIdx */ Bitmask idxCols; /* Bitmap of columns used for indexing */ Bitmask extraCols; /* Bitmap of additional columns */ - u8 sentWarning = 0; /* True if a warning has been issued */ - u8 useBloomFilter = 0; /* True to also add a Bloom filter */ + u8 sentWarning = 0; /* True if a warnning has been issued */ Expr *pPartial = 0; /* Partial Index Expression */ int iContinue = 0; /* Jump here to skip excluded rows */ SrcItem *pTabItem; /* FROM clause term being indexed */ int addrCounter = 0; /* Address where integer counter is initialized */ int regBase; /* Array of registers where record is assembled */ -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS - int addrExp = 0; /* Address of OP_Explain */ -#endif /* 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 ); @@ -158506,15 +152904,11 @@ ** original table never needs to be accessed. Automatic indices must ** be a covering index because the index will not be updated if the ** original table changes and the index and table cannot both be used ** if they go out of sync. */ - if( IsView(pTable) ){ - extraCols = ALLBITS; - }else{ - extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1)); - } + extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1)); mxBitCol = MIN(BMS-1,pTable->nCol); testcase( pTable->nCol==BMS-1 ); testcase( pTable->nCol==BMS-2 ); for(i=0; iaiColumn[n] = pTerm->u.x.leftColumn; pColl = sqlite3ExprCompareCollSeq(pParse, pX); assert( pColl!=0 || pParse->nErr>0 ); /* TH3 collate01.800 */ pIdx->azColl[n] = pColl ? pColl->zName : sqlite3StrBINARY; n++; - if( ALWAYS(pX->pLeft!=0) - && sqlite3ExprAffinity(pX->pLeft)!=SQLITE_AFF_TEXT - ){ - /* TUNING: only use a Bloom filter on an automatic index - ** if one or more key columns has the ability to hold numeric - ** values, since strings all have the same hash in the Bloom - ** filter implementation and hence a Bloom filter on a text column - ** is not usually helpful. */ - useBloomFilter = 1; - } } } } assert( (u32)n==pLoop->u.btree.nEq ); @@ -158582,18 +152966,16 @@ assert( n==nKeyCol ); pIdx->aiColumn[n] = XN_ROWID; pIdx->azColl[n] = sqlite3StrBINARY; /* Create the automatic index */ - explainAutomaticIndex(pParse, pIdx, pPartial!=0, &addrExp); assert( pLevel->iIdxCur>=0 ); pLevel->iIdxCur = pParse->nTab++; sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1); sqlite3VdbeSetP4KeyInfo(pParse, pIdx); VdbeComment((v, "for %s", pTable->zName)); - if( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) && useBloomFilter ){ - sqlite3WhereExplainBloomFilter(pParse, pWC->pWInfo, pLevel); + if( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ){ pLevel->regFilter = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Blob, 10000, pLevel->regFilter); } /* Fill the automatic index with content */ @@ -158619,11 +153001,10 @@ ); if( pLevel->regFilter ){ sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, regBase, pLoop->u.btree.nEq); } - sqlite3VdbeScanStatusCounters(v, addrExp, addrExp, sqlite3VdbeCurrentAddr(v)); sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue); if( pTabItem->fg.viaCoroutine ){ sqlite3VdbeChangeP2(v, addrCounter, regBase+n); @@ -158640,11 +153021,10 @@ sqlite3VdbeJumpHere(v, addrTop); sqlite3ReleaseTempReg(pParse, regRecord); /* Jump here when skipping the initialization */ sqlite3VdbeJumpHere(v, addrInit); - sqlite3VdbeScanStatusRange(v, addrExp, addrExp, -1); end_auto_index_create: sqlite3ExprDelete(pParse->db, pPartial); } #endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ @@ -158682,14 +153062,10 @@ const WhereTerm *pWCEnd; /* Last WHERE clause term */ Parse *pParse = pWInfo->pParse; /* Parsing context */ Vdbe *v = pParse->pVdbe; /* VDBE under construction */ WhereLoop *pLoop = pLevel->pWLoop; /* The loop being coded */ int iCur; /* Cursor for table getting the filter */ - IndexedExpr *saved_pIdxEpr; /* saved copy of Parse.pIdxEpr */ - - saved_pIdxEpr = pParse->pIdxEpr; - pParse->pIdxEpr = 0; assert( pLoop!=0 ); assert( v!=0 ); assert( pLoop->wsFlags & WHERE_BLOOMFILTER ); @@ -158742,12 +153118,13 @@ Index *pIdx = pLoop->u.btree.pIndex; int n = pLoop->u.btree.nEq; int r1 = sqlite3GetTempRange(pParse, n); int jj; for(jj=0; jjaiColumn[jj]; assert( pIdx->pTable==pItem->pTab ); - sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iCur, jj, r1+jj); + sqlite3ExprCodeGetColumnOfTable(v, pIdx->pTable, iCur, iCol,r1+jj); } sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, n); sqlite3ReleaseTempRange(pParse, r1, n); } sqlite3VdbeResolveLabel(v, addrCont); @@ -158758,11 +153135,11 @@ if( OptimizationDisabled(pParse->db, SQLITE_BloomPulldown) ) break; while( ++iLevel < pWInfo->nLevel ){ const SrcItem *pTabItem; pLevel = &pWInfo->a[iLevel]; pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; - if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ) ) continue; + if( pTabItem->fg.jointype & JT_LEFT ) continue; pLoop = pLevel->pWLoop; if( NEVER(pLoop==0) ) continue; if( pLoop->prereq & notReady ) continue; if( (pLoop->wsFlags & (WHERE_BLOOMFILTER|WHERE_COLUMN_IN)) ==WHERE_BLOOMFILTER @@ -158774,11 +153151,10 @@ break; } } }while( iLevel < pWInfo->nLevel ); sqlite3VdbeJumpHere(v, addrOnce); - pParse->pIdxEpr = saved_pIdxEpr; } #ifndef SQLITE_OMIT_VIRTUALTABLE /* @@ -158830,12 +153206,16 @@ if( pTerm->wtFlags & TERM_VNULL ) continue; assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); assert( pTerm->u.x.leftColumn>=XN_ROWID ); assert( pTerm->u.x.leftColumnnCol ); - if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 - && !constraintCompatibleWithOuterJoin(pTerm,pSrc) + + /* tag-20191211-002: WHERE-clause constraints are not useful to the + ** right-hand table of a LEFT JOIN. See tag-20191211-001 for the + ** equivalent restriction for ordinary tables. */ + if( (pSrc->fg.jointype & JT_LEFT)!=0 + && !ExprHasProperty(pTerm->pExpr, EP_FromJoin) ){ continue; } nTerm++; pTerm->wtFlags |= TERM_OK; @@ -158856,11 +153236,11 @@ if( sqlite3ExprIsConstant(pExpr) ){ continue; } /* Virtual tables are unable to deal with NULLS FIRST */ - if( pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_BIGNULL ) break; + if( pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL ) break; /* First case - a direct column references without a COLLATE operator */ if( pExpr->op==TK_COLUMN && pExpr->iTable==pSrc->iCursor ){ assert( pExpr->iColumn>=XN_ROWID && pExpr->iColumnnCol ); continue; @@ -158886,14 +153266,12 @@ /* No matches cause a break out of the loop */ break; } if( i==n ){ nOrderBy = n; - if( (pWInfo->wctrlFlags & WHERE_DISTINCTBY) ){ - eDistinct = 2 + ((pWInfo->wctrlFlags & WHERE_SORTBYGROUP)!=0); - }else if( pWInfo->wctrlFlags & WHERE_GROUPBY ){ - eDistinct = 1; + if( (pWInfo->wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY)) ){ + eDistinct = 1 + ((pWInfo->wctrlFlags & WHERE_DISTINCTBY)!=0); } } } /* Allocate the sqlite3_index_info structure @@ -158968,11 +153346,11 @@ if( sqlite3ExprIsConstant(pExpr) ) continue; assert( pExpr->op==TK_COLUMN || (pExpr->op==TK_COLLATE && pExpr->pLeft->op==TK_COLUMN && pExpr->iColumn==pExpr->pLeft->iColumn) ); pIdxOrderBy[j].iColumn = pExpr->iColumn; - pIdxOrderBy[j].desc = pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_DESC; + pIdxOrderBy[j].desc = pOrderBy->a[i].sortFlags & KEYINFO_ORDER_DESC; j++; } pIdxInfo->nOrderBy = j; *pmNoOmit = mNoOmit; @@ -159030,13 +153408,10 @@ sqlite3ErrorMsg(pParse, "%s", sqlite3ErrStr(rc)); }else{ sqlite3ErrorMsg(pParse, "%s", pVtab->zErrMsg); } } - if( pTab->u.vtab.p->bAllSchemas ){ - sqlite3VtabUsesAllSchemas(pParse); - } sqlite3_free(pVtab->zErrMsg); pVtab->zErrMsg = 0; return rc; } #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */ @@ -159075,12 +153450,11 @@ #ifndef SQLITE_DEBUG UNUSED_PARAMETER( pParse ); #endif assert( pRec!=0 ); assert( pIdx->nSample>0 ); - assert( pRec->nField>0 ); - + assert( pRec->nField>0 && pRec->nField<=pIdx->nSampleCol ); /* Do a binary search to find the first sample greater than or equal ** to pRec. If pRec contains a single field, the set of samples to search ** is simply the aSample[] array. If the samples in aSample[] contain more ** than one fields, all fields following the first are ignored. @@ -159122,16 +153496,11 @@ ** appears that it should be 1 field in size. However, that would make it ** smaller than sample 1, so the binary search would not work. As a result, ** it is extended to two fields. The duplicates that this creates do not ** cause any problems. */ - if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){ - nField = pIdx->nKeyCol; - }else{ - nField = pIdx->nColumn; - } - nField = MIN(pRec->nField, nField); + nField = pRec->nField; iCol = 0; iSample = pIdx->nSample * nField; do{ int iSamp; /* Index in aSample[] of test sample */ int n; /* Number of fields in test sample */ @@ -159193,16 +153562,16 @@ ** be greater than or equal to the (iCol) field prefix of sample i. ** If (i>0), then pRec must also be greater than sample (i-1). */ if( iCol>0 ){ pRec->nField = iCol; assert( sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)<=0 - || pParse->db->mallocFailed || CORRUPT_DB ); + || pParse->db->mallocFailed ); } if( i>0 ){ pRec->nField = nField; assert( sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0 - || pParse->db->mallocFailed || CORRUPT_DB ); + || pParse->db->mallocFailed ); } } } #endif /* ifdef SQLITE_DEBUG */ @@ -159215,11 +153584,11 @@ /* At this point, the (iCol+1) field prefix of aSample[i] is the first ** sample that is greater than pRec. Or, if i==pIdx->nSample then pRec ** is larger than all samples in the array. */ tRowcnt iUpper, iGap; if( i>=pIdx->nSample ){ - iUpper = pIdx->nRowEst0; + iUpper = sqlite3LogEstToInt(pIdx->aiRowLogEst[0]); }else{ iUpper = aSample[i].anLt[iCol]; } if( iLower>=iUpper ){ @@ -159371,11 +153740,11 @@ ** using the method described in the header comment for this function. */ if( nDiff!=1 || pUpper==0 || pLower==0 ){ int nAdjust = (sqlite3LogEst(p->nSample) - sqlite3LogEst(nDiff)); pLoop->nOut -= nAdjust; *pbDone = 1; - WHERETRACE(0x20, ("range skip-scan regions: %u..%u adjust=%d est=%d\n", + WHERETRACE(0x10, ("range skip-scan regions: %u..%u adjust=%d est=%d\n", nLower, nUpper, nAdjust*-1, pLoop->nOut)); } }else{ assert( *pbDone==0 ); @@ -159549,11 +153918,11 @@ nNew = 10; assert( 10==sqlite3LogEst(2) ); } if( nNewwtFlags & TERM_VNULL)==0 || pParse->nErr>0 ); + assert( pUpper==0 || (pUpper->wtFlags & TERM_VNULL)==0 ); nNew = whereRangeAdjust(pLower, nOut); nNew = whereRangeAdjust(pUpper, nNew); /* TUNING: If there is both an upper and lower limit and neither limit ** has an application-defined likelihood(), assume the range is @@ -159582,11 +153951,11 @@ nOut -= (pLower!=0) + (pUpper!=0); if( nNew<10 ) nNew = 10; if( nNewnOut>nOut ){ - WHERETRACE(0x20,("Range scan lowers nOut from %d to %d\n", + WHERETRACE(0x10,("Range scan lowers nOut from %d to %d\n", pLoop->nOut, nOut)); } #endif pLoop->nOut = (LogEst)nOut; return rc; @@ -159647,11 +154016,11 @@ if( rc!=SQLITE_OK ) return rc; if( bOk==0 ) return SQLITE_NOTFOUND; pBuilder->nRecValid = nEq; whereKeyStats(pParse, p, pRec, 0, a); - WHERETRACE(0x20,("equality scan regions %s(%d): %d\n", + WHERETRACE(0x10,("equality scan regions %s(%d): %d\n", p->zName, nEq-1, (int)a[1])); *pnRow = a[1]; return rc; } @@ -159695,13 +154064,13 @@ nRowEst += nEst; pBuilder->nRecValid = nRecValid; } if( rc==SQLITE_OK ){ - if( nRowEst > (tRowcnt)nRow0 ) nRowEst = nRow0; + if( nRowEst > nRow0 ) nRowEst = nRow0; *pnRow = nRowEst; - WHERETRACE(0x20,("IN row estimate: est=%d\n", nRowEst)); + WHERETRACE(0x10,("IN row estimate: est=%d\n", nRowEst)); } assert( pBuilder->nRecValid==nRecValid ); return rc; } #endif /* SQLITE_ENABLE_STAT4 */ @@ -159718,11 +154087,11 @@ char zType[8]; char zLeft[50]; memcpy(zType, "....", 5); if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V'; if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E'; - if( ExprHasProperty(pTerm->pExpr, EP_OuterON) ) zType[2] = 'L'; + if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L'; if( pTerm->wtFlags & TERM_CODED ) zType[3] = 'C'; if( pTerm->eOperator & WO_SINGLE ){ assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); sqlite3_snprintf(sizeof(zLeft),zLeft,"left={%d:%d}", pTerm->leftCursor, pTerm->u.x.leftColumn); @@ -159806,11 +154175,11 @@ sqlite3DebugPrintf(" f %06x %d-%d", p->wsFlags, p->nLTerm,p->nSkip); }else{ sqlite3DebugPrintf(" f %06x N %d", p->wsFlags, p->nLTerm); } sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut); - if( p->nLTerm && (sqlite3WhereTrace & 0x4000)!=0 ){ + if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){ int i; for(i=0; inLTerm; i++){ sqlite3WhereTermPrint(p->aLTerm[i], i); } } @@ -159844,22 +154213,16 @@ } } } /* -** Deallocate internal memory used by a WhereLoop object. Leave the -** object in an initialized state, as if it had been newly allocated. +** Deallocate internal memory used by a WhereLoop object */ static void whereLoopClear(sqlite3 *db, WhereLoop *p){ - if( p->aLTerm!=p->aLTermSpace ){ - sqlite3DbFreeNN(db, p->aLTerm); - p->aLTerm = p->aLTermSpace; - p->nLSlot = ArraySize(p->aLTermSpace); - } + if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFreeNN(db, p->aLTerm); whereLoopClearUnion(db, p); - p->nLTerm = 0; - p->wsFlags = 0; + whereLoopInit(p); } /* ** Increase the memory allocation for pLoop->aLTerm[] to be at least n. */ @@ -159879,13 +154242,11 @@ /* ** Transfer content from the second pLoop into the first. */ static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){ whereLoopClearUnion(db, pTo); - if( pFrom->nLTerm > pTo->nLSlot - && whereLoopResize(db, pTo, pFrom->nLTerm) - ){ + if( whereLoopResize(db, pTo, pFrom->nLTerm) ){ memset(pTo, 0, WHERE_LOOP_XFER_SZ); return SQLITE_NOMEM_BKPT; } memcpy(pTo, pFrom, WHERE_LOOP_XFER_SZ); memcpy(pTo->aLTerm, pFrom->aLTerm, pTo->nLTerm*sizeof(pTo->aLTerm[0])); @@ -159899,33 +154260,46 @@ /* ** Delete a WhereLoop object */ static void whereLoopDelete(sqlite3 *db, WhereLoop *p){ - assert( db!=0 ); whereLoopClear(db, p); - sqlite3DbNNFreeNN(db, p); + sqlite3DbFreeNN(db, p); } /* ** Free a WhereInfo structure */ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ + int i; assert( pWInfo!=0 ); - assert( db!=0 ); + for(i=0; inLevel; i++){ + WhereLevel *pLevel = &pWInfo->a[i]; + if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE)!=0 ){ + assert( (pLevel->pWLoop->wsFlags & WHERE_MULTI_OR)==0 ); + sqlite3DbFree(db, pLevel->u.in.aInLoop); + } + } sqlite3WhereClauseClear(&pWInfo->sWC); while( pWInfo->pLoops ){ WhereLoop *p = pWInfo->pLoops; pWInfo->pLoops = p->pNextLoop; whereLoopDelete(db, p); } - while( pWInfo->pMemToFree ){ - WhereMemBlock *pNext = pWInfo->pMemToFree->pNext; - sqlite3DbNNFreeNN(db, pWInfo->pMemToFree); - pWInfo->pMemToFree = pNext; + assert( pWInfo->pExprMods==0 ); + sqlite3DbFreeNN(db, pWInfo); +} + +/* Undo all Expr node modifications +*/ +static void whereUndoExprMods(WhereInfo *pWInfo){ + while( pWInfo->pExprMods ){ + WhereExprMod *p = pWInfo->pExprMods; + pWInfo->pExprMods = p->pNext; + memcpy(p->pExpr, &p->orig, sizeof(p->orig)); + sqlite3DbFree(pWInfo->pParse->db, p); } - sqlite3DbNNFreeNN(db, pWInfo); } /* ** Return TRUE if all of the following are true: ** @@ -160270,24 +154644,22 @@ if( pX==0 ) continue; if( pX==pTerm ) break; if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break; } if( j<0 ){ - sqlite3ProgressCheck(pWC->pWInfo->pParse); if( pLoop->maskSelf==pTerm->prereqAll ){ /* If there are extra terms in the WHERE clause not used by an index ** that depend only on the table being scanned, and that will tend to ** cause many rows to be omitted, then mark that table as ** "self-culling". ** ** 2022-03-24: Self-culling only applies if either the extra terms ** are straight comparison operators that are non-true with NULL - ** operand, or if the loop is not an OUTER JOIN. + ** operand, or if the loop is not a LEFT JOIN. */ if( (pTerm->eOperator & 0x3f)!=0 - || (pWC->pWInfo->pTabList->a[pLoop->iTab].fg.jointype - & (JT_LEFT|JT_LTORJ))==0 + || (pWC->pWInfo->pTabList->a[pLoop->iTab].fg.jointype & JT_LEFT)==0 ){ pLoop->wsFlags |= WHERE_SELFCULL; } } if( pTerm->truthProb<=0 ){ @@ -160438,14 +154810,11 @@ LogEst rSize; /* Number of rows in the table */ LogEst rLogSize; /* Logarithm of table size */ WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */ pNew = pBuilder->pNew; - assert( db->mallocFailed==0 || pParse->nErr>0 ); - if( pParse->nErr ){ - return pParse->rc; - } + if( db->mallocFailed ) return SQLITE_NOMEM_BKPT; WHERETRACE(0x800, ("BEGIN %s.addBtreeIdx(%s), nEq=%d, nSkip=%d, rRun=%d\n", pProbe->pTable->zName,pProbe->zName, pNew->u.btree.nEq, pNew->nSkip, pNew->rRun)); assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 ); @@ -160492,15 +154861,19 @@ /* Do not allow the upper bound of a LIKE optimization range constraint ** to mix with a lower range bound from some other source */ if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue; - if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 - && !constraintCompatibleWithOuterJoin(pTerm,pSrc) + /* tag-20191211-001: Do not allow constraints from the WHERE clause to + ** be used by the right table of a LEFT JOIN. Only constraints in the + ** ON clause are allowed. See tag-20191211-002 for the vtab equivalent. */ + if( (pSrc->fg.jointype & JT_LEFT)!=0 + && !ExprHasProperty(pTerm->pExpr, EP_FromJoin) ){ continue; } + if( IsUniqueIndex(pProbe) && saved_nEq==pProbe->nKeyCol-1 ){ pBuilder->bldFlags1 |= SQLITE_BLDF1_UNIQUE; }else{ pBuilder->bldFlags1 |= SQLITE_BLDF1_INDEXED; } @@ -160507,15 +154880,11 @@ pNew->wsFlags = saved_wsFlags; pNew->u.btree.nEq = saved_nEq; pNew->u.btree.nBtm = saved_nBtm; pNew->u.btree.nTop = saved_nTop; pNew->nLTerm = saved_nLTerm; - if( pNew->nLTerm>=pNew->nLSlot - && whereLoopResize(db, pNew, pNew->nLTerm+1) - ){ - break; /* OOM while trying to enlarge the pNew->aLTerm array */ - } + if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ pNew->aLTerm[pNew->nLTerm++] = pTerm; pNew->prereq = (saved_prereq | pTerm->prereqRight) & ~pNew->maskSelf; assert( nInMul==0 || (pNew->wsFlags & WHERE_COLUMN_NULL)!=0 @@ -160604,43 +154973,42 @@ } } if( scan.iEquiv>1 ) pNew->wsFlags |= WHERE_TRANSCONS; }else if( eOp & WO_ISNULL ){ pNew->wsFlags |= WHERE_COLUMN_NULL; + }else if( eOp & (WO_GT|WO_GE) ){ + testcase( eOp & WO_GT ); + testcase( eOp & WO_GE ); + pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT; + pNew->u.btree.nBtm = whereRangeVectorLen( + pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm + ); + pBtm = pTerm; + pTop = 0; + if( pTerm->wtFlags & TERM_LIKEOPT ){ + /* Range constraints that come from the LIKE optimization are + ** always used in pairs. */ + pTop = &pTerm[1]; + assert( (pTop-(pTerm->pWC->a))pWC->nTerm ); + assert( pTop->wtFlags & TERM_LIKEOPT ); + assert( pTop->eOperator==WO_LT ); + if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ + pNew->aLTerm[pNew->nLTerm++] = pTop; + pNew->wsFlags |= WHERE_TOP_LIMIT; + pNew->u.btree.nTop = 1; + } }else{ - int nVecLen = whereRangeVectorLen( + assert( eOp & (WO_LT|WO_LE) ); + testcase( eOp & WO_LT ); + testcase( eOp & WO_LE ); + pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT; + pNew->u.btree.nTop = whereRangeVectorLen( pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm ); - if( eOp & (WO_GT|WO_GE) ){ - testcase( eOp & WO_GT ); - testcase( eOp & WO_GE ); - pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT; - pNew->u.btree.nBtm = nVecLen; - pBtm = pTerm; - pTop = 0; - if( pTerm->wtFlags & TERM_LIKEOPT ){ - /* Range constraints that come from the LIKE optimization are - ** always used in pairs. */ - pTop = &pTerm[1]; - assert( (pTop-(pTerm->pWC->a))pWC->nTerm ); - assert( pTop->wtFlags & TERM_LIKEOPT ); - assert( pTop->eOperator==WO_LT ); - if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ - pNew->aLTerm[pNew->nLTerm++] = pTop; - pNew->wsFlags |= WHERE_TOP_LIMIT; - pNew->u.btree.nTop = 1; - } - }else{ - assert( eOp & (WO_LT|WO_LE) ); - testcase( eOp & WO_LT ); - testcase( eOp & WO_LE ); - pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT; - pNew->u.btree.nTop = nVecLen; - pTop = pTerm; - pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ? - pNew->aLTerm[pNew->nLTerm-2] : 0; - } + pTop = pTerm; + pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ? + pNew->aLTerm[pNew->nLTerm-2] : 0; } /* At this point pNew->nOut is set to the number of rows expected to ** be visited by the index scan before considering term pTerm, or the ** values of nIn and nInMul. In other words, assuming that all @@ -160688,11 +155056,11 @@ ** to be true for half or more of the rows in the table. ** See tag-202002240-1 */ && pNew->nOut+10 > pProbe->aiRowLogEst[0] ){ #if WHERETRACE_ENABLED /* 0x01 */ - if( sqlite3WhereTrace & 0x20 ){ + if( sqlite3WhereTrace & 0x01 ){ sqlite3DebugPrintf( "STAT4 determines term has low selectivity:\n"); sqlite3WhereTermPrint(pTerm, 999); } #endif @@ -160725,21 +155093,13 @@ /* Set rCostIdx to the cost of visiting selected rows in index. Add ** it to pNew->rRun, which is currently set to the cost of the index ** seek only. Then, if this is a non-covering index, add the cost of ** visiting the rows in the main table. */ assert( pSrc->pTab->szTabRow>0 ); - if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){ - /* The pProbe->szIdxRow is low for an IPK table since the interior - ** pages are small. Thuse szIdxRow gives a good estimate of seek cost. - ** But the leaf pages are full-size, so pProbe->szIdxRow would badly - ** under-estimate the scanning cost. */ - rCostIdx = pNew->nOut + 16; - }else{ - rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; - } + rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx); - if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK|WHERE_EXPRIDX))==0 ){ + if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16); } ApplyCostMultiplier(pNew->rRun, pProbe->pTable->costMult); nOutUnadjusted = pNew->nOut; @@ -160757,13 +155117,10 @@ if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 && pNew->u.btree.nEqnColumn && (pNew->u.btree.nEqnKeyCol || pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY) ){ - if( pNew->u.btree.nEq>3 ){ - sqlite3ProgressCheck(pParse); - } whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn); } pNew->nOut = saved_nOut; #ifdef SQLITE_ENABLE_STAT4 pBuilder->nRecValid = nRecValid; @@ -160862,182 +155219,36 @@ /* Check to see if a partial index with pPartIndexWhere can be used ** in the current query. Return true if it can be and false if not. */ static int whereUsablePartialIndex( int iTab, /* The table for which we want an index */ - u8 jointype, /* The JT_* flags on the join */ + int isLeft, /* True if iTab is the right table of a LEFT JOIN */ WhereClause *pWC, /* The WHERE clause of the query */ Expr *pWhere /* The WHERE clause from the partial index */ ){ int i; WhereTerm *pTerm; - Parse *pParse; - - if( jointype & JT_LTORJ ) return 0; - pParse = pWC->pWInfo->pParse; + Parse *pParse = pWC->pWInfo->pParse; while( pWhere->op==TK_AND ){ - if( !whereUsablePartialIndex(iTab,jointype,pWC,pWhere->pLeft) ) return 0; + if( !whereUsablePartialIndex(iTab,isLeft,pWC,pWhere->pLeft) ) return 0; pWhere = pWhere->pRight; } if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0; for(i=0, pTerm=pWC->a; inTerm; i++, pTerm++){ Expr *pExpr; pExpr = pTerm->pExpr; - if( (!ExprHasProperty(pExpr, EP_OuterON) || pExpr->w.iJoin==iTab) - && ((jointype & JT_OUTER)==0 || ExprHasProperty(pExpr, EP_OuterON)) + if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->w.iRightJoinTable==iTab) + && (isLeft==0 || ExprHasProperty(pExpr, EP_FromJoin)) && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab) && (pTerm->wtFlags & TERM_VNULL)==0 ){ return 1; } } return 0; } -/* -** pIdx is an index containing expressions. Check it see if any of the -** expressions in the index match the pExpr expression. -*/ -static int exprIsCoveredByIndex( - const Expr *pExpr, - const Index *pIdx, - int iTabCur -){ - int i; - for(i=0; inColumn; i++){ - if( pIdx->aiColumn[i]==XN_EXPR - && sqlite3ExprCompare(0, pExpr, pIdx->aColExpr->a[i].pExpr, iTabCur)==0 - ){ - return 1; - } - } - return 0; -} - -/* -** Structure passed to the whereIsCoveringIndex Walker callback. -*/ -typedef struct CoveringIndexCheck CoveringIndexCheck; -struct CoveringIndexCheck { - Index *pIdx; /* The index */ - int iTabCur; /* Cursor number for the corresponding table */ - u8 bExpr; /* Uses an indexed expression */ - u8 bUnidx; /* Uses an unindexed column not within an indexed expr */ -}; - -/* -** Information passed in is pWalk->u.pCovIdxCk. Call it pCk. -** -** If the Expr node references the table with cursor pCk->iTabCur, then -** make sure that column is covered by the index pCk->pIdx. We know that -** all columns less than 63 (really BMS-1) are covered, so we don't need -** to check them. But we do need to check any column at 63 or greater. -** -** If the index does not cover the column, then set pWalk->eCode to -** non-zero and return WRC_Abort to stop the search. -** -** If this node does not disprove that the index can be a covering index, -** then just return WRC_Continue, to continue the search. -** -** If pCk->pIdx contains indexed expressions and one of those expressions -** matches pExpr, then prune the search. -*/ -static int whereIsCoveringIndexWalkCallback(Walker *pWalk, Expr *pExpr){ - int i; /* Loop counter */ - const Index *pIdx; /* The index of interest */ - const i16 *aiColumn; /* Columns contained in the index */ - u16 nColumn; /* Number of columns in the index */ - CoveringIndexCheck *pCk; /* Info about this search */ - - pCk = pWalk->u.pCovIdxCk; - pIdx = pCk->pIdx; - if( (pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN) ){ - /* if( pExpr->iColumn<(BMS-1) && pIdx->bHasExpr==0 ) return WRC_Continue;*/ - if( pExpr->iTable!=pCk->iTabCur ) return WRC_Continue; - pIdx = pWalk->u.pCovIdxCk->pIdx; - aiColumn = pIdx->aiColumn; - nColumn = pIdx->nColumn; - for(i=0; iiColumn ) return WRC_Continue; - } - pCk->bUnidx = 1; - return WRC_Abort; - }else if( pIdx->bHasExpr - && exprIsCoveredByIndex(pExpr, pIdx, pWalk->u.pCovIdxCk->iTabCur) ){ - pCk->bExpr = 1; - return WRC_Prune; - } - return WRC_Continue; -} - - -/* -** pIdx is an index that covers all of the low-number columns used by -** pWInfo->pSelect (columns from 0 through 62) or an index that has -** expressions terms. Hence, we cannot determine whether or not it is -** a covering index by using the colUsed bitmasks. We have to do a search -** to see if the index is covering. This routine does that search. -** -** The return value is one of these: -** -** 0 The index is definitely not a covering index -** -** WHERE_IDX_ONLY The index is definitely a covering index -** -** WHERE_EXPRIDX The index is likely a covering index, but it is -** difficult to determine precisely because of the -** expressions that are indexed. Score it as a -** covering index, but still keep the main table open -** just in case we need it. -** -** This routine is an optimization. It is always safe to return zero. -** But returning one of the other two values when zero should have been -** returned can lead to incorrect bytecode and assertion faults. -*/ -static SQLITE_NOINLINE u32 whereIsCoveringIndex( - WhereInfo *pWInfo, /* The WHERE clause context */ - Index *pIdx, /* Index that is being tested */ - int iTabCur /* Cursor for the table being indexed */ -){ - int i, rc; - struct CoveringIndexCheck ck; - Walker w; - if( pWInfo->pSelect==0 ){ - /* We don't have access to the full query, so we cannot check to see - ** if pIdx is covering. Assume it is not. */ - return 0; - } - if( pIdx->bHasExpr==0 ){ - for(i=0; inColumn; i++){ - if( pIdx->aiColumn[i]>=BMS-1 ) break; - } - if( i>=pIdx->nColumn ){ - /* pIdx does not index any columns greater than 62, but we know from - ** colMask that columns greater than 62 are used, so this is not a - ** covering index */ - return 0; - } - } - ck.pIdx = pIdx; - ck.iTabCur = iTabCur; - ck.bExpr = 0; - ck.bUnidx = 0; - memset(&w, 0, sizeof(w)); - w.xExprCallback = whereIsCoveringIndexWalkCallback; - w.xSelectCallback = sqlite3SelectWalkNoop; - w.u.pCovIdxCk = &ck; - sqlite3WalkSelect(&w, pWInfo->pSelect); - if( ck.bUnidx ){ - rc = 0; - }else if( ck.bExpr ){ - rc = WHERE_EXPRIDX; - }else{ - rc = WHERE_IDX_ONLY; - } - return rc; -} - /* ** Add all WhereLoop objects for a single table of the join where the table ** is identified by pBuilder->pNew->iTab. That table is guaranteed to be ** a b-tree table, not a virtual table. ** @@ -161116,11 +155327,11 @@ sPk.nColumn = 1; sPk.aiColumn = &aiColumnPk; sPk.aiRowLogEst = aiRowEstPk; sPk.onError = OE_Replace; sPk.pTable = pTab; - sPk.szIdxRow = 3; /* TUNING: Interior rows of IPK table are very small */ + sPk.szIdxRow = pTab->szTabRow; sPk.idxType = SQLITE_IDXTYPE_IPK; aiRowEstPk[0] = pTab->nRowLogEst; aiRowEstPk[1] = 0; pFirst = pSrc->pTab->pIndex; if( pSrc->fg.notIndexed==0 ){ @@ -161133,18 +155344,17 @@ rSize = pTab->nRowLogEst; #ifndef SQLITE_OMIT_AUTOMATIC_INDEX /* Automatic indexes */ if( !pBuilder->pOrSet /* Not part of an OR optimization */ - && (pWInfo->wctrlFlags & (WHERE_RIGHT_JOIN|WHERE_OR_SUBCLAUSE))==0 + && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0 && !pSrc->fg.isIndexedBy /* Has no INDEXED BY clause */ && !pSrc->fg.notIndexed /* Has no NOT INDEXED clause */ && HasRowid(pTab) /* Not WITHOUT ROWID table. (FIXME: Why not?) */ && !pSrc->fg.isCorrelated /* Not a correlated subquery */ && !pSrc->fg.isRecursive /* Not a recursive common table expression. */ - && (pSrc->fg.jointype & JT_RIGHT)==0 /* Not the right tab of a RIGHT JOIN */ ){ /* Generate auto-index WhereLoops */ LogEst rLogSize; /* Logarithm of the number of rows in the table */ WhereTerm *pTerm; WhereTerm *pWCEnd = pWC->a + pWC->nTerm; @@ -161167,12 +155377,11 @@ ** indexes on subqueries and views. */ pNew->rSetup = rLogSize + rSize; if( !IsView(pTab) && (pTab->tabFlags & TF_Ephemeral)==0 ){ pNew->rSetup += 28; }else{ - pNew->rSetup -= 25; /* Greatly reduced setup cost for auto indexes - ** on ephemeral materializations of views */ + pNew->rSetup -= 10; } ApplyCostMultiplier(pNew->rSetup, pTab->costMult); if( pNew->rSetup<0 ) pNew->rSetup = 0; /* TUNING: Each index lookup yields 20 rows in the table. This ** is more than the usual guess of 10 rows, since we have no way @@ -161191,12 +155400,13 @@ /* Loop over all indices. If there was an INDEXED BY clause, then only ** consider index pProbe. */ for(; rc==SQLITE_OK && pProbe; pProbe=(pSrc->fg.isIndexedBy ? 0 : pProbe->pNext), iSortIdx++ ){ + int isLeft = (pSrc->fg.jointype & JT_OUTER)!=0; if( pProbe->pPartIdxWhere!=0 - && !whereUsablePartialIndex(pSrc->iCursor, pSrc->fg.jointype, pWC, + && !whereUsablePartialIndex(pSrc->iCursor, isLeft, pWC, pProbe->pPartIdxWhere) ){ testcase( pNew->iTab!=pSrc->iCursor ); /* See ticket [98d973b8f5] */ continue; /* Partial index inappropriate for this query */ } @@ -161237,53 +155447,23 @@ #ifdef SQLITE_ENABLE_STAT4 pNew->rRun = rSize + 16 - 2*((pTab->tabFlags & TF_HasStat4)!=0); #else pNew->rRun = rSize + 16; #endif - if( IsView(pTab) || (pTab->tabFlags & TF_Ephemeral)!=0 ){ - pNew->wsFlags |= WHERE_VIEWSCAN; - } ApplyCostMultiplier(pNew->rRun, pTab->costMult); whereLoopOutputAdjust(pWC, pNew, rSize); rc = whereLoopInsert(pBuilder, pNew); pNew->nOut = rSize; if( rc ) break; }else{ Bitmask m; if( pProbe->isCovering ){ - m = 0; pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED; + m = 0; }else{ m = pSrc->colUsed & pProbe->colNotIdxed; - pNew->wsFlags = WHERE_INDEXED; - if( m==TOPBIT || (pProbe->bHasExpr && !pProbe->bHasVCol && m!=0) ){ - u32 isCov = whereIsCoveringIndex(pWInfo, pProbe, pSrc->iCursor); - if( isCov==0 ){ - WHERETRACE(0x200, - ("-> %s is not a covering index" - " according to whereIsCoveringIndex()\n", pProbe->zName)); - assert( m!=0 ); - }else{ - m = 0; - pNew->wsFlags |= isCov; - if( isCov & WHERE_IDX_ONLY ){ - WHERETRACE(0x200, - ("-> %s is a covering expression index" - " according to whereIsCoveringIndex()\n", pProbe->zName)); - }else{ - assert( isCov==WHERE_EXPRIDX ); - WHERETRACE(0x200, - ("-> %s might be a covering expression index" - " according to whereIsCoveringIndex()\n", pProbe->zName)); - } - } - }else if( m==0 ){ - WHERETRACE(0x200, - ("-> %s a covering index according to bitmasks\n", - pProbe->zName, m==0 ? "is" : "is not")); - pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED; - } + pNew->wsFlags = (m==0) ? (WHERE_IDX_ONLY|WHERE_INDEXED) : WHERE_INDEXED; } /* Full scan via index */ if( b || !HasRowid(pTab) @@ -161330,18 +155510,11 @@ pNew->rRun = sqlite3LogEstAdd(pNew->rRun, nLookup); } ApplyCostMultiplier(pNew->rRun, pTab->costMult); whereLoopOutputAdjust(pWC, pNew, rSize); - if( (pSrc->fg.jointype & JT_RIGHT)!=0 && pProbe->aColExpr ){ - /* Do not do an SCAN of a index-on-expression in a RIGHT JOIN - ** because the cursor used to access the index might not be - ** positioned to the correct row during the right-join no-match - ** loop. */ - }else{ - rc = whereLoopInsert(pBuilder, pNew); - } + rc = whereLoopInsert(pBuilder, pNew); pNew->nOut = rSize; if( rc ) break; } } @@ -161452,11 +155625,11 @@ if( rc==SQLITE_CONSTRAINT ){ /* If the xBestIndex method returns SQLITE_CONSTRAINT, that means ** that the particular combination of parameters provided is unusable. ** Make no entries in the loop table. */ - WHERETRACE(0xffffffff, (" ^^^^--- non-viable plan rejected!\n")); + WHERETRACE(0xffff, (" ^^^^--- non-viable plan rejected!\n")); return SQLITE_OK; } return rc; } @@ -161512,11 +155685,10 @@ pIdxInfo->orderByConsumed = 0; pIdxInfo->idxFlags &= ~SQLITE_INDEX_SCAN_UNIQUE; *pbIn = 1; assert( (mExclude & WO_IN)==0 ); } - assert( pbRetryLimit || !isLimitTerm(pTerm) ); if( isLimitTerm(pTerm) && *pbIn ){ /* If there is an IN(...) term handled as an == (separate call to ** xFilter for each value on the RHS of the IN) and a LIMIT or ** OFFSET term handled as well, the plan is unusable. Set output ** variable *pbRetryLimit to true to tell the caller to retry with @@ -161563,11 +155735,11 @@ rc = whereLoopInsert(pBuilder, pNew); if( pNew->u.vtab.needFree ){ sqlite3_free(pNew->u.vtab.idxStr); pNew->u.vtab.needFree = 0; } - WHERETRACE(0xffffffff, (" bIn=%d prereqIn=%04llx prereqOut=%04llx\n", + WHERETRACE(0xffff, (" bIn=%d prereqIn=%04llx prereqOut=%04llx\n", *pbIn, (sqlite3_uint64)mPrereq, (sqlite3_uint64)(pNew->prereq & ~mPrereq))); return rc; } @@ -161660,35 +155832,31 @@ /* ** Return true if ORDER BY clause may be handled as DISTINCT. */ SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info *pIdxInfo){ HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; - assert( pHidden->eDistinct>=0 && pHidden->eDistinct<=3 ); + assert( pHidden->eDistinct==0 + || pHidden->eDistinct==1 + || pHidden->eDistinct==2 ); return pHidden->eDistinct; } +#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \ + && !defined(SQLITE_OMIT_VIRTUALTABLE) /* ** Cause the prepared statement that is associated with a call to -** xBestIndex to potentially use all schemas. If the statement being -** prepared is read-only, then just start read transactions on all -** schemas. But if this is a write operation, start writes on all -** schemas. -** +** xBestIndex to open write transactions on all attached schemas. ** This is used by the (built-in) sqlite_dbpage virtual table. */ -SQLITE_PRIVATE void sqlite3VtabUsesAllSchemas(Parse *pParse){ +SQLITE_PRIVATE void sqlite3VtabWriteAll(sqlite3_index_info *pIdxInfo){ + HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; + Parse *pParse = pHidden->pParse; int nDb = pParse->db->nDb; int i; - for(i=0; iwriteMask) ){ - for(i=0; ipNew->iTab. That table is guaranteed to be a virtual table. ** @@ -161750,11 +155918,11 @@ return SQLITE_NOMEM_BKPT; } /* First call xBestIndex() with all constraints usable. */ WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName)); - WHERETRACE(0x800, (" VirtualOne: all usable\n")); + WHERETRACE(0x40, (" VirtualOne: all usable\n")); rc = whereLoopAddVirtualOne( pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, &bRetry ); if( bRetry ){ assert( rc==SQLITE_OK ); @@ -161775,11 +155943,11 @@ Bitmask mBestNoIn = 0; /* If the plan produced by the earlier call uses an IN(...) term, call ** xBestIndex again, this time with IN(...) terms disabled. */ if( bIn ){ - WHERETRACE(0x800, (" VirtualOne: all usable w/o IN\n")); + WHERETRACE(0x40, (" VirtualOne: all usable w/o IN\n")); rc = whereLoopAddVirtualOne( pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn, 0); assert( bIn==0 ); mBestNoIn = pNew->prereq & ~mPrereq; if( mBestNoIn==0 ){ @@ -161801,11 +155969,11 @@ if( mThis>mPrev && mThisprereq==mPrereq ){ seenZero = 1; @@ -161815,21 +155983,21 @@ /* If the calls to xBestIndex() in the above loop did not find a plan ** that requires no source tables at all (i.e. one guaranteed to be ** usable), make a call here with all source tables disabled */ if( rc==SQLITE_OK && seenZero==0 ){ - WHERETRACE(0x800, (" VirtualOne: all disabled\n")); + WHERETRACE(0x40, (" VirtualOne: all disabled\n")); rc = whereLoopAddVirtualOne( pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn, 0); if( bIn==0 ) seenZeroNoIN = 1; } /* If the calls to xBestIndex() have so far failed to find a plan ** that requires no source tables at all and does not use an IN(...) ** operator, make a final call to obtain one here. */ if( rc==SQLITE_OK && seenZeroNoIN==0 ){ - WHERETRACE(0x800, (" VirtualOne: all disabled and w/o IN\n")); + WHERETRACE(0x40, (" VirtualOne: all disabled and w/o IN\n")); rc = whereLoopAddVirtualOne( pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn, 0); } } @@ -161865,13 +156033,10 @@ pNew = pBuilder->pNew; memset(&sSum, 0, sizeof(sSum)); pItem = pWInfo->pTabList->a + pNew->iTab; iCur = pItem->iCursor; - /* The multi-index OR optimization does not work for RIGHT and FULL JOIN */ - if( pItem->fg.jointype & JT_RIGHT ) return SQLITE_OK; - for(pTerm=pWC->a; pTermeOperator & WO_OR)!=0 && (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0 ){ WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc; @@ -161881,11 +156046,11 @@ int i, j; sSubBuild = *pBuilder; sSubBuild.pOrSet = &sCur; - WHERETRACE(0x400, ("Begin processing OR-clause %p\n", pTerm)); + WHERETRACE(0x200, ("Begin processing OR-clause %p\n", pTerm)); for(pOrTerm=pOrWC->a; pOrTermeOperator & WO_AND)!=0 ){ sSubBuild.pWC = &pOrTerm->u.pAndInfo->wc; }else if( pOrTerm->leftCursor==iCur ){ tempWC.pWInfo = pWC->pWInfo; @@ -161898,13 +156063,13 @@ }else{ continue; } sCur.n = 0; #ifdef WHERETRACE_ENABLED - WHERETRACE(0x400, ("OR-term %d of %p has %d subterms:\n", + WHERETRACE(0x200, ("OR-term %d of %p has %d subterms:\n", (int)(pOrTerm-pOrWC->a), pTerm, sSubBuild.pWC->nTerm)); - if( sqlite3WhereTrace & 0x20000 ){ + if( sqlite3WhereTrace & 0x400 ){ sqlite3WhereClausePrint(sSubBuild.pWC); } #endif #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pItem->pTab) ){ @@ -161915,10 +156080,12 @@ rc = whereLoopAddBtree(&sSubBuild, mPrereq); } if( rc==SQLITE_OK ){ rc = whereLoopAddOr(&sSubBuild, mPrereq, mUnusable); } + assert( rc==SQLITE_OK || rc==SQLITE_DONE || sCur.n==0 + || rc==SQLITE_NOMEM ); testcase( rc==SQLITE_NOMEM && sCur.n>0 ); testcase( rc==SQLITE_DONE ); if( sCur.n==0 ){ sSum.n = 0; break; @@ -161960,11 +156127,11 @@ pNew->rRun = sSum.a[i].rRun + 1; pNew->nOut = sSum.a[i].nOut; pNew->prereq = sSum.a[i].prereq; rc = whereLoopInsert(pBuilder, pNew); } - WHERETRACE(0x400, ("End processing OR-clause %p\n", pTerm)); + WHERETRACE(0x200, ("End processing OR-clause %p\n", pTerm)); } } return rc; } @@ -161979,54 +156146,33 @@ SrcList *pTabList = pWInfo->pTabList; SrcItem *pItem; SrcItem *pEnd = &pTabList->a[pWInfo->nLevel]; sqlite3 *db = pWInfo->pParse->db; int rc = SQLITE_OK; - int bFirstPastRJ = 0; - int hasRightJoin = 0; WhereLoop *pNew; - /* Loop over the tables in the join, from left to right */ pNew = pBuilder->pNew; - - /* Verify that pNew has already been initialized */ - assert( pNew->nLTerm==0 ); - assert( pNew->wsFlags==0 ); - assert( pNew->nLSlot>=ArraySize(pNew->aLTermSpace) ); - assert( pNew->aLTerm!=0 ); - + whereLoopInit(pNew); pBuilder->iPlanLimit = SQLITE_QUERY_PLANNER_LIMIT; for(iTab=0, pItem=pTabList->a; pItemiTab = iTab; pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR; pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor); - if( bFirstPastRJ - || (pItem->fg.jointype & (JT_OUTER|JT_CROSS|JT_LTORJ))!=0 - ){ - /* Add prerequisites to prevent reordering of FROM clause terms - ** across CROSS joins and outer joins. The bFirstPastRJ boolean - ** prevents the right operand of a RIGHT JOIN from being swapped with - ** other elements even further to the right. - ** - ** The JT_LTORJ case and the hasRightJoin flag work together to - ** prevent FROM-clause terms from moving from the right side of - ** a LEFT JOIN over to the left side of that join if the LEFT JOIN - ** is itself on the left side of a RIGHT JOIN. - */ - if( pItem->fg.jointype & JT_LTORJ ) hasRightJoin = 1; - mPrereq |= mPrior; - bFirstPastRJ = (pItem->fg.jointype & JT_RIGHT)!=0; - }else if( !hasRightJoin ){ + if( (pItem->fg.jointype & (JT_LEFT|JT_CROSS))!=0 ){ + /* This condition is true when pItem is the FROM clause term on the + ** right-hand-side of a LEFT or CROSS JOIN. */ + mPrereq = mPrior; + }else{ mPrereq = 0; } #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pItem->pTab) ){ SrcItem *p; for(p=&pItem[1]; pfg.jointype & (JT_OUTER|JT_CROSS)) ){ + if( mUnusable || (p->fg.jointype & (JT_LEFT|JT_CROSS)) ){ mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor); } } rc = whereLoopAddVirtual(pBuilder, mPrereq, mUnusable); }else @@ -162147,13 +156293,11 @@ if( wctrlFlags & WHERE_ORDERBY_LIMIT ) continue; }else{ pLoop = pLast; } if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){ - if( pLoop->u.vtab.isOrdered - && ((wctrlFlags&(WHERE_DISTINCTBY|WHERE_SORTBYGROUP))!=WHERE_DISTINCTBY) - ){ + if( pLoop->u.vtab.isOrdered && (wctrlFlags & WHERE_DISTINCTBY)==0 ){ obSat = obDone; } break; }else if( wctrlFlags & WHERE_DISTINCTBY ){ pLoop->u.btree.nDistinctCol = 0; @@ -162308,12 +156452,12 @@ if( iColumn>=XN_ROWID ){ if( pOBExpr->op!=TK_COLUMN && pOBExpr->op!=TK_AGG_COLUMN ) continue; if( pOBExpr->iTable!=iCur ) continue; if( pOBExpr->iColumn!=iColumn ) continue; }else{ - Expr *pIxExpr = pIndex->aColExpr->a[j].pExpr; - if( sqlite3ExprCompareSkip(pOBExpr, pIxExpr, iCur) ){ + Expr *pIdxExpr = pIndex->aColExpr->a[j].pExpr; + if( sqlite3ExprCompareSkip(pOBExpr, pIdxExpr, iCur) ){ continue; } } if( iColumn!=XN_ROWID ){ pColl = sqlite3ExprNNCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr); @@ -162327,22 +156471,20 @@ } if( isMatch && (wctrlFlags & WHERE_GROUPBY)==0 ){ /* Make sure the sort order is compatible in an ORDER BY clause. ** Sort order is irrelevant for a GROUP BY clause. */ if( revSet ){ - if( (rev ^ revIdx) - != (pOrderBy->a[i].fg.sortFlags&KEYINFO_ORDER_DESC) - ){ + if( (rev ^ revIdx)!=(pOrderBy->a[i].sortFlags&KEYINFO_ORDER_DESC) ){ isMatch = 0; } }else{ - rev = revIdx ^ (pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_DESC); + rev = revIdx ^ (pOrderBy->a[i].sortFlags & KEYINFO_ORDER_DESC); if( rev ) *pRevMask |= MASKBIT(iLoop); revSet = 1; } } - if( isMatch && (pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_BIGNULL) ){ + if( isMatch && (pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL) ){ if( j==pLoop->u.btree.nEq ){ pLoop->wsFlags |= WHERE_BIGNULL_SORT; }else{ isMatch = 0; } @@ -162418,11 +156560,11 @@ ** ** SELECT * FROM t1 GROUP BY x,y ORDER BY x,y; -- IsSorted()==1 ** SELECT * FROM t1 GROUP BY y,x ORDER BY y,x; -- IsSorted()==0 */ SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo *pWInfo){ - assert( pWInfo->wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY) ); + assert( pWInfo->wctrlFlags & WHERE_GROUPBY ); assert( pWInfo->wctrlFlags & WHERE_SORTBYGROUP ); return pWInfo->sorted; } #ifdef WHERETRACE_ENABLED @@ -162441,60 +156583,41 @@ ** Return the cost of sorting nRow rows, assuming that the keys have ** nOrderby columns and that the first nSorted columns are already in ** order. */ static LogEst whereSortingCost( - WhereInfo *pWInfo, /* Query planning context */ - LogEst nRow, /* Estimated number of rows to sort */ - int nOrderBy, /* Number of ORDER BY clause terms */ - int nSorted /* Number of initial ORDER BY terms naturally in order */ + WhereInfo *pWInfo, + LogEst nRow, + int nOrderBy, + int nSorted ){ - /* Estimated cost of a full external sort, where N is + /* TUNING: Estimated cost of a full external sort, where N is ** the number of rows to sort is: ** - ** cost = (K * N * log(N)). + ** cost = (3.0 * N * log(N)). ** ** Or, if the order-by clause has X terms but only the last Y ** terms are out of order, then block-sorting will reduce the ** sorting cost to: ** - ** cost = (K * N * log(N)) * (Y/X) - ** - ** The constant K is at least 2.0 but will be larger if there are a - ** large number of columns to be sorted, as the sorting time is - ** proportional to the amount of content to be sorted. The algorithm - ** does not currently distinguish between fat columns (BLOBs and TEXTs) - ** and skinny columns (INTs). It just uses the number of columns as - ** an approximation for the row width. - ** - ** And extra factor of 2.0 or 3.0 is added to the sorting cost if the sort - ** is built using OP_IdxInsert and OP_Sort rather than with OP_SorterInsert. - */ - LogEst rSortCost, nCol; - assert( pWInfo->pSelect!=0 ); - assert( pWInfo->pSelect->pEList!=0 ); - /* TUNING: sorting cost proportional to the number of output columns: */ - nCol = sqlite3LogEst((pWInfo->pSelect->pEList->nExpr+59)/30); - rSortCost = nRow + nCol; - if( nSorted>0 ){ - /* Scale the result by (Y/X) */ - rSortCost += sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66; - } + ** cost = (3.0 * N * log(N)) * (Y/X) + ** + ** The (Y/X) term is implemented using stack variable rScale + ** below. + */ + LogEst rScale, rSortCost; + assert( nOrderBy>0 && 66==sqlite3LogEst(100) ); + rScale = sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66; + rSortCost = nRow + rScale + 16; /* Multiple by log(M) where M is the number of output rows. ** Use the LIMIT for M if it is smaller. Or if this sort is for ** a DISTINCT operator, M will be the number of distinct output ** rows, so fudge it downwards a bit. */ - if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 ){ - rSortCost += 10; /* TUNING: Extra 2.0x if using LIMIT */ - if( nSorted!=0 ){ - rSortCost += 6; /* TUNING: Extra 1.5x if also using partial sort */ - } - if( pWInfo->iLimitiLimit; - } + if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 && pWInfo->iLimitiLimit; }else if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT) ){ /* TUNING: In the sort for a DISTINCT operator, assume that the DISTINCT ** reduces the number of output rows by a factor of 2 */ if( nRow>10 ){ nRow -= 10; assert( 10==sqlite3LogEst(2) ); } } @@ -162516,10 +156639,11 @@ */ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ int mxChoice; /* Maximum number of simultaneous paths tracked */ int nLoop; /* Number of terms in the join */ Parse *pParse; /* Parsing context */ + sqlite3 *db; /* The database connection */ int iLoop; /* Loop counter over the terms of the join */ int ii, jj; /* Loop counters */ int mxI = 0; /* Index of next entry to replace */ int nOrderBy; /* Number of ORDER BY clause terms */ LogEst mxCost = 0; /* Maximum cost of a set of paths */ @@ -162534,10 +156658,11 @@ LogEst *aSortCost = 0; /* Sorting and partial sorting costs */ char *pSpace; /* Temporary memory used by this routine */ int nSpace; /* Bytes of space allocated at pSpace */ pParse = pWInfo->pParse; + db = pParse->db; nLoop = pWInfo->nLevel; /* TUNING: For simple queries, only the best path is tracked. ** For 2-way joins, the 5 best paths are followed. ** For joins of 3 or more tables, track the 10 best paths */ mxChoice = (nLoop<=1) ? 1 : (nLoop==2 ? 5 : 10); @@ -162556,11 +156681,11 @@ } /* Allocate and initialize space for aTo, aFrom and aSortCost[] */ nSpace = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2; nSpace += sizeof(LogEst) * nOrderBy; - pSpace = sqlite3StackAllocRawNN(pParse->db, nSpace); + pSpace = sqlite3DbMallocRawNN(db, nSpace); if( pSpace==0 ) return SQLITE_NOMEM_BKPT; aTo = (WherePath*)pSpace; aFrom = aTo+mxChoice; memset(aFrom, 0, sizeof(aFrom[0])); pX = (WhereLoop**)(aFrom+mxChoice); @@ -162606,13 +156731,13 @@ for(ii=0, pFrom=aFrom; iipLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ LogEst nOut; /* Rows visited by (pFrom+pWLoop) */ LogEst rCost; /* Cost of path (pFrom+pWLoop) */ LogEst rUnsorted; /* Unsorted cost of (pFrom+pWLoop) */ - i8 isOrdered; /* isOrdered for (pFrom+pWLoop) */ + i8 isOrdered = pFrom->isOrdered; /* isOrdered for (pFrom+pWLoop) */ Bitmask maskNew; /* Mask of src visited by (..) */ - Bitmask revMask; /* Mask of rev-order loops for (..) */ + Bitmask revMask = 0; /* Mask of rev-order loops for (..) */ if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue; if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue; if( (pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 && pFrom->nRow<3 ){ /* Do not use an automatic index if the this loop is expected @@ -162627,13 +156752,11 @@ ** Compute its cost */ rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow); rUnsorted = sqlite3LogEstAdd(rUnsorted, pFrom->rUnsorted); nOut = pFrom->nRow + pWLoop->nOut; maskNew = pFrom->maskLoop | pWLoop->maskSelf; - isOrdered = pFrom->isOrdered; if( isOrdered<0 ){ - revMask = 0; isOrdered = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags, iLoop, pWLoop, &revMask); }else{ revMask = pFrom->revLoop; @@ -162642,15 +156765,15 @@ if( aSortCost[isOrdered]==0 ){ aSortCost[isOrdered] = whereSortingCost( pWInfo, nRowEst, nOrderBy, isOrdered ); } - /* TUNING: Add a small extra penalty (3) to sorting as an + /* TUNING: Add a small extra penalty (5) to sorting as an ** extra encouragment to the query planner to select a plan ** where the rows emerge in the correct order without any sorting ** required. */ - rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]) + 3; + rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]) + 5; WHERETRACE(0x002, ("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n", aSortCost[isOrdered], (nOrderBy-isOrdered), nOrderBy, rUnsorted, rCost)); @@ -162657,17 +156780,10 @@ }else{ rCost = rUnsorted; rUnsorted -= 2; /* TUNING: Slight bias in favor of no-sort plans */ } - /* TUNING: A full-scan of a VIEW or subquery in the outer loop - ** is not so bad. */ - if( iLoop==0 && (pWLoop->wsFlags & WHERE_VIEWSCAN)!=0 ){ - rCost += -10; - nOut += -30; - } - /* Check to see if pWLoop should be added to the set of ** mxChoice best-so-far paths. ** ** First look for an existing path among best-so-far paths ** that covers the same set of loops and has the same isOrdered @@ -162814,11 +156930,11 @@ nFrom = nTo; } if( nFrom==0 ){ sqlite3ErrorMsg(pParse, "no query solution"); - sqlite3StackFreeNN(pParse->db, pSpace); + sqlite3DbFreeNN(db, pSpace); return SQLITE_ERROR; } /* Find the lowest cost path. pFrom will be left pointing to that path */ pFrom = aFrom; @@ -162845,20 +156961,16 @@ pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; } } pWInfo->bOrderedInnerLoop = 0; if( pWInfo->pOrderBy ){ - pWInfo->nOBSat = pFrom->isOrdered; if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){ if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){ pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; } - if( pWInfo->pSelect->pOrderBy - && pWInfo->nOBSat > pWInfo->pSelect->pOrderBy->nExpr ){ - pWInfo->nOBSat = pWInfo->pSelect->pOrderBy->nExpr; - } }else{ + pWInfo->nOBSat = pFrom->isOrdered; pWInfo->revMask = pFrom->revLoop; if( pWInfo->nOBSat<=0 ){ pWInfo->nOBSat = 0; if( nLoop>0 ){ u32 wsFlags = pFrom->aLoop[nLoop-1]->wsFlags; @@ -162900,11 +157012,11 @@ pWInfo->nRowOut = pFrom->nRow; /* Free temporary memory and return success */ - sqlite3StackFreeNN(pParse->db, pSpace); + sqlite3DbFreeNN(db, pSpace); return SQLITE_OK; } /* ** Most queries use only a single table (they are not joins) and have @@ -162933,15 +157045,11 @@ if( pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE ) return 0; assert( pWInfo->pTabList->nSrc>=1 ); pItem = pWInfo->pTabList->a; pTab = pItem->pTab; if( IsVirtual(pTab) ) return 0; - if( pItem->fg.isIndexedBy || pItem->fg.notIndexed ){ - testcase( pItem->fg.isIndexedBy ); - testcase( pItem->fg.notIndexed ); - return 0; - } + if( pItem->fg.isIndexedBy ) return 0; iCur = pItem->iCursor; pWC = &pWInfo->sWC; pLoop = pBuilder->pNew; pLoop->wsFlags = 0; pLoop->nSkip = 0; @@ -162998,11 +157106,11 @@ if( scan.iEquiv>1 ) pLoop->wsFlags |= WHERE_TRANSCONS; #ifdef SQLITE_DEBUG pLoop->cId = '0'; #endif #ifdef WHERETRACE_ENABLED - if( sqlite3WhereTrace & 0x02 ){ + if( sqlite3WhereTrace ){ sqlite3DebugPrintf("whereShortCut() used to compute solution\n"); } #endif return 1; } @@ -163110,29 +157218,29 @@ WhereTerm *pTerm, *pEnd; SrcItem *pItem; WhereLoop *pLoop; pLoop = pWInfo->a[i].pWLoop; pItem = &pWInfo->pTabList->a[pLoop->iTab]; - if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ) continue; + if( (pItem->fg.jointype & JT_LEFT)==0 ) continue; if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)==0 && (pLoop->wsFlags & WHERE_ONEROW)==0 ){ continue; } if( (tabUsed & pLoop->maskSelf)!=0 ) continue; pEnd = pWInfo->sWC.a + pWInfo->sWC.nTerm; for(pTerm=pWInfo->sWC.a; pTermprereqAll & pLoop->maskSelf)!=0 ){ - if( !ExprHasProperty(pTerm->pExpr, EP_OuterON) - || pTerm->pExpr->w.iJoin!=pItem->iCursor + if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin) + || pTerm->pExpr->w.iRightJoinTable!=pItem->iCursor ){ break; } } } if( pTerm drop loop %c not used\n", pLoop->cId)); + WHERETRACE(0xffff, ("-> drop loop %c not used\n", pLoop->cId)); notReady &= ~pLoop->maskSelf; for(pTerm=pWInfo->sWC.a; pTermprereqAll & pLoop->maskSelf)!=0 ){ pTerm->wtFlags |= TERM_CODED; } @@ -163167,31 +157275,32 @@ */ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful( const WhereInfo *pWInfo ){ int i; - LogEst nSearch = 0; + LogEst nSearch; assert( pWInfo->nLevel>=2 ); assert( OptimizationEnabled(pWInfo->pParse->db, SQLITE_BloomFilter) ); - for(i=0; inLevel; i++){ + nSearch = pWInfo->a[0].pWLoop->nOut; + for(i=1; inLevel; i++){ WhereLoop *pLoop = pWInfo->a[i].pWLoop; const unsigned int reqFlags = (WHERE_SELFCULL|WHERE_COLUMN_EQ); - SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab]; - Table *pTab = pItem->pTab; - if( (pTab->tabFlags & TF_HasStat1)==0 ) break; - pTab->tabFlags |= TF_StatsUsed; - if( i>=1 - && (pLoop->wsFlags & reqFlags)==reqFlags + if( (pLoop->wsFlags & reqFlags)==reqFlags /* vvvvvv--- Always the case if WHERE_COLUMN_EQ is defined */ && ALWAYS((pLoop->wsFlags & (WHERE_IPK|WHERE_INDEXED))!=0) ){ - if( nSearch > pTab->nRowLogEst ){ + SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab]; + Table *pTab = pItem->pTab; + pTab->tabFlags |= TF_StatsUsed; + if( nSearch > pTab->nRowLogEst + && (pTab->tabFlags & TF_HasStat1)!=0 + ){ testcase( pItem->fg.jointype & JT_LEFT ); pLoop->wsFlags |= WHERE_BLOOMFILTER; pLoop->wsFlags &= ~WHERE_IDX_ONLY; - WHERETRACE(0xffffffff, ( + WHERETRACE(0xffff, ( "-> use Bloom-filter on loop %c because there are ~%.1e " "lookups into %s which has only ~%.1e rows\n", pLoop->cId, (double)sqlite3LogEstToInt(nSearch), pTab->zName, (double)sqlite3LogEstToInt(pTab->nRowLogEst))); } @@ -163198,90 +157307,10 @@ } nSearch += pLoop->nOut; } } -/* -** This is an sqlite3ParserAddCleanup() callback that is invoked to -** free the Parse->pIdxEpr list when the Parse object is destroyed. -*/ -static void whereIndexedExprCleanup(sqlite3 *db, void *pObject){ - Parse *pParse = (Parse*)pObject; - while( pParse->pIdxEpr!=0 ){ - IndexedExpr *p = pParse->pIdxEpr; - pParse->pIdxEpr = p->pIENext; - sqlite3ExprDelete(db, p->pExpr); - sqlite3DbFreeNN(db, p); - } -} - -/* -** The index pIdx is used by a query and contains one or more expressions. -** In other words pIdx is an index on an expression. iIdxCur is the cursor -** number for the index and iDataCur is the cursor number for the corresponding -** table. -** -** This routine adds IndexedExpr entries to the Parse->pIdxEpr field for -** each of the expressions in the index so that the expression code generator -** will know to replace occurrences of the indexed expression with -** references to the corresponding column of the index. -*/ -static SQLITE_NOINLINE void whereAddIndexedExpr( - Parse *pParse, /* Add IndexedExpr entries to pParse->pIdxEpr */ - Index *pIdx, /* The index-on-expression that contains the expressions */ - int iIdxCur, /* Cursor number for pIdx */ - SrcItem *pTabItem /* The FROM clause entry for the table */ -){ - int i; - IndexedExpr *p; - Table *pTab; - assert( pIdx->bHasExpr ); - pTab = pIdx->pTable; - for(i=0; inColumn; i++){ - Expr *pExpr; - int j = pIdx->aiColumn[i]; - int bMaybeNullRow; - if( j==XN_EXPR ){ - pExpr = pIdx->aColExpr->a[i].pExpr; - testcase( pTabItem->fg.jointype & JT_LEFT ); - testcase( pTabItem->fg.jointype & JT_RIGHT ); - testcase( pTabItem->fg.jointype & JT_LTORJ ); - bMaybeNullRow = (pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0; - }else if( j>=0 && (pTab->aCol[j].colFlags & COLFLAG_VIRTUAL)!=0 ){ - pExpr = sqlite3ColumnExpr(pTab, &pTab->aCol[j]); - bMaybeNullRow = 0; - }else{ - continue; - } - if( sqlite3ExprIsConstant(pExpr) ) continue; - p = sqlite3DbMallocRaw(pParse->db, sizeof(IndexedExpr)); - if( p==0 ) break; - p->pIENext = pParse->pIdxEpr; -#ifdef WHERETRACE_ENABLED - if( sqlite3WhereTrace & 0x200 ){ - sqlite3DebugPrintf("New pParse->pIdxEpr term {%d,%d}\n", iIdxCur, i); - if( sqlite3WhereTrace & 0x5000 ) sqlite3ShowExpr(pExpr); - } -#endif - p->pExpr = sqlite3ExprDup(pParse->db, pExpr, 0); - p->iDataCur = pTabItem->iCursor; - p->iIdxCur = iIdxCur; - p->iIdxCol = i; - p->bMaybeNullRow = bMaybeNullRow; - if( sqlite3IndexAffinityStr(pParse->db, pIdx) ){ - p->aff = pIdx->zColAff[i]; - } -#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS - p->zIdxName = pIdx->zName; -#endif - pParse->pIdxEpr = p; - if( p->pIENext==0 ){ - sqlite3ParserAddCleanup(pParse, whereIndexedExprCleanup, pParse); - } - } -} - /* ** 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 sqlite3WhereEnd() with the return value of this function @@ -163372,11 +157401,11 @@ Parse *pParse, /* The parser context */ SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */ Expr *pWhere, /* The WHERE clause */ ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */ ExprList *pResultSet, /* Query result set. Req'd for DISTINCT */ - Select *pSelect, /* The entire SELECT statement */ + Select *pLimit, /* Use this LIMIT/OFFSET clause, if any */ u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */ int iAuxArg /* If WHERE_OR_SUBCLAUSE is set, index cursor number ** If WHERE_USE_LIMIT, then the limit amount */ ){ int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */ @@ -163431,31 +157460,31 @@ ** 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. */ - nByteWInfo = ROUND8P(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel)); + nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel)); pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop)); if( db->mallocFailed ){ sqlite3DbFree(db, pWInfo); pWInfo = 0; goto whereBeginError; } pWInfo->pParse = pParse; pWInfo->pTabList = pTabList; pWInfo->pOrderBy = pOrderBy; -#if WHERETRACE_ENABLED pWInfo->pWhere = pWhere; -#endif pWInfo->pResultSet = pResultSet; pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1; pWInfo->nLevel = nTabList; pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(pParse); pWInfo->wctrlFlags = wctrlFlags; pWInfo->iLimit = iAuxArg; pWInfo->savedNQueryLoop = pParse->nQueryLoop; - pWInfo->pSelect = pSelect; +#ifndef SQLITE_OMIT_VIRTUALTABLE + pWInfo->pLimit = pLimit; +#endif memset(&pWInfo->nOBSat, 0, offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat)); memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel)); assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */ pMaskSet = &pWInfo->sMaskSet; @@ -163520,14 +157549,12 @@ #endif } /* Analyze all of the subexpressions. */ sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC); - if( pSelect && pSelect->pLimit ){ - sqlite3WhereAddLimit(&pWInfo->sWC, pSelect); - } - if( pParse->nErr ) goto whereBeginError; + sqlite3WhereAddLimit(&pWInfo->sWC, pLimit); + if( db->mallocFailed ) goto whereBeginError; /* Special case: WHERE terms that do not refer to any tables in the join ** (constant expressions). Evaluate each such term, and jump over all the ** generated code if the result is not true. ** @@ -163563,30 +157590,30 @@ } } /* Construct the WhereLoop objects */ #if defined(WHERETRACE_ENABLED) - if( sqlite3WhereTrace & 0xffffffff ){ + if( sqlite3WhereTrace & 0xffff ){ sqlite3DebugPrintf("*** Optimizer Start *** (wctrlFlags: 0x%x",wctrlFlags); if( wctrlFlags & WHERE_USE_LIMIT ){ sqlite3DebugPrintf(", limit: %d", iAuxArg); } sqlite3DebugPrintf(")\n"); - if( sqlite3WhereTrace & 0x8000 ){ + if( sqlite3WhereTrace & 0x100 ){ Select sSelect; memset(&sSelect, 0, sizeof(sSelect)); sSelect.selFlags = SF_WhereBegin; sSelect.pSrc = pTabList; sSelect.pWhere = pWhere; sSelect.pOrderBy = pOrderBy; sSelect.pEList = pResultSet; sqlite3TreeViewSelect(0, &sSelect, 0); } - if( sqlite3WhereTrace & 0x4000 ){ /* Display all WHERE clause terms */ - sqlite3DebugPrintf("---- WHERE clause at start of analysis:\n"); - sqlite3WhereClausePrint(sWLB.pWC); - } + } + if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */ + sqlite3DebugPrintf("---- WHERE clause at start of analysis:\n"); + sqlite3WhereClausePrint(sWLB.pWC); } #endif if( nTabList!=1 || whereShortCut(&sWLB)==0 ){ rc = whereLoopAddAll(&sWLB); @@ -163598,11 +157625,11 @@ ** changed based on STAT4 information while computing subsequent loops, ** then we need to rerun the whole loop building process so that all ** loops will be built using the revised truthProb values. */ if( sWLB.bldFlags2 & SQLITE_BLDF2_2NDPASS ){ WHERETRACE_ALL_LOOPS(pWInfo, sWLB.pWC); - WHERETRACE(0xffffffff, + WHERETRACE(0xffff, ("**** Redo all loop computations due to" " TERM_HIGHTRUTH changes ****\n")); while( pWInfo->pLoops ){ WhereLoop *p = pWInfo->pLoops; pWInfo->pLoops = p->pNextLoop; @@ -163684,15 +157711,15 @@ ){ whereCheckIfBloomFilterIsUseful(pWInfo); } #if defined(WHERETRACE_ENABLED) - if( sqlite3WhereTrace & 0x4000 ){ /* Display all terms of the WHERE clause */ + if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */ sqlite3DebugPrintf("---- WHERE clause at end of analysis:\n"); sqlite3WhereClausePrint(sWLB.pWC); } - WHERETRACE(0xffffffff,("*** Optimizer Finished ***\n")); + WHERETRACE(0xffff,("*** Optimizer Finished ***\n")); #endif pWInfo->pParse->nQueryLoop += pWInfo->nRowOut; /* If the caller is an UPDATE or DELETE statement that is requesting ** to use a one-pass algorithm, determine if this is appropriate. @@ -163755,14 +157782,12 @@ sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB); }else if( IsVirtual(pTab) ){ /* noop */ }else #endif - if( ((pLoop->wsFlags & WHERE_IDX_ONLY)==0 - && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0) - || (pTabItem->fg.jointype & (JT_LTORJ|JT_RIGHT))!=0 - ){ + if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 + && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){ int op = OP_OpenRead; if( pWInfo->eOnePass!=ONEPASS_OFF ){ op = OP_OpenWrite; pWInfo->aiCurOnePass[0] = pTabItem->iCursor; }; @@ -163783,11 +157808,11 @@ for(; b; b=b>>1, n++){} sqlite3VdbeChangeP4(v, -1, SQLITE_INT_TO_PTR(n), P4_INT32); assert( n<=pTab->nCol ); } #ifdef SQLITE_ENABLE_CURSOR_HINTS - if( pLoop->u.btree.pIndex!=0 && (pTab->tabFlags & TF_WithoutRowid)==0 ){ + if( pLoop->u.btree.pIndex!=0 ){ sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ|bFordelete); }else #endif { sqlite3VdbeChangeP5(v, bFordelete); @@ -163825,16 +157850,12 @@ }else if( iAuxArg && (wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 ){ iIndexCur = iAuxArg; op = OP_ReopenIdx; }else{ iIndexCur = pParse->nTab++; - if( pIx->bHasExpr && OptimizationEnabled(db, SQLITE_IndexedExpr) ){ - whereAddIndexedExpr(pParse, pIx, iIndexCur, pTabItem); - } } pLevel->iIdxCur = iIndexCur; - assert( pIx!=0 ); assert( pIx->pSchema==pTab->pSchema ); assert( iIndexCur>=0 ); if( op ){ sqlite3VdbeAddOp3(v, op, iIndexCur, pIx->tnum, iDb); sqlite3VdbeSetP4KeyInfo(pParse, pIx); @@ -163864,41 +157885,10 @@ } #endif /* SQLITE_ENABLE_COLUMN_USED_MASK */ } } if( iDb>=0 ) sqlite3CodeVerifySchema(pParse, iDb); - if( (pTabItem->fg.jointype & JT_RIGHT)!=0 - && (pLevel->pRJ = sqlite3WhereMalloc(pWInfo, sizeof(WhereRightJoin)))!=0 - ){ - WhereRightJoin *pRJ = pLevel->pRJ; - pRJ->iMatch = pParse->nTab++; - pRJ->regBloom = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_Blob, 65536, pRJ->regBloom); - pRJ->regReturn = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_Null, 0, pRJ->regReturn); - assert( pTab==pTabItem->pTab ); - if( HasRowid(pTab) ){ - KeyInfo *pInfo; - sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, 1); - pInfo = sqlite3KeyInfoAlloc(pParse->db, 1, 0); - if( pInfo ){ - pInfo->aColl[0] = 0; - pInfo->aSortFlags[0] = 0; - sqlite3VdbeAppendP4(v, pInfo, P4_KEYINFO); - } - }else{ - Index *pPk = sqlite3PrimaryKeyIndex(pTab); - sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, pPk->nKeyCol); - sqlite3VdbeSetP4KeyInfo(pParse, pPk); - } - pLoop->wsFlags &= ~WHERE_IDX_ONLY; - /* The nature of RIGHT JOIN processing is such that it messes up - ** the output order. So omit any ORDER BY/GROUP BY elimination - ** optimizations. We need to do an actual sort for RIGHT JOIN. */ - pWInfo->nOBSat = 0; - pWInfo->eDistinct = WHERE_DISTINCT_UNORDERED; - } } pWInfo->iTop = sqlite3VdbeCurrentAddr(v); if( db->mallocFailed ) goto whereBeginError; /* Generate the code to do the search. Each iteration of the for @@ -163906,24 +157896,13 @@ ** program. */ for(ii=0; iinErr ) goto whereBeginError; pLevel = &pWInfo->a[ii]; wsFlags = pLevel->pWLoop->wsFlags; - pSrc = &pTabList->a[pLevel->iFrom]; - if( pSrc->fg.isMaterialized ){ - if( pSrc->fg.isCorrelated ){ - sqlite3VdbeAddOp2(v, OP_Gosub, pSrc->regReturn, pSrc->addrFillSub); - }else{ - int iOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Gosub, pSrc->regReturn, pSrc->addrFillSub); - sqlite3VdbeJumpHere(v, iOnce); - } - } if( (wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))!=0 ){ if( (wsFlags & WHERE_AUTO_INDEX)!=0 ){ #ifndef SQLITE_OMIT_AUTOMATIC_INDEX constructAutomaticIndex(pParse, &pWInfo->sWC, &pTabList->a[pLevel->iFrom], notReady, pLevel); @@ -163950,10 +157929,12 @@ return pWInfo; /* Jump here if malloc fails */ whereBeginError: if( pWInfo ){ + testcase( pWInfo->pExprMods!=0 ); + whereUndoExprMods(pWInfo); pParse->nQueryLoop = pWInfo->savedNQueryLoop; whereInfoFree(db, pWInfo); } return 0; } @@ -164009,29 +157990,17 @@ WhereLevel *pLevel; WhereLoop *pLoop; SrcList *pTabList = pWInfo->pTabList; sqlite3 *db = pParse->db; int iEnd = sqlite3VdbeCurrentAddr(v); - int nRJ = 0; /* Generate loop termination code. */ VdbeModuleComment((v, "End WHERE-core")); for(i=pWInfo->nLevel-1; i>=0; i--){ int addr; pLevel = &pWInfo->a[i]; - if( pLevel->pRJ ){ - /* Terminate the subroutine that forms the interior of the loop of - ** the RIGHT JOIN table */ - WhereRightJoin *pRJ = pLevel->pRJ; - sqlite3VdbeResolveLabel(v, pLevel->addrCont); - pLevel->addrCont = 0; - pRJ->endSubrtn = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp3(v, OP_Return, pRJ->regReturn, pRJ->addrSubrtn, 1); - VdbeCoverage(v); - nRJ++; - } pLoop = pLevel->pWLoop; if( pLevel->op!=OP_Noop ){ #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT int addrSeek = 0; Index *pIdx; @@ -164055,11 +158024,11 @@ VdbeCoverageIf(v, op==OP_SeekGT); sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2); } #endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */ /* The common case: Advance to the next row */ - if( pLevel->addrCont ) sqlite3VdbeResolveLabel(v, pLevel->addrCont); + sqlite3VdbeResolveLabel(v, pLevel->addrCont); sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3); sqlite3VdbeChangeP5(v, pLevel->p5); VdbeCoverage(v); VdbeCoverageIf(v, pLevel->op==OP_Next); VdbeCoverageIf(v, pLevel->op==OP_Prev); @@ -164070,11 +158039,11 @@ VdbeCoverage(v); } #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek); #endif - }else if( pLevel->addrCont ){ + }else{ sqlite3VdbeResolveLabel(v, pLevel->addrCont); } if( (pLoop->wsFlags & WHERE_IN_ABLE)!=0 && pLevel->u.in.nIn>0 ){ struct InLoop *pIn; int j; @@ -164120,14 +158089,10 @@ } sqlite3VdbeJumpHere(v, pIn->addrInTop-1); } } sqlite3VdbeResolveLabel(v, pLevel->addrBrk); - if( pLevel->pRJ ){ - sqlite3VdbeAddOp3(v, OP_Return, pLevel->pRJ->regReturn, 0, 1); - VdbeCoverage(v); - } if( pLevel->addrSkip ){ sqlite3VdbeGoto(v, pLevel->addrSkip); VdbeComment((v, "next skip-scan on %s", pLoop->u.btree.pIndex->zName)); sqlite3VdbeJumpHere(v, pLevel->addrSkip); sqlite3VdbeJumpHere(v, pLevel->addrSkip-2); @@ -164167,10 +158132,15 @@ } VdbeModuleComment((v, "End WHERE-loop%d: %s", i, pWInfo->pTabList->a[pLevel->iFrom].pTab->zName)); } + /* The "break" point is here, just past the end of the outer loop. + ** Set it. + */ + sqlite3VdbeResolveLabel(v, pWInfo->iBreak); + assert( pWInfo->nLevel<=pTabList->nSrc ); for(i=0, pLevel=pWInfo->a; inLevel; i++, pLevel++){ int k, last; VdbeOp *pOp, *pLastOp; Index *pIdx = 0; @@ -164177,19 +158147,10 @@ SrcItem *pTabItem = &pTabList->a[pLevel->iFrom]; Table *pTab = pTabItem->pTab; assert( pTab!=0 ); pLoop = pLevel->pWLoop; - /* Do RIGHT JOIN processing. Generate code that will output the - ** unmatched rows of the right operand of the RIGHT JOIN with - ** all of the columns of the left operand set to NULL. - */ - if( pLevel->pRJ ){ - sqlite3WhereRightJoinLoop(pWInfo, i, pLevel); - continue; - } - /* For a co-routine, change all OP_Column references to the table of ** the co-routine into OP_Copy of result contained in a register. ** OP_Rowid becomes OP_Null. */ if( pTabItem->fg.viaCoroutine ){ @@ -164196,10 +158157,33 @@ testcase( pParse->db->mallocFailed ); translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur, pTabItem->regResult, 0); continue; } + +#ifdef SQLITE_ENABLE_EARLY_CURSOR_CLOSE + /* Close all of the cursors that were opened by sqlite3WhereBegin. + ** Except, do not close cursors that will be reused by the OR optimization + ** (WHERE_OR_SUBCLAUSE). And do not close the OP_OpenWrite cursors + ** created for the ONEPASS optimization. + */ + if( (pTab->tabFlags & TF_Ephemeral)==0 + && !IsView(pTab) + && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 + ){ + int ws = pLoop->wsFlags; + if( pWInfo->eOnePass==ONEPASS_OFF && (ws & WHERE_IDX_ONLY)==0 ){ + sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor); + } + if( (ws & WHERE_INDEXED)!=0 + && (ws & (WHERE_IPK|WHERE_AUTO_INDEX))==0 + && pLevel->iIdxCur!=pWInfo->aiCurOnePass[1] + ){ + sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur); + } + } +#endif /* If this scan uses an index, make VDBE code substitutions to read data ** from the index instead of from the table where possible. In some cases ** this optimization prevents the table from ever being read, which can ** yield a significant performance boost. @@ -164221,32 +158205,14 @@ if( pWInfo->eOnePass==ONEPASS_OFF || !HasRowid(pIdx->pTable) ){ last = iEnd; }else{ last = pWInfo->iEndWhere; } - if( pIdx->bHasExpr ){ - IndexedExpr *p = pParse->pIdxEpr; - while( p ){ - if( p->iIdxCur==pLevel->iIdxCur ){ -#ifdef WHERETRACE_ENABLED - if( sqlite3WhereTrace & 0x200 ){ - sqlite3DebugPrintf("Disable pParse->pIdxEpr term {%d,%d}\n", - p->iIdxCur, p->iIdxCol); - if( sqlite3WhereTrace & 0x5000 ) sqlite3ShowExpr(p->pExpr); - } -#endif - p->iDataCur = -1; - p->iIdxCur = -1; - } - p = p->pIENext; - } - } k = pLevel->addrBody + 1; #ifdef SQLITE_DEBUG if( db->flags & SQLITE_VdbeAddopTrace ){ - printf("TRANSLATE cursor %d->%d in opcode range %d..%d\n", - pLevel->iTabCur, pLevel->iIdxCur, k, last-1); + printf("TRANSLATE opcodes in range %d..%d\n", k, last-1); } /* Proof that the "+1" on the k value above is safe */ pOp = sqlite3VdbeGetOp(v, k - 1); assert( pOp->opcode!=OP_Column || pOp->p1!=pLevel->iTabCur ); assert( pOp->opcode!=OP_Rowid || pOp->p1!=pLevel->iTabCur ); @@ -164315,20 +158281,15 @@ if( db->flags & SQLITE_VdbeAddopTrace ) printf("TRANSLATE complete\n"); #endif } } - /* The "break" point is here, just past the end of the outer loop. - ** Set it. - */ - sqlite3VdbeResolveLabel(v, pWInfo->iBreak); - /* Final cleanup */ + if( pWInfo->pExprMods ) whereUndoExprMods(pWInfo); pParse->nQueryLoop = pWInfo->savedNQueryLoop; whereInfoFree(db, pWInfo); - pParse->withinRJSubrtn -= nRJ; return; } /************** End of where.c ***********************************************/ /************** Begin file window.c ******************************************/ @@ -165056,11 +159017,11 @@ break; } } } } - pWin->pWFunc = pFunc; + pWin->pFunc = pFunc; } /* ** Context object passed through sqlite3WalkExprList() to ** selectWindowRewriteExprCb() by selectWindowRewriteEList(). @@ -165117,11 +159078,10 @@ } } } /* no break */ deliberate_fall_through - case TK_IF_NULL_ROW: case TK_AGG_FUNCTION: case TK_COLUMN: { int iCol = -1; if( pParse->db->mallocFailed ) return WRC_Abort; if( p->pSub ){ @@ -165233,10 +159193,11 @@ int i; int nInit = pList ? pList->nExpr : 0; for(i=0; inExpr; i++){ sqlite3 *db = pParse->db; Expr *pDup = sqlite3ExprDup(db, pAppend->a[i].pExpr, 0); + assert( pDup==0 || !ExprHasProperty(pDup, EP_MemToken) ); if( db->mallocFailed ){ sqlite3ExprDelete(db, pDup); break; } if( bIntToNull ){ @@ -165248,11 +159209,11 @@ pSub->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse); pSub->u.zToken = 0; } } pList = sqlite3ExprListAppend(pParse, pList, pDup); - if( pList ) pList->a[nInit+i].fg.sortFlags = pAppend->a[i].fg.sortFlags; + if( pList ) pList->a[nInit+i].sortFlags = pAppend->a[i].sortFlags; } } return pList; } @@ -165368,13 +159329,13 @@ ** window function - one for the accumulator, another for interim ** results. */ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ ExprList *pArgs; assert( ExprUseXList(pWin->pOwner) ); - assert( pWin->pWFunc!=0 ); + assert( pWin->pFunc!=0 ); pArgs = pWin->pOwner->x.pList; - if( pWin->pWFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){ + if( pWin->pFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){ selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist); pWin->iArgCol = (pSublist ? pSublist->nExpr : 0); pWin->bExprArgs = 1; }else{ pWin->iArgCol = (pSublist ? pSublist->nExpr : 0); @@ -165402,21 +159363,20 @@ } pSub = sqlite3SelectNew( pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0 ); - TREETRACE(0x40,pParse,pSub, + SELECTTRACE(1,pParse,pSub, ("New window-function subquery in FROM clause of (%u/%p)\n", p->selId, p)); p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); assert( pSub!=0 || p->pSrc==0 ); /* Due to db->mallocFailed test inside ** of sqlite3DbMallocRawNN() called from ** sqlite3SrcListAppend() */ if( p->pSrc ){ Table *pTab2; p->pSrc->a[0].pSelect = pSub; - p->pSrc->a[0].fg.isCorrelated = 1; sqlite3SrcListAssignCursors(pParse, p->pSrc); pSub->selFlags |= SF_Expanded|SF_OrderByReqd; pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE); pSub->selFlags |= (selFlags & SF_Aggregate); if( pTab2==0 ){ @@ -165753,11 +159713,11 @@ sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->csrApp, pMWin->iEphCsr); return; } for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ - FuncDef *p = pWin->pWFunc; + FuncDef *p = pWin->pFunc; if( (p->funcFlags & SQLITE_FUNC_MINMAX) && pWin->eStart!=TK_UNBOUNDED ){ /* The inline versions of min() and max() require a single ephemeral ** table and 3 registers. The registers are used as follows: ** ** regApp+0: slot to copy min()/max() argument to for MakeRecord @@ -165770,11 +159730,11 @@ pList = pWin->pOwner->x.pList; pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0); pWin->csrApp = pParse->nTab++; pWin->regApp = pParse->nMem+1; pParse->nMem += 3; - if( pKeyInfo && pWin->pWFunc->zName[1]=='i' ){ + if( pKeyInfo && pWin->pFunc->zName[1]=='i' ){ assert( pKeyInfo->aSortFlags[0]==0 ); pKeyInfo->aSortFlags[0] = KEYINFO_ORDER_DESC; } sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2); sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO); @@ -165993,11 +159953,11 @@ ){ Parse *pParse = p->pParse; Vdbe *v = sqlite3GetVdbe(pParse); Window *pWin; for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ - FuncDef *pFunc = pWin->pWFunc; + FuncDef *pFunc = pWin->pFunc; int regArg; int nArg = pWin->bExprArgs ? 0 : windowArgCount(pWin); int i; assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED ); @@ -166107,11 +160067,11 @@ Vdbe *v = sqlite3GetVdbe(pParse); Window *pWin; for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ if( pMWin->regStartRowid==0 - && (pWin->pWFunc->funcFlags & SQLITE_FUNC_MINMAX) + && (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX) && (pWin->eStart!=TK_UNBOUNDED) ){ sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult); sqlite3VdbeAddOp1(v, OP_Last, pWin->csrApp); VdbeCoverage(v); @@ -166121,16 +160081,16 @@ assert( pMWin->regStartRowid==0 ); }else{ int nArg = windowArgCount(pWin); if( bFin ){ sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, nArg); - sqlite3VdbeAppendP4(v, pWin->pWFunc, P4_FUNCDEF); + sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF); sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult); sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); }else{ sqlite3VdbeAddOp3(v, OP_AggValue,pWin->regAccum,nArg,pWin->regResult); - sqlite3VdbeAppendP4(v, pWin->pWFunc, P4_FUNCDEF); + sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF); } } } } @@ -166255,11 +160215,11 @@ }else{ Parse *pParse = p->pParse; Window *pWin; for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ - FuncDef *pFunc = pWin->pWFunc; + FuncDef *pFunc = pWin->pFunc; assert( ExprUseXList(pWin->pOwner) ); if( pFunc->zName==nth_valueName || pFunc->zName==first_valueName ){ int csr = pWin->csrApp; @@ -166327,11 +160287,11 @@ Vdbe *v = sqlite3GetVdbe(pParse); int regArg; int nArg = 0; Window *pWin; for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ - FuncDef *pFunc = pWin->pWFunc; + FuncDef *pFunc = pWin->pFunc; assert( pWin->regAccum ); sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); nArg = MAX(nArg, windowArgCount(pWin)); if( pMWin->regStartRowid==0 ){ if( pFunc->zName==nth_valueName || pFunc->zName==first_valueName ){ @@ -166357,11 +160317,11 @@ */ static int windowCacheFrame(Window *pMWin){ Window *pWin; if( pMWin->regStartRowid ) return 1; for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ - FuncDef *pFunc = pWin->pWFunc; + FuncDef *pFunc = pWin->pFunc; if( (pFunc->zName==nth_valueName) || (pFunc->zName==first_valueName) || (pFunc->zName==leadName) || (pFunc->zName==lagName) ){ @@ -166450,11 +160410,11 @@ windowReadPeerValues(p, csr1, reg1); windowReadPeerValues(p, csr2, reg2); assert( op==OP_Ge || op==OP_Gt || op==OP_Le ); assert( pOrderBy && pOrderBy->nExpr==1 ); - if( pOrderBy->a[0].fg.sortFlags & KEYINFO_ORDER_DESC ){ + if( pOrderBy->a[0].sortFlags & KEYINFO_ORDER_DESC ){ switch( op ){ case OP_Ge: op = OP_Le; break; case OP_Gt: op = OP_Lt; break; default: assert( op==OP_Le ); op = OP_Ge; break; } @@ -166483,11 +160443,11 @@ ** } ** ** Additionally, if either reg1 or reg2 are NULL but the jump to lbl is ** not taken, control jumps over the comparison operator coded below this ** block. */ - if( pOrderBy->a[0].fg.sortFlags & KEYINFO_ORDER_BIGNULL ){ + if( pOrderBy->a[0].sortFlags & KEYINFO_ORDER_BIGNULL ){ /* This block runs if reg1 contains a NULL. */ int addr = sqlite3VdbeAddOp1(v, OP_NotNull, reg1); VdbeCoverage(v); switch( op ){ case OP_Ge: sqlite3VdbeAddOp2(v, OP_Goto, 0, lbl); @@ -166504,13 +160464,14 @@ } sqlite3VdbeAddOp2(v, OP_Goto, 0, addrDone); /* This block runs if reg1 is not NULL, but reg2 is. */ sqlite3VdbeJumpHere(v, addr); - sqlite3VdbeAddOp2(v, OP_IsNull, reg2, - (op==OP_Gt || op==OP_Ge) ? addrDone : lbl); - VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); VdbeCoverage(v); + if( op==OP_Gt || op==OP_Ge ){ + sqlite3VdbeChangeP2(v, -1, addrDone); + } } /* Register reg1 currently contains csr1.peerVal (the peer-value from csr1). ** This block adds (or subtracts for DESC) the numeric value in regVal ** from it. Or, if reg1 is not numeric (it is a NULL, a text value or a blob), @@ -166714,11 +160675,11 @@ pNew = sqlite3DbMallocZero(db, sizeof(Window)); if( pNew ){ pNew->zName = sqlite3DbStrDup(db, p->zName); pNew->zBase = sqlite3DbStrDup(db, p->zBase); pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0); - pNew->pWFunc = p->pWFunc; + pNew->pFunc = p->pFunc; pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0); pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0); pNew->eFrmType = p->eFrmType; pNew->eEnd = p->eEnd; pNew->eStart = p->eStart; @@ -167278,11 +161239,12 @@ int op = ((pMWin->eStart==TK_FOLLOWING) ? OP_Ge : OP_Le); int addrGe = sqlite3VdbeAddOp3(v, op, regStart, 0, regEnd); VdbeCoverageNeverNullIf(v, op==OP_Ge); /* NeverNull because bound */ VdbeCoverageNeverNullIf(v, op==OP_Le); /* values previously checked */ windowAggFinal(&s, 0); - sqlite3VdbeAddOp1(v, OP_Rewind, s.current.csr); + sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1); + VdbeCoverageNeverTaken(v); windowReturnOneRow(&s); sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr); sqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd); sqlite3VdbeJumpHere(v, addrGe); } @@ -167290,14 +161252,17 @@ assert( pMWin->eEnd==TK_FOLLOWING ); sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regStart); } if( pMWin->eStart!=TK_UNBOUNDED ){ - sqlite3VdbeAddOp1(v, OP_Rewind, s.start.csr); + sqlite3VdbeAddOp2(v, OP_Rewind, s.start.csr, 1); + VdbeCoverageNeverTaken(v); } - sqlite3VdbeAddOp1(v, OP_Rewind, s.current.csr); - sqlite3VdbeAddOp1(v, OP_Rewind, s.end.csr); + sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1); + VdbeCoverageNeverTaken(v); + sqlite3VdbeAddOp2(v, OP_Rewind, s.end.csr, 1); + VdbeCoverageNeverTaken(v); if( regPeer && pOrderBy ){ sqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, pOrderBy->nExpr-1); sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.start.reg, pOrderBy->nExpr-1); sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.current.reg, pOrderBy->nExpr-1); sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.end.reg, pOrderBy->nExpr-1); @@ -167596,11 +161561,11 @@ /* memset(p, 0, sizeof(Expr)); */ p->op = (u8)op; p->affExpr = 0; p->flags = EP_Leaf; ExprClearVVAProperties(p); - /* p->iAgg = -1; // Not required */ + p->iAgg = -1; p->pLeft = p->pRight = 0; p->pAggInfo = 0; memset(&p->x, 0, sizeof(p->x)); memset(&p->y, 0, sizeof(p->y)); p->op2 = 0; @@ -167929,11 +161894,10 @@ Upsert* yy444; u8 yy516; With* yy521; const char* yy522; Expr* yy528; - OnOrUsing yy561; struct FrameBound yy595; } YYMINORTYPE; #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 #endif @@ -167946,22 +161910,22 @@ #define sqlite3ParserCTX_PDECL ,Parse *pParse #define sqlite3ParserCTX_PARAM ,pParse #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse; #define sqlite3ParserCTX_STORE yypParser->pParse=pParse; #define YYFALLBACK 1 -#define YYNSTATE 575 -#define YYNRULE 403 -#define YYNRULE_WITH_ACTION 341 +#define YYNSTATE 574 +#define YYNRULE 402 +#define YYNRULE_WITH_ACTION 340 #define YYNTOKEN 185 -#define YY_MAX_SHIFT 574 -#define YY_MIN_SHIFTREDUCE 833 -#define YY_MAX_SHIFTREDUCE 1235 -#define YY_ERROR_ACTION 1236 -#define YY_ACCEPT_ACTION 1237 -#define YY_NO_ACTION 1238 -#define YY_MIN_REDUCE 1239 -#define YY_MAX_REDUCE 1641 +#define YY_MAX_SHIFT 573 +#define YY_MIN_SHIFTREDUCE 831 +#define YY_MAX_SHIFTREDUCE 1232 +#define YY_ERROR_ACTION 1233 +#define YY_ACCEPT_ACTION 1234 +#define YY_NO_ACTION 1235 +#define YY_MIN_REDUCE 1236 +#define YY_MAX_REDUCE 1637 /************* End control #defines *******************************************/ #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) /* Define the yytestcase() macro to be a no-op if is not already defined ** otherwise. @@ -168024,434 +161988,431 @@ ** yy_reduce_ofst[] For each state, the offset into yy_action for ** shifting non-terminals after a reduce. ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (2096) +#define YY_ACTTAB_COUNT (2070) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 568, 208, 568, 118, 115, 229, 568, 118, 115, 229, - /* 10 */ 568, 1310, 377, 1289, 408, 562, 562, 562, 568, 409, - /* 20 */ 378, 1310, 1272, 41, 41, 41, 41, 208, 1521, 71, - /* 30 */ 71, 969, 419, 41, 41, 491, 303, 279, 303, 970, - /* 40 */ 397, 71, 71, 125, 126, 80, 1213, 1213, 1047, 1050, - /* 50 */ 1037, 1037, 123, 123, 124, 124, 124, 124, 476, 409, - /* 60 */ 1237, 1, 1, 574, 2, 1241, 550, 118, 115, 229, - /* 70 */ 317, 480, 146, 480, 524, 118, 115, 229, 529, 1323, - /* 80 */ 417, 523, 142, 125, 126, 80, 1213, 1213, 1047, 1050, - /* 90 */ 1037, 1037, 123, 123, 124, 124, 124, 124, 118, 115, - /* 100 */ 229, 327, 122, 122, 122, 122, 121, 121, 120, 120, - /* 110 */ 120, 119, 116, 444, 284, 284, 284, 284, 442, 442, - /* 120 */ 442, 1562, 376, 1564, 1189, 375, 1160, 565, 1160, 565, - /* 130 */ 409, 1562, 537, 259, 226, 444, 101, 145, 449, 316, - /* 140 */ 559, 240, 122, 122, 122, 122, 121, 121, 120, 120, - /* 150 */ 120, 119, 116, 444, 125, 126, 80, 1213, 1213, 1047, - /* 160 */ 1050, 1037, 1037, 123, 123, 124, 124, 124, 124, 142, - /* 170 */ 294, 1189, 339, 448, 120, 120, 120, 119, 116, 444, - /* 180 */ 127, 1189, 1190, 1189, 148, 441, 440, 568, 119, 116, - /* 190 */ 444, 124, 124, 124, 124, 117, 122, 122, 122, 122, - /* 200 */ 121, 121, 120, 120, 120, 119, 116, 444, 454, 113, - /* 210 */ 13, 13, 546, 122, 122, 122, 122, 121, 121, 120, - /* 220 */ 120, 120, 119, 116, 444, 422, 316, 559, 1189, 1190, - /* 230 */ 1189, 149, 1220, 409, 1220, 124, 124, 124, 124, 122, - /* 240 */ 122, 122, 122, 121, 121, 120, 120, 120, 119, 116, - /* 250 */ 444, 465, 342, 1034, 1034, 1048, 1051, 125, 126, 80, - /* 260 */ 1213, 1213, 1047, 1050, 1037, 1037, 123, 123, 124, 124, - /* 270 */ 124, 124, 1275, 522, 222, 1189, 568, 409, 224, 514, - /* 280 */ 175, 82, 83, 122, 122, 122, 122, 121, 121, 120, - /* 290 */ 120, 120, 119, 116, 444, 1005, 16, 16, 1189, 133, - /* 300 */ 133, 125, 126, 80, 1213, 1213, 1047, 1050, 1037, 1037, - /* 310 */ 123, 123, 124, 124, 124, 124, 122, 122, 122, 122, - /* 320 */ 121, 121, 120, 120, 120, 119, 116, 444, 1038, 546, - /* 330 */ 1189, 373, 1189, 1190, 1189, 252, 1429, 399, 504, 501, - /* 340 */ 500, 111, 560, 566, 4, 924, 924, 433, 499, 340, - /* 350 */ 460, 328, 360, 394, 1233, 1189, 1190, 1189, 563, 568, - /* 360 */ 122, 122, 122, 122, 121, 121, 120, 120, 120, 119, - /* 370 */ 116, 444, 284, 284, 369, 1575, 1601, 441, 440, 154, - /* 380 */ 409, 445, 71, 71, 1282, 565, 1217, 1189, 1190, 1189, - /* 390 */ 85, 1219, 271, 557, 543, 515, 1556, 568, 98, 1218, - /* 400 */ 6, 1274, 472, 142, 125, 126, 80, 1213, 1213, 1047, - /* 410 */ 1050, 1037, 1037, 123, 123, 124, 124, 124, 124, 550, - /* 420 */ 13, 13, 1024, 507, 1220, 1189, 1220, 549, 109, 109, - /* 430 */ 222, 568, 1234, 175, 568, 427, 110, 197, 445, 569, - /* 440 */ 445, 430, 1547, 1014, 325, 551, 1189, 270, 287, 368, - /* 450 */ 510, 363, 509, 257, 71, 71, 543, 71, 71, 359, - /* 460 */ 316, 559, 1607, 122, 122, 122, 122, 121, 121, 120, - /* 470 */ 120, 120, 119, 116, 444, 1014, 1014, 1016, 1017, 27, - /* 480 */ 284, 284, 1189, 1190, 1189, 1155, 568, 1606, 409, 899, - /* 490 */ 190, 550, 356, 565, 550, 935, 533, 517, 1155, 516, - /* 500 */ 413, 1155, 552, 1189, 1190, 1189, 568, 544, 1549, 51, - /* 510 */ 51, 214, 125, 126, 80, 1213, 1213, 1047, 1050, 1037, - /* 520 */ 1037, 123, 123, 124, 124, 124, 124, 1189, 474, 135, - /* 530 */ 135, 409, 284, 284, 1485, 505, 121, 121, 120, 120, - /* 540 */ 120, 119, 116, 444, 1005, 565, 518, 217, 541, 1556, - /* 550 */ 316, 559, 142, 6, 532, 125, 126, 80, 1213, 1213, - /* 560 */ 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, 124, - /* 570 */ 1550, 122, 122, 122, 122, 121, 121, 120, 120, 120, - /* 580 */ 119, 116, 444, 485, 1189, 1190, 1189, 482, 281, 1263, - /* 590 */ 955, 252, 1189, 373, 504, 501, 500, 1189, 340, 570, - /* 600 */ 1189, 570, 409, 292, 499, 955, 874, 191, 480, 316, - /* 610 */ 559, 384, 290, 380, 122, 122, 122, 122, 121, 121, - /* 620 */ 120, 120, 120, 119, 116, 444, 125, 126, 80, 1213, - /* 630 */ 1213, 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, - /* 640 */ 124, 409, 394, 1133, 1189, 867, 100, 284, 284, 1189, - /* 650 */ 1190, 1189, 373, 1090, 1189, 1190, 1189, 1189, 1190, 1189, - /* 660 */ 565, 455, 32, 373, 233, 125, 126, 80, 1213, 1213, - /* 670 */ 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, 124, - /* 680 */ 1428, 957, 568, 228, 956, 122, 122, 122, 122, 121, - /* 690 */ 121, 120, 120, 120, 119, 116, 444, 1155, 228, 1189, - /* 700 */ 157, 1189, 1190, 1189, 1548, 13, 13, 301, 955, 1228, - /* 710 */ 1155, 153, 409, 1155, 373, 1578, 1173, 5, 369, 1575, - /* 720 */ 429, 1234, 3, 955, 122, 122, 122, 122, 121, 121, - /* 730 */ 120, 120, 120, 119, 116, 444, 125, 126, 80, 1213, - /* 740 */ 1213, 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, - /* 750 */ 124, 409, 208, 567, 1189, 1025, 1189, 1190, 1189, 1189, - /* 760 */ 388, 850, 155, 1547, 286, 402, 1095, 1095, 488, 568, - /* 770 */ 465, 342, 1315, 1315, 1547, 125, 126, 80, 1213, 1213, - /* 780 */ 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, 124, - /* 790 */ 129, 568, 13, 13, 374, 122, 122, 122, 122, 121, - /* 800 */ 121, 120, 120, 120, 119, 116, 444, 302, 568, 453, - /* 810 */ 528, 1189, 1190, 1189, 13, 13, 1189, 1190, 1189, 1293, - /* 820 */ 463, 1263, 409, 1313, 1313, 1547, 1010, 453, 452, 200, - /* 830 */ 299, 71, 71, 1261, 122, 122, 122, 122, 121, 121, - /* 840 */ 120, 120, 120, 119, 116, 444, 125, 126, 80, 1213, - /* 850 */ 1213, 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, - /* 860 */ 124, 409, 227, 1070, 1155, 284, 284, 419, 312, 278, - /* 870 */ 278, 285, 285, 1415, 406, 405, 382, 1155, 565, 568, - /* 880 */ 1155, 1192, 565, 1595, 565, 125, 126, 80, 1213, 1213, - /* 890 */ 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, 124, - /* 900 */ 453, 1477, 13, 13, 1531, 122, 122, 122, 122, 121, - /* 910 */ 121, 120, 120, 120, 119, 116, 444, 201, 568, 354, - /* 920 */ 1581, 574, 2, 1241, 838, 839, 840, 1557, 317, 1208, - /* 930 */ 146, 6, 409, 255, 254, 253, 206, 1323, 9, 1192, - /* 940 */ 262, 71, 71, 424, 122, 122, 122, 122, 121, 121, - /* 950 */ 120, 120, 120, 119, 116, 444, 125, 126, 80, 1213, - /* 960 */ 1213, 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, - /* 970 */ 124, 568, 284, 284, 568, 1209, 409, 573, 313, 1241, - /* 980 */ 349, 1292, 352, 419, 317, 565, 146, 491, 525, 1637, - /* 990 */ 395, 371, 491, 1323, 70, 70, 1291, 71, 71, 240, - /* 1000 */ 1321, 104, 80, 1213, 1213, 1047, 1050, 1037, 1037, 123, - /* 1010 */ 123, 124, 124, 124, 124, 122, 122, 122, 122, 121, - /* 1020 */ 121, 120, 120, 120, 119, 116, 444, 1111, 284, 284, - /* 1030 */ 428, 448, 1520, 1209, 439, 284, 284, 1484, 1348, 311, - /* 1040 */ 474, 565, 1112, 969, 491, 491, 217, 1259, 565, 1533, - /* 1050 */ 568, 970, 207, 568, 1024, 240, 383, 1113, 519, 122, - /* 1060 */ 122, 122, 122, 121, 121, 120, 120, 120, 119, 116, - /* 1070 */ 444, 1015, 107, 71, 71, 1014, 13, 13, 910, 568, - /* 1080 */ 1490, 568, 284, 284, 97, 526, 491, 448, 911, 1322, - /* 1090 */ 1318, 545, 409, 284, 284, 565, 151, 209, 1490, 1492, - /* 1100 */ 262, 450, 55, 55, 56, 56, 565, 1014, 1014, 1016, - /* 1110 */ 443, 332, 409, 527, 12, 295, 125, 126, 80, 1213, - /* 1120 */ 1213, 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, - /* 1130 */ 124, 347, 409, 862, 1529, 1209, 125, 126, 80, 1213, - /* 1140 */ 1213, 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, - /* 1150 */ 124, 1134, 1635, 474, 1635, 371, 125, 114, 80, 1213, - /* 1160 */ 1213, 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, - /* 1170 */ 124, 1490, 329, 474, 331, 122, 122, 122, 122, 121, - /* 1180 */ 121, 120, 120, 120, 119, 116, 444, 203, 1415, 568, - /* 1190 */ 1290, 862, 464, 1209, 436, 122, 122, 122, 122, 121, - /* 1200 */ 121, 120, 120, 120, 119, 116, 444, 553, 1134, 1636, - /* 1210 */ 539, 1636, 15, 15, 890, 122, 122, 122, 122, 121, - /* 1220 */ 121, 120, 120, 120, 119, 116, 444, 568, 298, 538, - /* 1230 */ 1132, 1415, 1554, 1555, 1327, 409, 6, 6, 1166, 1264, - /* 1240 */ 415, 320, 284, 284, 1415, 508, 565, 525, 300, 457, - /* 1250 */ 43, 43, 568, 891, 12, 565, 330, 478, 425, 407, - /* 1260 */ 126, 80, 1213, 1213, 1047, 1050, 1037, 1037, 123, 123, - /* 1270 */ 124, 124, 124, 124, 568, 57, 57, 288, 1189, 1415, - /* 1280 */ 496, 458, 392, 392, 391, 273, 389, 1132, 1553, 847, - /* 1290 */ 1166, 407, 6, 568, 321, 1155, 470, 44, 44, 1552, - /* 1300 */ 1111, 426, 234, 6, 323, 256, 540, 256, 1155, 431, - /* 1310 */ 568, 1155, 322, 17, 487, 1112, 58, 58, 122, 122, - /* 1320 */ 122, 122, 121, 121, 120, 120, 120, 119, 116, 444, - /* 1330 */ 1113, 216, 481, 59, 59, 1189, 1190, 1189, 111, 560, - /* 1340 */ 324, 4, 236, 456, 526, 568, 237, 456, 568, 437, - /* 1350 */ 168, 556, 420, 141, 479, 563, 568, 293, 568, 1092, - /* 1360 */ 568, 293, 568, 1092, 531, 568, 870, 8, 60, 60, - /* 1370 */ 235, 61, 61, 568, 414, 568, 414, 568, 445, 62, - /* 1380 */ 62, 45, 45, 46, 46, 47, 47, 199, 49, 49, - /* 1390 */ 557, 568, 359, 568, 100, 486, 50, 50, 63, 63, - /* 1400 */ 64, 64, 561, 415, 535, 410, 568, 1024, 568, 534, - /* 1410 */ 316, 559, 316, 559, 65, 65, 14, 14, 568, 1024, - /* 1420 */ 568, 512, 930, 870, 1015, 109, 109, 929, 1014, 66, - /* 1430 */ 66, 131, 131, 110, 451, 445, 569, 445, 416, 177, - /* 1440 */ 1014, 132, 132, 67, 67, 568, 467, 568, 930, 471, - /* 1450 */ 1360, 283, 226, 929, 315, 1359, 407, 568, 459, 407, - /* 1460 */ 1014, 1014, 1016, 239, 407, 86, 213, 1346, 52, 52, - /* 1470 */ 68, 68, 1014, 1014, 1016, 1017, 27, 1580, 1177, 447, - /* 1480 */ 69, 69, 288, 97, 108, 1536, 106, 392, 392, 391, - /* 1490 */ 273, 389, 568, 877, 847, 881, 568, 111, 560, 466, - /* 1500 */ 4, 568, 152, 30, 38, 568, 1129, 234, 396, 323, - /* 1510 */ 111, 560, 527, 4, 563, 53, 53, 322, 568, 163, - /* 1520 */ 163, 568, 337, 468, 164, 164, 333, 563, 76, 76, - /* 1530 */ 568, 289, 1509, 568, 31, 1508, 568, 445, 338, 483, - /* 1540 */ 100, 54, 54, 344, 72, 72, 296, 236, 1077, 557, - /* 1550 */ 445, 877, 1356, 134, 134, 168, 73, 73, 141, 161, - /* 1560 */ 161, 1569, 557, 535, 568, 319, 568, 348, 536, 1007, - /* 1570 */ 473, 261, 261, 889, 888, 235, 535, 568, 1024, 568, - /* 1580 */ 475, 534, 261, 367, 109, 109, 521, 136, 136, 130, - /* 1590 */ 130, 1024, 110, 366, 445, 569, 445, 109, 109, 1014, - /* 1600 */ 162, 162, 156, 156, 568, 110, 1077, 445, 569, 445, - /* 1610 */ 410, 351, 1014, 568, 353, 316, 559, 568, 343, 568, - /* 1620 */ 100, 497, 357, 258, 100, 896, 897, 140, 140, 355, - /* 1630 */ 1306, 1014, 1014, 1016, 1017, 27, 139, 139, 362, 451, - /* 1640 */ 137, 137, 138, 138, 1014, 1014, 1016, 1017, 27, 1177, - /* 1650 */ 447, 568, 372, 288, 111, 560, 1018, 4, 392, 392, - /* 1660 */ 391, 273, 389, 568, 1138, 847, 568, 1073, 568, 258, - /* 1670 */ 492, 563, 568, 211, 75, 75, 555, 960, 234, 261, - /* 1680 */ 323, 111, 560, 927, 4, 113, 77, 77, 322, 74, - /* 1690 */ 74, 42, 42, 1369, 445, 48, 48, 1414, 563, 972, - /* 1700 */ 973, 1089, 1088, 1089, 1088, 860, 557, 150, 928, 1342, - /* 1710 */ 113, 1354, 554, 1419, 1018, 1271, 1262, 1250, 236, 1249, - /* 1720 */ 1251, 445, 1588, 1339, 308, 276, 168, 309, 11, 141, - /* 1730 */ 393, 310, 232, 557, 1401, 1024, 335, 291, 1396, 219, - /* 1740 */ 336, 109, 109, 934, 297, 1406, 235, 341, 477, 110, - /* 1750 */ 502, 445, 569, 445, 1389, 1405, 1014, 400, 1289, 365, - /* 1760 */ 223, 1481, 1024, 1480, 1351, 1352, 1350, 1349, 109, 109, - /* 1770 */ 204, 1591, 1228, 558, 265, 218, 110, 205, 445, 569, - /* 1780 */ 445, 410, 387, 1014, 1528, 179, 316, 559, 1014, 1014, - /* 1790 */ 1016, 1017, 27, 230, 1526, 1225, 79, 560, 85, 4, - /* 1800 */ 418, 215, 548, 81, 84, 188, 1402, 173, 181, 461, - /* 1810 */ 451, 35, 462, 563, 183, 1014, 1014, 1016, 1017, 27, - /* 1820 */ 184, 1486, 185, 186, 495, 242, 98, 398, 1408, 36, - /* 1830 */ 1407, 484, 91, 469, 401, 1410, 445, 192, 1475, 246, - /* 1840 */ 1497, 490, 346, 277, 248, 196, 493, 511, 557, 350, - /* 1850 */ 1252, 249, 250, 403, 1309, 1308, 111, 560, 432, 4, - /* 1860 */ 1307, 1300, 93, 1605, 881, 1604, 224, 404, 434, 520, - /* 1870 */ 263, 435, 1574, 563, 1279, 1278, 364, 1024, 306, 1277, - /* 1880 */ 264, 1603, 1560, 109, 109, 370, 1299, 307, 1559, 438, - /* 1890 */ 128, 110, 1374, 445, 569, 445, 445, 546, 1014, 10, - /* 1900 */ 1461, 105, 381, 1373, 34, 571, 99, 1332, 557, 314, - /* 1910 */ 1183, 530, 272, 274, 379, 210, 1331, 547, 385, 386, - /* 1920 */ 275, 572, 1247, 1242, 411, 412, 1513, 165, 178, 1514, - /* 1930 */ 1014, 1014, 1016, 1017, 27, 1512, 1511, 1024, 78, 147, - /* 1940 */ 166, 220, 221, 109, 109, 834, 304, 167, 446, 212, - /* 1950 */ 318, 110, 231, 445, 569, 445, 144, 1087, 1014, 1085, - /* 1960 */ 326, 180, 169, 1208, 182, 334, 238, 913, 241, 1101, - /* 1970 */ 187, 170, 171, 421, 87, 88, 423, 189, 89, 90, - /* 1980 */ 172, 1104, 243, 1100, 244, 158, 18, 245, 345, 247, - /* 1990 */ 1014, 1014, 1016, 1017, 27, 261, 1093, 193, 1222, 489, - /* 2000 */ 194, 37, 366, 849, 494, 251, 195, 506, 92, 19, - /* 2010 */ 498, 358, 20, 503, 879, 361, 94, 892, 305, 159, - /* 2020 */ 513, 39, 95, 1171, 160, 1053, 964, 1140, 96, 174, - /* 2030 */ 1139, 225, 280, 282, 198, 958, 113, 1161, 1157, 260, - /* 2040 */ 21, 22, 23, 1159, 1165, 1164, 1145, 24, 33, 25, - /* 2050 */ 202, 542, 26, 100, 1068, 102, 1054, 103, 7, 1052, - /* 2060 */ 1056, 1110, 1057, 1109, 266, 267, 28, 40, 390, 1019, - /* 2070 */ 861, 112, 29, 564, 1179, 1178, 268, 176, 143, 923, - /* 2080 */ 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, - /* 2090 */ 1238, 1238, 1238, 1238, 269, 1596, + /* 0 */ 566, 1307, 566, 1286, 201, 201, 566, 116, 112, 222, + /* 10 */ 566, 1307, 377, 566, 116, 112, 222, 397, 408, 409, + /* 20 */ 1260, 378, 1269, 41, 41, 41, 41, 1412, 1517, 71, + /* 30 */ 71, 967, 1258, 41, 41, 491, 71, 71, 272, 968, + /* 40 */ 298, 476, 298, 123, 124, 114, 1210, 1210, 1044, 1047, + /* 50 */ 1036, 1036, 121, 121, 122, 122, 122, 122, 543, 409, + /* 60 */ 1234, 1, 1, 573, 2, 1238, 548, 116, 112, 222, + /* 70 */ 309, 480, 142, 548, 1272, 524, 116, 112, 222, 1320, + /* 80 */ 417, 523, 547, 123, 124, 114, 1210, 1210, 1044, 1047, + /* 90 */ 1036, 1036, 121, 121, 122, 122, 122, 122, 424, 116, + /* 100 */ 112, 222, 120, 120, 120, 120, 119, 119, 118, 118, + /* 110 */ 118, 117, 113, 444, 277, 277, 277, 277, 560, 560, + /* 120 */ 560, 1558, 376, 1560, 1186, 375, 1157, 563, 1157, 563, + /* 130 */ 409, 1558, 537, 252, 219, 1553, 99, 141, 449, 6, + /* 140 */ 365, 233, 120, 120, 120, 120, 119, 119, 118, 118, + /* 150 */ 118, 117, 113, 444, 123, 124, 114, 1210, 1210, 1044, + /* 160 */ 1047, 1036, 1036, 121, 121, 122, 122, 122, 122, 138, + /* 170 */ 289, 1186, 1546, 448, 118, 118, 118, 117, 113, 444, + /* 180 */ 125, 1186, 1187, 1188, 144, 465, 334, 566, 150, 127, + /* 190 */ 444, 122, 122, 122, 122, 115, 120, 120, 120, 120, + /* 200 */ 119, 119, 118, 118, 118, 117, 113, 444, 454, 419, + /* 210 */ 13, 13, 215, 120, 120, 120, 120, 119, 119, 118, + /* 220 */ 118, 118, 117, 113, 444, 422, 308, 557, 1186, 1187, + /* 230 */ 1188, 441, 440, 409, 1271, 122, 122, 122, 122, 120, + /* 240 */ 120, 120, 120, 119, 119, 118, 118, 118, 117, 113, + /* 250 */ 444, 1543, 98, 1033, 1033, 1045, 1048, 123, 124, 114, + /* 260 */ 1210, 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, + /* 270 */ 122, 122, 566, 406, 405, 1186, 566, 409, 1217, 319, + /* 280 */ 1217, 80, 81, 120, 120, 120, 120, 119, 119, 118, + /* 290 */ 118, 118, 117, 113, 444, 70, 70, 1186, 1604, 71, + /* 300 */ 71, 123, 124, 114, 1210, 1210, 1044, 1047, 1036, 1036, + /* 310 */ 121, 121, 122, 122, 122, 122, 120, 120, 120, 120, + /* 320 */ 119, 119, 118, 118, 118, 117, 113, 444, 1037, 210, + /* 330 */ 1186, 365, 1186, 1187, 1188, 245, 548, 399, 504, 501, + /* 340 */ 500, 108, 558, 138, 4, 516, 933, 433, 499, 217, + /* 350 */ 514, 522, 352, 879, 1186, 1187, 1188, 383, 561, 566, + /* 360 */ 120, 120, 120, 120, 119, 119, 118, 118, 118, 117, + /* 370 */ 113, 444, 277, 277, 16, 16, 1598, 441, 440, 153, + /* 380 */ 409, 445, 13, 13, 1279, 563, 1214, 1186, 1187, 1188, + /* 390 */ 1003, 1216, 264, 555, 1574, 186, 566, 427, 138, 1215, + /* 400 */ 308, 557, 472, 138, 123, 124, 114, 1210, 1210, 1044, + /* 410 */ 1047, 1036, 1036, 121, 121, 122, 122, 122, 122, 55, + /* 420 */ 55, 413, 1023, 507, 1217, 1186, 1217, 474, 106, 106, + /* 430 */ 1312, 1312, 1186, 171, 566, 384, 107, 380, 445, 568, + /* 440 */ 567, 430, 1543, 1013, 332, 549, 565, 263, 280, 360, + /* 450 */ 510, 355, 509, 250, 491, 308, 557, 71, 71, 351, + /* 460 */ 308, 557, 374, 120, 120, 120, 120, 119, 119, 118, + /* 470 */ 118, 118, 117, 113, 444, 1013, 1013, 1015, 1016, 27, + /* 480 */ 277, 277, 1186, 1187, 1188, 1152, 566, 528, 409, 1186, + /* 490 */ 1187, 1188, 348, 563, 548, 1260, 533, 517, 1152, 1516, + /* 500 */ 317, 1152, 285, 550, 485, 569, 566, 569, 482, 51, + /* 510 */ 51, 207, 123, 124, 114, 1210, 1210, 1044, 1047, 1036, + /* 520 */ 1036, 121, 121, 122, 122, 122, 122, 171, 1412, 13, + /* 530 */ 13, 409, 277, 277, 1186, 505, 119, 119, 118, 118, + /* 540 */ 118, 117, 113, 444, 429, 563, 518, 220, 515, 1552, + /* 550 */ 365, 546, 1186, 6, 532, 123, 124, 114, 1210, 1210, + /* 560 */ 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, 122, + /* 570 */ 145, 120, 120, 120, 120, 119, 119, 118, 118, 118, + /* 580 */ 117, 113, 444, 245, 566, 474, 504, 501, 500, 566, + /* 590 */ 1481, 1186, 1187, 1188, 1310, 1310, 499, 1186, 149, 425, + /* 600 */ 1186, 480, 409, 274, 365, 952, 872, 56, 56, 1186, + /* 610 */ 1187, 1188, 71, 71, 120, 120, 120, 120, 119, 119, + /* 620 */ 118, 118, 118, 117, 113, 444, 123, 124, 114, 1210, + /* 630 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, + /* 640 */ 122, 409, 541, 1552, 83, 865, 98, 6, 928, 529, + /* 650 */ 848, 543, 151, 927, 1186, 1187, 1188, 1186, 1187, 1188, + /* 660 */ 290, 1543, 187, 1633, 395, 123, 124, 114, 1210, 1210, + /* 670 */ 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, 122, + /* 680 */ 566, 954, 566, 453, 953, 120, 120, 120, 120, 119, + /* 690 */ 119, 118, 118, 118, 117, 113, 444, 1152, 221, 1186, + /* 700 */ 331, 453, 452, 13, 13, 13, 13, 1003, 365, 463, + /* 710 */ 1152, 193, 409, 1152, 382, 1543, 1170, 32, 297, 474, + /* 720 */ 195, 1527, 5, 952, 120, 120, 120, 120, 119, 119, + /* 730 */ 118, 118, 118, 117, 113, 444, 123, 124, 114, 1210, + /* 740 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, + /* 750 */ 122, 409, 1067, 419, 1186, 1024, 1186, 1187, 1188, 1186, + /* 760 */ 419, 332, 460, 320, 544, 1545, 442, 442, 442, 566, + /* 770 */ 3, 117, 113, 444, 453, 123, 124, 114, 1210, 1210, + /* 780 */ 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, 122, + /* 790 */ 1473, 566, 15, 15, 293, 120, 120, 120, 120, 119, + /* 800 */ 119, 118, 118, 118, 117, 113, 444, 1186, 566, 1486, + /* 810 */ 1412, 1186, 1187, 1188, 13, 13, 1186, 1187, 1188, 1544, + /* 820 */ 271, 271, 409, 286, 308, 557, 1008, 1486, 1488, 196, + /* 830 */ 288, 71, 71, 563, 120, 120, 120, 120, 119, 119, + /* 840 */ 118, 118, 118, 117, 113, 444, 123, 124, 114, 1210, + /* 850 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, + /* 860 */ 122, 409, 201, 1087, 1186, 1187, 1188, 1324, 304, 1529, + /* 870 */ 388, 278, 278, 450, 564, 402, 922, 922, 566, 563, + /* 880 */ 566, 426, 491, 480, 563, 123, 124, 114, 1210, 1210, + /* 890 */ 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, 122, + /* 900 */ 1486, 71, 71, 13, 13, 120, 120, 120, 120, 119, + /* 910 */ 119, 118, 118, 118, 117, 113, 444, 566, 545, 566, + /* 920 */ 1577, 573, 2, 1238, 1092, 1092, 488, 1480, 309, 1525, + /* 930 */ 142, 324, 409, 836, 837, 838, 312, 1320, 305, 363, + /* 940 */ 43, 43, 57, 57, 120, 120, 120, 120, 119, 119, + /* 950 */ 118, 118, 118, 117, 113, 444, 123, 124, 114, 1210, + /* 960 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, + /* 970 */ 122, 12, 277, 277, 566, 1152, 409, 572, 428, 1238, + /* 980 */ 465, 334, 296, 474, 309, 563, 142, 249, 1152, 308, + /* 990 */ 557, 1152, 321, 1320, 323, 491, 455, 71, 71, 233, + /* 1000 */ 283, 101, 114, 1210, 1210, 1044, 1047, 1036, 1036, 121, + /* 1010 */ 121, 122, 122, 122, 122, 120, 120, 120, 120, 119, + /* 1020 */ 119, 118, 118, 118, 117, 113, 444, 1108, 277, 277, + /* 1030 */ 1412, 448, 394, 1230, 439, 277, 277, 248, 247, 246, + /* 1040 */ 1319, 563, 1109, 313, 198, 294, 491, 1318, 563, 464, + /* 1050 */ 566, 1427, 394, 1130, 1023, 233, 414, 1110, 295, 120, + /* 1060 */ 120, 120, 120, 119, 119, 118, 118, 118, 117, 113, + /* 1070 */ 444, 1014, 104, 71, 71, 1013, 322, 496, 908, 566, + /* 1080 */ 277, 277, 277, 277, 1108, 1261, 415, 448, 909, 361, + /* 1090 */ 1571, 1315, 409, 563, 952, 563, 9, 202, 255, 1109, + /* 1100 */ 316, 487, 44, 44, 249, 559, 415, 1013, 1013, 1015, + /* 1110 */ 443, 1231, 409, 1603, 1110, 897, 123, 124, 114, 1210, + /* 1120 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, + /* 1130 */ 122, 1231, 409, 1207, 215, 554, 123, 124, 114, 1210, + /* 1140 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, + /* 1150 */ 122, 1131, 1631, 470, 1631, 255, 123, 111, 114, 1210, + /* 1160 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, + /* 1170 */ 122, 1131, 1632, 414, 1632, 120, 120, 120, 120, 119, + /* 1180 */ 119, 118, 118, 118, 117, 113, 444, 221, 209, 351, + /* 1190 */ 1207, 1207, 147, 1426, 491, 120, 120, 120, 120, 119, + /* 1200 */ 119, 118, 118, 118, 117, 113, 444, 1256, 539, 519, + /* 1210 */ 888, 551, 952, 12, 566, 120, 120, 120, 120, 119, + /* 1220 */ 119, 118, 118, 118, 117, 113, 444, 538, 566, 860, + /* 1230 */ 1129, 361, 1571, 346, 1356, 409, 1163, 58, 58, 339, + /* 1240 */ 1355, 508, 277, 277, 277, 277, 277, 277, 1207, 889, + /* 1250 */ 1129, 59, 59, 459, 363, 563, 566, 563, 96, 563, + /* 1260 */ 124, 114, 1210, 1210, 1044, 1047, 1036, 1036, 121, 121, + /* 1270 */ 122, 122, 122, 122, 566, 1412, 566, 281, 1186, 60, + /* 1280 */ 60, 110, 392, 392, 391, 266, 389, 860, 1163, 845, + /* 1290 */ 566, 481, 566, 436, 341, 1152, 344, 61, 61, 62, + /* 1300 */ 62, 967, 227, 1550, 315, 431, 540, 6, 1152, 968, + /* 1310 */ 566, 1152, 314, 45, 45, 46, 46, 512, 120, 120, + /* 1320 */ 120, 120, 119, 119, 118, 118, 118, 117, 113, 444, + /* 1330 */ 416, 173, 1532, 47, 47, 1186, 1187, 1188, 108, 558, + /* 1340 */ 325, 4, 229, 1551, 928, 566, 437, 6, 566, 927, + /* 1350 */ 164, 566, 1290, 137, 1190, 561, 566, 1549, 566, 1089, + /* 1360 */ 566, 6, 566, 1089, 531, 566, 868, 8, 49, 49, + /* 1370 */ 228, 50, 50, 566, 63, 63, 566, 457, 445, 64, + /* 1380 */ 64, 65, 65, 14, 14, 66, 66, 407, 129, 129, + /* 1390 */ 555, 566, 458, 566, 1505, 486, 67, 67, 566, 52, + /* 1400 */ 52, 546, 407, 467, 535, 410, 226, 1023, 566, 534, + /* 1410 */ 308, 557, 1190, 407, 68, 68, 69, 69, 566, 1023, + /* 1420 */ 566, 53, 53, 868, 1014, 106, 106, 525, 1013, 566, + /* 1430 */ 1504, 159, 159, 107, 451, 445, 568, 567, 471, 307, + /* 1440 */ 1013, 160, 160, 76, 76, 566, 1548, 466, 407, 407, + /* 1450 */ 6, 1225, 54, 54, 478, 276, 219, 566, 887, 886, + /* 1460 */ 1013, 1013, 1015, 84, 206, 1206, 230, 282, 72, 72, + /* 1470 */ 329, 483, 1013, 1013, 1015, 1016, 27, 1576, 1174, 447, + /* 1480 */ 130, 130, 281, 148, 105, 38, 103, 392, 392, 391, + /* 1490 */ 266, 389, 566, 1126, 845, 396, 566, 108, 558, 566, + /* 1500 */ 4, 311, 566, 30, 17, 566, 279, 227, 566, 315, + /* 1510 */ 108, 558, 468, 4, 561, 73, 73, 314, 566, 157, + /* 1520 */ 157, 566, 131, 131, 526, 132, 132, 561, 128, 128, + /* 1530 */ 566, 158, 158, 566, 31, 291, 566, 445, 330, 521, + /* 1540 */ 98, 152, 152, 420, 136, 136, 1005, 229, 254, 555, + /* 1550 */ 445, 479, 336, 135, 135, 164, 133, 133, 137, 134, + /* 1560 */ 134, 875, 555, 535, 566, 473, 566, 254, 536, 475, + /* 1570 */ 335, 254, 98, 894, 895, 228, 535, 566, 1023, 566, + /* 1580 */ 1074, 534, 210, 232, 106, 106, 1352, 75, 75, 77, + /* 1590 */ 77, 1023, 107, 340, 445, 568, 567, 106, 106, 1013, + /* 1600 */ 74, 74, 42, 42, 566, 107, 343, 445, 568, 567, + /* 1610 */ 410, 497, 1013, 251, 359, 308, 557, 1135, 349, 875, + /* 1620 */ 98, 1070, 345, 251, 358, 1591, 347, 48, 48, 1017, + /* 1630 */ 1303, 1013, 1013, 1015, 1016, 27, 1289, 1287, 1074, 451, + /* 1640 */ 961, 925, 254, 110, 1013, 1013, 1015, 1016, 27, 1174, + /* 1650 */ 447, 970, 971, 281, 108, 558, 1288, 4, 392, 392, + /* 1660 */ 391, 266, 389, 1343, 1086, 845, 1086, 1085, 858, 1085, + /* 1670 */ 146, 561, 926, 354, 110, 303, 364, 553, 227, 1364, + /* 1680 */ 315, 108, 558, 1411, 4, 1339, 492, 1017, 314, 1350, + /* 1690 */ 1565, 552, 1417, 1268, 445, 204, 1259, 1247, 561, 1246, + /* 1700 */ 1248, 1584, 269, 1336, 367, 369, 555, 371, 11, 212, + /* 1710 */ 393, 225, 1393, 284, 1398, 456, 287, 327, 229, 328, + /* 1720 */ 292, 445, 1386, 216, 333, 1403, 164, 477, 373, 137, + /* 1730 */ 1402, 400, 502, 555, 1286, 1023, 357, 1477, 199, 1587, + /* 1740 */ 211, 106, 106, 932, 1476, 1225, 228, 556, 175, 107, + /* 1750 */ 200, 445, 568, 567, 258, 387, 1013, 1524, 1522, 223, + /* 1760 */ 1222, 418, 1023, 83, 208, 79, 82, 184, 106, 106, + /* 1770 */ 1482, 169, 177, 461, 179, 462, 107, 1399, 445, 568, + /* 1780 */ 567, 410, 180, 1013, 495, 181, 308, 557, 1013, 1013, + /* 1790 */ 1015, 1016, 27, 182, 35, 235, 100, 558, 398, 4, + /* 1800 */ 96, 1405, 1404, 36, 484, 469, 1407, 188, 401, 1471, + /* 1810 */ 451, 89, 1493, 561, 239, 1013, 1013, 1015, 1016, 27, + /* 1820 */ 490, 338, 270, 241, 192, 342, 493, 242, 403, 1249, + /* 1830 */ 243, 511, 432, 1297, 1306, 91, 445, 1305, 1304, 879, + /* 1840 */ 217, 434, 435, 1570, 1276, 1602, 520, 1601, 555, 301, + /* 1850 */ 527, 404, 1275, 302, 356, 1274, 1600, 95, 1347, 366, + /* 1860 */ 1296, 362, 1348, 368, 256, 257, 1556, 1555, 438, 1346, + /* 1870 */ 370, 126, 1345, 10, 1371, 546, 381, 1023, 102, 1457, + /* 1880 */ 97, 530, 34, 106, 106, 570, 1180, 372, 265, 1329, + /* 1890 */ 379, 107, 203, 445, 568, 567, 1328, 385, 1013, 1370, + /* 1900 */ 386, 267, 268, 571, 1244, 161, 1239, 162, 1509, 1510, + /* 1910 */ 1508, 143, 1507, 299, 832, 213, 214, 78, 446, 205, + /* 1920 */ 310, 306, 163, 224, 1084, 140, 1082, 318, 165, 176, + /* 1930 */ 1013, 1013, 1015, 1016, 27, 178, 1206, 231, 911, 234, + /* 1940 */ 326, 1098, 183, 421, 166, 167, 411, 185, 85, 423, + /* 1950 */ 412, 86, 174, 87, 168, 88, 1101, 236, 1097, 237, + /* 1960 */ 154, 18, 238, 254, 337, 1219, 489, 1090, 240, 190, + /* 1970 */ 37, 847, 189, 494, 358, 244, 350, 506, 191, 877, + /* 1980 */ 90, 498, 19, 20, 503, 92, 353, 890, 300, 170, + /* 1990 */ 155, 93, 513, 94, 1168, 156, 1050, 1137, 39, 218, + /* 2000 */ 273, 275, 1136, 960, 194, 955, 110, 1154, 1158, 253, + /* 2010 */ 7, 1162, 1156, 21, 22, 1161, 1142, 23, 24, 25, + /* 2020 */ 33, 542, 26, 260, 197, 98, 1065, 1051, 1049, 1053, + /* 2030 */ 1107, 1054, 1106, 259, 28, 40, 562, 1018, 859, 109, + /* 2040 */ 29, 921, 390, 1176, 172, 139, 1175, 1235, 261, 1235, + /* 2050 */ 1235, 1235, 1235, 1235, 1235, 1235, 1235, 262, 1235, 1235, + /* 2060 */ 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1593, 1592, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 193, 193, 193, 274, 275, 276, 193, 274, 275, 276, - /* 10 */ 193, 223, 219, 225, 206, 210, 211, 212, 193, 19, - /* 20 */ 219, 233, 216, 216, 217, 216, 217, 193, 295, 216, - /* 30 */ 217, 31, 193, 216, 217, 193, 228, 213, 230, 39, - /* 40 */ 206, 216, 217, 43, 44, 45, 46, 47, 48, 49, + /* 0 */ 193, 223, 193, 225, 193, 193, 193, 274, 275, 276, + /* 10 */ 193, 233, 219, 193, 274, 275, 276, 206, 206, 19, + /* 20 */ 193, 219, 216, 216, 217, 216, 217, 193, 295, 216, + /* 30 */ 217, 31, 205, 216, 217, 193, 216, 217, 213, 39, + /* 40 */ 228, 193, 230, 43, 44, 45, 46, 47, 48, 49, /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 193, 19, /* 60 */ 185, 186, 187, 188, 189, 190, 253, 274, 275, 276, - /* 70 */ 195, 193, 197, 193, 261, 274, 275, 276, 253, 204, - /* 80 */ 238, 204, 81, 43, 44, 45, 46, 47, 48, 49, - /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 274, 275, - /* 100 */ 276, 262, 102, 103, 104, 105, 106, 107, 108, 109, + /* 70 */ 195, 193, 197, 253, 216, 262, 274, 275, 276, 204, + /* 80 */ 238, 204, 262, 43, 44, 45, 46, 47, 48, 49, + /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 264, 274, + /* 100 */ 275, 276, 102, 103, 104, 105, 106, 107, 108, 109, /* 110 */ 110, 111, 112, 113, 239, 240, 239, 240, 210, 211, /* 120 */ 212, 314, 315, 314, 59, 316, 86, 252, 88, 252, - /* 130 */ 19, 314, 315, 256, 257, 113, 25, 72, 296, 138, - /* 140 */ 139, 266, 102, 103, 104, 105, 106, 107, 108, 109, + /* 130 */ 19, 314, 315, 256, 257, 309, 25, 72, 296, 313, + /* 140 */ 193, 266, 102, 103, 104, 105, 106, 107, 108, 109, /* 150 */ 110, 111, 112, 113, 43, 44, 45, 46, 47, 48, /* 160 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 81, - /* 170 */ 292, 59, 292, 298, 108, 109, 110, 111, 112, 113, - /* 180 */ 69, 116, 117, 118, 72, 106, 107, 193, 111, 112, + /* 170 */ 292, 59, 307, 298, 108, 109, 110, 111, 112, 113, + /* 180 */ 69, 116, 117, 118, 72, 128, 129, 193, 241, 22, /* 190 */ 113, 54, 55, 56, 57, 58, 102, 103, 104, 105, - /* 200 */ 106, 107, 108, 109, 110, 111, 112, 113, 120, 25, - /* 210 */ 216, 217, 145, 102, 103, 104, 105, 106, 107, 108, + /* 200 */ 106, 107, 108, 109, 110, 111, 112, 113, 120, 193, + /* 210 */ 216, 217, 25, 102, 103, 104, 105, 106, 107, 108, /* 220 */ 109, 110, 111, 112, 113, 231, 138, 139, 116, 117, - /* 230 */ 118, 164, 153, 19, 155, 54, 55, 56, 57, 102, + /* 230 */ 118, 106, 107, 19, 216, 54, 55, 56, 57, 102, /* 240 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - /* 250 */ 113, 128, 129, 46, 47, 48, 49, 43, 44, 45, + /* 250 */ 113, 304, 25, 46, 47, 48, 49, 43, 44, 45, /* 260 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - /* 270 */ 56, 57, 216, 193, 25, 59, 193, 19, 165, 166, - /* 280 */ 193, 67, 24, 102, 103, 104, 105, 106, 107, 108, - /* 290 */ 109, 110, 111, 112, 113, 73, 216, 217, 59, 216, + /* 270 */ 56, 57, 193, 106, 107, 59, 193, 19, 153, 263, + /* 280 */ 155, 67, 24, 102, 103, 104, 105, 106, 107, 108, + /* 290 */ 109, 110, 111, 112, 113, 216, 217, 59, 230, 216, /* 300 */ 217, 43, 44, 45, 46, 47, 48, 49, 50, 51, /* 310 */ 52, 53, 54, 55, 56, 57, 102, 103, 104, 105, - /* 320 */ 106, 107, 108, 109, 110, 111, 112, 113, 121, 145, - /* 330 */ 59, 193, 116, 117, 118, 119, 273, 204, 122, 123, - /* 340 */ 124, 19, 20, 134, 22, 136, 137, 19, 132, 127, - /* 350 */ 128, 129, 24, 22, 23, 116, 117, 118, 36, 193, + /* 320 */ 106, 107, 108, 109, 110, 111, 112, 113, 121, 142, + /* 330 */ 59, 193, 116, 117, 118, 119, 253, 204, 122, 123, + /* 340 */ 124, 19, 20, 81, 22, 262, 108, 19, 132, 165, + /* 350 */ 166, 193, 24, 126, 116, 117, 118, 278, 36, 193, /* 360 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - /* 370 */ 112, 113, 239, 240, 311, 312, 215, 106, 107, 241, + /* 370 */ 112, 113, 239, 240, 216, 217, 215, 106, 107, 241, /* 380 */ 19, 59, 216, 217, 223, 252, 115, 116, 117, 118, - /* 390 */ 151, 120, 26, 71, 193, 308, 309, 193, 149, 128, - /* 400 */ 313, 216, 269, 81, 43, 44, 45, 46, 47, 48, - /* 410 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 253, - /* 420 */ 216, 217, 100, 95, 153, 59, 155, 261, 106, 107, - /* 430 */ 25, 193, 101, 193, 193, 231, 114, 25, 116, 117, - /* 440 */ 118, 113, 304, 121, 193, 204, 59, 119, 120, 121, - /* 450 */ 122, 123, 124, 125, 216, 217, 193, 216, 217, 131, - /* 460 */ 138, 139, 230, 102, 103, 104, 105, 106, 107, 108, + /* 390 */ 73, 120, 26, 71, 193, 22, 193, 231, 81, 128, + /* 400 */ 138, 139, 269, 81, 43, 44, 45, 46, 47, 48, + /* 410 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 216, + /* 420 */ 217, 198, 100, 95, 153, 59, 155, 193, 106, 107, + /* 430 */ 235, 236, 59, 193, 193, 249, 114, 251, 116, 117, + /* 440 */ 118, 113, 304, 121, 127, 204, 193, 119, 120, 121, + /* 450 */ 122, 123, 124, 125, 193, 138, 139, 216, 217, 131, + /* 460 */ 138, 139, 193, 102, 103, 104, 105, 106, 107, 108, /* 470 */ 109, 110, 111, 112, 113, 153, 154, 155, 156, 157, - /* 480 */ 239, 240, 116, 117, 118, 76, 193, 23, 19, 25, - /* 490 */ 22, 253, 23, 252, 253, 108, 87, 204, 89, 261, - /* 500 */ 198, 92, 261, 116, 117, 118, 193, 306, 307, 216, + /* 480 */ 239, 240, 116, 117, 118, 76, 193, 193, 19, 116, + /* 490 */ 117, 118, 23, 252, 253, 193, 87, 204, 89, 238, + /* 500 */ 193, 92, 268, 262, 281, 203, 193, 205, 285, 216, /* 510 */ 217, 150, 43, 44, 45, 46, 47, 48, 49, 50, - /* 520 */ 51, 52, 53, 54, 55, 56, 57, 59, 193, 216, - /* 530 */ 217, 19, 239, 240, 283, 23, 106, 107, 108, 109, - /* 540 */ 110, 111, 112, 113, 73, 252, 253, 142, 308, 309, - /* 550 */ 138, 139, 81, 313, 145, 43, 44, 45, 46, 47, + /* 520 */ 51, 52, 53, 54, 55, 56, 57, 193, 193, 216, + /* 530 */ 217, 19, 239, 240, 59, 23, 106, 107, 108, 109, + /* 540 */ 110, 111, 112, 113, 231, 252, 253, 193, 308, 309, + /* 550 */ 193, 145, 59, 313, 145, 43, 44, 45, 46, 47, /* 560 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 570 */ 307, 102, 103, 104, 105, 106, 107, 108, 109, 110, - /* 580 */ 111, 112, 113, 281, 116, 117, 118, 285, 23, 193, - /* 590 */ 25, 119, 59, 193, 122, 123, 124, 59, 127, 203, - /* 600 */ 59, 205, 19, 268, 132, 25, 23, 22, 193, 138, - /* 610 */ 139, 249, 204, 251, 102, 103, 104, 105, 106, 107, + /* 570 */ 164, 102, 103, 104, 105, 106, 107, 108, 109, 110, + /* 580 */ 111, 112, 113, 119, 193, 193, 122, 123, 124, 193, + /* 590 */ 283, 116, 117, 118, 235, 236, 132, 59, 241, 264, + /* 600 */ 59, 193, 19, 23, 193, 25, 23, 216, 217, 116, + /* 610 */ 117, 118, 216, 217, 102, 103, 104, 105, 106, 107, /* 620 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, /* 630 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 640 */ 57, 19, 22, 23, 59, 23, 25, 239, 240, 116, - /* 650 */ 117, 118, 193, 11, 116, 117, 118, 116, 117, 118, - /* 660 */ 252, 269, 22, 193, 15, 43, 44, 45, 46, 47, + /* 640 */ 57, 19, 308, 309, 151, 23, 25, 313, 135, 253, + /* 650 */ 21, 193, 241, 140, 116, 117, 118, 116, 117, 118, + /* 660 */ 268, 304, 22, 301, 302, 43, 44, 45, 46, 47, /* 670 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 680 */ 273, 143, 193, 118, 143, 102, 103, 104, 105, 106, + /* 680 */ 193, 143, 193, 193, 143, 102, 103, 104, 105, 106, /* 690 */ 107, 108, 109, 110, 111, 112, 113, 76, 118, 59, - /* 700 */ 241, 116, 117, 118, 304, 216, 217, 292, 143, 60, - /* 710 */ 89, 241, 19, 92, 193, 193, 23, 22, 311, 312, - /* 720 */ 231, 101, 22, 143, 102, 103, 104, 105, 106, 107, + /* 700 */ 292, 211, 212, 216, 217, 216, 217, 73, 193, 80, + /* 710 */ 89, 25, 19, 92, 193, 304, 23, 22, 231, 193, + /* 720 */ 231, 193, 22, 143, 102, 103, 104, 105, 106, 107, /* 730 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, /* 740 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 750 */ 57, 19, 193, 193, 59, 23, 116, 117, 118, 59, - /* 760 */ 201, 21, 241, 304, 22, 206, 127, 128, 129, 193, - /* 770 */ 128, 129, 235, 236, 304, 43, 44, 45, 46, 47, + /* 750 */ 57, 19, 123, 193, 59, 23, 116, 117, 118, 59, + /* 760 */ 193, 127, 128, 129, 306, 307, 210, 211, 212, 193, + /* 770 */ 22, 111, 112, 113, 284, 43, 44, 45, 46, 47, /* 780 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 790 */ 22, 193, 216, 217, 193, 102, 103, 104, 105, 106, - /* 800 */ 107, 108, 109, 110, 111, 112, 113, 231, 193, 193, - /* 810 */ 193, 116, 117, 118, 216, 217, 116, 117, 118, 226, - /* 820 */ 80, 193, 19, 235, 236, 304, 23, 211, 212, 231, - /* 830 */ 204, 216, 217, 205, 102, 103, 104, 105, 106, 107, + /* 790 */ 161, 193, 216, 217, 268, 102, 103, 104, 105, 106, + /* 800 */ 107, 108, 109, 110, 111, 112, 113, 59, 193, 193, + /* 810 */ 193, 116, 117, 118, 216, 217, 116, 117, 118, 304, + /* 820 */ 239, 240, 19, 263, 138, 139, 23, 211, 212, 231, + /* 830 */ 263, 216, 217, 252, 102, 103, 104, 105, 106, 107, /* 840 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, /* 850 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 860 */ 57, 19, 193, 123, 76, 239, 240, 193, 253, 239, - /* 870 */ 240, 239, 240, 193, 106, 107, 193, 89, 252, 193, - /* 880 */ 92, 59, 252, 141, 252, 43, 44, 45, 46, 47, + /* 860 */ 57, 19, 193, 11, 116, 117, 118, 240, 253, 193, + /* 870 */ 201, 239, 240, 193, 134, 206, 136, 137, 193, 252, + /* 880 */ 193, 264, 193, 193, 252, 43, 44, 45, 46, 47, /* 890 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 900 */ 284, 161, 216, 217, 193, 102, 103, 104, 105, 106, - /* 910 */ 107, 108, 109, 110, 111, 112, 113, 231, 193, 16, - /* 920 */ 187, 188, 189, 190, 7, 8, 9, 309, 195, 25, - /* 930 */ 197, 313, 19, 127, 128, 129, 262, 204, 22, 117, - /* 940 */ 24, 216, 217, 263, 102, 103, 104, 105, 106, 107, + /* 900 */ 284, 216, 217, 216, 217, 102, 103, 104, 105, 106, + /* 910 */ 107, 108, 109, 110, 111, 112, 113, 193, 231, 193, + /* 920 */ 187, 188, 189, 190, 127, 128, 129, 238, 195, 193, + /* 930 */ 197, 16, 19, 7, 8, 9, 193, 204, 253, 193, + /* 940 */ 216, 217, 216, 217, 102, 103, 104, 105, 106, 107, /* 950 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, /* 960 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 970 */ 57, 193, 239, 240, 193, 59, 19, 188, 253, 190, - /* 980 */ 77, 226, 79, 193, 195, 252, 197, 193, 19, 301, - /* 990 */ 302, 193, 193, 204, 216, 217, 226, 216, 217, 266, + /* 970 */ 57, 213, 239, 240, 193, 76, 19, 188, 232, 190, + /* 980 */ 128, 129, 292, 193, 195, 252, 197, 46, 89, 138, + /* 990 */ 139, 92, 77, 204, 79, 193, 269, 216, 217, 266, /* 1000 */ 204, 159, 45, 46, 47, 48, 49, 50, 51, 52, /* 1010 */ 53, 54, 55, 56, 57, 102, 103, 104, 105, 106, /* 1020 */ 107, 108, 109, 110, 111, 112, 113, 12, 239, 240, - /* 1030 */ 232, 298, 238, 117, 253, 239, 240, 238, 259, 260, - /* 1040 */ 193, 252, 27, 31, 193, 193, 142, 204, 252, 193, - /* 1050 */ 193, 39, 262, 193, 100, 266, 278, 42, 204, 102, + /* 1030 */ 193, 298, 22, 23, 253, 239, 240, 127, 128, 129, + /* 1040 */ 238, 252, 27, 193, 286, 204, 193, 204, 252, 291, + /* 1050 */ 193, 273, 22, 23, 100, 266, 115, 42, 268, 102, /* 1060 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - /* 1070 */ 113, 117, 159, 216, 217, 121, 216, 217, 63, 193, - /* 1080 */ 193, 193, 239, 240, 115, 116, 193, 298, 73, 238, - /* 1090 */ 238, 231, 19, 239, 240, 252, 22, 24, 211, 212, - /* 1100 */ 24, 193, 216, 217, 216, 217, 252, 153, 154, 155, - /* 1110 */ 253, 16, 19, 144, 213, 268, 43, 44, 45, 46, + /* 1070 */ 113, 117, 159, 216, 217, 121, 161, 19, 63, 193, + /* 1080 */ 239, 240, 239, 240, 12, 208, 209, 298, 73, 311, + /* 1090 */ 312, 238, 19, 252, 25, 252, 22, 24, 24, 27, + /* 1100 */ 193, 264, 216, 217, 46, 208, 209, 153, 154, 155, + /* 1110 */ 253, 101, 19, 23, 42, 25, 43, 44, 45, 46, /* 1120 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 1130 */ 57, 238, 19, 59, 193, 59, 43, 44, 45, 46, + /* 1130 */ 57, 101, 19, 59, 25, 63, 43, 44, 45, 46, /* 1140 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 1150 */ 57, 22, 23, 193, 25, 193, 43, 44, 45, 46, + /* 1150 */ 57, 22, 23, 115, 25, 24, 43, 44, 45, 46, /* 1160 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 1170 */ 57, 284, 77, 193, 79, 102, 103, 104, 105, 106, - /* 1180 */ 107, 108, 109, 110, 111, 112, 113, 286, 193, 193, - /* 1190 */ 193, 117, 291, 117, 232, 102, 103, 104, 105, 106, - /* 1200 */ 107, 108, 109, 110, 111, 112, 113, 204, 22, 23, - /* 1210 */ 66, 25, 216, 217, 35, 102, 103, 104, 105, 106, - /* 1220 */ 107, 108, 109, 110, 111, 112, 113, 193, 268, 85, - /* 1230 */ 101, 193, 309, 309, 240, 19, 313, 313, 94, 208, - /* 1240 */ 209, 193, 239, 240, 193, 66, 252, 19, 268, 244, - /* 1250 */ 216, 217, 193, 74, 213, 252, 161, 19, 263, 254, + /* 1170 */ 57, 22, 23, 115, 25, 102, 103, 104, 105, 106, + /* 1180 */ 107, 108, 109, 110, 111, 112, 113, 118, 150, 131, + /* 1190 */ 59, 117, 22, 273, 193, 102, 103, 104, 105, 106, + /* 1200 */ 107, 108, 109, 110, 111, 112, 113, 204, 66, 204, + /* 1210 */ 35, 204, 143, 213, 193, 102, 103, 104, 105, 106, + /* 1220 */ 107, 108, 109, 110, 111, 112, 113, 85, 193, 59, + /* 1230 */ 101, 311, 312, 16, 193, 19, 94, 216, 217, 238, + /* 1240 */ 193, 66, 239, 240, 239, 240, 239, 240, 117, 74, + /* 1250 */ 101, 216, 217, 193, 193, 252, 193, 252, 149, 252, /* 1260 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - /* 1270 */ 54, 55, 56, 57, 193, 216, 217, 5, 59, 193, - /* 1280 */ 19, 244, 10, 11, 12, 13, 14, 101, 309, 17, - /* 1290 */ 146, 254, 313, 193, 193, 76, 115, 216, 217, 309, - /* 1300 */ 12, 263, 30, 313, 32, 46, 87, 46, 89, 130, - /* 1310 */ 193, 92, 40, 22, 263, 27, 216, 217, 102, 103, + /* 1270 */ 54, 55, 56, 57, 193, 193, 193, 5, 59, 216, + /* 1280 */ 217, 25, 10, 11, 12, 13, 14, 117, 146, 17, + /* 1290 */ 193, 291, 193, 232, 77, 76, 79, 216, 217, 216, + /* 1300 */ 217, 31, 30, 309, 32, 130, 87, 313, 89, 39, + /* 1310 */ 193, 92, 40, 216, 217, 216, 217, 108, 102, 103, /* 1320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - /* 1330 */ 42, 150, 291, 216, 217, 116, 117, 118, 19, 20, - /* 1340 */ 193, 22, 70, 260, 116, 193, 24, 264, 193, 263, - /* 1350 */ 78, 63, 61, 81, 116, 36, 193, 260, 193, 29, - /* 1360 */ 193, 264, 193, 33, 145, 193, 59, 48, 216, 217, - /* 1370 */ 98, 216, 217, 193, 115, 193, 115, 193, 59, 216, - /* 1380 */ 217, 216, 217, 216, 217, 216, 217, 255, 216, 217, - /* 1390 */ 71, 193, 131, 193, 25, 65, 216, 217, 216, 217, - /* 1400 */ 216, 217, 208, 209, 85, 133, 193, 100, 193, 90, - /* 1410 */ 138, 139, 138, 139, 216, 217, 216, 217, 193, 100, - /* 1420 */ 193, 108, 135, 116, 117, 106, 107, 140, 121, 216, - /* 1430 */ 217, 216, 217, 114, 162, 116, 117, 118, 299, 300, - /* 1440 */ 121, 216, 217, 216, 217, 193, 244, 193, 135, 244, - /* 1450 */ 193, 256, 257, 140, 244, 193, 254, 193, 193, 254, - /* 1460 */ 153, 154, 155, 141, 254, 149, 150, 258, 216, 217, - /* 1470 */ 216, 217, 153, 154, 155, 156, 157, 0, 1, 2, - /* 1480 */ 216, 217, 5, 115, 158, 193, 160, 10, 11, 12, - /* 1490 */ 13, 14, 193, 59, 17, 126, 193, 19, 20, 129, - /* 1500 */ 22, 193, 22, 22, 24, 193, 23, 30, 25, 32, - /* 1510 */ 19, 20, 144, 22, 36, 216, 217, 40, 193, 216, - /* 1520 */ 217, 193, 152, 129, 216, 217, 193, 36, 216, 217, - /* 1530 */ 193, 99, 193, 193, 53, 193, 193, 59, 23, 193, - /* 1540 */ 25, 216, 217, 193, 216, 217, 152, 70, 59, 71, - /* 1550 */ 59, 117, 193, 216, 217, 78, 216, 217, 81, 216, - /* 1560 */ 217, 318, 71, 85, 193, 133, 193, 193, 90, 23, - /* 1570 */ 23, 25, 25, 120, 121, 98, 85, 193, 100, 193, - /* 1580 */ 23, 90, 25, 121, 106, 107, 19, 216, 217, 216, - /* 1590 */ 217, 100, 114, 131, 116, 117, 118, 106, 107, 121, - /* 1600 */ 216, 217, 216, 217, 193, 114, 117, 116, 117, 118, - /* 1610 */ 133, 193, 121, 193, 193, 138, 139, 193, 23, 193, - /* 1620 */ 25, 23, 23, 25, 25, 7, 8, 216, 217, 193, - /* 1630 */ 193, 153, 154, 155, 156, 157, 216, 217, 193, 162, - /* 1640 */ 216, 217, 216, 217, 153, 154, 155, 156, 157, 1, - /* 1650 */ 2, 193, 193, 5, 19, 20, 59, 22, 10, 11, - /* 1660 */ 12, 13, 14, 193, 97, 17, 193, 23, 193, 25, - /* 1670 */ 288, 36, 193, 242, 216, 217, 236, 23, 30, 25, - /* 1680 */ 32, 19, 20, 23, 22, 25, 216, 217, 40, 216, - /* 1690 */ 217, 216, 217, 193, 59, 216, 217, 193, 36, 83, - /* 1700 */ 84, 153, 153, 155, 155, 23, 71, 25, 23, 193, - /* 1710 */ 25, 193, 193, 193, 117, 193, 193, 193, 70, 193, - /* 1720 */ 193, 59, 193, 255, 255, 287, 78, 255, 243, 81, - /* 1730 */ 191, 255, 297, 71, 271, 100, 293, 245, 267, 214, - /* 1740 */ 246, 106, 107, 108, 246, 271, 98, 245, 293, 114, - /* 1750 */ 220, 116, 117, 118, 267, 271, 121, 271, 225, 219, - /* 1760 */ 229, 219, 100, 219, 259, 259, 259, 259, 106, 107, - /* 1770 */ 249, 196, 60, 280, 141, 243, 114, 249, 116, 117, - /* 1780 */ 118, 133, 245, 121, 200, 297, 138, 139, 153, 154, - /* 1790 */ 155, 156, 157, 297, 200, 38, 19, 20, 151, 22, - /* 1800 */ 200, 150, 140, 294, 294, 22, 272, 43, 234, 18, - /* 1810 */ 162, 270, 200, 36, 237, 153, 154, 155, 156, 157, - /* 1820 */ 237, 283, 237, 237, 18, 199, 149, 246, 272, 270, - /* 1830 */ 272, 200, 158, 246, 246, 234, 59, 234, 246, 199, - /* 1840 */ 290, 62, 289, 200, 199, 22, 221, 115, 71, 200, - /* 1850 */ 200, 199, 199, 221, 218, 218, 19, 20, 64, 22, - /* 1860 */ 218, 227, 22, 224, 126, 224, 165, 221, 24, 305, - /* 1870 */ 200, 113, 312, 36, 218, 220, 218, 100, 282, 218, - /* 1880 */ 91, 218, 317, 106, 107, 221, 227, 282, 317, 82, - /* 1890 */ 148, 114, 265, 116, 117, 118, 59, 145, 121, 22, - /* 1900 */ 277, 158, 200, 265, 25, 202, 147, 250, 71, 279, - /* 1910 */ 13, 146, 194, 194, 249, 248, 250, 140, 247, 246, - /* 1920 */ 6, 192, 192, 192, 303, 303, 213, 207, 300, 213, - /* 1930 */ 153, 154, 155, 156, 157, 213, 213, 100, 213, 222, - /* 1940 */ 207, 214, 214, 106, 107, 4, 222, 207, 3, 22, - /* 1950 */ 163, 114, 15, 116, 117, 118, 16, 23, 121, 23, - /* 1960 */ 139, 151, 130, 25, 142, 16, 24, 20, 144, 1, - /* 1970 */ 142, 130, 130, 61, 53, 53, 37, 151, 53, 53, - /* 1980 */ 130, 116, 34, 1, 141, 5, 22, 115, 161, 141, - /* 1990 */ 153, 154, 155, 156, 157, 25, 68, 68, 75, 41, - /* 2000 */ 115, 24, 131, 20, 19, 125, 22, 96, 22, 22, - /* 2010 */ 67, 23, 22, 67, 59, 24, 22, 28, 67, 23, - /* 2020 */ 22, 22, 149, 23, 23, 23, 116, 23, 25, 37, - /* 2030 */ 97, 141, 23, 23, 22, 143, 25, 75, 88, 34, - /* 2040 */ 34, 34, 34, 86, 75, 93, 23, 34, 22, 34, - /* 2050 */ 25, 24, 34, 25, 23, 142, 23, 142, 44, 23, - /* 2060 */ 23, 23, 11, 23, 25, 22, 22, 22, 15, 23, - /* 2070 */ 23, 22, 22, 25, 1, 1, 141, 25, 23, 135, + /* 1330 */ 299, 300, 193, 216, 217, 116, 117, 118, 19, 20, + /* 1340 */ 193, 22, 70, 309, 135, 193, 264, 313, 193, 140, + /* 1350 */ 78, 193, 226, 81, 59, 36, 193, 309, 193, 29, + /* 1360 */ 193, 313, 193, 33, 145, 193, 59, 48, 216, 217, + /* 1370 */ 98, 216, 217, 193, 216, 217, 193, 244, 59, 216, + /* 1380 */ 217, 216, 217, 216, 217, 216, 217, 254, 216, 217, + /* 1390 */ 71, 193, 244, 193, 193, 65, 216, 217, 193, 216, + /* 1400 */ 217, 145, 254, 244, 85, 133, 15, 100, 193, 90, + /* 1410 */ 138, 139, 117, 254, 216, 217, 216, 217, 193, 100, + /* 1420 */ 193, 216, 217, 116, 117, 106, 107, 19, 121, 193, + /* 1430 */ 193, 216, 217, 114, 162, 116, 117, 118, 244, 244, + /* 1440 */ 121, 216, 217, 216, 217, 193, 309, 129, 254, 254, + /* 1450 */ 313, 60, 216, 217, 19, 256, 257, 193, 120, 121, + /* 1460 */ 153, 154, 155, 149, 150, 25, 24, 99, 216, 217, + /* 1470 */ 152, 193, 153, 154, 155, 156, 157, 0, 1, 2, + /* 1480 */ 216, 217, 5, 22, 158, 24, 160, 10, 11, 12, + /* 1490 */ 13, 14, 193, 23, 17, 25, 193, 19, 20, 193, + /* 1500 */ 22, 133, 193, 22, 22, 193, 22, 30, 193, 32, + /* 1510 */ 19, 20, 129, 22, 36, 216, 217, 40, 193, 216, + /* 1520 */ 217, 193, 216, 217, 116, 216, 217, 36, 216, 217, + /* 1530 */ 193, 216, 217, 193, 53, 152, 193, 59, 23, 19, + /* 1540 */ 25, 216, 217, 61, 216, 217, 23, 70, 25, 71, + /* 1550 */ 59, 116, 193, 216, 217, 78, 216, 217, 81, 216, + /* 1560 */ 217, 59, 71, 85, 193, 23, 193, 25, 90, 23, + /* 1570 */ 23, 25, 25, 7, 8, 98, 85, 193, 100, 193, + /* 1580 */ 59, 90, 142, 141, 106, 107, 193, 216, 217, 216, + /* 1590 */ 217, 100, 114, 193, 116, 117, 118, 106, 107, 121, + /* 1600 */ 216, 217, 216, 217, 193, 114, 193, 116, 117, 118, + /* 1610 */ 133, 23, 121, 25, 121, 138, 139, 97, 23, 117, + /* 1620 */ 25, 23, 193, 25, 131, 141, 193, 216, 217, 59, + /* 1630 */ 193, 153, 154, 155, 156, 157, 226, 193, 117, 162, + /* 1640 */ 23, 23, 25, 25, 153, 154, 155, 156, 157, 1, + /* 1650 */ 2, 83, 84, 5, 19, 20, 226, 22, 10, 11, + /* 1660 */ 12, 13, 14, 258, 153, 17, 155, 153, 23, 155, + /* 1670 */ 25, 36, 23, 193, 25, 255, 193, 236, 30, 193, + /* 1680 */ 32, 19, 20, 193, 22, 193, 288, 117, 40, 193, + /* 1690 */ 318, 193, 193, 193, 59, 242, 193, 193, 36, 193, + /* 1700 */ 193, 193, 287, 255, 255, 255, 71, 255, 243, 214, + /* 1710 */ 191, 297, 267, 245, 271, 259, 259, 293, 70, 246, + /* 1720 */ 246, 59, 267, 229, 245, 271, 78, 293, 259, 81, + /* 1730 */ 271, 271, 220, 71, 225, 100, 219, 219, 249, 196, + /* 1740 */ 243, 106, 107, 108, 219, 60, 98, 280, 297, 114, + /* 1750 */ 249, 116, 117, 118, 141, 245, 121, 200, 200, 297, + /* 1760 */ 38, 200, 100, 151, 150, 294, 294, 22, 106, 107, + /* 1770 */ 283, 43, 234, 18, 237, 200, 114, 272, 116, 117, + /* 1780 */ 118, 133, 237, 121, 18, 237, 138, 139, 153, 154, + /* 1790 */ 155, 156, 157, 237, 270, 199, 19, 20, 246, 22, + /* 1800 */ 149, 272, 272, 270, 200, 246, 234, 234, 246, 246, + /* 1810 */ 162, 158, 290, 36, 199, 153, 154, 155, 156, 157, + /* 1820 */ 62, 289, 200, 199, 22, 200, 221, 199, 221, 200, + /* 1830 */ 199, 115, 64, 227, 218, 22, 59, 218, 218, 126, + /* 1840 */ 165, 24, 113, 312, 218, 224, 305, 224, 71, 282, + /* 1850 */ 144, 221, 220, 282, 218, 218, 218, 115, 261, 260, + /* 1860 */ 227, 221, 261, 260, 200, 91, 317, 317, 82, 261, + /* 1870 */ 260, 148, 261, 22, 265, 145, 200, 100, 158, 277, + /* 1880 */ 147, 146, 25, 106, 107, 202, 13, 260, 194, 250, + /* 1890 */ 249, 114, 248, 116, 117, 118, 250, 247, 121, 265, + /* 1900 */ 246, 194, 6, 192, 192, 207, 192, 207, 213, 213, + /* 1910 */ 213, 222, 213, 222, 4, 214, 214, 213, 3, 22, + /* 1920 */ 163, 279, 207, 15, 23, 16, 23, 139, 130, 151, + /* 1930 */ 153, 154, 155, 156, 157, 142, 25, 24, 20, 144, + /* 1940 */ 16, 1, 142, 61, 130, 130, 303, 151, 53, 37, + /* 1950 */ 303, 53, 300, 53, 130, 53, 116, 34, 1, 141, + /* 1960 */ 5, 22, 115, 25, 161, 75, 41, 68, 141, 115, + /* 1970 */ 24, 20, 68, 19, 131, 125, 23, 96, 22, 59, + /* 1980 */ 22, 67, 22, 22, 67, 22, 24, 28, 67, 37, + /* 1990 */ 23, 149, 22, 25, 23, 23, 23, 23, 22, 141, + /* 2000 */ 23, 23, 97, 116, 22, 143, 25, 88, 75, 34, + /* 2010 */ 44, 75, 86, 34, 34, 93, 23, 34, 34, 34, + /* 2020 */ 22, 24, 34, 22, 25, 25, 23, 23, 23, 23, + /* 2030 */ 23, 11, 23, 25, 22, 22, 25, 23, 23, 22, + /* 2040 */ 22, 135, 15, 1, 25, 23, 1, 319, 141, 319, + /* 2050 */ 319, 319, 319, 319, 319, 319, 319, 141, 319, 319, + /* 2060 */ 319, 319, 319, 319, 319, 319, 319, 319, 141, 141, + /* 2070 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, /* 2080 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2090 */ 319, 319, 319, 319, 141, 141, 319, 319, 319, 319, + /* 2090 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, /* 2100 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, /* 2110 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, /* 2120 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, /* 2130 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, /* 2140 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, @@ -168463,183 +162424,180 @@ /* 2200 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, /* 2210 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, /* 2220 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, /* 2230 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, /* 2240 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2250 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2260 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2270 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2280 */ 319, + /* 2250 */ 319, 319, 319, 319, 319, }; -#define YY_SHIFT_COUNT (574) +#define YY_SHIFT_COUNT (573) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (2074) +#define YY_SHIFT_MAX (2045) static const unsigned short int yy_shift_ofst[] = { - /* 0 */ 1648, 1477, 1272, 322, 322, 1, 1319, 1478, 1491, 1837, - /* 10 */ 1837, 1837, 471, 0, 0, 214, 1093, 1837, 1837, 1837, - /* 20 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, - /* 30 */ 271, 271, 1219, 1219, 216, 88, 1, 1, 1, 1, - /* 40 */ 1, 40, 111, 258, 361, 469, 512, 583, 622, 693, + /* 0 */ 1648, 1477, 1272, 322, 322, 262, 1319, 1478, 1491, 1662, + /* 10 */ 1662, 1662, 317, 0, 0, 214, 1093, 1662, 1662, 1662, + /* 20 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, + /* 30 */ 271, 271, 1219, 1219, 216, 88, 262, 262, 262, 262, + /* 40 */ 262, 40, 111, 258, 361, 469, 512, 583, 622, 693, /* 50 */ 732, 803, 842, 913, 1073, 1093, 1093, 1093, 1093, 1093, /* 60 */ 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, /* 70 */ 1093, 1093, 1093, 1113, 1093, 1216, 957, 957, 1635, 1662, - /* 80 */ 1777, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, - /* 90 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, - /* 100 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, - /* 110 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, - /* 120 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, - /* 130 */ 137, 181, 181, 181, 181, 181, 181, 181, 94, 430, - /* 140 */ 66, 65, 112, 366, 533, 533, 740, 1261, 533, 533, - /* 150 */ 79, 79, 533, 412, 412, 412, 77, 412, 123, 113, - /* 160 */ 113, 22, 22, 2096, 2096, 328, 328, 328, 239, 468, - /* 170 */ 468, 468, 468, 1015, 1015, 409, 366, 1129, 1186, 533, - /* 180 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 533, - /* 190 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 969, - /* 200 */ 621, 621, 533, 642, 788, 788, 1228, 1228, 822, 822, - /* 210 */ 67, 1274, 2096, 2096, 2096, 2096, 2096, 2096, 2096, 1307, - /* 220 */ 954, 954, 585, 472, 640, 387, 695, 538, 541, 700, - /* 230 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 533, - /* 240 */ 222, 533, 533, 533, 533, 533, 533, 533, 533, 533, - /* 250 */ 533, 533, 533, 1179, 1179, 1179, 533, 533, 533, 565, - /* 260 */ 533, 533, 533, 916, 1144, 533, 533, 1288, 533, 533, - /* 270 */ 533, 533, 533, 533, 533, 533, 639, 1330, 209, 1076, - /* 280 */ 1076, 1076, 1076, 580, 209, 209, 1313, 768, 917, 649, - /* 290 */ 1181, 1316, 405, 1316, 1238, 249, 1181, 1181, 249, 1181, - /* 300 */ 405, 1238, 1369, 464, 1259, 1012, 1012, 1012, 1368, 1368, - /* 310 */ 1368, 1368, 184, 184, 1326, 904, 1287, 1480, 1712, 1712, - /* 320 */ 1633, 1633, 1757, 1757, 1633, 1647, 1651, 1783, 1764, 1791, - /* 330 */ 1791, 1791, 1791, 1633, 1806, 1677, 1651, 1651, 1677, 1783, - /* 340 */ 1764, 1677, 1764, 1677, 1633, 1806, 1674, 1779, 1633, 1806, - /* 350 */ 1823, 1633, 1806, 1633, 1806, 1823, 1732, 1732, 1732, 1794, - /* 360 */ 1840, 1840, 1823, 1732, 1738, 1732, 1794, 1732, 1732, 1701, - /* 370 */ 1844, 1758, 1758, 1823, 1633, 1789, 1789, 1807, 1807, 1742, - /* 380 */ 1752, 1877, 1633, 1743, 1742, 1759, 1765, 1677, 1879, 1897, - /* 390 */ 1897, 1914, 1914, 1914, 2096, 2096, 2096, 2096, 2096, 2096, - /* 400 */ 2096, 2096, 2096, 2096, 2096, 2096, 2096, 2096, 2096, 207, - /* 410 */ 1095, 331, 620, 903, 806, 1074, 1483, 1432, 1481, 1322, - /* 420 */ 1370, 1394, 1515, 1291, 1546, 1547, 1557, 1595, 1598, 1599, - /* 430 */ 1434, 1453, 1618, 1462, 1567, 1489, 1644, 1654, 1616, 1660, - /* 440 */ 1548, 1549, 1682, 1685, 1597, 742, 1941, 1945, 1927, 1787, - /* 450 */ 1937, 1940, 1934, 1936, 1821, 1810, 1832, 1938, 1938, 1942, - /* 460 */ 1822, 1947, 1824, 1949, 1968, 1828, 1841, 1938, 1842, 1912, - /* 470 */ 1939, 1938, 1826, 1921, 1922, 1925, 1926, 1850, 1865, 1948, - /* 480 */ 1843, 1982, 1980, 1964, 1872, 1827, 1928, 1970, 1929, 1923, - /* 490 */ 1958, 1848, 1885, 1977, 1983, 1985, 1871, 1880, 1984, 1943, - /* 500 */ 1986, 1987, 1988, 1990, 1946, 1955, 1991, 1911, 1989, 1994, - /* 510 */ 1951, 1992, 1996, 1873, 1998, 2000, 2001, 2002, 2003, 2004, - /* 520 */ 1999, 1933, 1890, 2009, 2010, 1910, 2005, 2012, 1892, 2011, - /* 530 */ 2006, 2007, 2008, 2013, 1950, 1962, 1957, 2014, 1969, 1952, - /* 540 */ 2015, 2023, 2026, 2027, 2025, 2028, 2018, 1913, 1915, 2031, - /* 550 */ 2011, 2033, 2036, 2037, 2038, 2039, 2040, 2043, 2051, 2044, - /* 560 */ 2045, 2046, 2047, 2049, 2050, 2048, 1944, 1935, 1953, 1954, - /* 570 */ 2052, 2055, 2053, 2073, 2074, + /* 80 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, + /* 90 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, + /* 100 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, + /* 110 */ 1662, 1662, 1662, 1662, 1777, 1662, 1662, 1662, 1662, 1662, + /* 120 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 137, 181, + /* 130 */ 181, 181, 181, 181, 94, 430, 66, 65, 112, 366, + /* 140 */ 475, 475, 629, 1058, 475, 475, 125, 125, 475, 686, + /* 150 */ 686, 686, 660, 686, 57, 184, 184, 77, 77, 2070, + /* 160 */ 2070, 328, 328, 328, 493, 373, 373, 373, 373, 1015, + /* 170 */ 1015, 409, 366, 1129, 1149, 475, 475, 475, 475, 475, + /* 180 */ 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, + /* 190 */ 475, 475, 475, 475, 475, 621, 621, 475, 852, 899, + /* 200 */ 899, 1295, 1295, 406, 851, 2070, 2070, 2070, 2070, 2070, + /* 210 */ 2070, 2070, 1307, 954, 954, 640, 464, 695, 238, 700, + /* 220 */ 538, 541, 748, 475, 475, 475, 475, 475, 475, 475, + /* 230 */ 475, 475, 475, 634, 475, 475, 475, 475, 475, 475, + /* 240 */ 475, 475, 475, 475, 475, 475, 1175, 1175, 1175, 475, + /* 250 */ 475, 475, 580, 475, 475, 475, 1074, 1142, 475, 475, + /* 260 */ 1072, 475, 475, 475, 475, 475, 475, 475, 475, 797, + /* 270 */ 1330, 740, 1131, 1131, 1131, 1131, 1069, 740, 740, 1209, + /* 280 */ 167, 926, 1391, 1038, 1314, 187, 1408, 1314, 1408, 1435, + /* 290 */ 1109, 1038, 1038, 1109, 1038, 187, 1435, 227, 1090, 941, + /* 300 */ 1270, 1270, 1270, 1408, 1256, 1256, 1326, 1440, 513, 1461, + /* 310 */ 1685, 1685, 1613, 1613, 1722, 1722, 1613, 1612, 1614, 1745, + /* 320 */ 1728, 1755, 1755, 1755, 1755, 1613, 1766, 1651, 1614, 1614, + /* 330 */ 1651, 1745, 1728, 1651, 1728, 1651, 1613, 1766, 1653, 1758, + /* 340 */ 1613, 1766, 1802, 1613, 1766, 1613, 1766, 1802, 1716, 1716, + /* 350 */ 1716, 1768, 1813, 1813, 1802, 1716, 1713, 1716, 1768, 1716, + /* 360 */ 1716, 1675, 1817, 1729, 1729, 1802, 1706, 1742, 1706, 1742, + /* 370 */ 1706, 1742, 1706, 1742, 1613, 1774, 1774, 1786, 1786, 1723, + /* 380 */ 1730, 1851, 1613, 1720, 1723, 1733, 1735, 1651, 1857, 1873, + /* 390 */ 1873, 1896, 1896, 1896, 2070, 2070, 2070, 2070, 2070, 2070, + /* 400 */ 2070, 2070, 2070, 2070, 2070, 2070, 2070, 2070, 2070, 207, + /* 410 */ 915, 1010, 1030, 1217, 910, 1170, 1470, 1368, 1481, 1442, + /* 420 */ 1318, 1383, 1515, 1482, 1523, 1542, 1546, 1547, 1588, 1595, + /* 430 */ 1502, 1338, 1566, 1493, 1520, 1521, 1598, 1617, 1568, 1618, + /* 440 */ 1511, 1514, 1645, 1649, 1570, 1484, 1910, 1915, 1897, 1757, + /* 450 */ 1908, 1909, 1901, 1903, 1788, 1778, 1798, 1911, 1911, 1913, + /* 460 */ 1793, 1918, 1795, 1924, 1940, 1800, 1814, 1911, 1815, 1882, + /* 470 */ 1912, 1911, 1796, 1895, 1898, 1900, 1902, 1824, 1840, 1923, + /* 480 */ 1818, 1957, 1955, 1939, 1847, 1803, 1899, 1938, 1904, 1890, + /* 490 */ 1925, 1827, 1854, 1946, 1951, 1954, 1843, 1850, 1956, 1914, + /* 500 */ 1958, 1960, 1953, 1961, 1917, 1920, 1962, 1881, 1959, 1963, + /* 510 */ 1921, 1952, 1967, 1842, 1970, 1971, 1972, 1973, 1968, 1974, + /* 520 */ 1976, 1905, 1858, 1977, 1978, 1887, 1975, 1982, 1862, 1981, + /* 530 */ 1979, 1980, 1983, 1984, 1919, 1933, 1926, 1966, 1936, 1922, + /* 540 */ 1985, 1993, 1998, 1997, 1999, 2000, 1988, 2003, 1981, 2004, + /* 550 */ 2005, 2006, 2007, 2008, 2009, 2001, 2020, 2012, 2013, 2014, + /* 560 */ 2015, 2017, 2018, 2011, 1906, 1907, 1916, 1927, 1928, 2019, + /* 570 */ 2022, 2027, 2042, 2045, }; #define YY_REDUCE_COUNT (408) -#define YY_REDUCE_MIN (-271) -#define YY_REDUCE_MAX (1740) +#define YY_REDUCE_MIN (-267) +#define YY_REDUCE_MAX (1715) static const short yy_reduce_ofst[] = { /* 0 */ -125, 733, 789, 241, 293, -123, -193, -191, -183, -187, - /* 10 */ 166, 238, 133, -207, -199, -267, -176, -6, 204, 489, - /* 20 */ 576, -175, 598, 686, 615, 725, 860, 778, 781, 857, - /* 30 */ 616, 887, 87, 240, -192, 408, 626, 796, 843, 854, - /* 40 */ 1003, -271, -271, -271, -271, -271, -271, -271, -271, -271, - /* 50 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, - /* 60 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, - /* 70 */ -271, -271, -271, -271, -271, -271, -271, -271, 80, 83, - /* 80 */ 313, 886, 888, 996, 1034, 1059, 1081, 1100, 1117, 1152, - /* 90 */ 1155, 1163, 1165, 1167, 1169, 1172, 1180, 1182, 1184, 1198, - /* 100 */ 1200, 1213, 1215, 1225, 1227, 1252, 1254, 1264, 1299, 1303, - /* 110 */ 1308, 1312, 1325, 1328, 1337, 1340, 1343, 1371, 1373, 1384, - /* 120 */ 1386, 1411, 1420, 1424, 1426, 1458, 1470, 1473, 1475, 1479, - /* 130 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, - /* 140 */ -271, 138, 459, 396, -158, 470, 302, -212, 521, 201, - /* 150 */ -195, -92, 559, 630, 632, 630, -271, 632, 901, 63, - /* 160 */ 407, -271, -271, -271, -271, 161, 161, 161, 251, 335, - /* 170 */ 847, 960, 980, 537, 588, 618, 628, 688, 688, -166, - /* 180 */ -161, 674, 790, 794, 799, 851, 852, -122, 680, -120, - /* 190 */ 995, 1038, 415, 1051, 893, 798, 962, 400, 1086, 779, - /* 200 */ 923, 924, 263, 1041, 979, 990, 1083, 1097, 1031, 1194, - /* 210 */ 362, 994, 1139, 1005, 1037, 1202, 1205, 1195, 1210, -194, - /* 220 */ 56, 185, -135, 232, 522, 560, 601, 617, 669, 683, - /* 230 */ 711, 856, 908, 941, 1048, 1101, 1147, 1257, 1262, 1265, - /* 240 */ 392, 1292, 1333, 1339, 1342, 1346, 1350, 1359, 1374, 1418, - /* 250 */ 1421, 1436, 1437, 593, 755, 770, 997, 1445, 1459, 1209, - /* 260 */ 1500, 1504, 1516, 1132, 1243, 1518, 1519, 1440, 1520, 560, - /* 270 */ 1522, 1523, 1524, 1526, 1527, 1529, 1382, 1438, 1431, 1468, - /* 280 */ 1469, 1472, 1476, 1209, 1431, 1431, 1485, 1525, 1539, 1435, - /* 290 */ 1463, 1471, 1492, 1487, 1443, 1494, 1474, 1484, 1498, 1486, - /* 300 */ 1502, 1455, 1530, 1531, 1533, 1540, 1542, 1544, 1505, 1506, - /* 310 */ 1507, 1508, 1521, 1528, 1493, 1537, 1532, 1575, 1488, 1496, - /* 320 */ 1584, 1594, 1509, 1510, 1600, 1538, 1534, 1541, 1574, 1577, - /* 330 */ 1583, 1585, 1586, 1612, 1626, 1581, 1556, 1558, 1587, 1559, - /* 340 */ 1601, 1588, 1603, 1592, 1631, 1640, 1550, 1553, 1643, 1645, - /* 350 */ 1625, 1649, 1652, 1650, 1653, 1632, 1636, 1637, 1642, 1634, - /* 360 */ 1639, 1641, 1646, 1656, 1655, 1658, 1659, 1661, 1663, 1560, - /* 370 */ 1564, 1596, 1605, 1664, 1670, 1565, 1571, 1627, 1638, 1657, - /* 380 */ 1665, 1623, 1702, 1630, 1666, 1667, 1671, 1673, 1703, 1718, - /* 390 */ 1719, 1729, 1730, 1731, 1621, 1622, 1628, 1720, 1713, 1716, - /* 400 */ 1722, 1723, 1733, 1717, 1724, 1727, 1728, 1725, 1740, + /* 10 */ -180, 83, 133, -207, -198, -267, -175, -6, 166, 313, + /* 20 */ 487, 396, 489, 598, 615, 685, 687, 79, 781, 857, + /* 30 */ 490, 616, 240, 334, -188, 796, 841, 843, 1003, 1005, + /* 40 */ 1007, -260, -260, -260, -260, -260, -260, -260, -260, -260, + /* 50 */ -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, + /* 60 */ -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, + /* 70 */ -260, -260, -260, -260, -260, -260, -260, -260, 158, 203, + /* 80 */ 391, 576, 724, 726, 886, 1021, 1035, 1063, 1081, 1083, + /* 90 */ 1097, 1099, 1117, 1152, 1155, 1158, 1163, 1165, 1167, 1169, + /* 100 */ 1172, 1180, 1183, 1198, 1200, 1205, 1215, 1225, 1227, 1236, + /* 110 */ 1252, 1264, 1299, 1303, 1306, 1309, 1312, 1315, 1325, 1328, + /* 120 */ 1337, 1340, 1343, 1371, 1373, 1384, 1386, 1411, -260, -260, + /* 130 */ -260, -260, -260, -260, -260, -260, -260, -53, 138, 302, + /* 140 */ -158, 357, 223, -222, 411, 458, -92, 556, 669, 581, + /* 150 */ 632, 581, -260, 632, 758, 778, 920, -260, -260, -260, + /* 160 */ -260, 161, 161, 161, 307, 234, 392, 526, 790, 195, + /* 170 */ 359, -174, -173, 362, 362, -189, 16, 560, 567, 261, + /* 180 */ 689, 802, 853, -122, -166, 408, 335, 617, 690, 837, + /* 190 */ 1001, 746, 1061, 515, 1082, 994, 1034, -135, 1000, 1048, + /* 200 */ 1137, 877, 897, 186, 627, 1031, 1133, 1148, 1159, 1194, + /* 210 */ 1199, 1195, -194, -142, 18, -152, 68, 201, 253, 269, + /* 220 */ 294, 354, 521, 528, 676, 680, 736, 743, 850, 907, + /* 230 */ 1041, 1047, 1060, 727, 1139, 1147, 1201, 1237, 1278, 1359, + /* 240 */ 1393, 1400, 1413, 1429, 1433, 1437, 1126, 1410, 1430, 1444, + /* 250 */ 1480, 1483, 1405, 1486, 1490, 1492, 1420, 1372, 1496, 1498, + /* 260 */ 1441, 1499, 253, 1500, 1503, 1504, 1506, 1507, 1508, 1398, + /* 270 */ 1415, 1453, 1448, 1449, 1450, 1452, 1405, 1453, 1453, 1465, + /* 280 */ 1495, 1519, 1414, 1443, 1445, 1468, 1456, 1455, 1457, 1424, + /* 290 */ 1473, 1454, 1459, 1474, 1460, 1479, 1434, 1512, 1494, 1509, + /* 300 */ 1517, 1518, 1525, 1469, 1489, 1501, 1467, 1510, 1497, 1543, + /* 310 */ 1451, 1462, 1557, 1558, 1471, 1472, 1561, 1487, 1505, 1524, + /* 320 */ 1538, 1537, 1545, 1548, 1556, 1575, 1596, 1552, 1529, 1530, + /* 330 */ 1559, 1533, 1572, 1562, 1573, 1563, 1604, 1615, 1522, 1532, + /* 340 */ 1622, 1624, 1605, 1625, 1628, 1629, 1631, 1607, 1616, 1619, + /* 350 */ 1620, 1606, 1621, 1623, 1630, 1626, 1632, 1636, 1633, 1637, + /* 360 */ 1638, 1531, 1541, 1567, 1571, 1640, 1597, 1599, 1601, 1603, + /* 370 */ 1608, 1610, 1611, 1627, 1664, 1549, 1550, 1609, 1634, 1639, + /* 380 */ 1641, 1602, 1676, 1642, 1646, 1644, 1650, 1654, 1683, 1694, + /* 390 */ 1707, 1711, 1712, 1714, 1643, 1647, 1652, 1698, 1695, 1696, + /* 400 */ 1697, 1699, 1700, 1689, 1691, 1701, 1702, 1704, 1715, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 1641, 1641, 1641, 1470, 1236, 1347, 1236, 1236, 1236, 1470, - /* 10 */ 1470, 1470, 1236, 1377, 1377, 1523, 1269, 1236, 1236, 1236, - /* 20 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1469, 1236, 1236, - /* 30 */ 1236, 1236, 1558, 1558, 1236, 1236, 1236, 1236, 1236, 1236, - /* 40 */ 1236, 1236, 1386, 1236, 1393, 1236, 1236, 1236, 1236, 1236, - /* 50 */ 1471, 1472, 1236, 1236, 1236, 1522, 1524, 1487, 1400, 1399, - /* 60 */ 1398, 1397, 1505, 1365, 1391, 1384, 1388, 1465, 1466, 1464, - /* 70 */ 1468, 1472, 1471, 1236, 1387, 1433, 1449, 1432, 1236, 1236, - /* 80 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 90 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 100 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 110 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 120 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 130 */ 1441, 1448, 1447, 1446, 1455, 1445, 1442, 1435, 1434, 1436, - /* 140 */ 1437, 1236, 1236, 1260, 1236, 1236, 1257, 1311, 1236, 1236, - /* 150 */ 1236, 1236, 1236, 1542, 1541, 1236, 1438, 1236, 1269, 1427, - /* 160 */ 1426, 1452, 1439, 1451, 1450, 1530, 1594, 1593, 1488, 1236, - /* 170 */ 1236, 1236, 1236, 1236, 1236, 1558, 1236, 1236, 1236, 1236, - /* 180 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 190 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1367, - /* 200 */ 1558, 1558, 1236, 1269, 1558, 1558, 1368, 1368, 1265, 1265, - /* 210 */ 1371, 1236, 1537, 1338, 1338, 1338, 1338, 1347, 1338, 1236, - /* 220 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 230 */ 1236, 1236, 1236, 1236, 1527, 1525, 1236, 1236, 1236, 1236, - /* 240 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 250 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 260 */ 1236, 1236, 1236, 1343, 1236, 1236, 1236, 1236, 1236, 1236, - /* 270 */ 1236, 1236, 1236, 1236, 1236, 1587, 1236, 1500, 1325, 1343, - /* 280 */ 1343, 1343, 1343, 1345, 1326, 1324, 1337, 1270, 1243, 1633, - /* 290 */ 1403, 1392, 1344, 1392, 1630, 1390, 1403, 1403, 1390, 1403, - /* 300 */ 1344, 1630, 1286, 1609, 1281, 1377, 1377, 1377, 1367, 1367, - /* 310 */ 1367, 1367, 1371, 1371, 1467, 1344, 1337, 1236, 1633, 1633, - /* 320 */ 1353, 1353, 1632, 1632, 1353, 1488, 1617, 1412, 1314, 1320, - /* 330 */ 1320, 1320, 1320, 1353, 1254, 1390, 1617, 1617, 1390, 1412, - /* 340 */ 1314, 1390, 1314, 1390, 1353, 1254, 1504, 1627, 1353, 1254, - /* 350 */ 1478, 1353, 1254, 1353, 1254, 1478, 1312, 1312, 1312, 1301, - /* 360 */ 1236, 1236, 1478, 1312, 1286, 1312, 1301, 1312, 1312, 1576, - /* 370 */ 1236, 1482, 1482, 1478, 1353, 1568, 1568, 1380, 1380, 1385, - /* 380 */ 1371, 1473, 1353, 1236, 1385, 1383, 1381, 1390, 1304, 1590, - /* 390 */ 1590, 1586, 1586, 1586, 1638, 1638, 1537, 1602, 1269, 1269, - /* 400 */ 1269, 1269, 1602, 1288, 1288, 1270, 1270, 1269, 1602, 1236, - /* 410 */ 1236, 1236, 1236, 1236, 1236, 1597, 1236, 1532, 1489, 1357, - /* 420 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 430 */ 1236, 1236, 1236, 1236, 1543, 1236, 1236, 1236, 1236, 1236, - /* 440 */ 1236, 1236, 1236, 1236, 1236, 1417, 1236, 1239, 1534, 1236, - /* 450 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1394, 1395, 1358, - /* 460 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1409, 1236, 1236, - /* 470 */ 1236, 1404, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 480 */ 1629, 1236, 1236, 1236, 1236, 1236, 1236, 1503, 1502, 1236, - /* 490 */ 1236, 1355, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 500 */ 1236, 1236, 1236, 1236, 1236, 1284, 1236, 1236, 1236, 1236, - /* 510 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 520 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1382, - /* 530 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 540 */ 1236, 1236, 1236, 1236, 1573, 1372, 1236, 1236, 1236, 1236, - /* 550 */ 1620, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 560 */ 1236, 1236, 1236, 1236, 1236, 1613, 1328, 1418, 1236, 1421, - /* 570 */ 1258, 1236, 1248, 1236, 1236, + /* 0 */ 1637, 1637, 1637, 1466, 1233, 1344, 1233, 1233, 1233, 1466, + /* 10 */ 1466, 1466, 1233, 1374, 1374, 1519, 1266, 1233, 1233, 1233, + /* 20 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1465, 1233, 1233, + /* 30 */ 1233, 1233, 1554, 1554, 1233, 1233, 1233, 1233, 1233, 1233, + /* 40 */ 1233, 1233, 1383, 1233, 1390, 1233, 1233, 1233, 1233, 1233, + /* 50 */ 1467, 1468, 1233, 1233, 1233, 1518, 1520, 1483, 1397, 1396, + /* 60 */ 1395, 1394, 1501, 1361, 1388, 1381, 1385, 1461, 1462, 1460, + /* 70 */ 1464, 1468, 1467, 1233, 1384, 1431, 1445, 1430, 1233, 1233, + /* 80 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 90 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 100 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 110 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 120 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1439, 1444, + /* 130 */ 1451, 1443, 1440, 1433, 1432, 1434, 1435, 1233, 1233, 1257, + /* 140 */ 1233, 1233, 1254, 1308, 1233, 1233, 1233, 1233, 1233, 1538, + /* 150 */ 1537, 1233, 1436, 1233, 1266, 1425, 1424, 1448, 1437, 1447, + /* 160 */ 1446, 1526, 1590, 1589, 1484, 1233, 1233, 1233, 1233, 1233, + /* 170 */ 1233, 1554, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 180 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 190 */ 1233, 1233, 1233, 1233, 1233, 1554, 1554, 1233, 1266, 1554, + /* 200 */ 1554, 1262, 1262, 1368, 1233, 1533, 1335, 1335, 1335, 1335, + /* 210 */ 1344, 1335, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 220 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1523, 1521, 1233, + /* 230 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 240 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 250 */ 1233, 1233, 1233, 1233, 1233, 1233, 1340, 1233, 1233, 1233, + /* 260 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1583, 1233, + /* 270 */ 1496, 1322, 1340, 1340, 1340, 1340, 1342, 1323, 1321, 1334, + /* 280 */ 1267, 1240, 1629, 1400, 1389, 1341, 1363, 1389, 1363, 1626, + /* 290 */ 1387, 1400, 1400, 1387, 1400, 1341, 1626, 1283, 1606, 1278, + /* 300 */ 1374, 1374, 1374, 1363, 1368, 1368, 1463, 1341, 1334, 1233, + /* 310 */ 1629, 1629, 1349, 1349, 1628, 1628, 1349, 1484, 1613, 1409, + /* 320 */ 1311, 1317, 1317, 1317, 1317, 1349, 1251, 1387, 1613, 1613, + /* 330 */ 1387, 1409, 1311, 1387, 1311, 1387, 1349, 1251, 1500, 1623, + /* 340 */ 1349, 1251, 1474, 1349, 1251, 1349, 1251, 1474, 1309, 1309, + /* 350 */ 1309, 1298, 1233, 1233, 1474, 1309, 1283, 1309, 1298, 1309, + /* 360 */ 1309, 1572, 1233, 1478, 1478, 1474, 1367, 1362, 1367, 1362, + /* 370 */ 1367, 1362, 1367, 1362, 1349, 1564, 1564, 1377, 1377, 1382, + /* 380 */ 1368, 1469, 1349, 1233, 1382, 1380, 1378, 1387, 1301, 1586, + /* 390 */ 1586, 1582, 1582, 1582, 1634, 1634, 1533, 1599, 1266, 1266, + /* 400 */ 1266, 1266, 1599, 1285, 1285, 1267, 1267, 1266, 1599, 1233, + /* 410 */ 1233, 1233, 1233, 1233, 1233, 1594, 1233, 1528, 1485, 1353, + /* 420 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 430 */ 1233, 1233, 1233, 1233, 1539, 1233, 1233, 1233, 1233, 1233, + /* 440 */ 1233, 1233, 1233, 1233, 1233, 1414, 1233, 1236, 1530, 1233, + /* 450 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1391, 1392, 1354, + /* 460 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1406, 1233, 1233, + /* 470 */ 1233, 1401, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 480 */ 1625, 1233, 1233, 1233, 1233, 1233, 1233, 1499, 1498, 1233, + /* 490 */ 1233, 1351, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 500 */ 1233, 1233, 1233, 1233, 1233, 1281, 1233, 1233, 1233, 1233, + /* 510 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 520 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1379, + /* 530 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 540 */ 1233, 1233, 1233, 1233, 1569, 1369, 1233, 1233, 1616, 1233, + /* 550 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 560 */ 1233, 1233, 1233, 1610, 1325, 1416, 1233, 1415, 1419, 1255, + /* 570 */ 1233, 1245, 1233, 1233, }; /********** End of lemon-generated parsing tables *****************************/ /* The next table maps tokens (terminal symbols) into fallback tokens. ** If a construct like the following: @@ -169187,16 +163145,16 @@ /* 254 */ "sclp", /* 255 */ "as", /* 256 */ "seltablist", /* 257 */ "stl_prefix", /* 258 */ "joinop", - /* 259 */ "on_using", - /* 260 */ "indexed_by", - /* 261 */ "exprlist", - /* 262 */ "xfullname", - /* 263 */ "idlist", - /* 264 */ "indexed_opt", + /* 259 */ "indexed_opt", + /* 260 */ "on_opt", + /* 261 */ "using_opt", + /* 262 */ "exprlist", + /* 263 */ "xfullname", + /* 264 */ "idlist", /* 265 */ "nulls", /* 266 */ "with", /* 267 */ "where_opt_ret", /* 268 */ "setlist", /* 269 */ "insert_cmd", @@ -169363,33 +163321,33 @@ /* 104 */ "as ::=", /* 105 */ "from ::=", /* 106 */ "from ::= FROM seltablist", /* 107 */ "stl_prefix ::= seltablist joinop", /* 108 */ "stl_prefix ::=", - /* 109 */ "seltablist ::= stl_prefix nm dbnm as on_using", - /* 110 */ "seltablist ::= stl_prefix nm dbnm as indexed_by on_using", - /* 111 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using", - /* 112 */ "seltablist ::= stl_prefix LP select RP as on_using", - /* 113 */ "seltablist ::= stl_prefix LP seltablist RP as on_using", - /* 114 */ "dbnm ::=", - /* 115 */ "dbnm ::= DOT nm", - /* 116 */ "fullname ::= nm", - /* 117 */ "fullname ::= nm DOT nm", - /* 118 */ "xfullname ::= nm", - /* 119 */ "xfullname ::= nm DOT nm", - /* 120 */ "xfullname ::= nm DOT nm AS nm", - /* 121 */ "xfullname ::= nm AS nm", - /* 122 */ "joinop ::= COMMA|JOIN", - /* 123 */ "joinop ::= JOIN_KW JOIN", - /* 124 */ "joinop ::= JOIN_KW nm JOIN", - /* 125 */ "joinop ::= JOIN_KW nm nm JOIN", - /* 126 */ "on_using ::= ON expr", - /* 127 */ "on_using ::= USING LP idlist RP", - /* 128 */ "on_using ::=", - /* 129 */ "indexed_opt ::=", - /* 130 */ "indexed_by ::= INDEXED BY nm", - /* 131 */ "indexed_by ::= NOT INDEXED", + /* 109 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt", + /* 110 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt", + /* 111 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt", + /* 112 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt", + /* 113 */ "dbnm ::=", + /* 114 */ "dbnm ::= DOT nm", + /* 115 */ "fullname ::= nm", + /* 116 */ "fullname ::= nm DOT nm", + /* 117 */ "xfullname ::= nm", + /* 118 */ "xfullname ::= nm DOT nm", + /* 119 */ "xfullname ::= nm DOT nm AS nm", + /* 120 */ "xfullname ::= nm AS nm", + /* 121 */ "joinop ::= COMMA|JOIN", + /* 122 */ "joinop ::= JOIN_KW JOIN", + /* 123 */ "joinop ::= JOIN_KW nm JOIN", + /* 124 */ "joinop ::= JOIN_KW nm nm JOIN", + /* 125 */ "on_opt ::= ON expr", + /* 126 */ "on_opt ::=", + /* 127 */ "indexed_opt ::=", + /* 128 */ "indexed_opt ::= INDEXED BY nm", + /* 129 */ "indexed_opt ::= NOT INDEXED", + /* 130 */ "using_opt ::= USING LP idlist RP", + /* 131 */ "using_opt ::=", /* 132 */ "orderby_opt ::=", /* 133 */ "orderby_opt ::= ORDER BY sortlist", /* 134 */ "sortlist ::= sortlist COMMA expr sortorder nulls", /* 135 */ "sortlist ::= expr sortorder nulls", /* 136 */ "sortorder ::= ASC", @@ -169432,190 +163390,190 @@ /* 173 */ "idlist_opt ::=", /* 174 */ "idlist_opt ::= LP idlist RP", /* 175 */ "idlist ::= idlist COMMA nm", /* 176 */ "idlist ::= nm", /* 177 */ "expr ::= LP expr RP", - /* 178 */ "expr ::= ID|INDEXED|JOIN_KW", - /* 179 */ "expr ::= nm DOT nm", - /* 180 */ "expr ::= nm DOT nm DOT nm", - /* 181 */ "term ::= NULL|FLOAT|BLOB", - /* 182 */ "term ::= STRING", - /* 183 */ "term ::= INTEGER", - /* 184 */ "expr ::= VARIABLE", - /* 185 */ "expr ::= expr COLLATE ID|STRING", - /* 186 */ "expr ::= CAST LP expr AS typetoken RP", - /* 187 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP", - /* 188 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP", - /* 189 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over", - /* 190 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over", - /* 191 */ "term ::= CTIME_KW", - /* 192 */ "expr ::= LP nexprlist COMMA expr RP", - /* 193 */ "expr ::= expr AND expr", - /* 194 */ "expr ::= expr OR expr", - /* 195 */ "expr ::= expr LT|GT|GE|LE expr", - /* 196 */ "expr ::= expr EQ|NE expr", - /* 197 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", - /* 198 */ "expr ::= expr PLUS|MINUS expr", - /* 199 */ "expr ::= expr STAR|SLASH|REM expr", - /* 200 */ "expr ::= expr CONCAT expr", - /* 201 */ "likeop ::= NOT LIKE_KW|MATCH", - /* 202 */ "expr ::= expr likeop expr", - /* 203 */ "expr ::= expr likeop expr ESCAPE expr", - /* 204 */ "expr ::= expr ISNULL|NOTNULL", - /* 205 */ "expr ::= expr NOT NULL", - /* 206 */ "expr ::= expr IS expr", - /* 207 */ "expr ::= expr IS NOT expr", - /* 208 */ "expr ::= expr IS NOT DISTINCT FROM expr", - /* 209 */ "expr ::= expr IS DISTINCT FROM expr", - /* 210 */ "expr ::= NOT expr", - /* 211 */ "expr ::= BITNOT expr", - /* 212 */ "expr ::= PLUS|MINUS expr", - /* 213 */ "expr ::= expr PTR expr", - /* 214 */ "between_op ::= BETWEEN", - /* 215 */ "between_op ::= NOT BETWEEN", - /* 216 */ "expr ::= expr between_op expr AND expr", - /* 217 */ "in_op ::= IN", - /* 218 */ "in_op ::= NOT IN", - /* 219 */ "expr ::= expr in_op LP exprlist RP", - /* 220 */ "expr ::= LP select RP", - /* 221 */ "expr ::= expr in_op LP select RP", - /* 222 */ "expr ::= expr in_op nm dbnm paren_exprlist", - /* 223 */ "expr ::= EXISTS LP select RP", - /* 224 */ "expr ::= CASE case_operand case_exprlist case_else END", - /* 225 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", - /* 226 */ "case_exprlist ::= WHEN expr THEN expr", - /* 227 */ "case_else ::= ELSE expr", - /* 228 */ "case_else ::=", - /* 229 */ "case_operand ::= expr", - /* 230 */ "case_operand ::=", - /* 231 */ "exprlist ::=", - /* 232 */ "nexprlist ::= nexprlist COMMA expr", - /* 233 */ "nexprlist ::= expr", - /* 234 */ "paren_exprlist ::=", - /* 235 */ "paren_exprlist ::= LP exprlist RP", - /* 236 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", - /* 237 */ "uniqueflag ::= UNIQUE", - /* 238 */ "uniqueflag ::=", - /* 239 */ "eidlist_opt ::=", - /* 240 */ "eidlist_opt ::= LP eidlist RP", - /* 241 */ "eidlist ::= eidlist COMMA nm collate sortorder", - /* 242 */ "eidlist ::= nm collate sortorder", - /* 243 */ "collate ::=", - /* 244 */ "collate ::= COLLATE ID|STRING", - /* 245 */ "cmd ::= DROP INDEX ifexists fullname", - /* 246 */ "cmd ::= VACUUM vinto", - /* 247 */ "cmd ::= VACUUM nm vinto", - /* 248 */ "vinto ::= INTO expr", - /* 249 */ "vinto ::=", - /* 250 */ "cmd ::= PRAGMA nm dbnm", - /* 251 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", - /* 252 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", - /* 253 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", - /* 254 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", - /* 255 */ "plus_num ::= PLUS INTEGER|FLOAT", - /* 256 */ "minus_num ::= MINUS INTEGER|FLOAT", - /* 257 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", - /* 258 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", - /* 259 */ "trigger_time ::= BEFORE|AFTER", - /* 260 */ "trigger_time ::= INSTEAD OF", - /* 261 */ "trigger_time ::=", - /* 262 */ "trigger_event ::= DELETE|INSERT", - /* 263 */ "trigger_event ::= UPDATE", - /* 264 */ "trigger_event ::= UPDATE OF idlist", - /* 265 */ "when_clause ::=", - /* 266 */ "when_clause ::= WHEN expr", - /* 267 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", - /* 268 */ "trigger_cmd_list ::= trigger_cmd SEMI", - /* 269 */ "trnm ::= nm DOT nm", - /* 270 */ "tridxby ::= INDEXED BY nm", - /* 271 */ "tridxby ::= NOT INDEXED", - /* 272 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", - /* 273 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", - /* 274 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", - /* 275 */ "trigger_cmd ::= scanpt select scanpt", - /* 276 */ "expr ::= RAISE LP IGNORE RP", - /* 277 */ "expr ::= RAISE LP raisetype COMMA nm RP", - /* 278 */ "raisetype ::= ROLLBACK", - /* 279 */ "raisetype ::= ABORT", - /* 280 */ "raisetype ::= FAIL", - /* 281 */ "cmd ::= DROP TRIGGER ifexists fullname", - /* 282 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", - /* 283 */ "cmd ::= DETACH database_kw_opt expr", - /* 284 */ "key_opt ::=", - /* 285 */ "key_opt ::= KEY expr", - /* 286 */ "cmd ::= REINDEX", - /* 287 */ "cmd ::= REINDEX nm dbnm", - /* 288 */ "cmd ::= ANALYZE", - /* 289 */ "cmd ::= ANALYZE nm dbnm", - /* 290 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", - /* 291 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", - /* 292 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm", - /* 293 */ "add_column_fullname ::= fullname", - /* 294 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", - /* 295 */ "cmd ::= create_vtab", - /* 296 */ "cmd ::= create_vtab LP vtabarglist RP", - /* 297 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", - /* 298 */ "vtabarg ::=", - /* 299 */ "vtabargtoken ::= ANY", - /* 300 */ "vtabargtoken ::= lp anylist RP", - /* 301 */ "lp ::= LP", - /* 302 */ "with ::= WITH wqlist", - /* 303 */ "with ::= WITH RECURSIVE wqlist", - /* 304 */ "wqas ::= AS", - /* 305 */ "wqas ::= AS MATERIALIZED", - /* 306 */ "wqas ::= AS NOT MATERIALIZED", - /* 307 */ "wqitem ::= nm eidlist_opt wqas LP select RP", - /* 308 */ "wqlist ::= wqitem", - /* 309 */ "wqlist ::= wqlist COMMA wqitem", - /* 310 */ "windowdefn_list ::= windowdefn", - /* 311 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", - /* 312 */ "windowdefn ::= nm AS LP window RP", - /* 313 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", - /* 314 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", - /* 315 */ "window ::= ORDER BY sortlist frame_opt", - /* 316 */ "window ::= nm ORDER BY sortlist frame_opt", - /* 317 */ "window ::= frame_opt", - /* 318 */ "window ::= nm frame_opt", - /* 319 */ "frame_opt ::=", - /* 320 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", - /* 321 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", - /* 322 */ "range_or_rows ::= RANGE|ROWS|GROUPS", - /* 323 */ "frame_bound_s ::= frame_bound", - /* 324 */ "frame_bound_s ::= UNBOUNDED PRECEDING", - /* 325 */ "frame_bound_e ::= frame_bound", - /* 326 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", - /* 327 */ "frame_bound ::= expr PRECEDING|FOLLOWING", - /* 328 */ "frame_bound ::= CURRENT ROW", - /* 329 */ "frame_exclude_opt ::=", - /* 330 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", - /* 331 */ "frame_exclude ::= NO OTHERS", - /* 332 */ "frame_exclude ::= CURRENT ROW", - /* 333 */ "frame_exclude ::= GROUP|TIES", - /* 334 */ "window_clause ::= WINDOW windowdefn_list", - /* 335 */ "filter_over ::= filter_clause over_clause", - /* 336 */ "filter_over ::= over_clause", - /* 337 */ "filter_over ::= filter_clause", - /* 338 */ "over_clause ::= OVER LP window RP", - /* 339 */ "over_clause ::= OVER nm", - /* 340 */ "filter_clause ::= FILTER LP WHERE expr RP", - /* 341 */ "input ::= cmdlist", - /* 342 */ "cmdlist ::= cmdlist ecmd", - /* 343 */ "cmdlist ::= ecmd", - /* 344 */ "ecmd ::= SEMI", - /* 345 */ "ecmd ::= cmdx SEMI", - /* 346 */ "ecmd ::= explain cmdx SEMI", - /* 347 */ "trans_opt ::=", - /* 348 */ "trans_opt ::= TRANSACTION", - /* 349 */ "trans_opt ::= TRANSACTION nm", - /* 350 */ "savepoint_opt ::= SAVEPOINT", - /* 351 */ "savepoint_opt ::=", - /* 352 */ "cmd ::= create_table create_table_args", - /* 353 */ "table_option_set ::= table_option", - /* 354 */ "columnlist ::= columnlist COMMA columnname carglist", - /* 355 */ "columnlist ::= columnname carglist", - /* 356 */ "nm ::= ID|INDEXED|JOIN_KW", - /* 357 */ "nm ::= STRING", + /* 178 */ "expr ::= ID|INDEXED", + /* 179 */ "expr ::= JOIN_KW", + /* 180 */ "expr ::= nm DOT nm", + /* 181 */ "expr ::= nm DOT nm DOT nm", + /* 182 */ "term ::= NULL|FLOAT|BLOB", + /* 183 */ "term ::= STRING", + /* 184 */ "term ::= INTEGER", + /* 185 */ "expr ::= VARIABLE", + /* 186 */ "expr ::= expr COLLATE ID|STRING", + /* 187 */ "expr ::= CAST LP expr AS typetoken RP", + /* 188 */ "expr ::= ID|INDEXED LP distinct exprlist RP", + /* 189 */ "expr ::= ID|INDEXED LP STAR RP", + /* 190 */ "expr ::= ID|INDEXED LP distinct exprlist RP filter_over", + /* 191 */ "expr ::= ID|INDEXED LP STAR RP filter_over", + /* 192 */ "term ::= CTIME_KW", + /* 193 */ "expr ::= LP nexprlist COMMA expr RP", + /* 194 */ "expr ::= expr AND expr", + /* 195 */ "expr ::= expr OR expr", + /* 196 */ "expr ::= expr LT|GT|GE|LE expr", + /* 197 */ "expr ::= expr EQ|NE expr", + /* 198 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", + /* 199 */ "expr ::= expr PLUS|MINUS expr", + /* 200 */ "expr ::= expr STAR|SLASH|REM expr", + /* 201 */ "expr ::= expr CONCAT expr", + /* 202 */ "likeop ::= NOT LIKE_KW|MATCH", + /* 203 */ "expr ::= expr likeop expr", + /* 204 */ "expr ::= expr likeop expr ESCAPE expr", + /* 205 */ "expr ::= expr ISNULL|NOTNULL", + /* 206 */ "expr ::= expr NOT NULL", + /* 207 */ "expr ::= expr IS expr", + /* 208 */ "expr ::= expr IS NOT expr", + /* 209 */ "expr ::= NOT expr", + /* 210 */ "expr ::= BITNOT expr", + /* 211 */ "expr ::= PLUS|MINUS expr", + /* 212 */ "expr ::= expr PTR expr", + /* 213 */ "between_op ::= BETWEEN", + /* 214 */ "between_op ::= NOT BETWEEN", + /* 215 */ "expr ::= expr between_op expr AND expr", + /* 216 */ "in_op ::= IN", + /* 217 */ "in_op ::= NOT IN", + /* 218 */ "expr ::= expr in_op LP exprlist RP", + /* 219 */ "expr ::= LP select RP", + /* 220 */ "expr ::= expr in_op LP select RP", + /* 221 */ "expr ::= expr in_op nm dbnm paren_exprlist", + /* 222 */ "expr ::= EXISTS LP select RP", + /* 223 */ "expr ::= CASE case_operand case_exprlist case_else END", + /* 224 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", + /* 225 */ "case_exprlist ::= WHEN expr THEN expr", + /* 226 */ "case_else ::= ELSE expr", + /* 227 */ "case_else ::=", + /* 228 */ "case_operand ::= expr", + /* 229 */ "case_operand ::=", + /* 230 */ "exprlist ::=", + /* 231 */ "nexprlist ::= nexprlist COMMA expr", + /* 232 */ "nexprlist ::= expr", + /* 233 */ "paren_exprlist ::=", + /* 234 */ "paren_exprlist ::= LP exprlist RP", + /* 235 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", + /* 236 */ "uniqueflag ::= UNIQUE", + /* 237 */ "uniqueflag ::=", + /* 238 */ "eidlist_opt ::=", + /* 239 */ "eidlist_opt ::= LP eidlist RP", + /* 240 */ "eidlist ::= eidlist COMMA nm collate sortorder", + /* 241 */ "eidlist ::= nm collate sortorder", + /* 242 */ "collate ::=", + /* 243 */ "collate ::= COLLATE ID|STRING", + /* 244 */ "cmd ::= DROP INDEX ifexists fullname", + /* 245 */ "cmd ::= VACUUM vinto", + /* 246 */ "cmd ::= VACUUM nm vinto", + /* 247 */ "vinto ::= INTO expr", + /* 248 */ "vinto ::=", + /* 249 */ "cmd ::= PRAGMA nm dbnm", + /* 250 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", + /* 251 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", + /* 252 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", + /* 253 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", + /* 254 */ "plus_num ::= PLUS INTEGER|FLOAT", + /* 255 */ "minus_num ::= MINUS INTEGER|FLOAT", + /* 256 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", + /* 257 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", + /* 258 */ "trigger_time ::= BEFORE|AFTER", + /* 259 */ "trigger_time ::= INSTEAD OF", + /* 260 */ "trigger_time ::=", + /* 261 */ "trigger_event ::= DELETE|INSERT", + /* 262 */ "trigger_event ::= UPDATE", + /* 263 */ "trigger_event ::= UPDATE OF idlist", + /* 264 */ "when_clause ::=", + /* 265 */ "when_clause ::= WHEN expr", + /* 266 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", + /* 267 */ "trigger_cmd_list ::= trigger_cmd SEMI", + /* 268 */ "trnm ::= nm DOT nm", + /* 269 */ "tridxby ::= INDEXED BY nm", + /* 270 */ "tridxby ::= NOT INDEXED", + /* 271 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", + /* 272 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", + /* 273 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", + /* 274 */ "trigger_cmd ::= scanpt select scanpt", + /* 275 */ "expr ::= RAISE LP IGNORE RP", + /* 276 */ "expr ::= RAISE LP raisetype COMMA nm RP", + /* 277 */ "raisetype ::= ROLLBACK", + /* 278 */ "raisetype ::= ABORT", + /* 279 */ "raisetype ::= FAIL", + /* 280 */ "cmd ::= DROP TRIGGER ifexists fullname", + /* 281 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", + /* 282 */ "cmd ::= DETACH database_kw_opt expr", + /* 283 */ "key_opt ::=", + /* 284 */ "key_opt ::= KEY expr", + /* 285 */ "cmd ::= REINDEX", + /* 286 */ "cmd ::= REINDEX nm dbnm", + /* 287 */ "cmd ::= ANALYZE", + /* 288 */ "cmd ::= ANALYZE nm dbnm", + /* 289 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", + /* 290 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", + /* 291 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm", + /* 292 */ "add_column_fullname ::= fullname", + /* 293 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", + /* 294 */ "cmd ::= create_vtab", + /* 295 */ "cmd ::= create_vtab LP vtabarglist RP", + /* 296 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", + /* 297 */ "vtabarg ::=", + /* 298 */ "vtabargtoken ::= ANY", + /* 299 */ "vtabargtoken ::= lp anylist RP", + /* 300 */ "lp ::= LP", + /* 301 */ "with ::= WITH wqlist", + /* 302 */ "with ::= WITH RECURSIVE wqlist", + /* 303 */ "wqas ::= AS", + /* 304 */ "wqas ::= AS MATERIALIZED", + /* 305 */ "wqas ::= AS NOT MATERIALIZED", + /* 306 */ "wqitem ::= nm eidlist_opt wqas LP select RP", + /* 307 */ "wqlist ::= wqitem", + /* 308 */ "wqlist ::= wqlist COMMA wqitem", + /* 309 */ "windowdefn_list ::= windowdefn", + /* 310 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", + /* 311 */ "windowdefn ::= nm AS LP window RP", + /* 312 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", + /* 313 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", + /* 314 */ "window ::= ORDER BY sortlist frame_opt", + /* 315 */ "window ::= nm ORDER BY sortlist frame_opt", + /* 316 */ "window ::= frame_opt", + /* 317 */ "window ::= nm frame_opt", + /* 318 */ "frame_opt ::=", + /* 319 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", + /* 320 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", + /* 321 */ "range_or_rows ::= RANGE|ROWS|GROUPS", + /* 322 */ "frame_bound_s ::= frame_bound", + /* 323 */ "frame_bound_s ::= UNBOUNDED PRECEDING", + /* 324 */ "frame_bound_e ::= frame_bound", + /* 325 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", + /* 326 */ "frame_bound ::= expr PRECEDING|FOLLOWING", + /* 327 */ "frame_bound ::= CURRENT ROW", + /* 328 */ "frame_exclude_opt ::=", + /* 329 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", + /* 330 */ "frame_exclude ::= NO OTHERS", + /* 331 */ "frame_exclude ::= CURRENT ROW", + /* 332 */ "frame_exclude ::= GROUP|TIES", + /* 333 */ "window_clause ::= WINDOW windowdefn_list", + /* 334 */ "filter_over ::= filter_clause over_clause", + /* 335 */ "filter_over ::= over_clause", + /* 336 */ "filter_over ::= filter_clause", + /* 337 */ "over_clause ::= OVER LP window RP", + /* 338 */ "over_clause ::= OVER nm", + /* 339 */ "filter_clause ::= FILTER LP WHERE expr RP", + /* 340 */ "input ::= cmdlist", + /* 341 */ "cmdlist ::= cmdlist ecmd", + /* 342 */ "cmdlist ::= ecmd", + /* 343 */ "ecmd ::= SEMI", + /* 344 */ "ecmd ::= cmdx SEMI", + /* 345 */ "ecmd ::= explain cmdx SEMI", + /* 346 */ "trans_opt ::=", + /* 347 */ "trans_opt ::= TRANSACTION", + /* 348 */ "trans_opt ::= TRANSACTION nm", + /* 349 */ "savepoint_opt ::= SAVEPOINT", + /* 350 */ "savepoint_opt ::=", + /* 351 */ "cmd ::= create_table create_table_args", + /* 352 */ "table_option_set ::= table_option", + /* 353 */ "columnlist ::= columnlist COMMA columnname carglist", + /* 354 */ "columnlist ::= columnname carglist", + /* 355 */ "nm ::= ID|INDEXED", + /* 356 */ "nm ::= STRING", + /* 357 */ "nm ::= JOIN_KW", /* 358 */ "typetoken ::= typename", /* 359 */ "typename ::= ID|STRING", /* 360 */ "signed ::= plus_num", /* 361 */ "signed ::= minus_num", /* 362 */ "carglist ::= carglist ccons", @@ -169631,36 +163589,35 @@ /* 372 */ "resolvetype ::= raisetype", /* 373 */ "selectnowith ::= oneselect", /* 374 */ "oneselect ::= values", /* 375 */ "sclp ::= selcollist COMMA", /* 376 */ "as ::= ID|STRING", - /* 377 */ "indexed_opt ::= indexed_by", - /* 378 */ "returning ::=", - /* 379 */ "expr ::= term", - /* 380 */ "likeop ::= LIKE_KW|MATCH", - /* 381 */ "exprlist ::= nexprlist", - /* 382 */ "nmnum ::= plus_num", - /* 383 */ "nmnum ::= nm", - /* 384 */ "nmnum ::= ON", - /* 385 */ "nmnum ::= DELETE", - /* 386 */ "nmnum ::= DEFAULT", - /* 387 */ "plus_num ::= INTEGER|FLOAT", - /* 388 */ "foreach_clause ::=", - /* 389 */ "foreach_clause ::= FOR EACH ROW", - /* 390 */ "trnm ::= nm", - /* 391 */ "tridxby ::=", - /* 392 */ "database_kw_opt ::= DATABASE", - /* 393 */ "database_kw_opt ::=", - /* 394 */ "kwcolumn_opt ::=", - /* 395 */ "kwcolumn_opt ::= COLUMNKW", - /* 396 */ "vtabarglist ::= vtabarg", - /* 397 */ "vtabarglist ::= vtabarglist COMMA vtabarg", - /* 398 */ "vtabarg ::= vtabarg vtabargtoken", - /* 399 */ "anylist ::=", - /* 400 */ "anylist ::= anylist LP anylist RP", - /* 401 */ "anylist ::= anylist ANY", - /* 402 */ "with ::=", + /* 377 */ "returning ::=", + /* 378 */ "expr ::= term", + /* 379 */ "likeop ::= LIKE_KW|MATCH", + /* 380 */ "exprlist ::= nexprlist", + /* 381 */ "nmnum ::= plus_num", + /* 382 */ "nmnum ::= nm", + /* 383 */ "nmnum ::= ON", + /* 384 */ "nmnum ::= DELETE", + /* 385 */ "nmnum ::= DEFAULT", + /* 386 */ "plus_num ::= INTEGER|FLOAT", + /* 387 */ "foreach_clause ::=", + /* 388 */ "foreach_clause ::= FOR EACH ROW", + /* 389 */ "trnm ::= nm", + /* 390 */ "tridxby ::=", + /* 391 */ "database_kw_opt ::= DATABASE", + /* 392 */ "database_kw_opt ::=", + /* 393 */ "kwcolumn_opt ::=", + /* 394 */ "kwcolumn_opt ::= COLUMNKW", + /* 395 */ "vtabarglist ::= vtabarg", + /* 396 */ "vtabarglist ::= vtabarglist COMMA vtabarg", + /* 397 */ "vtabarg ::= vtabarg vtabargtoken", + /* 398 */ "anylist ::=", + /* 399 */ "anylist ::= anylist LP anylist RP", + /* 400 */ "anylist ::= anylist ANY", + /* 401 */ "with ::=", }; #endif /* NDEBUG */ #if YYSTACKDEPTH<=0 @@ -169794,10 +163751,11 @@ break; case 216: /* term */ case 217: /* expr */ case 246: /* where_opt */ case 248: /* having_opt */ + case 260: /* on_opt */ case 267: /* where_opt_ret */ case 278: /* case_operand */ case 280: /* case_else */ case 283: /* vinto */ case 290: /* when_clause */ @@ -169813,11 +163771,11 @@ case 244: /* selcollist */ case 247: /* groupby_opt */ case 249: /* orderby_opt */ case 253: /* nexprlist */ case 254: /* sclp */ - case 261: /* exprlist */ + case 262: /* exprlist */ case 268: /* setlist */ case 277: /* paren_exprlist */ case 279: /* case_exprlist */ case 310: /* part_opt */ { @@ -169826,11 +163784,11 @@ break; case 238: /* fullname */ case 245: /* from */ case 256: /* seltablist */ case 257: /* stl_prefix */ - case 262: /* xfullname */ + case 263: /* xfullname */ { sqlite3SrcListDelete(pParse->db, (yypminor->yy131)); } break; case 241: /* wqlist */ @@ -169842,11 +163800,12 @@ case 306: /* windowdefn_list */ { sqlite3WindowListDelete(pParse->db, (yypminor->yy41)); } break; - case 263: /* idlist */ + case 261: /* using_opt */ + case 264: /* idlist */ case 270: /* idlist_opt */ { sqlite3IdListDelete(pParse->db, (yypminor->yy254)); } break; @@ -170272,33 +164231,33 @@ 255, /* (104) as ::= */ 245, /* (105) from ::= */ 245, /* (106) from ::= FROM seltablist */ 257, /* (107) stl_prefix ::= seltablist joinop */ 257, /* (108) stl_prefix ::= */ - 256, /* (109) seltablist ::= stl_prefix nm dbnm as on_using */ - 256, /* (110) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ - 256, /* (111) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ - 256, /* (112) seltablist ::= stl_prefix LP select RP as on_using */ - 256, /* (113) seltablist ::= stl_prefix LP seltablist RP as on_using */ - 200, /* (114) dbnm ::= */ - 200, /* (115) dbnm ::= DOT nm */ - 238, /* (116) fullname ::= nm */ - 238, /* (117) fullname ::= nm DOT nm */ - 262, /* (118) xfullname ::= nm */ - 262, /* (119) xfullname ::= nm DOT nm */ - 262, /* (120) xfullname ::= nm DOT nm AS nm */ - 262, /* (121) xfullname ::= nm AS nm */ - 258, /* (122) joinop ::= COMMA|JOIN */ - 258, /* (123) joinop ::= JOIN_KW JOIN */ - 258, /* (124) joinop ::= JOIN_KW nm JOIN */ - 258, /* (125) joinop ::= JOIN_KW nm nm JOIN */ - 259, /* (126) on_using ::= ON expr */ - 259, /* (127) on_using ::= USING LP idlist RP */ - 259, /* (128) on_using ::= */ - 264, /* (129) indexed_opt ::= */ - 260, /* (130) indexed_by ::= INDEXED BY nm */ - 260, /* (131) indexed_by ::= NOT INDEXED */ + 256, /* (109) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ + 256, /* (110) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ + 256, /* (111) seltablist ::= stl_prefix LP select RP as on_opt using_opt */ + 256, /* (112) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ + 200, /* (113) dbnm ::= */ + 200, /* (114) dbnm ::= DOT nm */ + 238, /* (115) fullname ::= nm */ + 238, /* (116) fullname ::= nm DOT nm */ + 263, /* (117) xfullname ::= nm */ + 263, /* (118) xfullname ::= nm DOT nm */ + 263, /* (119) xfullname ::= nm DOT nm AS nm */ + 263, /* (120) xfullname ::= nm AS nm */ + 258, /* (121) joinop ::= COMMA|JOIN */ + 258, /* (122) joinop ::= JOIN_KW JOIN */ + 258, /* (123) joinop ::= JOIN_KW nm JOIN */ + 258, /* (124) joinop ::= JOIN_KW nm nm JOIN */ + 260, /* (125) on_opt ::= ON expr */ + 260, /* (126) on_opt ::= */ + 259, /* (127) indexed_opt ::= */ + 259, /* (128) indexed_opt ::= INDEXED BY nm */ + 259, /* (129) indexed_opt ::= NOT INDEXED */ + 261, /* (130) using_opt ::= USING LP idlist RP */ + 261, /* (131) using_opt ::= */ 249, /* (132) orderby_opt ::= */ 249, /* (133) orderby_opt ::= ORDER BY sortlist */ 231, /* (134) sortlist ::= sortlist COMMA expr sortorder nulls */ 231, /* (135) sortlist ::= expr sortorder nulls */ 219, /* (136) sortorder ::= ASC */ @@ -170338,193 +164297,193 @@ 272, /* (170) returning ::= RETURNING selcollist */ 269, /* (171) insert_cmd ::= INSERT orconf */ 269, /* (172) insert_cmd ::= REPLACE */ 270, /* (173) idlist_opt ::= */ 270, /* (174) idlist_opt ::= LP idlist RP */ - 263, /* (175) idlist ::= idlist COMMA nm */ - 263, /* (176) idlist ::= nm */ + 264, /* (175) idlist ::= idlist COMMA nm */ + 264, /* (176) idlist ::= nm */ 217, /* (177) expr ::= LP expr RP */ - 217, /* (178) expr ::= ID|INDEXED|JOIN_KW */ - 217, /* (179) expr ::= nm DOT nm */ - 217, /* (180) expr ::= nm DOT nm DOT nm */ - 216, /* (181) term ::= NULL|FLOAT|BLOB */ - 216, /* (182) term ::= STRING */ - 216, /* (183) term ::= INTEGER */ - 217, /* (184) expr ::= VARIABLE */ - 217, /* (185) expr ::= expr COLLATE ID|STRING */ - 217, /* (186) expr ::= CAST LP expr AS typetoken RP */ - 217, /* (187) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ - 217, /* (188) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ - 217, /* (189) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ - 217, /* (190) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ - 216, /* (191) term ::= CTIME_KW */ - 217, /* (192) expr ::= LP nexprlist COMMA expr RP */ - 217, /* (193) expr ::= expr AND expr */ - 217, /* (194) expr ::= expr OR expr */ - 217, /* (195) expr ::= expr LT|GT|GE|LE expr */ - 217, /* (196) expr ::= expr EQ|NE expr */ - 217, /* (197) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ - 217, /* (198) expr ::= expr PLUS|MINUS expr */ - 217, /* (199) expr ::= expr STAR|SLASH|REM expr */ - 217, /* (200) expr ::= expr CONCAT expr */ - 274, /* (201) likeop ::= NOT LIKE_KW|MATCH */ - 217, /* (202) expr ::= expr likeop expr */ - 217, /* (203) expr ::= expr likeop expr ESCAPE expr */ - 217, /* (204) expr ::= expr ISNULL|NOTNULL */ - 217, /* (205) expr ::= expr NOT NULL */ - 217, /* (206) expr ::= expr IS expr */ - 217, /* (207) expr ::= expr IS NOT expr */ - 217, /* (208) expr ::= expr IS NOT DISTINCT FROM expr */ - 217, /* (209) expr ::= expr IS DISTINCT FROM expr */ - 217, /* (210) expr ::= NOT expr */ - 217, /* (211) expr ::= BITNOT expr */ - 217, /* (212) expr ::= PLUS|MINUS expr */ - 217, /* (213) expr ::= expr PTR expr */ - 275, /* (214) between_op ::= BETWEEN */ - 275, /* (215) between_op ::= NOT BETWEEN */ - 217, /* (216) expr ::= expr between_op expr AND expr */ - 276, /* (217) in_op ::= IN */ - 276, /* (218) in_op ::= NOT IN */ - 217, /* (219) expr ::= expr in_op LP exprlist RP */ - 217, /* (220) expr ::= LP select RP */ - 217, /* (221) expr ::= expr in_op LP select RP */ - 217, /* (222) expr ::= expr in_op nm dbnm paren_exprlist */ - 217, /* (223) expr ::= EXISTS LP select RP */ - 217, /* (224) expr ::= CASE case_operand case_exprlist case_else END */ - 279, /* (225) case_exprlist ::= case_exprlist WHEN expr THEN expr */ - 279, /* (226) case_exprlist ::= WHEN expr THEN expr */ - 280, /* (227) case_else ::= ELSE expr */ - 280, /* (228) case_else ::= */ - 278, /* (229) case_operand ::= expr */ - 278, /* (230) case_operand ::= */ - 261, /* (231) exprlist ::= */ - 253, /* (232) nexprlist ::= nexprlist COMMA expr */ - 253, /* (233) nexprlist ::= expr */ - 277, /* (234) paren_exprlist ::= */ - 277, /* (235) paren_exprlist ::= LP exprlist RP */ - 190, /* (236) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ - 281, /* (237) uniqueflag ::= UNIQUE */ - 281, /* (238) uniqueflag ::= */ - 221, /* (239) eidlist_opt ::= */ - 221, /* (240) eidlist_opt ::= LP eidlist RP */ - 232, /* (241) eidlist ::= eidlist COMMA nm collate sortorder */ - 232, /* (242) eidlist ::= nm collate sortorder */ - 282, /* (243) collate ::= */ - 282, /* (244) collate ::= COLLATE ID|STRING */ - 190, /* (245) cmd ::= DROP INDEX ifexists fullname */ - 190, /* (246) cmd ::= VACUUM vinto */ - 190, /* (247) cmd ::= VACUUM nm vinto */ - 283, /* (248) vinto ::= INTO expr */ - 283, /* (249) vinto ::= */ - 190, /* (250) cmd ::= PRAGMA nm dbnm */ - 190, /* (251) cmd ::= PRAGMA nm dbnm EQ nmnum */ - 190, /* (252) cmd ::= PRAGMA nm dbnm LP nmnum RP */ - 190, /* (253) cmd ::= PRAGMA nm dbnm EQ minus_num */ - 190, /* (254) cmd ::= PRAGMA nm dbnm LP minus_num RP */ - 211, /* (255) plus_num ::= PLUS INTEGER|FLOAT */ - 212, /* (256) minus_num ::= MINUS INTEGER|FLOAT */ - 190, /* (257) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ - 285, /* (258) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ - 287, /* (259) trigger_time ::= BEFORE|AFTER */ - 287, /* (260) trigger_time ::= INSTEAD OF */ - 287, /* (261) trigger_time ::= */ - 288, /* (262) trigger_event ::= DELETE|INSERT */ - 288, /* (263) trigger_event ::= UPDATE */ - 288, /* (264) trigger_event ::= UPDATE OF idlist */ - 290, /* (265) when_clause ::= */ - 290, /* (266) when_clause ::= WHEN expr */ - 286, /* (267) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ - 286, /* (268) trigger_cmd_list ::= trigger_cmd SEMI */ - 292, /* (269) trnm ::= nm DOT nm */ - 293, /* (270) tridxby ::= INDEXED BY nm */ - 293, /* (271) tridxby ::= NOT INDEXED */ - 291, /* (272) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ - 291, /* (273) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ - 291, /* (274) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ - 291, /* (275) trigger_cmd ::= scanpt select scanpt */ - 217, /* (276) expr ::= RAISE LP IGNORE RP */ - 217, /* (277) expr ::= RAISE LP raisetype COMMA nm RP */ - 236, /* (278) raisetype ::= ROLLBACK */ - 236, /* (279) raisetype ::= ABORT */ - 236, /* (280) raisetype ::= FAIL */ - 190, /* (281) cmd ::= DROP TRIGGER ifexists fullname */ - 190, /* (282) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ - 190, /* (283) cmd ::= DETACH database_kw_opt expr */ - 295, /* (284) key_opt ::= */ - 295, /* (285) key_opt ::= KEY expr */ - 190, /* (286) cmd ::= REINDEX */ - 190, /* (287) cmd ::= REINDEX nm dbnm */ - 190, /* (288) cmd ::= ANALYZE */ - 190, /* (289) cmd ::= ANALYZE nm dbnm */ - 190, /* (290) cmd ::= ALTER TABLE fullname RENAME TO nm */ - 190, /* (291) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ - 190, /* (292) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ - 296, /* (293) add_column_fullname ::= fullname */ - 190, /* (294) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ - 190, /* (295) cmd ::= create_vtab */ - 190, /* (296) cmd ::= create_vtab LP vtabarglist RP */ - 298, /* (297) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ - 300, /* (298) vtabarg ::= */ - 301, /* (299) vtabargtoken ::= ANY */ - 301, /* (300) vtabargtoken ::= lp anylist RP */ - 302, /* (301) lp ::= LP */ - 266, /* (302) with ::= WITH wqlist */ - 266, /* (303) with ::= WITH RECURSIVE wqlist */ - 305, /* (304) wqas ::= AS */ - 305, /* (305) wqas ::= AS MATERIALIZED */ - 305, /* (306) wqas ::= AS NOT MATERIALIZED */ - 304, /* (307) wqitem ::= nm eidlist_opt wqas LP select RP */ - 241, /* (308) wqlist ::= wqitem */ - 241, /* (309) wqlist ::= wqlist COMMA wqitem */ - 306, /* (310) windowdefn_list ::= windowdefn */ - 306, /* (311) windowdefn_list ::= windowdefn_list COMMA windowdefn */ - 307, /* (312) windowdefn ::= nm AS LP window RP */ - 308, /* (313) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ - 308, /* (314) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ - 308, /* (315) window ::= ORDER BY sortlist frame_opt */ - 308, /* (316) window ::= nm ORDER BY sortlist frame_opt */ - 308, /* (317) window ::= frame_opt */ - 308, /* (318) window ::= nm frame_opt */ - 309, /* (319) frame_opt ::= */ - 309, /* (320) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ - 309, /* (321) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ - 313, /* (322) range_or_rows ::= RANGE|ROWS|GROUPS */ - 315, /* (323) frame_bound_s ::= frame_bound */ - 315, /* (324) frame_bound_s ::= UNBOUNDED PRECEDING */ - 316, /* (325) frame_bound_e ::= frame_bound */ - 316, /* (326) frame_bound_e ::= UNBOUNDED FOLLOWING */ - 314, /* (327) frame_bound ::= expr PRECEDING|FOLLOWING */ - 314, /* (328) frame_bound ::= CURRENT ROW */ - 317, /* (329) frame_exclude_opt ::= */ - 317, /* (330) frame_exclude_opt ::= EXCLUDE frame_exclude */ - 318, /* (331) frame_exclude ::= NO OTHERS */ - 318, /* (332) frame_exclude ::= CURRENT ROW */ - 318, /* (333) frame_exclude ::= GROUP|TIES */ - 251, /* (334) window_clause ::= WINDOW windowdefn_list */ - 273, /* (335) filter_over ::= filter_clause over_clause */ - 273, /* (336) filter_over ::= over_clause */ - 273, /* (337) filter_over ::= filter_clause */ - 312, /* (338) over_clause ::= OVER LP window RP */ - 312, /* (339) over_clause ::= OVER nm */ - 311, /* (340) filter_clause ::= FILTER LP WHERE expr RP */ - 185, /* (341) input ::= cmdlist */ - 186, /* (342) cmdlist ::= cmdlist ecmd */ - 186, /* (343) cmdlist ::= ecmd */ - 187, /* (344) ecmd ::= SEMI */ - 187, /* (345) ecmd ::= cmdx SEMI */ - 187, /* (346) ecmd ::= explain cmdx SEMI */ - 192, /* (347) trans_opt ::= */ - 192, /* (348) trans_opt ::= TRANSACTION */ - 192, /* (349) trans_opt ::= TRANSACTION nm */ - 194, /* (350) savepoint_opt ::= SAVEPOINT */ - 194, /* (351) savepoint_opt ::= */ - 190, /* (352) cmd ::= create_table create_table_args */ - 203, /* (353) table_option_set ::= table_option */ - 201, /* (354) columnlist ::= columnlist COMMA columnname carglist */ - 201, /* (355) columnlist ::= columnname carglist */ - 193, /* (356) nm ::= ID|INDEXED|JOIN_KW */ - 193, /* (357) nm ::= STRING */ + 217, /* (178) expr ::= ID|INDEXED */ + 217, /* (179) expr ::= JOIN_KW */ + 217, /* (180) expr ::= nm DOT nm */ + 217, /* (181) expr ::= nm DOT nm DOT nm */ + 216, /* (182) term ::= NULL|FLOAT|BLOB */ + 216, /* (183) term ::= STRING */ + 216, /* (184) term ::= INTEGER */ + 217, /* (185) expr ::= VARIABLE */ + 217, /* (186) expr ::= expr COLLATE ID|STRING */ + 217, /* (187) expr ::= CAST LP expr AS typetoken RP */ + 217, /* (188) expr ::= ID|INDEXED LP distinct exprlist RP */ + 217, /* (189) expr ::= ID|INDEXED LP STAR RP */ + 217, /* (190) expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ + 217, /* (191) expr ::= ID|INDEXED LP STAR RP filter_over */ + 216, /* (192) term ::= CTIME_KW */ + 217, /* (193) expr ::= LP nexprlist COMMA expr RP */ + 217, /* (194) expr ::= expr AND expr */ + 217, /* (195) expr ::= expr OR expr */ + 217, /* (196) expr ::= expr LT|GT|GE|LE expr */ + 217, /* (197) expr ::= expr EQ|NE expr */ + 217, /* (198) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ + 217, /* (199) expr ::= expr PLUS|MINUS expr */ + 217, /* (200) expr ::= expr STAR|SLASH|REM expr */ + 217, /* (201) expr ::= expr CONCAT expr */ + 274, /* (202) likeop ::= NOT LIKE_KW|MATCH */ + 217, /* (203) expr ::= expr likeop expr */ + 217, /* (204) expr ::= expr likeop expr ESCAPE expr */ + 217, /* (205) expr ::= expr ISNULL|NOTNULL */ + 217, /* (206) expr ::= expr NOT NULL */ + 217, /* (207) expr ::= expr IS expr */ + 217, /* (208) expr ::= expr IS NOT expr */ + 217, /* (209) expr ::= NOT expr */ + 217, /* (210) expr ::= BITNOT expr */ + 217, /* (211) expr ::= PLUS|MINUS expr */ + 217, /* (212) expr ::= expr PTR expr */ + 275, /* (213) between_op ::= BETWEEN */ + 275, /* (214) between_op ::= NOT BETWEEN */ + 217, /* (215) expr ::= expr between_op expr AND expr */ + 276, /* (216) in_op ::= IN */ + 276, /* (217) in_op ::= NOT IN */ + 217, /* (218) expr ::= expr in_op LP exprlist RP */ + 217, /* (219) expr ::= LP select RP */ + 217, /* (220) expr ::= expr in_op LP select RP */ + 217, /* (221) expr ::= expr in_op nm dbnm paren_exprlist */ + 217, /* (222) expr ::= EXISTS LP select RP */ + 217, /* (223) expr ::= CASE case_operand case_exprlist case_else END */ + 279, /* (224) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + 279, /* (225) case_exprlist ::= WHEN expr THEN expr */ + 280, /* (226) case_else ::= ELSE expr */ + 280, /* (227) case_else ::= */ + 278, /* (228) case_operand ::= expr */ + 278, /* (229) case_operand ::= */ + 262, /* (230) exprlist ::= */ + 253, /* (231) nexprlist ::= nexprlist COMMA expr */ + 253, /* (232) nexprlist ::= expr */ + 277, /* (233) paren_exprlist ::= */ + 277, /* (234) paren_exprlist ::= LP exprlist RP */ + 190, /* (235) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + 281, /* (236) uniqueflag ::= UNIQUE */ + 281, /* (237) uniqueflag ::= */ + 221, /* (238) eidlist_opt ::= */ + 221, /* (239) eidlist_opt ::= LP eidlist RP */ + 232, /* (240) eidlist ::= eidlist COMMA nm collate sortorder */ + 232, /* (241) eidlist ::= nm collate sortorder */ + 282, /* (242) collate ::= */ + 282, /* (243) collate ::= COLLATE ID|STRING */ + 190, /* (244) cmd ::= DROP INDEX ifexists fullname */ + 190, /* (245) cmd ::= VACUUM vinto */ + 190, /* (246) cmd ::= VACUUM nm vinto */ + 283, /* (247) vinto ::= INTO expr */ + 283, /* (248) vinto ::= */ + 190, /* (249) cmd ::= PRAGMA nm dbnm */ + 190, /* (250) cmd ::= PRAGMA nm dbnm EQ nmnum */ + 190, /* (251) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + 190, /* (252) cmd ::= PRAGMA nm dbnm EQ minus_num */ + 190, /* (253) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + 211, /* (254) plus_num ::= PLUS INTEGER|FLOAT */ + 212, /* (255) minus_num ::= MINUS INTEGER|FLOAT */ + 190, /* (256) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + 285, /* (257) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + 287, /* (258) trigger_time ::= BEFORE|AFTER */ + 287, /* (259) trigger_time ::= INSTEAD OF */ + 287, /* (260) trigger_time ::= */ + 288, /* (261) trigger_event ::= DELETE|INSERT */ + 288, /* (262) trigger_event ::= UPDATE */ + 288, /* (263) trigger_event ::= UPDATE OF idlist */ + 290, /* (264) when_clause ::= */ + 290, /* (265) when_clause ::= WHEN expr */ + 286, /* (266) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + 286, /* (267) trigger_cmd_list ::= trigger_cmd SEMI */ + 292, /* (268) trnm ::= nm DOT nm */ + 293, /* (269) tridxby ::= INDEXED BY nm */ + 293, /* (270) tridxby ::= NOT INDEXED */ + 291, /* (271) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ + 291, /* (272) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + 291, /* (273) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + 291, /* (274) trigger_cmd ::= scanpt select scanpt */ + 217, /* (275) expr ::= RAISE LP IGNORE RP */ + 217, /* (276) expr ::= RAISE LP raisetype COMMA nm RP */ + 236, /* (277) raisetype ::= ROLLBACK */ + 236, /* (278) raisetype ::= ABORT */ + 236, /* (279) raisetype ::= FAIL */ + 190, /* (280) cmd ::= DROP TRIGGER ifexists fullname */ + 190, /* (281) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + 190, /* (282) cmd ::= DETACH database_kw_opt expr */ + 295, /* (283) key_opt ::= */ + 295, /* (284) key_opt ::= KEY expr */ + 190, /* (285) cmd ::= REINDEX */ + 190, /* (286) cmd ::= REINDEX nm dbnm */ + 190, /* (287) cmd ::= ANALYZE */ + 190, /* (288) cmd ::= ANALYZE nm dbnm */ + 190, /* (289) cmd ::= ALTER TABLE fullname RENAME TO nm */ + 190, /* (290) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + 190, /* (291) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + 296, /* (292) add_column_fullname ::= fullname */ + 190, /* (293) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + 190, /* (294) cmd ::= create_vtab */ + 190, /* (295) cmd ::= create_vtab LP vtabarglist RP */ + 298, /* (296) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 300, /* (297) vtabarg ::= */ + 301, /* (298) vtabargtoken ::= ANY */ + 301, /* (299) vtabargtoken ::= lp anylist RP */ + 302, /* (300) lp ::= LP */ + 266, /* (301) with ::= WITH wqlist */ + 266, /* (302) with ::= WITH RECURSIVE wqlist */ + 305, /* (303) wqas ::= AS */ + 305, /* (304) wqas ::= AS MATERIALIZED */ + 305, /* (305) wqas ::= AS NOT MATERIALIZED */ + 304, /* (306) wqitem ::= nm eidlist_opt wqas LP select RP */ + 241, /* (307) wqlist ::= wqitem */ + 241, /* (308) wqlist ::= wqlist COMMA wqitem */ + 306, /* (309) windowdefn_list ::= windowdefn */ + 306, /* (310) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + 307, /* (311) windowdefn ::= nm AS LP window RP */ + 308, /* (312) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + 308, /* (313) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + 308, /* (314) window ::= ORDER BY sortlist frame_opt */ + 308, /* (315) window ::= nm ORDER BY sortlist frame_opt */ + 308, /* (316) window ::= frame_opt */ + 308, /* (317) window ::= nm frame_opt */ + 309, /* (318) frame_opt ::= */ + 309, /* (319) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + 309, /* (320) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + 313, /* (321) range_or_rows ::= RANGE|ROWS|GROUPS */ + 315, /* (322) frame_bound_s ::= frame_bound */ + 315, /* (323) frame_bound_s ::= UNBOUNDED PRECEDING */ + 316, /* (324) frame_bound_e ::= frame_bound */ + 316, /* (325) frame_bound_e ::= UNBOUNDED FOLLOWING */ + 314, /* (326) frame_bound ::= expr PRECEDING|FOLLOWING */ + 314, /* (327) frame_bound ::= CURRENT ROW */ + 317, /* (328) frame_exclude_opt ::= */ + 317, /* (329) frame_exclude_opt ::= EXCLUDE frame_exclude */ + 318, /* (330) frame_exclude ::= NO OTHERS */ + 318, /* (331) frame_exclude ::= CURRENT ROW */ + 318, /* (332) frame_exclude ::= GROUP|TIES */ + 251, /* (333) window_clause ::= WINDOW windowdefn_list */ + 273, /* (334) filter_over ::= filter_clause over_clause */ + 273, /* (335) filter_over ::= over_clause */ + 273, /* (336) filter_over ::= filter_clause */ + 312, /* (337) over_clause ::= OVER LP window RP */ + 312, /* (338) over_clause ::= OVER nm */ + 311, /* (339) filter_clause ::= FILTER LP WHERE expr RP */ + 185, /* (340) input ::= cmdlist */ + 186, /* (341) cmdlist ::= cmdlist ecmd */ + 186, /* (342) cmdlist ::= ecmd */ + 187, /* (343) ecmd ::= SEMI */ + 187, /* (344) ecmd ::= cmdx SEMI */ + 187, /* (345) ecmd ::= explain cmdx SEMI */ + 192, /* (346) trans_opt ::= */ + 192, /* (347) trans_opt ::= TRANSACTION */ + 192, /* (348) trans_opt ::= TRANSACTION nm */ + 194, /* (349) savepoint_opt ::= SAVEPOINT */ + 194, /* (350) savepoint_opt ::= */ + 190, /* (351) cmd ::= create_table create_table_args */ + 203, /* (352) table_option_set ::= table_option */ + 201, /* (353) columnlist ::= columnlist COMMA columnname carglist */ + 201, /* (354) columnlist ::= columnname carglist */ + 193, /* (355) nm ::= ID|INDEXED */ + 193, /* (356) nm ::= STRING */ + 193, /* (357) nm ::= JOIN_KW */ 208, /* (358) typetoken ::= typename */ 209, /* (359) typename ::= ID|STRING */ 210, /* (360) signed ::= plus_num */ 210, /* (361) signed ::= minus_num */ 207, /* (362) carglist ::= carglist ccons */ @@ -170540,36 +164499,35 @@ 235, /* (372) resolvetype ::= raisetype */ 239, /* (373) selectnowith ::= oneselect */ 240, /* (374) oneselect ::= values */ 254, /* (375) sclp ::= selcollist COMMA */ 255, /* (376) as ::= ID|STRING */ - 264, /* (377) indexed_opt ::= indexed_by */ - 272, /* (378) returning ::= */ - 217, /* (379) expr ::= term */ - 274, /* (380) likeop ::= LIKE_KW|MATCH */ - 261, /* (381) exprlist ::= nexprlist */ - 284, /* (382) nmnum ::= plus_num */ - 284, /* (383) nmnum ::= nm */ - 284, /* (384) nmnum ::= ON */ - 284, /* (385) nmnum ::= DELETE */ - 284, /* (386) nmnum ::= DEFAULT */ - 211, /* (387) plus_num ::= INTEGER|FLOAT */ - 289, /* (388) foreach_clause ::= */ - 289, /* (389) foreach_clause ::= FOR EACH ROW */ - 292, /* (390) trnm ::= nm */ - 293, /* (391) tridxby ::= */ - 294, /* (392) database_kw_opt ::= DATABASE */ - 294, /* (393) database_kw_opt ::= */ - 297, /* (394) kwcolumn_opt ::= */ - 297, /* (395) kwcolumn_opt ::= COLUMNKW */ - 299, /* (396) vtabarglist ::= vtabarg */ - 299, /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */ - 300, /* (398) vtabarg ::= vtabarg vtabargtoken */ - 303, /* (399) anylist ::= */ - 303, /* (400) anylist ::= anylist LP anylist RP */ - 303, /* (401) anylist ::= anylist ANY */ - 266, /* (402) with ::= */ + 272, /* (377) returning ::= */ + 217, /* (378) expr ::= term */ + 274, /* (379) likeop ::= LIKE_KW|MATCH */ + 262, /* (380) exprlist ::= nexprlist */ + 284, /* (381) nmnum ::= plus_num */ + 284, /* (382) nmnum ::= nm */ + 284, /* (383) nmnum ::= ON */ + 284, /* (384) nmnum ::= DELETE */ + 284, /* (385) nmnum ::= DEFAULT */ + 211, /* (386) plus_num ::= INTEGER|FLOAT */ + 289, /* (387) foreach_clause ::= */ + 289, /* (388) foreach_clause ::= FOR EACH ROW */ + 292, /* (389) trnm ::= nm */ + 293, /* (390) tridxby ::= */ + 294, /* (391) database_kw_opt ::= DATABASE */ + 294, /* (392) database_kw_opt ::= */ + 297, /* (393) kwcolumn_opt ::= */ + 297, /* (394) kwcolumn_opt ::= COLUMNKW */ + 299, /* (395) vtabarglist ::= vtabarg */ + 299, /* (396) vtabarglist ::= vtabarglist COMMA vtabarg */ + 300, /* (397) vtabarg ::= vtabarg vtabargtoken */ + 303, /* (398) anylist ::= */ + 303, /* (399) anylist ::= anylist LP anylist RP */ + 303, /* (400) anylist ::= anylist ANY */ + 266, /* (401) with ::= */ }; /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number ** of symbols on the right-hand side of that rule. */ static const signed char yyRuleInfoNRhs[] = { @@ -170680,33 +164638,33 @@ 0, /* (104) as ::= */ 0, /* (105) from ::= */ -2, /* (106) from ::= FROM seltablist */ -2, /* (107) stl_prefix ::= seltablist joinop */ 0, /* (108) stl_prefix ::= */ - -5, /* (109) seltablist ::= stl_prefix nm dbnm as on_using */ - -6, /* (110) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ - -8, /* (111) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ - -6, /* (112) seltablist ::= stl_prefix LP select RP as on_using */ - -6, /* (113) seltablist ::= stl_prefix LP seltablist RP as on_using */ - 0, /* (114) dbnm ::= */ - -2, /* (115) dbnm ::= DOT nm */ - -1, /* (116) fullname ::= nm */ - -3, /* (117) fullname ::= nm DOT nm */ - -1, /* (118) xfullname ::= nm */ - -3, /* (119) xfullname ::= nm DOT nm */ - -5, /* (120) xfullname ::= nm DOT nm AS nm */ - -3, /* (121) xfullname ::= nm AS nm */ - -1, /* (122) joinop ::= COMMA|JOIN */ - -2, /* (123) joinop ::= JOIN_KW JOIN */ - -3, /* (124) joinop ::= JOIN_KW nm JOIN */ - -4, /* (125) joinop ::= JOIN_KW nm nm JOIN */ - -2, /* (126) on_using ::= ON expr */ - -4, /* (127) on_using ::= USING LP idlist RP */ - 0, /* (128) on_using ::= */ - 0, /* (129) indexed_opt ::= */ - -3, /* (130) indexed_by ::= INDEXED BY nm */ - -2, /* (131) indexed_by ::= NOT INDEXED */ + -7, /* (109) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ + -9, /* (110) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ + -7, /* (111) seltablist ::= stl_prefix LP select RP as on_opt using_opt */ + -7, /* (112) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ + 0, /* (113) dbnm ::= */ + -2, /* (114) dbnm ::= DOT nm */ + -1, /* (115) fullname ::= nm */ + -3, /* (116) fullname ::= nm DOT nm */ + -1, /* (117) xfullname ::= nm */ + -3, /* (118) xfullname ::= nm DOT nm */ + -5, /* (119) xfullname ::= nm DOT nm AS nm */ + -3, /* (120) xfullname ::= nm AS nm */ + -1, /* (121) joinop ::= COMMA|JOIN */ + -2, /* (122) joinop ::= JOIN_KW JOIN */ + -3, /* (123) joinop ::= JOIN_KW nm JOIN */ + -4, /* (124) joinop ::= JOIN_KW nm nm JOIN */ + -2, /* (125) on_opt ::= ON expr */ + 0, /* (126) on_opt ::= */ + 0, /* (127) indexed_opt ::= */ + -3, /* (128) indexed_opt ::= INDEXED BY nm */ + -2, /* (129) indexed_opt ::= NOT INDEXED */ + -4, /* (130) using_opt ::= USING LP idlist RP */ + 0, /* (131) using_opt ::= */ 0, /* (132) orderby_opt ::= */ -3, /* (133) orderby_opt ::= ORDER BY sortlist */ -5, /* (134) sortlist ::= sortlist COMMA expr sortorder nulls */ -3, /* (135) sortlist ::= expr sortorder nulls */ -1, /* (136) sortorder ::= ASC */ @@ -170749,190 +164707,190 @@ 0, /* (173) idlist_opt ::= */ -3, /* (174) idlist_opt ::= LP idlist RP */ -3, /* (175) idlist ::= idlist COMMA nm */ -1, /* (176) idlist ::= nm */ -3, /* (177) expr ::= LP expr RP */ - -1, /* (178) expr ::= ID|INDEXED|JOIN_KW */ - -3, /* (179) expr ::= nm DOT nm */ - -5, /* (180) expr ::= nm DOT nm DOT nm */ - -1, /* (181) term ::= NULL|FLOAT|BLOB */ - -1, /* (182) term ::= STRING */ - -1, /* (183) term ::= INTEGER */ - -1, /* (184) expr ::= VARIABLE */ - -3, /* (185) expr ::= expr COLLATE ID|STRING */ - -6, /* (186) expr ::= CAST LP expr AS typetoken RP */ - -5, /* (187) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ - -4, /* (188) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ - -6, /* (189) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ - -5, /* (190) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ - -1, /* (191) term ::= CTIME_KW */ - -5, /* (192) expr ::= LP nexprlist COMMA expr RP */ - -3, /* (193) expr ::= expr AND expr */ - -3, /* (194) expr ::= expr OR expr */ - -3, /* (195) expr ::= expr LT|GT|GE|LE expr */ - -3, /* (196) expr ::= expr EQ|NE expr */ - -3, /* (197) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ - -3, /* (198) expr ::= expr PLUS|MINUS expr */ - -3, /* (199) expr ::= expr STAR|SLASH|REM expr */ - -3, /* (200) expr ::= expr CONCAT expr */ - -2, /* (201) likeop ::= NOT LIKE_KW|MATCH */ - -3, /* (202) expr ::= expr likeop expr */ - -5, /* (203) expr ::= expr likeop expr ESCAPE expr */ - -2, /* (204) expr ::= expr ISNULL|NOTNULL */ - -3, /* (205) expr ::= expr NOT NULL */ - -3, /* (206) expr ::= expr IS expr */ - -4, /* (207) expr ::= expr IS NOT expr */ - -6, /* (208) expr ::= expr IS NOT DISTINCT FROM expr */ - -5, /* (209) expr ::= expr IS DISTINCT FROM expr */ - -2, /* (210) expr ::= NOT expr */ - -2, /* (211) expr ::= BITNOT expr */ - -2, /* (212) expr ::= PLUS|MINUS expr */ - -3, /* (213) expr ::= expr PTR expr */ - -1, /* (214) between_op ::= BETWEEN */ - -2, /* (215) between_op ::= NOT BETWEEN */ - -5, /* (216) expr ::= expr between_op expr AND expr */ - -1, /* (217) in_op ::= IN */ - -2, /* (218) in_op ::= NOT IN */ - -5, /* (219) expr ::= expr in_op LP exprlist RP */ - -3, /* (220) expr ::= LP select RP */ - -5, /* (221) expr ::= expr in_op LP select RP */ - -5, /* (222) expr ::= expr in_op nm dbnm paren_exprlist */ - -4, /* (223) expr ::= EXISTS LP select RP */ - -5, /* (224) expr ::= CASE case_operand case_exprlist case_else END */ - -5, /* (225) case_exprlist ::= case_exprlist WHEN expr THEN expr */ - -4, /* (226) case_exprlist ::= WHEN expr THEN expr */ - -2, /* (227) case_else ::= ELSE expr */ - 0, /* (228) case_else ::= */ - -1, /* (229) case_operand ::= expr */ - 0, /* (230) case_operand ::= */ - 0, /* (231) exprlist ::= */ - -3, /* (232) nexprlist ::= nexprlist COMMA expr */ - -1, /* (233) nexprlist ::= expr */ - 0, /* (234) paren_exprlist ::= */ - -3, /* (235) paren_exprlist ::= LP exprlist RP */ - -12, /* (236) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ - -1, /* (237) uniqueflag ::= UNIQUE */ - 0, /* (238) uniqueflag ::= */ - 0, /* (239) eidlist_opt ::= */ - -3, /* (240) eidlist_opt ::= LP eidlist RP */ - -5, /* (241) eidlist ::= eidlist COMMA nm collate sortorder */ - -3, /* (242) eidlist ::= nm collate sortorder */ - 0, /* (243) collate ::= */ - -2, /* (244) collate ::= COLLATE ID|STRING */ - -4, /* (245) cmd ::= DROP INDEX ifexists fullname */ - -2, /* (246) cmd ::= VACUUM vinto */ - -3, /* (247) cmd ::= VACUUM nm vinto */ - -2, /* (248) vinto ::= INTO expr */ - 0, /* (249) vinto ::= */ - -3, /* (250) cmd ::= PRAGMA nm dbnm */ - -5, /* (251) cmd ::= PRAGMA nm dbnm EQ nmnum */ - -6, /* (252) cmd ::= PRAGMA nm dbnm LP nmnum RP */ - -5, /* (253) cmd ::= PRAGMA nm dbnm EQ minus_num */ - -6, /* (254) cmd ::= PRAGMA nm dbnm LP minus_num RP */ - -2, /* (255) plus_num ::= PLUS INTEGER|FLOAT */ - -2, /* (256) minus_num ::= MINUS INTEGER|FLOAT */ - -5, /* (257) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ - -11, /* (258) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ - -1, /* (259) trigger_time ::= BEFORE|AFTER */ - -2, /* (260) trigger_time ::= INSTEAD OF */ - 0, /* (261) trigger_time ::= */ - -1, /* (262) trigger_event ::= DELETE|INSERT */ - -1, /* (263) trigger_event ::= UPDATE */ - -3, /* (264) trigger_event ::= UPDATE OF idlist */ - 0, /* (265) when_clause ::= */ - -2, /* (266) when_clause ::= WHEN expr */ - -3, /* (267) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ - -2, /* (268) trigger_cmd_list ::= trigger_cmd SEMI */ - -3, /* (269) trnm ::= nm DOT nm */ - -3, /* (270) tridxby ::= INDEXED BY nm */ - -2, /* (271) tridxby ::= NOT INDEXED */ - -9, /* (272) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ - -8, /* (273) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ - -6, /* (274) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ - -3, /* (275) trigger_cmd ::= scanpt select scanpt */ - -4, /* (276) expr ::= RAISE LP IGNORE RP */ - -6, /* (277) expr ::= RAISE LP raisetype COMMA nm RP */ - -1, /* (278) raisetype ::= ROLLBACK */ - -1, /* (279) raisetype ::= ABORT */ - -1, /* (280) raisetype ::= FAIL */ - -4, /* (281) cmd ::= DROP TRIGGER ifexists fullname */ - -6, /* (282) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ - -3, /* (283) cmd ::= DETACH database_kw_opt expr */ - 0, /* (284) key_opt ::= */ - -2, /* (285) key_opt ::= KEY expr */ - -1, /* (286) cmd ::= REINDEX */ - -3, /* (287) cmd ::= REINDEX nm dbnm */ - -1, /* (288) cmd ::= ANALYZE */ - -3, /* (289) cmd ::= ANALYZE nm dbnm */ - -6, /* (290) cmd ::= ALTER TABLE fullname RENAME TO nm */ - -7, /* (291) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ - -6, /* (292) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ - -1, /* (293) add_column_fullname ::= fullname */ - -8, /* (294) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ - -1, /* (295) cmd ::= create_vtab */ - -4, /* (296) cmd ::= create_vtab LP vtabarglist RP */ - -8, /* (297) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ - 0, /* (298) vtabarg ::= */ - -1, /* (299) vtabargtoken ::= ANY */ - -3, /* (300) vtabargtoken ::= lp anylist RP */ - -1, /* (301) lp ::= LP */ - -2, /* (302) with ::= WITH wqlist */ - -3, /* (303) with ::= WITH RECURSIVE wqlist */ - -1, /* (304) wqas ::= AS */ - -2, /* (305) wqas ::= AS MATERIALIZED */ - -3, /* (306) wqas ::= AS NOT MATERIALIZED */ - -6, /* (307) wqitem ::= nm eidlist_opt wqas LP select RP */ - -1, /* (308) wqlist ::= wqitem */ - -3, /* (309) wqlist ::= wqlist COMMA wqitem */ - -1, /* (310) windowdefn_list ::= windowdefn */ - -3, /* (311) windowdefn_list ::= windowdefn_list COMMA windowdefn */ - -5, /* (312) windowdefn ::= nm AS LP window RP */ - -5, /* (313) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ - -6, /* (314) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ - -4, /* (315) window ::= ORDER BY sortlist frame_opt */ - -5, /* (316) window ::= nm ORDER BY sortlist frame_opt */ - -1, /* (317) window ::= frame_opt */ - -2, /* (318) window ::= nm frame_opt */ - 0, /* (319) frame_opt ::= */ - -3, /* (320) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ - -6, /* (321) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ - -1, /* (322) range_or_rows ::= RANGE|ROWS|GROUPS */ - -1, /* (323) frame_bound_s ::= frame_bound */ - -2, /* (324) frame_bound_s ::= UNBOUNDED PRECEDING */ - -1, /* (325) frame_bound_e ::= frame_bound */ - -2, /* (326) frame_bound_e ::= UNBOUNDED FOLLOWING */ - -2, /* (327) frame_bound ::= expr PRECEDING|FOLLOWING */ - -2, /* (328) frame_bound ::= CURRENT ROW */ - 0, /* (329) frame_exclude_opt ::= */ - -2, /* (330) frame_exclude_opt ::= EXCLUDE frame_exclude */ - -2, /* (331) frame_exclude ::= NO OTHERS */ - -2, /* (332) frame_exclude ::= CURRENT ROW */ - -1, /* (333) frame_exclude ::= GROUP|TIES */ - -2, /* (334) window_clause ::= WINDOW windowdefn_list */ - -2, /* (335) filter_over ::= filter_clause over_clause */ - -1, /* (336) filter_over ::= over_clause */ - -1, /* (337) filter_over ::= filter_clause */ - -4, /* (338) over_clause ::= OVER LP window RP */ - -2, /* (339) over_clause ::= OVER nm */ - -5, /* (340) filter_clause ::= FILTER LP WHERE expr RP */ - -1, /* (341) input ::= cmdlist */ - -2, /* (342) cmdlist ::= cmdlist ecmd */ - -1, /* (343) cmdlist ::= ecmd */ - -1, /* (344) ecmd ::= SEMI */ - -2, /* (345) ecmd ::= cmdx SEMI */ - -3, /* (346) ecmd ::= explain cmdx SEMI */ - 0, /* (347) trans_opt ::= */ - -1, /* (348) trans_opt ::= TRANSACTION */ - -2, /* (349) trans_opt ::= TRANSACTION nm */ - -1, /* (350) savepoint_opt ::= SAVEPOINT */ - 0, /* (351) savepoint_opt ::= */ - -2, /* (352) cmd ::= create_table create_table_args */ - -1, /* (353) table_option_set ::= table_option */ - -4, /* (354) columnlist ::= columnlist COMMA columnname carglist */ - -2, /* (355) columnlist ::= columnname carglist */ - -1, /* (356) nm ::= ID|INDEXED|JOIN_KW */ - -1, /* (357) nm ::= STRING */ + -1, /* (178) expr ::= ID|INDEXED */ + -1, /* (179) expr ::= JOIN_KW */ + -3, /* (180) expr ::= nm DOT nm */ + -5, /* (181) expr ::= nm DOT nm DOT nm */ + -1, /* (182) term ::= NULL|FLOAT|BLOB */ + -1, /* (183) term ::= STRING */ + -1, /* (184) term ::= INTEGER */ + -1, /* (185) expr ::= VARIABLE */ + -3, /* (186) expr ::= expr COLLATE ID|STRING */ + -6, /* (187) expr ::= CAST LP expr AS typetoken RP */ + -5, /* (188) expr ::= ID|INDEXED LP distinct exprlist RP */ + -4, /* (189) expr ::= ID|INDEXED LP STAR RP */ + -6, /* (190) expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ + -5, /* (191) expr ::= ID|INDEXED LP STAR RP filter_over */ + -1, /* (192) term ::= CTIME_KW */ + -5, /* (193) expr ::= LP nexprlist COMMA expr RP */ + -3, /* (194) expr ::= expr AND expr */ + -3, /* (195) expr ::= expr OR expr */ + -3, /* (196) expr ::= expr LT|GT|GE|LE expr */ + -3, /* (197) expr ::= expr EQ|NE expr */ + -3, /* (198) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ + -3, /* (199) expr ::= expr PLUS|MINUS expr */ + -3, /* (200) expr ::= expr STAR|SLASH|REM expr */ + -3, /* (201) expr ::= expr CONCAT expr */ + -2, /* (202) likeop ::= NOT LIKE_KW|MATCH */ + -3, /* (203) expr ::= expr likeop expr */ + -5, /* (204) expr ::= expr likeop expr ESCAPE expr */ + -2, /* (205) expr ::= expr ISNULL|NOTNULL */ + -3, /* (206) expr ::= expr NOT NULL */ + -3, /* (207) expr ::= expr IS expr */ + -4, /* (208) expr ::= expr IS NOT expr */ + -2, /* (209) expr ::= NOT expr */ + -2, /* (210) expr ::= BITNOT expr */ + -2, /* (211) expr ::= PLUS|MINUS expr */ + -3, /* (212) expr ::= expr PTR expr */ + -1, /* (213) between_op ::= BETWEEN */ + -2, /* (214) between_op ::= NOT BETWEEN */ + -5, /* (215) expr ::= expr between_op expr AND expr */ + -1, /* (216) in_op ::= IN */ + -2, /* (217) in_op ::= NOT IN */ + -5, /* (218) expr ::= expr in_op LP exprlist RP */ + -3, /* (219) expr ::= LP select RP */ + -5, /* (220) expr ::= expr in_op LP select RP */ + -5, /* (221) expr ::= expr in_op nm dbnm paren_exprlist */ + -4, /* (222) expr ::= EXISTS LP select RP */ + -5, /* (223) expr ::= CASE case_operand case_exprlist case_else END */ + -5, /* (224) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + -4, /* (225) case_exprlist ::= WHEN expr THEN expr */ + -2, /* (226) case_else ::= ELSE expr */ + 0, /* (227) case_else ::= */ + -1, /* (228) case_operand ::= expr */ + 0, /* (229) case_operand ::= */ + 0, /* (230) exprlist ::= */ + -3, /* (231) nexprlist ::= nexprlist COMMA expr */ + -1, /* (232) nexprlist ::= expr */ + 0, /* (233) paren_exprlist ::= */ + -3, /* (234) paren_exprlist ::= LP exprlist RP */ + -12, /* (235) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + -1, /* (236) uniqueflag ::= UNIQUE */ + 0, /* (237) uniqueflag ::= */ + 0, /* (238) eidlist_opt ::= */ + -3, /* (239) eidlist_opt ::= LP eidlist RP */ + -5, /* (240) eidlist ::= eidlist COMMA nm collate sortorder */ + -3, /* (241) eidlist ::= nm collate sortorder */ + 0, /* (242) collate ::= */ + -2, /* (243) collate ::= COLLATE ID|STRING */ + -4, /* (244) cmd ::= DROP INDEX ifexists fullname */ + -2, /* (245) cmd ::= VACUUM vinto */ + -3, /* (246) cmd ::= VACUUM nm vinto */ + -2, /* (247) vinto ::= INTO expr */ + 0, /* (248) vinto ::= */ + -3, /* (249) cmd ::= PRAGMA nm dbnm */ + -5, /* (250) cmd ::= PRAGMA nm dbnm EQ nmnum */ + -6, /* (251) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + -5, /* (252) cmd ::= PRAGMA nm dbnm EQ minus_num */ + -6, /* (253) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + -2, /* (254) plus_num ::= PLUS INTEGER|FLOAT */ + -2, /* (255) minus_num ::= MINUS INTEGER|FLOAT */ + -5, /* (256) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + -11, /* (257) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + -1, /* (258) trigger_time ::= BEFORE|AFTER */ + -2, /* (259) trigger_time ::= INSTEAD OF */ + 0, /* (260) trigger_time ::= */ + -1, /* (261) trigger_event ::= DELETE|INSERT */ + -1, /* (262) trigger_event ::= UPDATE */ + -3, /* (263) trigger_event ::= UPDATE OF idlist */ + 0, /* (264) when_clause ::= */ + -2, /* (265) when_clause ::= WHEN expr */ + -3, /* (266) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + -2, /* (267) trigger_cmd_list ::= trigger_cmd SEMI */ + -3, /* (268) trnm ::= nm DOT nm */ + -3, /* (269) tridxby ::= INDEXED BY nm */ + -2, /* (270) tridxby ::= NOT INDEXED */ + -9, /* (271) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ + -8, /* (272) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + -6, /* (273) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + -3, /* (274) trigger_cmd ::= scanpt select scanpt */ + -4, /* (275) expr ::= RAISE LP IGNORE RP */ + -6, /* (276) expr ::= RAISE LP raisetype COMMA nm RP */ + -1, /* (277) raisetype ::= ROLLBACK */ + -1, /* (278) raisetype ::= ABORT */ + -1, /* (279) raisetype ::= FAIL */ + -4, /* (280) cmd ::= DROP TRIGGER ifexists fullname */ + -6, /* (281) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + -3, /* (282) cmd ::= DETACH database_kw_opt expr */ + 0, /* (283) key_opt ::= */ + -2, /* (284) key_opt ::= KEY expr */ + -1, /* (285) cmd ::= REINDEX */ + -3, /* (286) cmd ::= REINDEX nm dbnm */ + -1, /* (287) cmd ::= ANALYZE */ + -3, /* (288) cmd ::= ANALYZE nm dbnm */ + -6, /* (289) cmd ::= ALTER TABLE fullname RENAME TO nm */ + -7, /* (290) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + -6, /* (291) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + -1, /* (292) add_column_fullname ::= fullname */ + -8, /* (293) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + -1, /* (294) cmd ::= create_vtab */ + -4, /* (295) cmd ::= create_vtab LP vtabarglist RP */ + -8, /* (296) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 0, /* (297) vtabarg ::= */ + -1, /* (298) vtabargtoken ::= ANY */ + -3, /* (299) vtabargtoken ::= lp anylist RP */ + -1, /* (300) lp ::= LP */ + -2, /* (301) with ::= WITH wqlist */ + -3, /* (302) with ::= WITH RECURSIVE wqlist */ + -1, /* (303) wqas ::= AS */ + -2, /* (304) wqas ::= AS MATERIALIZED */ + -3, /* (305) wqas ::= AS NOT MATERIALIZED */ + -6, /* (306) wqitem ::= nm eidlist_opt wqas LP select RP */ + -1, /* (307) wqlist ::= wqitem */ + -3, /* (308) wqlist ::= wqlist COMMA wqitem */ + -1, /* (309) windowdefn_list ::= windowdefn */ + -3, /* (310) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + -5, /* (311) windowdefn ::= nm AS LP window RP */ + -5, /* (312) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + -6, /* (313) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + -4, /* (314) window ::= ORDER BY sortlist frame_opt */ + -5, /* (315) window ::= nm ORDER BY sortlist frame_opt */ + -1, /* (316) window ::= frame_opt */ + -2, /* (317) window ::= nm frame_opt */ + 0, /* (318) frame_opt ::= */ + -3, /* (319) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + -6, /* (320) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + -1, /* (321) range_or_rows ::= RANGE|ROWS|GROUPS */ + -1, /* (322) frame_bound_s ::= frame_bound */ + -2, /* (323) frame_bound_s ::= UNBOUNDED PRECEDING */ + -1, /* (324) frame_bound_e ::= frame_bound */ + -2, /* (325) frame_bound_e ::= UNBOUNDED FOLLOWING */ + -2, /* (326) frame_bound ::= expr PRECEDING|FOLLOWING */ + -2, /* (327) frame_bound ::= CURRENT ROW */ + 0, /* (328) frame_exclude_opt ::= */ + -2, /* (329) frame_exclude_opt ::= EXCLUDE frame_exclude */ + -2, /* (330) frame_exclude ::= NO OTHERS */ + -2, /* (331) frame_exclude ::= CURRENT ROW */ + -1, /* (332) frame_exclude ::= GROUP|TIES */ + -2, /* (333) window_clause ::= WINDOW windowdefn_list */ + -2, /* (334) filter_over ::= filter_clause over_clause */ + -1, /* (335) filter_over ::= over_clause */ + -1, /* (336) filter_over ::= filter_clause */ + -4, /* (337) over_clause ::= OVER LP window RP */ + -2, /* (338) over_clause ::= OVER nm */ + -5, /* (339) filter_clause ::= FILTER LP WHERE expr RP */ + -1, /* (340) input ::= cmdlist */ + -2, /* (341) cmdlist ::= cmdlist ecmd */ + -1, /* (342) cmdlist ::= ecmd */ + -1, /* (343) ecmd ::= SEMI */ + -2, /* (344) ecmd ::= cmdx SEMI */ + -3, /* (345) ecmd ::= explain cmdx SEMI */ + 0, /* (346) trans_opt ::= */ + -1, /* (347) trans_opt ::= TRANSACTION */ + -2, /* (348) trans_opt ::= TRANSACTION nm */ + -1, /* (349) savepoint_opt ::= SAVEPOINT */ + 0, /* (350) savepoint_opt ::= */ + -2, /* (351) cmd ::= create_table create_table_args */ + -1, /* (352) table_option_set ::= table_option */ + -4, /* (353) columnlist ::= columnlist COMMA columnname carglist */ + -2, /* (354) columnlist ::= columnname carglist */ + -1, /* (355) nm ::= ID|INDEXED */ + -1, /* (356) nm ::= STRING */ + -1, /* (357) nm ::= JOIN_KW */ -1, /* (358) typetoken ::= typename */ -1, /* (359) typename ::= ID|STRING */ -1, /* (360) signed ::= plus_num */ -1, /* (361) signed ::= minus_num */ -2, /* (362) carglist ::= carglist ccons */ @@ -170948,36 +164906,35 @@ -1, /* (372) resolvetype ::= raisetype */ -1, /* (373) selectnowith ::= oneselect */ -1, /* (374) oneselect ::= values */ -2, /* (375) sclp ::= selcollist COMMA */ -1, /* (376) as ::= ID|STRING */ - -1, /* (377) indexed_opt ::= indexed_by */ - 0, /* (378) returning ::= */ - -1, /* (379) expr ::= term */ - -1, /* (380) likeop ::= LIKE_KW|MATCH */ - -1, /* (381) exprlist ::= nexprlist */ - -1, /* (382) nmnum ::= plus_num */ - -1, /* (383) nmnum ::= nm */ - -1, /* (384) nmnum ::= ON */ - -1, /* (385) nmnum ::= DELETE */ - -1, /* (386) nmnum ::= DEFAULT */ - -1, /* (387) plus_num ::= INTEGER|FLOAT */ - 0, /* (388) foreach_clause ::= */ - -3, /* (389) foreach_clause ::= FOR EACH ROW */ - -1, /* (390) trnm ::= nm */ - 0, /* (391) tridxby ::= */ - -1, /* (392) database_kw_opt ::= DATABASE */ - 0, /* (393) database_kw_opt ::= */ - 0, /* (394) kwcolumn_opt ::= */ - -1, /* (395) kwcolumn_opt ::= COLUMNKW */ - -1, /* (396) vtabarglist ::= vtabarg */ - -3, /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */ - -2, /* (398) vtabarg ::= vtabarg vtabargtoken */ - 0, /* (399) anylist ::= */ - -4, /* (400) anylist ::= anylist LP anylist RP */ - -2, /* (401) anylist ::= anylist ANY */ - 0, /* (402) with ::= */ + 0, /* (377) returning ::= */ + -1, /* (378) expr ::= term */ + -1, /* (379) likeop ::= LIKE_KW|MATCH */ + -1, /* (380) exprlist ::= nexprlist */ + -1, /* (381) nmnum ::= plus_num */ + -1, /* (382) nmnum ::= nm */ + -1, /* (383) nmnum ::= ON */ + -1, /* (384) nmnum ::= DELETE */ + -1, /* (385) nmnum ::= DEFAULT */ + -1, /* (386) plus_num ::= INTEGER|FLOAT */ + 0, /* (387) foreach_clause ::= */ + -3, /* (388) foreach_clause ::= FOR EACH ROW */ + -1, /* (389) trnm ::= nm */ + 0, /* (390) tridxby ::= */ + -1, /* (391) database_kw_opt ::= DATABASE */ + 0, /* (392) database_kw_opt ::= */ + 0, /* (393) kwcolumn_opt ::= */ + -1, /* (394) kwcolumn_opt ::= COLUMNKW */ + -1, /* (395) vtabarglist ::= vtabarg */ + -3, /* (396) vtabarglist ::= vtabarglist COMMA vtabarg */ + -2, /* (397) vtabarg ::= vtabarg vtabargtoken */ + 0, /* (398) anylist ::= */ + -4, /* (399) anylist ::= anylist LP anylist RP */ + -2, /* (400) anylist ::= anylist ANY */ + 0, /* (401) with ::= */ }; static void yy_accept(yyParser*); /* Forward Declaration */ /* @@ -171033,11 +164990,11 @@ {yymsp[1].minor.yy394 = TK_DEFERRED;} break; case 5: /* transtype ::= DEFERRED */ case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6); case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7); - case 322: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==322); + case 321: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==321); {yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/} break; case 8: /* cmd ::= COMMIT|END trans_opt */ case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9); {sqlite3EndTransaction(pParse,yymsp[-1].major);} @@ -171070,11 +165027,11 @@ case 47: /* autoinc ::= */ yytestcase(yyruleno==47); case 62: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==62); case 72: /* defer_subclause_opt ::= */ yytestcase(yyruleno==72); case 81: /* ifexists ::= */ yytestcase(yyruleno==81); case 98: /* distinct ::= */ yytestcase(yyruleno==98); - case 243: /* collate ::= */ yytestcase(yyruleno==243); + case 242: /* collate ::= */ yytestcase(yyruleno==242); {yymsp[1].minor.yy394 = 0;} break; case 16: /* ifnotexists ::= IF NOT EXISTS */ {yymsp[-2].minor.yy394 = 1;} break; @@ -171254,13 +165211,13 @@ case 171: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==171); {yymsp[-1].minor.yy394 = yymsp[0].minor.yy394;} break; case 63: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ case 80: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==80); - case 215: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==215); - case 218: /* in_op ::= NOT IN */ yytestcase(yyruleno==218); - case 244: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==244); + case 214: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==214); + case 217: /* in_op ::= NOT IN */ yytestcase(yyruleno==217); + case 243: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==243); {yymsp[-1].minor.yy394 = 1;} break; case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ {yymsp[-1].minor.yy394 = 0;} break; @@ -171341,11 +165298,11 @@ if( pRhs && pRhs->pPrior ){ SrcList *pFrom; Token x; x.n = 0; parserDoubleLinkSelect(pParse, pRhs); - pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0); + pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0); pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0); } if( pRhs ){ pRhs->op = (u8)yymsp[-1].minor.yy394; pRhs->pPrior = pLhs; @@ -171406,13 +165363,13 @@ {yymsp[0].minor.yy394 = SF_All;} break; case 99: /* sclp ::= */ case 132: /* orderby_opt ::= */ yytestcase(yyruleno==132); case 142: /* groupby_opt ::= */ yytestcase(yyruleno==142); - case 231: /* exprlist ::= */ yytestcase(yyruleno==231); - case 234: /* paren_exprlist ::= */ yytestcase(yyruleno==234); - case 239: /* eidlist_opt ::= */ yytestcase(yyruleno==239); + case 230: /* exprlist ::= */ yytestcase(yyruleno==230); + case 233: /* paren_exprlist ::= */ yytestcase(yyruleno==233); + case 238: /* eidlist_opt ::= */ yytestcase(yyruleno==238); {yymsp[1].minor.yy322 = 0;} break; case 100: /* selcollist ::= sclp scanpt expr scanpt as */ { yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[-2].minor.yy528); @@ -171433,147 +165390,155 @@ Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, pDot); } break; case 103: /* as ::= AS nm */ - case 115: /* dbnm ::= DOT nm */ yytestcase(yyruleno==115); - case 255: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==255); - case 256: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==256); + case 114: /* dbnm ::= DOT nm */ yytestcase(yyruleno==114); + case 254: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==254); + case 255: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==255); {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;} break; case 105: /* from ::= */ case 108: /* stl_prefix ::= */ yytestcase(yyruleno==108); {yymsp[1].minor.yy131 = 0;} break; case 106: /* from ::= FROM seltablist */ { yymsp[-1].minor.yy131 = yymsp[0].minor.yy131; - sqlite3SrcListShiftJoinType(pParse,yymsp[-1].minor.yy131); + sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy131); } break; case 107: /* stl_prefix ::= seltablist joinop */ { if( ALWAYS(yymsp[-1].minor.yy131 && yymsp[-1].minor.yy131->nSrc>0) ) yymsp[-1].minor.yy131->a[yymsp[-1].minor.yy131->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy394; } break; - case 109: /* seltablist ::= stl_prefix nm dbnm as on_using */ -{ - yymsp[-4].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-4].minor.yy131,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561); -} - break; - case 110: /* seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ -{ - yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy561); - sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy131, &yymsp[-1].minor.yy0); -} - break; - case 111: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ -{ - yymsp[-7].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-7].minor.yy131,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561); - sqlite3SrcListFuncArgs(pParse, yymsp[-7].minor.yy131, yymsp[-3].minor.yy322); -} - break; - case 112: /* seltablist ::= stl_prefix LP select RP as on_using */ -{ - yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,yymsp[-3].minor.yy47,&yymsp[0].minor.yy561); - } - break; - case 113: /* seltablist ::= stl_prefix LP seltablist RP as on_using */ -{ - if( yymsp[-5].minor.yy131==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy561.pOn==0 && yymsp[0].minor.yy561.pUsing==0 ){ - yymsp[-5].minor.yy131 = yymsp[-3].minor.yy131; - }else if( yymsp[-3].minor.yy131->nSrc==1 ){ - yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561); - if( yymsp[-5].minor.yy131 ){ - SrcItem *pNew = &yymsp[-5].minor.yy131->a[yymsp[-5].minor.yy131->nSrc-1]; - SrcItem *pOld = yymsp[-3].minor.yy131->a; + case 109: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ +{ + yymsp[-6].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy131,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy528,yymsp[0].minor.yy254); + sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy131, &yymsp[-2].minor.yy0); +} + break; + case 110: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ +{ + yymsp[-8].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy131,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy528,yymsp[0].minor.yy254); + sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy131, yymsp[-4].minor.yy322); +} + break; + case 111: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */ +{ + yymsp[-6].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy131,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy47,yymsp[-1].minor.yy528,yymsp[0].minor.yy254); + } + break; + case 112: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ +{ + if( yymsp[-6].minor.yy131==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy528==0 && yymsp[0].minor.yy254==0 ){ + yymsp[-6].minor.yy131 = yymsp[-4].minor.yy131; + }else if( yymsp[-4].minor.yy131->nSrc==1 ){ + yymsp[-6].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy131,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy528,yymsp[0].minor.yy254); + if( yymsp[-6].minor.yy131 ){ + SrcItem *pNew = &yymsp[-6].minor.yy131->a[yymsp[-6].minor.yy131->nSrc-1]; + SrcItem *pOld = yymsp[-4].minor.yy131->a; pNew->zName = pOld->zName; pNew->zDatabase = pOld->zDatabase; pNew->pSelect = pOld->pSelect; - if( pNew->pSelect && (pNew->pSelect->selFlags & SF_NestedFrom)!=0 ){ - pNew->fg.isNestedFrom = 1; - } if( pOld->fg.isTabFunc ){ pNew->u1.pFuncArg = pOld->u1.pFuncArg; pOld->u1.pFuncArg = 0; pOld->fg.isTabFunc = 0; pNew->fg.isTabFunc = 1; } pOld->zName = pOld->zDatabase = 0; pOld->pSelect = 0; } - sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy131); + sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy131); }else{ Select *pSubquery; - sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy131); - pSubquery = sqlite3SelectNew(pParse,0,yymsp[-3].minor.yy131,0,0,0,0,SF_NestedFrom,0); - yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,pSubquery,&yymsp[0].minor.yy561); + sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy131); + pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy131,0,0,0,0,SF_NestedFrom,0); + yymsp[-6].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy131,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy528,yymsp[0].minor.yy254); } } break; - case 114: /* dbnm ::= */ - case 129: /* indexed_opt ::= */ yytestcase(yyruleno==129); + case 113: /* dbnm ::= */ + case 127: /* indexed_opt ::= */ yytestcase(yyruleno==127); {yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;} break; - case 116: /* fullname ::= nm */ + case 115: /* fullname ::= nm */ { yylhsminor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); if( IN_RENAME_OBJECT && yylhsminor.yy131 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy131->a[0].zName, &yymsp[0].minor.yy0); } yymsp[0].minor.yy131 = yylhsminor.yy131; break; - case 117: /* fullname ::= nm DOT nm */ + case 116: /* fullname ::= nm DOT nm */ { yylhsminor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); if( IN_RENAME_OBJECT && yylhsminor.yy131 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy131->a[0].zName, &yymsp[0].minor.yy0); } yymsp[-2].minor.yy131 = yylhsminor.yy131; break; - case 118: /* xfullname ::= nm */ + case 117: /* xfullname ::= nm */ {yymsp[0].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/} break; - case 119: /* xfullname ::= nm DOT nm */ + case 118: /* xfullname ::= nm DOT nm */ {yymsp[-2].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} break; - case 120: /* xfullname ::= nm DOT nm AS nm */ + case 119: /* xfullname ::= nm DOT nm AS nm */ { yymsp[-4].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ if( yymsp[-4].minor.yy131 ) yymsp[-4].minor.yy131->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); } break; - case 121: /* xfullname ::= nm AS nm */ + case 120: /* xfullname ::= nm AS nm */ { yymsp[-2].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ if( yymsp[-2].minor.yy131 ) yymsp[-2].minor.yy131->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); } break; - case 122: /* joinop ::= COMMA|JOIN */ + case 121: /* joinop ::= COMMA|JOIN */ { yymsp[0].minor.yy394 = JT_INNER; } break; - case 123: /* joinop ::= JOIN_KW JOIN */ + case 122: /* joinop ::= JOIN_KW JOIN */ {yymsp[-1].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} break; - case 124: /* joinop ::= JOIN_KW nm JOIN */ + case 123: /* joinop ::= JOIN_KW nm JOIN */ {yymsp[-2].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} break; - case 125: /* joinop ::= JOIN_KW nm nm JOIN */ + case 124: /* joinop ::= JOIN_KW nm nm JOIN */ {yymsp[-3].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} break; - case 126: /* on_using ::= ON expr */ -{yymsp[-1].minor.yy561.pOn = yymsp[0].minor.yy528; yymsp[-1].minor.yy561.pUsing = 0;} - break; - case 127: /* on_using ::= USING LP idlist RP */ -{yymsp[-3].minor.yy561.pOn = 0; yymsp[-3].minor.yy561.pUsing = yymsp[-1].minor.yy254;} - break; - case 128: /* on_using ::= */ -{yymsp[1].minor.yy561.pOn = 0; yymsp[1].minor.yy561.pUsing = 0;} - break; - case 130: /* indexed_by ::= INDEXED BY nm */ + case 125: /* on_opt ::= ON expr */ + case 145: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==145); + case 152: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==152); + case 154: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==154); + case 226: /* case_else ::= ELSE expr */ yytestcase(yyruleno==226); + case 247: /* vinto ::= INTO expr */ yytestcase(yyruleno==247); +{yymsp[-1].minor.yy528 = yymsp[0].minor.yy528;} + break; + case 126: /* on_opt ::= */ + case 144: /* having_opt ::= */ yytestcase(yyruleno==144); + case 146: /* limit_opt ::= */ yytestcase(yyruleno==146); + case 151: /* where_opt ::= */ yytestcase(yyruleno==151); + case 153: /* where_opt_ret ::= */ yytestcase(yyruleno==153); + case 227: /* case_else ::= */ yytestcase(yyruleno==227); + case 229: /* case_operand ::= */ yytestcase(yyruleno==229); + case 248: /* vinto ::= */ yytestcase(yyruleno==248); +{yymsp[1].minor.yy528 = 0;} + break; + case 128: /* indexed_opt ::= INDEXED BY nm */ {yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;} break; - case 131: /* indexed_by ::= NOT INDEXED */ + case 129: /* indexed_opt ::= NOT INDEXED */ {yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;} + break; + case 130: /* using_opt ::= USING LP idlist RP */ +{yymsp[-3].minor.yy254 = yymsp[-1].minor.yy254;} + break; + case 131: /* using_opt ::= */ + case 173: /* idlist_opt ::= */ yytestcase(yyruleno==173); +{yymsp[1].minor.yy254 = 0;} break; case 133: /* orderby_opt ::= ORDER BY sortlist */ case 143: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==143); {yymsp[-2].minor.yy322 = yymsp[0].minor.yy322;} break; @@ -171603,26 +165568,10 @@ {yymsp[-1].minor.yy394 = SQLITE_SO_ASC;} break; case 140: /* nulls ::= NULLS LAST */ {yymsp[-1].minor.yy394 = SQLITE_SO_DESC;} break; - case 144: /* having_opt ::= */ - case 146: /* limit_opt ::= */ yytestcase(yyruleno==146); - case 151: /* where_opt ::= */ yytestcase(yyruleno==151); - case 153: /* where_opt_ret ::= */ yytestcase(yyruleno==153); - case 228: /* case_else ::= */ yytestcase(yyruleno==228); - case 230: /* case_operand ::= */ yytestcase(yyruleno==230); - case 249: /* vinto ::= */ yytestcase(yyruleno==249); -{yymsp[1].minor.yy528 = 0;} - break; - case 145: /* having_opt ::= HAVING expr */ - case 152: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==152); - case 154: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==154); - case 227: /* case_else ::= ELSE expr */ yytestcase(yyruleno==227); - case 248: /* vinto ::= INTO expr */ yytestcase(yyruleno==248); -{yymsp[-1].minor.yy528 = yymsp[0].minor.yy528;} - break; case 147: /* limit_opt ::= LIMIT expr */ {yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy528,0);} break; case 148: /* limit_opt ::= LIMIT expr OFFSET expr */ {yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} @@ -171644,22 +165593,11 @@ break; case 157: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ { sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy131, &yymsp[-4].minor.yy0); sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy322,"set list"); - if( yymsp[-1].minor.yy131 ){ - SrcList *pFromClause = yymsp[-1].minor.yy131; - if( pFromClause->nSrc>1 ){ - Select *pSubquery; - Token as; - pSubquery = sqlite3SelectNew(pParse,0,pFromClause,0,0,0,0,SF_NestedFrom,0); - as.n = 0; - as.z = 0; - pFromClause = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&as,pSubquery,0); - } - yymsp[-5].minor.yy131 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy131, pFromClause); - } + yymsp[-5].minor.yy131 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy131, yymsp[-1].minor.yy131); sqlite3Update(pParse,yymsp[-5].minor.yy131,yymsp[-2].minor.yy322,yymsp[0].minor.yy528,yymsp[-6].minor.yy394,0,0,0); } break; case 158: /* setlist ::= setlist COMMA nm EQ expr */ { @@ -171713,13 +165651,10 @@ { yymsp[-7].minor.yy444 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528,0);} break; case 170: /* returning ::= RETURNING selcollist */ {sqlite3AddReturning(pParse,yymsp[0].minor.yy322);} break; - case 173: /* idlist_opt ::= */ -{yymsp[1].minor.yy254 = 0;} - break; case 174: /* idlist_opt ::= LP idlist RP */ {yymsp[-2].minor.yy254 = yymsp[-1].minor.yy254;} break; case 175: /* idlist ::= idlist COMMA nm */ {yymsp[-2].minor.yy254 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);} @@ -171728,22 +165663,23 @@ {yymsp[0].minor.yy254 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} break; case 177: /* expr ::= LP expr RP */ {yymsp[-2].minor.yy528 = yymsp[-1].minor.yy528;} break; - case 178: /* expr ::= ID|INDEXED|JOIN_KW */ + case 178: /* expr ::= ID|INDEXED */ + case 179: /* expr ::= JOIN_KW */ yytestcase(yyruleno==179); {yymsp[0].minor.yy528=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} break; - case 179: /* expr ::= nm DOT nm */ + case 180: /* expr ::= nm DOT nm */ { Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0); Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); } yymsp[-2].minor.yy528 = yylhsminor.yy528; break; - case 180: /* expr ::= nm DOT nm DOT nm */ + case 181: /* expr ::= nm DOT nm DOT nm */ { Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-4].minor.yy0); Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0); Expr *temp3 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3); @@ -171752,22 +165688,22 @@ } yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); } yymsp[-4].minor.yy528 = yylhsminor.yy528; break; - case 181: /* term ::= NULL|FLOAT|BLOB */ - case 182: /* term ::= STRING */ yytestcase(yyruleno==182); + case 182: /* term ::= NULL|FLOAT|BLOB */ + case 183: /* term ::= STRING */ yytestcase(yyruleno==183); {yymsp[0].minor.yy528=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} break; - case 183: /* term ::= INTEGER */ + case 184: /* term ::= INTEGER */ { yylhsminor.yy528 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); if( yylhsminor.yy528 ) yylhsminor.yy528->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail); } yymsp[0].minor.yy528 = yylhsminor.yy528; break; - case 184: /* expr ::= VARIABLE */ + case 185: /* expr ::= VARIABLE */ { if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){ u32 n = yymsp[0].minor.yy0.n; yymsp[0].minor.yy528 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy528, n); @@ -171785,54 +165721,54 @@ if( yymsp[0].minor.yy528 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy528->iTable); } } } break; - case 185: /* expr ::= expr COLLATE ID|STRING */ + case 186: /* expr ::= expr COLLATE ID|STRING */ { yymsp[-2].minor.yy528 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy528, &yymsp[0].minor.yy0, 1); } break; - case 186: /* expr ::= CAST LP expr AS typetoken RP */ + case 187: /* expr ::= CAST LP expr AS typetoken RP */ { yymsp[-5].minor.yy528 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy528, yymsp[-3].minor.yy528, 0); } break; - case 187: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ + case 188: /* expr ::= ID|INDEXED LP distinct exprlist RP */ { yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy394); } yymsp[-4].minor.yy528 = yylhsminor.yy528; break; - case 188: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ + case 189: /* expr ::= ID|INDEXED LP STAR RP */ { yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); } yymsp[-3].minor.yy528 = yylhsminor.yy528; break; - case 189: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ + case 190: /* expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ { yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy322, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy394); sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41); } yymsp[-5].minor.yy528 = yylhsminor.yy528; break; - case 190: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ + case 191: /* expr ::= ID|INDEXED LP STAR RP filter_over */ { yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41); } yymsp[-4].minor.yy528 = yylhsminor.yy528; break; - case 191: /* term ::= CTIME_KW */ + case 192: /* term ::= CTIME_KW */ { yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); } yymsp[0].minor.yy528 = yylhsminor.yy528; break; - case 192: /* expr ::= LP nexprlist COMMA expr RP */ + case 193: /* expr ::= LP nexprlist COMMA expr RP */ { ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528); yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); if( yymsp[-4].minor.yy528 ){ yymsp[-4].minor.yy528->x.pList = pList; @@ -171842,26 +165778,26 @@ }else{ sqlite3ExprListDelete(pParse->db, pList); } } break; - case 193: /* expr ::= expr AND expr */ + case 194: /* expr ::= expr AND expr */ {yymsp[-2].minor.yy528=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} break; - case 194: /* expr ::= expr OR expr */ - case 195: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==195); - case 196: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==196); - case 197: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==197); - case 198: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==198); - case 199: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==199); - case 200: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==200); + case 195: /* expr ::= expr OR expr */ + case 196: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==196); + case 197: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==197); + case 198: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==198); + case 199: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==199); + case 200: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==200); + case 201: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==201); {yymsp[-2].minor.yy528=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} break; - case 201: /* likeop ::= NOT LIKE_KW|MATCH */ + case 202: /* likeop ::= NOT LIKE_KW|MATCH */ {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/} break; - case 202: /* expr ::= expr likeop expr */ + case 203: /* expr ::= expr likeop expr */ { ExprList *pList; int bNot = yymsp[-1].minor.yy0.n & 0x80000000; yymsp[-1].minor.yy0.n &= 0x7fffffff; pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy528); @@ -171869,11 +165805,11 @@ yymsp[-2].minor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); if( bNot ) yymsp[-2].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy528, 0); if( yymsp[-2].minor.yy528 ) yymsp[-2].minor.yy528->flags |= EP_InfixFunc; } break; - case 203: /* expr ::= expr likeop expr ESCAPE expr */ + case 204: /* expr ::= expr likeop expr ESCAPE expr */ { ExprList *pList; int bNot = yymsp[-3].minor.yy0.n & 0x80000000; yymsp[-3].minor.yy0.n &= 0x7fffffff; pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); @@ -171882,63 +165818,51 @@ yymsp[-4].minor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); if( bNot ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); if( yymsp[-4].minor.yy528 ) yymsp[-4].minor.yy528->flags |= EP_InfixFunc; } break; - case 204: /* expr ::= expr ISNULL|NOTNULL */ + case 205: /* expr ::= expr ISNULL|NOTNULL */ {yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy528,0);} break; - case 205: /* expr ::= expr NOT NULL */ + case 206: /* expr ::= expr NOT NULL */ {yymsp[-2].minor.yy528 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy528,0);} break; - case 206: /* expr ::= expr IS expr */ + case 207: /* expr ::= expr IS expr */ { yymsp[-2].minor.yy528 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy528,yymsp[0].minor.yy528); binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-2].minor.yy528, TK_ISNULL); } break; - case 207: /* expr ::= expr IS NOT expr */ + case 208: /* expr ::= expr IS NOT expr */ { yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy528,yymsp[0].minor.yy528); binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-3].minor.yy528, TK_NOTNULL); } break; - case 208: /* expr ::= expr IS NOT DISTINCT FROM expr */ -{ - yymsp[-5].minor.yy528 = sqlite3PExpr(pParse,TK_IS,yymsp[-5].minor.yy528,yymsp[0].minor.yy528); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-5].minor.yy528, TK_ISNULL); -} - break; - case 209: /* expr ::= expr IS DISTINCT FROM expr */ -{ - yymsp[-4].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-4].minor.yy528,yymsp[0].minor.yy528); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-4].minor.yy528, TK_NOTNULL); -} - break; - case 210: /* expr ::= NOT expr */ - case 211: /* expr ::= BITNOT expr */ yytestcase(yyruleno==211); + case 209: /* expr ::= NOT expr */ + case 210: /* expr ::= BITNOT expr */ yytestcase(yyruleno==210); {yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy528, 0);/*A-overwrites-B*/} break; - case 212: /* expr ::= PLUS|MINUS expr */ + case 211: /* expr ::= PLUS|MINUS expr */ { yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy528, 0); /*A-overwrites-B*/ } break; - case 213: /* expr ::= expr PTR expr */ + case 212: /* expr ::= expr PTR expr */ { ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy528); pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy528); yylhsminor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); } yymsp[-2].minor.yy528 = yylhsminor.yy528; break; - case 214: /* between_op ::= BETWEEN */ - case 217: /* in_op ::= IN */ yytestcase(yyruleno==217); + case 213: /* between_op ::= BETWEEN */ + case 216: /* in_op ::= IN */ yytestcase(yyruleno==216); {yymsp[0].minor.yy394 = 0;} break; - case 216: /* expr ::= expr between_op expr AND expr */ + case 215: /* expr ::= expr between_op expr AND expr */ { ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy528); yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy528, 0); if( yymsp[-4].minor.yy528 ){ @@ -171947,11 +165871,11 @@ sqlite3ExprListDelete(pParse->db, pList); } if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); } break; - case 219: /* expr ::= expr in_op LP exprlist RP */ + case 218: /* expr ::= expr in_op LP exprlist RP */ { if( yymsp[-1].minor.yy322==0 ){ /* Expressions of the form ** ** expr1 IN () @@ -171959,24 +165883,18 @@ ** ** simplify to constants 0 (false) and 1 (true), respectively, ** regardless of the value of expr1. */ sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy528); - yymsp[-4].minor.yy528 = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy394 ? "true" : "false"); - if( yymsp[-4].minor.yy528 ) sqlite3ExprIdToTrueFalse(yymsp[-4].minor.yy528); + yymsp[-4].minor.yy528 = sqlite3Expr(pParse->db, TK_INTEGER, yymsp[-3].minor.yy394 ? "1" : "0"); }else{ Expr *pRHS = yymsp[-1].minor.yy322->a[0].pExpr; if( yymsp[-1].minor.yy322->nExpr==1 && sqlite3ExprIsConstant(pRHS) && yymsp[-4].minor.yy528->op!=TK_VECTOR ){ yymsp[-1].minor.yy322->a[0].pExpr = 0; sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322); pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0); yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy528, pRHS); - }else if( yymsp[-1].minor.yy322->nExpr==1 && pRHS->op==TK_SELECT ){ - yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, pRHS->x.pSelect); - pRHS->x.pSelect = 0; - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322); }else{ yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); if( yymsp[-4].minor.yy528==0 ){ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322); }else if( yymsp[-4].minor.yy528->pLeft->op==TK_VECTOR ){ @@ -171993,41 +165911,41 @@ } if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); } } break; - case 220: /* expr ::= LP select RP */ + case 219: /* expr ::= LP select RP */ { yymsp[-2].minor.yy528 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy528, yymsp[-1].minor.yy47); } break; - case 221: /* expr ::= expr in_op LP select RP */ + case 220: /* expr ::= expr in_op LP select RP */ { yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, yymsp[-1].minor.yy47); if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); } break; - case 222: /* expr ::= expr in_op nm dbnm paren_exprlist */ + case 221: /* expr ::= expr in_op nm dbnm paren_exprlist */ { SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0); if( yymsp[0].minor.yy322 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy322); yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, pSelect); if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); } break; - case 223: /* expr ::= EXISTS LP select RP */ + case 222: /* expr ::= EXISTS LP select RP */ { Expr *p; p = yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy47); } break; - case 224: /* expr ::= CASE case_operand case_exprlist case_else END */ + case 223: /* expr ::= CASE case_operand case_exprlist case_else END */ { yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy528, 0); if( yymsp[-4].minor.yy528 ){ yymsp[-4].minor.yy528->x.pList = yymsp[-1].minor.yy528 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528) : yymsp[-2].minor.yy322; sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy528); @@ -172035,406 +165953,406 @@ sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy322); sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy528); } } break; - case 225: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ + case 224: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ { yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[-2].minor.yy528); yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[0].minor.yy528); } break; - case 226: /* case_exprlist ::= WHEN expr THEN expr */ + case 225: /* case_exprlist ::= WHEN expr THEN expr */ { yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322, yymsp[0].minor.yy528); } break; - case 229: /* case_operand ::= expr */ + case 228: /* case_operand ::= expr */ {yymsp[0].minor.yy528 = yymsp[0].minor.yy528; /*A-overwrites-X*/} break; - case 232: /* nexprlist ::= nexprlist COMMA expr */ + case 231: /* nexprlist ::= nexprlist COMMA expr */ {yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy528);} break; - case 233: /* nexprlist ::= expr */ + case 232: /* nexprlist ::= expr */ {yymsp[0].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy528); /*A-overwrites-Y*/} break; - case 235: /* paren_exprlist ::= LP exprlist RP */ - case 240: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==240); + case 234: /* paren_exprlist ::= LP exprlist RP */ + case 239: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==239); {yymsp[-2].minor.yy322 = yymsp[-1].minor.yy322;} break; - case 236: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + case 235: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ { sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy322, yymsp[-10].minor.yy394, &yymsp[-11].minor.yy0, yymsp[0].minor.yy528, SQLITE_SO_ASC, yymsp[-8].minor.yy394, SQLITE_IDXTYPE_APPDEF); if( IN_RENAME_OBJECT && pParse->pNewIndex ){ sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0); } } break; - case 237: /* uniqueflag ::= UNIQUE */ - case 279: /* raisetype ::= ABORT */ yytestcase(yyruleno==279); + case 236: /* uniqueflag ::= UNIQUE */ + case 278: /* raisetype ::= ABORT */ yytestcase(yyruleno==278); {yymsp[0].minor.yy394 = OE_Abort;} break; - case 238: /* uniqueflag ::= */ + case 237: /* uniqueflag ::= */ {yymsp[1].minor.yy394 = OE_None;} break; - case 241: /* eidlist ::= eidlist COMMA nm collate sortorder */ + case 240: /* eidlist ::= eidlist COMMA nm collate sortorder */ { yymsp[-4].minor.yy322 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394); } break; - case 242: /* eidlist ::= nm collate sortorder */ + case 241: /* eidlist ::= nm collate sortorder */ { yymsp[-2].minor.yy322 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394); /*A-overwrites-Y*/ } break; - case 245: /* cmd ::= DROP INDEX ifexists fullname */ + case 244: /* cmd ::= DROP INDEX ifexists fullname */ {sqlite3DropIndex(pParse, yymsp[0].minor.yy131, yymsp[-1].minor.yy394);} break; - case 246: /* cmd ::= VACUUM vinto */ + case 245: /* cmd ::= VACUUM vinto */ {sqlite3Vacuum(pParse,0,yymsp[0].minor.yy528);} break; - case 247: /* cmd ::= VACUUM nm vinto */ + case 246: /* cmd ::= VACUUM nm vinto */ {sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy528);} break; - case 250: /* cmd ::= PRAGMA nm dbnm */ + case 249: /* cmd ::= PRAGMA nm dbnm */ {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} break; - case 251: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ + case 250: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);} break; - case 252: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ + case 251: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);} break; - case 253: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ + case 252: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);} break; - case 254: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ + case 253: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);} break; - case 257: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + case 256: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ { Token all; all.z = yymsp[-3].minor.yy0.z; all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n; sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy33, &all); } break; - case 258: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + case 257: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ { sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy394, yymsp[-4].minor.yy180.a, yymsp[-4].minor.yy180.b, yymsp[-2].minor.yy131, yymsp[0].minor.yy528, yymsp[-10].minor.yy394, yymsp[-8].minor.yy394); yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/ } break; - case 259: /* trigger_time ::= BEFORE|AFTER */ + case 258: /* trigger_time ::= BEFORE|AFTER */ { yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/ } break; - case 260: /* trigger_time ::= INSTEAD OF */ + case 259: /* trigger_time ::= INSTEAD OF */ { yymsp[-1].minor.yy394 = TK_INSTEAD;} break; - case 261: /* trigger_time ::= */ + case 260: /* trigger_time ::= */ { yymsp[1].minor.yy394 = TK_BEFORE; } break; - case 262: /* trigger_event ::= DELETE|INSERT */ - case 263: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==263); + case 261: /* trigger_event ::= DELETE|INSERT */ + case 262: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==262); {yymsp[0].minor.yy180.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy180.b = 0;} break; - case 264: /* trigger_event ::= UPDATE OF idlist */ + case 263: /* trigger_event ::= UPDATE OF idlist */ {yymsp[-2].minor.yy180.a = TK_UPDATE; yymsp[-2].minor.yy180.b = yymsp[0].minor.yy254;} break; - case 265: /* when_clause ::= */ - case 284: /* key_opt ::= */ yytestcase(yyruleno==284); + case 264: /* when_clause ::= */ + case 283: /* key_opt ::= */ yytestcase(yyruleno==283); { yymsp[1].minor.yy528 = 0; } break; - case 266: /* when_clause ::= WHEN expr */ - case 285: /* key_opt ::= KEY expr */ yytestcase(yyruleno==285); + case 265: /* when_clause ::= WHEN expr */ + case 284: /* key_opt ::= KEY expr */ yytestcase(yyruleno==284); { yymsp[-1].minor.yy528 = yymsp[0].minor.yy528; } break; - case 267: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + case 266: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ { assert( yymsp[-2].minor.yy33!=0 ); yymsp[-2].minor.yy33->pLast->pNext = yymsp[-1].minor.yy33; yymsp[-2].minor.yy33->pLast = yymsp[-1].minor.yy33; } break; - case 268: /* trigger_cmd_list ::= trigger_cmd SEMI */ + case 267: /* trigger_cmd_list ::= trigger_cmd SEMI */ { assert( yymsp[-1].minor.yy33!=0 ); yymsp[-1].minor.yy33->pLast = yymsp[-1].minor.yy33; } break; - case 269: /* trnm ::= nm DOT nm */ + case 268: /* trnm ::= nm DOT nm */ { yymsp[-2].minor.yy0 = yymsp[0].minor.yy0; sqlite3ErrorMsg(pParse, "qualified table names are not allowed on INSERT, UPDATE, and DELETE " "statements within triggers"); } break; - case 270: /* tridxby ::= INDEXED BY nm */ + case 269: /* tridxby ::= INDEXED BY nm */ { sqlite3ErrorMsg(pParse, "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 271: /* tridxby ::= NOT INDEXED */ + case 270: /* tridxby ::= NOT INDEXED */ { sqlite3ErrorMsg(pParse, "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 272: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ + case 271: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ {yylhsminor.yy33 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy131, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528, yymsp[-7].minor.yy394, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy522);} yymsp[-8].minor.yy33 = yylhsminor.yy33; break; - case 273: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + case 272: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ { yylhsminor.yy33 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy254,yymsp[-2].minor.yy47,yymsp[-6].minor.yy394,yymsp[-1].minor.yy444,yymsp[-7].minor.yy522,yymsp[0].minor.yy522);/*yylhsminor.yy33-overwrites-yymsp[-6].minor.yy394*/ } yymsp[-7].minor.yy33 = yylhsminor.yy33; break; - case 274: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + case 273: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ {yylhsminor.yy33 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy528, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy522);} yymsp[-5].minor.yy33 = yylhsminor.yy33; break; - case 275: /* trigger_cmd ::= scanpt select scanpt */ + case 274: /* trigger_cmd ::= scanpt select scanpt */ {yylhsminor.yy33 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy47, yymsp[-2].minor.yy522, yymsp[0].minor.yy522); /*yylhsminor.yy33-overwrites-yymsp[-1].minor.yy47*/} yymsp[-2].minor.yy33 = yylhsminor.yy33; break; - case 276: /* expr ::= RAISE LP IGNORE RP */ + case 275: /* expr ::= RAISE LP IGNORE RP */ { yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); if( yymsp[-3].minor.yy528 ){ yymsp[-3].minor.yy528->affExpr = OE_Ignore; } } break; - case 277: /* expr ::= RAISE LP raisetype COMMA nm RP */ + case 276: /* expr ::= RAISE LP raisetype COMMA nm RP */ { yymsp[-5].minor.yy528 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); if( yymsp[-5].minor.yy528 ) { yymsp[-5].minor.yy528->affExpr = (char)yymsp[-3].minor.yy394; } } break; - case 278: /* raisetype ::= ROLLBACK */ + case 277: /* raisetype ::= ROLLBACK */ {yymsp[0].minor.yy394 = OE_Rollback;} break; - case 280: /* raisetype ::= FAIL */ + case 279: /* raisetype ::= FAIL */ {yymsp[0].minor.yy394 = OE_Fail;} break; - case 281: /* cmd ::= DROP TRIGGER ifexists fullname */ + case 280: /* cmd ::= DROP TRIGGER ifexists fullname */ { sqlite3DropTrigger(pParse,yymsp[0].minor.yy131,yymsp[-1].minor.yy394); } break; - case 282: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + case 281: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ { sqlite3Attach(pParse, yymsp[-3].minor.yy528, yymsp[-1].minor.yy528, yymsp[0].minor.yy528); } break; - case 283: /* cmd ::= DETACH database_kw_opt expr */ + case 282: /* cmd ::= DETACH database_kw_opt expr */ { sqlite3Detach(pParse, yymsp[0].minor.yy528); } break; - case 286: /* cmd ::= REINDEX */ + case 285: /* cmd ::= REINDEX */ {sqlite3Reindex(pParse, 0, 0);} break; - case 287: /* cmd ::= REINDEX nm dbnm */ + case 286: /* cmd ::= REINDEX nm dbnm */ {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 288: /* cmd ::= ANALYZE */ + case 287: /* cmd ::= ANALYZE */ {sqlite3Analyze(pParse, 0, 0);} break; - case 289: /* cmd ::= ANALYZE nm dbnm */ + case 288: /* cmd ::= ANALYZE nm dbnm */ {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 290: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ + case 289: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ { sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy131,&yymsp[0].minor.yy0); } break; - case 291: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + case 290: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ { yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n; sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0); } break; - case 292: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + case 291: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ { sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy131, &yymsp[0].minor.yy0); } break; - case 293: /* add_column_fullname ::= fullname */ + case 292: /* add_column_fullname ::= fullname */ { disableLookaside(pParse); sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy131); } break; - case 294: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + case 293: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ { sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy131, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } break; - case 295: /* cmd ::= create_vtab */ + case 294: /* cmd ::= create_vtab */ {sqlite3VtabFinishParse(pParse,0);} break; - case 296: /* cmd ::= create_vtab LP vtabarglist RP */ + case 295: /* cmd ::= create_vtab LP vtabarglist RP */ {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} break; - case 297: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + case 296: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ { sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy394); } break; - case 298: /* vtabarg ::= */ + case 297: /* vtabarg ::= */ {sqlite3VtabArgInit(pParse);} break; - case 299: /* vtabargtoken ::= ANY */ - case 300: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==300); - case 301: /* lp ::= LP */ yytestcase(yyruleno==301); + case 298: /* vtabargtoken ::= ANY */ + case 299: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==299); + case 300: /* lp ::= LP */ yytestcase(yyruleno==300); {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} break; - case 302: /* with ::= WITH wqlist */ - case 303: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==303); + case 301: /* with ::= WITH wqlist */ + case 302: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==302); { sqlite3WithPush(pParse, yymsp[0].minor.yy521, 1); } break; - case 304: /* wqas ::= AS */ + case 303: /* wqas ::= AS */ {yymsp[0].minor.yy516 = M10d_Any;} break; - case 305: /* wqas ::= AS MATERIALIZED */ + case 304: /* wqas ::= AS MATERIALIZED */ {yymsp[-1].minor.yy516 = M10d_Yes;} break; - case 306: /* wqas ::= AS NOT MATERIALIZED */ + case 305: /* wqas ::= AS NOT MATERIALIZED */ {yymsp[-2].minor.yy516 = M10d_No;} break; - case 307: /* wqitem ::= nm eidlist_opt wqas LP select RP */ + case 306: /* wqitem ::= nm eidlist_opt wqas LP select RP */ { yymsp[-5].minor.yy385 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy322, yymsp[-1].minor.yy47, yymsp[-3].minor.yy516); /*A-overwrites-X*/ } break; - case 308: /* wqlist ::= wqitem */ + case 307: /* wqlist ::= wqitem */ { yymsp[0].minor.yy521 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy385); /*A-overwrites-X*/ } break; - case 309: /* wqlist ::= wqlist COMMA wqitem */ + case 308: /* wqlist ::= wqlist COMMA wqitem */ { yymsp[-2].minor.yy521 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy521, yymsp[0].minor.yy385); } break; - case 310: /* windowdefn_list ::= windowdefn */ + case 309: /* windowdefn_list ::= windowdefn */ { yylhsminor.yy41 = yymsp[0].minor.yy41; } yymsp[0].minor.yy41 = yylhsminor.yy41; break; - case 311: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ + case 310: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ { assert( yymsp[0].minor.yy41!=0 ); sqlite3WindowChain(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy41); yymsp[0].minor.yy41->pNextWin = yymsp[-2].minor.yy41; yylhsminor.yy41 = yymsp[0].minor.yy41; } yymsp[-2].minor.yy41 = yylhsminor.yy41; break; - case 312: /* windowdefn ::= nm AS LP window RP */ + case 311: /* windowdefn ::= nm AS LP window RP */ { if( ALWAYS(yymsp[-1].minor.yy41) ){ yymsp[-1].minor.yy41->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n); } yylhsminor.yy41 = yymsp[-1].minor.yy41; } yymsp[-4].minor.yy41 = yylhsminor.yy41; break; - case 313: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + case 312: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ { yymsp[-4].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, 0); } break; - case 314: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + case 313: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ { yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, &yymsp[-5].minor.yy0); } yymsp[-5].minor.yy41 = yylhsminor.yy41; break; - case 315: /* window ::= ORDER BY sortlist frame_opt */ + case 314: /* window ::= ORDER BY sortlist frame_opt */ { yymsp[-3].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, 0); } break; - case 316: /* window ::= nm ORDER BY sortlist frame_opt */ + case 315: /* window ::= nm ORDER BY sortlist frame_opt */ { yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0); } yymsp[-4].minor.yy41 = yylhsminor.yy41; break; - case 317: /* window ::= frame_opt */ - case 336: /* filter_over ::= over_clause */ yytestcase(yyruleno==336); + case 316: /* window ::= frame_opt */ + case 335: /* filter_over ::= over_clause */ yytestcase(yyruleno==335); { yylhsminor.yy41 = yymsp[0].minor.yy41; } yymsp[0].minor.yy41 = yylhsminor.yy41; break; - case 318: /* window ::= nm frame_opt */ + case 317: /* window ::= nm frame_opt */ { yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, 0, &yymsp[-1].minor.yy0); } yymsp[-1].minor.yy41 = yylhsminor.yy41; break; - case 319: /* frame_opt ::= */ + case 318: /* frame_opt ::= */ { yymsp[1].minor.yy41 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0); } break; - case 320: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + case 319: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ { yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy394, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy516); } yymsp[-2].minor.yy41 = yylhsminor.yy41; break; - case 321: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + case 320: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ { yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy394, yymsp[-3].minor.yy595.eType, yymsp[-3].minor.yy595.pExpr, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, yymsp[0].minor.yy516); } yymsp[-5].minor.yy41 = yylhsminor.yy41; break; - case 323: /* frame_bound_s ::= frame_bound */ - case 325: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==325); + case 322: /* frame_bound_s ::= frame_bound */ + case 324: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==324); {yylhsminor.yy595 = yymsp[0].minor.yy595;} yymsp[0].minor.yy595 = yylhsminor.yy595; break; - case 324: /* frame_bound_s ::= UNBOUNDED PRECEDING */ - case 326: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==326); - case 328: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==328); + case 323: /* frame_bound_s ::= UNBOUNDED PRECEDING */ + case 325: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==325); + case 327: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==327); {yylhsminor.yy595.eType = yymsp[-1].major; yylhsminor.yy595.pExpr = 0;} yymsp[-1].minor.yy595 = yylhsminor.yy595; break; - case 327: /* frame_bound ::= expr PRECEDING|FOLLOWING */ + case 326: /* frame_bound ::= expr PRECEDING|FOLLOWING */ {yylhsminor.yy595.eType = yymsp[0].major; yylhsminor.yy595.pExpr = yymsp[-1].minor.yy528;} yymsp[-1].minor.yy595 = yylhsminor.yy595; break; - case 329: /* frame_exclude_opt ::= */ + case 328: /* frame_exclude_opt ::= */ {yymsp[1].minor.yy516 = 0;} break; - case 330: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ + case 329: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ {yymsp[-1].minor.yy516 = yymsp[0].minor.yy516;} break; - case 331: /* frame_exclude ::= NO OTHERS */ - case 332: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==332); + case 330: /* frame_exclude ::= NO OTHERS */ + case 331: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==331); {yymsp[-1].minor.yy516 = yymsp[-1].major; /*A-overwrites-X*/} break; - case 333: /* frame_exclude ::= GROUP|TIES */ + case 332: /* frame_exclude ::= GROUP|TIES */ {yymsp[0].minor.yy516 = yymsp[0].major; /*A-overwrites-X*/} break; - case 334: /* window_clause ::= WINDOW windowdefn_list */ + case 333: /* window_clause ::= WINDOW windowdefn_list */ { yymsp[-1].minor.yy41 = yymsp[0].minor.yy41; } break; - case 335: /* filter_over ::= filter_clause over_clause */ + case 334: /* filter_over ::= filter_clause over_clause */ { if( yymsp[0].minor.yy41 ){ yymsp[0].minor.yy41->pFilter = yymsp[-1].minor.yy528; }else{ sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy528); @@ -172441,11 +166359,11 @@ } yylhsminor.yy41 = yymsp[0].minor.yy41; } yymsp[-1].minor.yy41 = yylhsminor.yy41; break; - case 337: /* filter_over ::= filter_clause */ + case 336: /* filter_over ::= filter_clause */ { yylhsminor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); if( yylhsminor.yy41 ){ yylhsminor.yy41->eFrmType = TK_FILTER; yylhsminor.yy41->pFilter = yymsp[0].minor.yy528; @@ -172453,45 +166371,46 @@ sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy528); } } yymsp[0].minor.yy41 = yylhsminor.yy41; break; - case 338: /* over_clause ::= OVER LP window RP */ + case 337: /* over_clause ::= OVER LP window RP */ { yymsp[-3].minor.yy41 = yymsp[-1].minor.yy41; assert( yymsp[-3].minor.yy41!=0 ); } break; - case 339: /* over_clause ::= OVER nm */ + case 338: /* over_clause ::= OVER nm */ { yymsp[-1].minor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); if( yymsp[-1].minor.yy41 ){ yymsp[-1].minor.yy41->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n); } } break; - case 340: /* filter_clause ::= FILTER LP WHERE expr RP */ + case 339: /* filter_clause ::= FILTER LP WHERE expr RP */ { yymsp[-4].minor.yy528 = yymsp[-1].minor.yy528; } break; default: - /* (341) input ::= cmdlist */ yytestcase(yyruleno==341); - /* (342) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==342); - /* (343) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=343); - /* (344) ecmd ::= SEMI */ yytestcase(yyruleno==344); - /* (345) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==345); - /* (346) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=346); - /* (347) trans_opt ::= */ yytestcase(yyruleno==347); - /* (348) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==348); - /* (349) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==349); - /* (350) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==350); - /* (351) savepoint_opt ::= */ yytestcase(yyruleno==351); - /* (352) cmd ::= create_table create_table_args */ yytestcase(yyruleno==352); - /* (353) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=353); - /* (354) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==354); - /* (355) columnlist ::= columnname carglist */ yytestcase(yyruleno==355); - /* (356) nm ::= ID|INDEXED|JOIN_KW */ yytestcase(yyruleno==356); - /* (357) nm ::= STRING */ yytestcase(yyruleno==357); + /* (340) input ::= cmdlist */ yytestcase(yyruleno==340); + /* (341) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==341); + /* (342) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=342); + /* (343) ecmd ::= SEMI */ yytestcase(yyruleno==343); + /* (344) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==344); + /* (345) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=345); + /* (346) trans_opt ::= */ yytestcase(yyruleno==346); + /* (347) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==347); + /* (348) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==348); + /* (349) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==349); + /* (350) savepoint_opt ::= */ yytestcase(yyruleno==350); + /* (351) cmd ::= create_table create_table_args */ yytestcase(yyruleno==351); + /* (352) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=352); + /* (353) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==353); + /* (354) columnlist ::= columnname carglist */ yytestcase(yyruleno==354); + /* (355) nm ::= ID|INDEXED */ yytestcase(yyruleno==355); + /* (356) nm ::= STRING */ yytestcase(yyruleno==356); + /* (357) nm ::= JOIN_KW */ yytestcase(yyruleno==357); /* (358) typetoken ::= typename */ yytestcase(yyruleno==358); /* (359) typename ::= ID|STRING */ yytestcase(yyruleno==359); /* (360) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=360); /* (361) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=361); /* (362) carglist ::= carglist ccons */ yytestcase(yyruleno==362); @@ -172507,36 +166426,35 @@ /* (372) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=372); /* (373) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=373); /* (374) oneselect ::= values */ yytestcase(yyruleno==374); /* (375) sclp ::= selcollist COMMA */ yytestcase(yyruleno==375); /* (376) as ::= ID|STRING */ yytestcase(yyruleno==376); - /* (377) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=377); - /* (378) returning ::= */ yytestcase(yyruleno==378); - /* (379) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=379); - /* (380) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==380); - /* (381) exprlist ::= nexprlist */ yytestcase(yyruleno==381); - /* (382) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=382); - /* (383) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=383); - /* (384) nmnum ::= ON */ yytestcase(yyruleno==384); - /* (385) nmnum ::= DELETE */ yytestcase(yyruleno==385); - /* (386) nmnum ::= DEFAULT */ yytestcase(yyruleno==386); - /* (387) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==387); - /* (388) foreach_clause ::= */ yytestcase(yyruleno==388); - /* (389) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==389); - /* (390) trnm ::= nm */ yytestcase(yyruleno==390); - /* (391) tridxby ::= */ yytestcase(yyruleno==391); - /* (392) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==392); - /* (393) database_kw_opt ::= */ yytestcase(yyruleno==393); - /* (394) kwcolumn_opt ::= */ yytestcase(yyruleno==394); - /* (395) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==395); - /* (396) vtabarglist ::= vtabarg */ yytestcase(yyruleno==396); - /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==397); - /* (398) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==398); - /* (399) anylist ::= */ yytestcase(yyruleno==399); - /* (400) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==400); - /* (401) anylist ::= anylist ANY */ yytestcase(yyruleno==401); - /* (402) with ::= */ yytestcase(yyruleno==402); + /* (377) returning ::= */ yytestcase(yyruleno==377); + /* (378) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=378); + /* (379) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==379); + /* (380) exprlist ::= nexprlist */ yytestcase(yyruleno==380); + /* (381) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=381); + /* (382) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=382); + /* (383) nmnum ::= ON */ yytestcase(yyruleno==383); + /* (384) nmnum ::= DELETE */ yytestcase(yyruleno==384); + /* (385) nmnum ::= DEFAULT */ yytestcase(yyruleno==385); + /* (386) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==386); + /* (387) foreach_clause ::= */ yytestcase(yyruleno==387); + /* (388) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==388); + /* (389) trnm ::= nm */ yytestcase(yyruleno==389); + /* (390) tridxby ::= */ yytestcase(yyruleno==390); + /* (391) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==391); + /* (392) database_kw_opt ::= */ yytestcase(yyruleno==392); + /* (393) kwcolumn_opt ::= */ yytestcase(yyruleno==393); + /* (394) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==394); + /* (395) vtabarglist ::= vtabarg */ yytestcase(yyruleno==395); + /* (396) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==396); + /* (397) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==397); + /* (398) anylist ::= */ yytestcase(yyruleno==398); + /* (399) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==399); + /* (400) anylist ::= anylist ANY */ yytestcase(yyruleno==400); + /* (401) with ::= */ yytestcase(yyruleno==401); break; /********** End reduce actions ************************************************/ }; assert( yyruleno=2 ){ i = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n*1) % 127; - for(i=(int)aKWHash[i]; i>0; i=aKWNext[i]){ + for(i=((int)aKWHash[i])-1; i>=0; i=((int)aKWNext[i])-1){ if( aKWLen[i]!=n ) continue; zKW = &zKWText[aKWOffset[i]]; #ifdef SQLITE_ASCII if( (z[0]&~0x20)!=zKW[0] ) continue; if( (z[1]&~0x20)!=zKW[1] ) continue; @@ -173339,157 +167257,157 @@ if( toupper(z[1])!=zKW[1] ) continue; j = 2; while( j=SQLITE_N_KEYWORD ) return SQLITE_ERROR; - i++; *pzName = zKWText + aKWOffset[i]; *pnName = aKWLen[i]; return SQLITE_OK; } SQLITE_API int sqlite3_keyword_count(void){ return SQLITE_N_KEYWORD; } @@ -173980,11 +167897,10 @@ while( 1 ){ n = sqlite3GetToken((u8*)zSql, &tokenType); mxSqlLen -= n; if( mxSqlLen<0 ){ pParse->rc = SQLITE_TOOBIG; - pParse->nErr++; break; } #ifndef SQLITE_OMIT_WINDOWFUNC if( tokenType>=TK_WINDOW ){ assert( tokenType==TK_SPACE || tokenType==TK_OVER || tokenType==TK_FILTER @@ -174077,11 +167993,11 @@ sqlite3DeleteTable(db, pParse->pNewTable); } if( pParse->pNewTrigger && !IN_RENAME_OBJECT ){ sqlite3DeleteTrigger(db, pParse->pNewTrigger); } - if( pParse->pVList ) sqlite3DbNNFreeNN(db, pParse->pVList); + sqlite3DbFree(db, pParse->pVList); db->pParse = pParentParse; assert( nErr==0 || pParse->rc!=SQLITE_OK ); return nErr; } @@ -175039,25 +168955,13 @@ */ SQLITE_API int sqlite3_config(int op, ...){ va_list ap; int rc = SQLITE_OK; - /* sqlite3_config() normally returns SQLITE_MISUSE if it is invoked while - ** the SQLite library is in use. Except, a few selected opcodes - ** are allowed. - */ - if( sqlite3GlobalConfig.isInit ){ - static const u64 mAnytimeConfigOption = 0 - | MASKBIT64( SQLITE_CONFIG_LOG ) - | MASKBIT64( SQLITE_CONFIG_PCACHE_HDRSZ ) - ; - if( op<0 || op>63 || (MASKBIT64(op) & mAnytimeConfigOption)==0 ){ - return SQLITE_MISUSE_BKPT; - } - testcase( op==SQLITE_CONFIG_LOG ); - testcase( op==SQLITE_CONFIG_PCACHE_HDRSZ ); - } + /* sqlite3_config() shall return SQLITE_MISUSE if it is invoked while + ** the SQLite library is in use. */ + if( sqlite3GlobalConfig.isInit ) return SQLITE_MISUSE_BKPT; va_start(ap, op); switch( op ){ /* Mutex configuration options are only available in a threadsafe @@ -175122,11 +169026,10 @@ if( sqlite3GlobalConfig.m.xMalloc==0 ) sqlite3MemSetDefault(); *va_arg(ap, sqlite3_mem_methods*) = sqlite3GlobalConfig.m; break; } case SQLITE_CONFIG_MEMSTATUS: { - assert( !sqlite3GlobalConfig.isInit ); /* Cannot change at runtime */ /* EVIDENCE-OF: R-61275-35157 The SQLITE_CONFIG_MEMSTATUS option takes ** single argument of type int, interpreted as a boolean, which enables ** or disables the collection of memory allocation statistics. */ sqlite3GlobalConfig.bMemstat = va_arg(ap, int); break; @@ -175246,14 +169149,12 @@ /* MSVC is picky about pulling func ptrs from va lists. ** http://support.microsoft.com/kb/47961 ** sqlite3GlobalConfig.xLog = va_arg(ap, void(*)(void*,int,const char*)); */ typedef void(*LOGFUNC_t)(void*,int,const char*); - LOGFUNC_t xLog = va_arg(ap, LOGFUNC_t); - void *pLogArg = va_arg(ap, void*); - AtomicStore(&sqlite3GlobalConfig.xLog, xLog); - AtomicStore(&sqlite3GlobalConfig.pLogArg, pLogArg); + sqlite3GlobalConfig.xLog = va_arg(ap, LOGFUNC_t); + sqlite3GlobalConfig.pLogArg = va_arg(ap, void*); break; } /* EVIDENCE-OF: R-55548-33817 The compile-time setting for URI filenames ** can be changed at start-time using the @@ -175263,12 +169164,11 @@ case SQLITE_CONFIG_URI: { /* EVIDENCE-OF: R-25451-61125 The SQLITE_CONFIG_URI option takes a single ** argument of type int. If non-zero, then URI handling is globally ** enabled. If the parameter is zero, then URI handling is globally ** disabled. */ - int bOpenUri = va_arg(ap, int); - AtomicStore(&sqlite3GlobalConfig.bOpenUri, bOpenUri); + sqlite3GlobalConfig.bOpenUri = va_arg(ap, int); break; } case SQLITE_CONFIG_COVERING_INDEX_SCAN: { /* EVIDENCE-OF: R-36592-02772 The SQLITE_CONFIG_COVERING_INDEX_SCAN @@ -175449,23 +169349,22 @@ db->lookaside.pEnd = p; db->lookaside.bDisable = 0; db->lookaside.bMalloced = pBuf==0 ?1:0; db->lookaside.nSlot = nBig+nSm; }else{ - db->lookaside.pStart = 0; + db->lookaside.pStart = db; #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE db->lookaside.pSmallInit = 0; db->lookaside.pSmallFree = 0; - db->lookaside.pMiddle = 0; + db->lookaside.pMiddle = db; #endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ - db->lookaside.pEnd = 0; + db->lookaside.pEnd = db; db->lookaside.bDisable = 1; db->lookaside.sz = 0; db->lookaside.bMalloced = 0; db->lookaside.nSlot = 0; } - db->lookaside.pTrueEnd = db->lookaside.pEnd; assert( sqlite3LookasideUsed(db,0)==0 ); #endif /* SQLITE_OMIT_LOOKASIDE */ return SQLITE_OK; } @@ -175540,11 +169439,10 @@ ** Configuration settings for an individual database connection */ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){ va_list ap; int rc; - sqlite3_mutex_enter(db->mutex); va_start(ap, op); switch( op ){ case SQLITE_DBCONFIG_MAINDBNAME: { /* IMP: R-06824-28531 */ /* IMP: R-36257-52125 */ @@ -175579,12 +169477,10 @@ { SQLITE_DBCONFIG_LEGACY_ALTER_TABLE, SQLITE_LegacyAlter }, { SQLITE_DBCONFIG_DQS_DDL, SQLITE_DqsDDL }, { SQLITE_DBCONFIG_DQS_DML, SQLITE_DqsDML }, { SQLITE_DBCONFIG_LEGACY_FILE_FORMAT, SQLITE_LegacyFileFmt }, { SQLITE_DBCONFIG_TRUSTED_SCHEMA, SQLITE_TrustedSchema }, - { SQLITE_DBCONFIG_STMT_SCANSTATUS, SQLITE_StmtScanStatus }, - { SQLITE_DBCONFIG_REVERSE_SCANORDER, SQLITE_ReverseOrder }, }; unsigned int i; rc = SQLITE_ERROR; /* IMP: R-42790-23372 */ for(i=0; imutex); return rc; } /* ** This is the default collating function named "BINARY" which is always @@ -176193,11 +170088,10 @@ case SQLITE_ROW: zName = "SQLITE_ROW"; break; case SQLITE_NOTICE: zName = "SQLITE_NOTICE"; break; case SQLITE_NOTICE_RECOVER_WAL: zName = "SQLITE_NOTICE_RECOVER_WAL";break; case SQLITE_NOTICE_RECOVER_ROLLBACK: zName = "SQLITE_NOTICE_RECOVER_ROLLBACK"; break; - case SQLITE_NOTICE_RBU: zName = "SQLITE_NOTICE_RBU"; break; case SQLITE_WARNING: zName = "SQLITE_WARNING"; break; case SQLITE_WARNING_AUTOINDEX: zName = "SQLITE_WARNING_AUTOINDEX"; break; case SQLITE_DONE: zName = "SQLITE_DONE"; break; } } @@ -176423,35 +170317,18 @@ /* ** Cause any pending operation to stop at its earliest opportunity. */ SQLITE_API void sqlite3_interrupt(sqlite3 *db){ #ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) - && (db==0 || db->eOpenState!=SQLITE_STATE_ZOMBIE) - ){ + if( !sqlite3SafetyCheckOk(db) && (db==0 || db->eOpenState!=SQLITE_STATE_ZOMBIE) ){ (void)SQLITE_MISUSE_BKPT; return; } #endif AtomicStore(&db->u1.isInterrupted, 1); } -/* -** Return true or false depending on whether or not an interrupt is -** pending on connection db. -*/ -SQLITE_API int sqlite3_is_interrupted(sqlite3 *db){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) - && (db==0 || db->eOpenState!=SQLITE_STATE_ZOMBIE) - ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif - return AtomicLoad(&db->u1.isInterrupted)!=0; -} /* ** This function is exactly the same as sqlite3_create_function(), except ** that it is designed to be called by internal code. The difference is ** that if a malloc() fails in sqlite3_create_function(), an error code @@ -176492,11 +170369,11 @@ enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY); /* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But ** the meaning is inverted. So flip the bit. */ assert( SQLITE_FUNC_UNSAFE==SQLITE_INNOCUOUS ); - extraFlags ^= SQLITE_FUNC_UNSAFE; /* tag-20230109-1 */ + extraFlags ^= SQLITE_FUNC_UNSAFE; #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 @@ -176510,15 +170387,15 @@ enc = SQLITE_UTF16NATIVE; break; case SQLITE_ANY: { int rc; rc = sqlite3CreateFunc(db, zFunctionName, nArg, - (SQLITE_UTF8|extraFlags)^SQLITE_FUNC_UNSAFE, /* tag-20230109-1 */ + (SQLITE_UTF8|extraFlags)^SQLITE_FUNC_UNSAFE, pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor); if( rc==SQLITE_OK ){ rc = sqlite3CreateFunc(db, zFunctionName, nArg, - (SQLITE_UTF16LE|extraFlags)^SQLITE_FUNC_UNSAFE, /* tag-20230109-1*/ + (SQLITE_UTF16LE|extraFlags)^SQLITE_FUNC_UNSAFE, pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor); } if( rc!=SQLITE_OK ){ return rc; } @@ -176763,11 +170640,11 @@ #endif sqlite3_mutex_enter(db->mutex); rc = sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)!=0; sqlite3_mutex_leave(db->mutex); if( rc ) return SQLITE_OK; - zCopy = sqlite3_mprintf("%s", zName); + zCopy = sqlite3_mprintf(zName); if( zCopy==0 ) return SQLITE_NOMEM; return sqlite3_create_function_v2(db, zName, nArg, SQLITE_UTF8, zCopy, sqlite3InvalidFunction, 0, 0, sqlite3_free); } @@ -177566,13 +171443,13 @@ char c; int nUri = sqlite3Strlen30(zUri); assert( *pzErrMsg==0 ); - if( ((flags & SQLITE_OPEN_URI) /* IMP: R-48725-32206 */ - || AtomicLoad(&sqlite3GlobalConfig.bOpenUri)) /* IMP: R-51689-46548 */ - && nUri>=5 && memcmp(zUri, "file:", 5)==0 /* IMP: R-57884-37496 */ + if( ((flags & SQLITE_OPEN_URI) /* IMP: R-48725-32206 */ + || sqlite3GlobalConfig.bOpenUri) /* IMP: R-51689-46548 */ + && nUri>=5 && memcmp(zUri, "file:", 5)==0 /* IMP: R-57884-37496 */ ){ char *zOpt; int eState; /* Parser state when parsing URI */ int iIn; /* Input character index */ int iOut = 0; /* Output character index */ @@ -177975,13 +171852,10 @@ | SQLITE_Defensive #endif #if defined(SQLITE_DEFAULT_LEGACY_ALTER_TABLE) | SQLITE_LegacyAlter #endif -#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) - | SQLITE_StmtScanStatus -#endif ; sqlite3HashInit(&db->aCollSeq); #ifndef SQLITE_OMIT_VIRTUALTABLE sqlite3HashInit(&db->aModule); #endif @@ -178000,23 +171874,10 @@ createCollation(db, "RTRIM", SQLITE_UTF8, 0, rtrimCollFunc, 0); if( db->mallocFailed ){ goto opendb_out; } -#if SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL) - /* Process magic filenames ":localStorage:" and ":sessionStorage:" */ - if( zFilename && zFilename[0]==':' ){ - if( strcmp(zFilename, ":localStorage:")==0 ){ - zFilename = "file:local?vfs=kvvfs"; - flags |= SQLITE_OPEN_URI; - }else if( strcmp(zFilename, ":sessionStorage:")==0 ){ - zFilename = "file:session?vfs=kvvfs"; - flags |= SQLITE_OPEN_URI; - } - } -#endif /* SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL) */ - /* Parse the filename/URI argument ** ** Only allow sensible combinations of bits in the flags argument. ** Throw an error if any non-sense combination is used. If we ** do not block illegal combinations here, it could trigger @@ -178043,16 +171904,10 @@ if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); sqlite3ErrorWithMsg(db, rc, zErrMsg ? "%s" : 0, zErrMsg); sqlite3_free(zErrMsg); goto opendb_out; } - assert( db->pVfs!=0 ); -#if SQLITE_OS_KV || defined(SQLITE_OS_KV_OPTIONAL) - if( sqlite3_stricmp(db->pVfs->zName, "kvvfs")==0 ){ - db->temp_store = 2; - } -#endif /* Open the backend database driver */ rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, 0, flags | SQLITE_OPEN_MAIN_DB); if( rc!=SQLITE_OK ){ @@ -178598,13 +172453,10 @@ *(int*)pArg = sqlite3BtreeGetRequestedReserve(pBtree); if( iNew>=0 && iNew<=255 ){ sqlite3BtreeSetPageSize(pBtree, 0, iNew, 0); } rc = SQLITE_OK; - }else if( op==SQLITE_FCNTL_RESET_CACHE ){ - sqlite3BtreeClearCache(pBtree); - rc = SQLITE_OK; }else{ int nSave = db->busyHandler.nBusy; rc = sqlite3OsFileControl(fd, op, pArg); db->busyHandler.nBusy = nSave; } @@ -178770,32 +172622,10 @@ */ case SQLITE_TESTCTRL_ASSERT: { volatile int x = 0; assert( /*side-effects-ok*/ (x = va_arg(ap,int))!=0 ); rc = x; -#if defined(SQLITE_DEBUG) - /* Invoke these debugging routines so that the compiler does not - ** issue "defined but not used" warnings. */ - if( x==9999 ){ - sqlite3ShowExpr(0); - sqlite3ShowExpr(0); - sqlite3ShowExprList(0); - sqlite3ShowIdList(0); - sqlite3ShowSrcList(0); - sqlite3ShowWith(0); - sqlite3ShowUpsert(0); - sqlite3ShowTriggerStep(0); - sqlite3ShowTriggerStepList(0); - sqlite3ShowTrigger(0); - sqlite3ShowTriggerList(0); -#ifndef SQLITE_OMIT_WINDOWFUNC - sqlite3ShowWindow(0); - sqlite3ShowWinFunc(0); -#endif - sqlite3ShowSelect(0); - } -#endif break; } /* @@ -179053,23 +172883,23 @@ /* sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, op, ptr) ** ** "ptr" is a pointer to a u32. ** - ** op==0 Store the current sqlite3TreeTrace in *ptr - ** op==1 Set sqlite3TreeTrace to the value *ptr + ** op==0 Store the current sqlite3SelectTrace in *ptr + ** op==1 Set sqlite3SelectTrace to the value *ptr ** op==3 Store the current sqlite3WhereTrace in *ptr ** op==3 Set sqlite3WhereTrace to the value *ptr */ case SQLITE_TESTCTRL_TRACEFLAGS: { int opTrace = va_arg(ap, int); u32 *ptr = va_arg(ap, u32*); switch( opTrace ){ - case 0: *ptr = sqlite3TreeTrace; break; - case 1: sqlite3TreeTrace = *ptr; break; - case 2: *ptr = sqlite3WhereTrace; break; - case 3: sqlite3WhereTrace = *ptr; break; + case 0: *ptr = sqlite3SelectTrace; break; + case 1: sqlite3SelectTrace = *ptr; break; + case 2: *ptr = sqlite3WhereTrace; break; + case 3: sqlite3WhereTrace = *ptr; break; } break; } /* sqlite3_test_control(SQLITE_TESTCTRL_LOGEST, @@ -179082,16 +172912,14 @@ ** Test access for the LogEst conversion routines. */ case SQLITE_TESTCTRL_LOGEST: { double rIn = va_arg(ap, double); LogEst rLogEst = sqlite3LogEstFromDouble(rIn); - int *pI1 = va_arg(ap,int*); - u64 *pU64 = va_arg(ap,u64*); - int *pI2 = va_arg(ap,int*); - *pI1 = rLogEst; - *pU64 = sqlite3LogEstToInt(rLogEst); - *pI2 = sqlite3LogEst(*pU64); + u64 iInt = sqlite3LogEstToInt(rLogEst); + va_arg(ap, int*)[0] = rLogEst; + va_arg(ap, u64*)[0] = iInt; + va_arg(ap, int*)[0] = sqlite3LogEst(iInt); break; } #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD) @@ -179161,11 +172989,11 @@ ** functions. ** ** Memory layout must be compatible with that generated by the pager ** and expected by sqlite3_uri_parameter() and databaseName(). */ -SQLITE_API const char *sqlite3_create_filename( +SQLITE_API char *sqlite3_create_filename( const char *zDatabase, const char *zJournal, const char *zWal, int nParam, const char **azParam @@ -179197,14 +173025,14 @@ /* ** Free memory obtained from sqlite3_create_filename(). It is a severe ** error to call this routine with any parameter other than a pointer ** previously obtained from sqlite3_create_filename() or a NULL pointer. */ -SQLITE_API void sqlite3_free_filename(const char *p){ +SQLITE_API void sqlite3_free_filename(char *p){ if( p==0 ) return; - p = databaseName(p); - sqlite3_free((char*)p - 4); + p = (char*)databaseName(p); + sqlite3_free(p - 4); } /* ** This is a utility routine, useful to VFS implementations, that checks @@ -179302,28 +173130,10 @@ SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){ int iDb = zDbName ? sqlite3FindDbName(db, zDbName) : 0; return iDb<0 ? 0 : db->aDb[iDb].pBt; } -/* -** Return the name of the N-th database schema. Return NULL if N is out -** of range. -*/ -SQLITE_API const char *sqlite3_db_name(sqlite3 *db, int N){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif - if( N<0 || N>=db->nDb ){ - return 0; - }else{ - return db->aDb[N].zDbSName; - } -} - /* ** Return the filename of the database associated with a database ** connection. */ SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){ @@ -179451,12 +173261,12 @@ ** Recover as many snapshots as possible from the wal file associated with ** schema zDb of database db. */ SQLITE_API int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb){ int rc = SQLITE_ERROR; -#ifndef SQLITE_OMIT_WAL int iDb; +#ifndef SQLITE_OMIT_WAL #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ){ return SQLITE_MISUSE_BKPT; } @@ -181007,11 +174817,11 @@ Fts3SegReader **apSegment; /* Array of Fts3SegReader objects */ int nSegment; /* Size of apSegment array */ int nAdvance; /* How many seg-readers to advance */ Fts3SegFilter *pFilter; /* Pointer to filter object */ char *aBuffer; /* Buffer to merge doclists in */ - i64 nBuffer; /* Allocated size of aBuffer[] in bytes */ + int nBuffer; /* Allocated size of aBuffer[] in bytes */ int iColFilter; /* If >=0, filter for this column */ int bRestart; /* Used by fts3.c only. */ @@ -181099,12 +174909,10 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int, int); SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int); SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int); #endif -SQLITE_PRIVATE int sqlite3Fts3ExprIterate(Fts3Expr*, int (*x)(Fts3Expr*,int,void*), void*); - #endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */ #endif /* _FTSINT_H */ /************** End of fts3Int.h *********************************************/ /************** Continuing where we left off in fts3.c ***********************/ @@ -183705,11 +177513,11 @@ ** as a single-byte delta, whereas in the second it must be stored as a ** FTS3_VARINT_MAX byte varint. ** ** Similar padding is added in the fts3DoclistOrMerge() function. */ - pTS->aaOutput[0] = sqlite3_malloc64((i64)nDoclist + FTS3_VARINT_MAX + 1); + pTS->aaOutput[0] = sqlite3_malloc(nDoclist + FTS3_VARINT_MAX + 1); pTS->anOutput[0] = nDoclist; if( pTS->aaOutput[0] ){ memcpy(pTS->aaOutput[0], aDoclist, nDoclist); memset(&pTS->aaOutput[0][nDoclist], 0, FTS3_VARINT_MAX); }else{ @@ -185125,11 +178933,12 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){ int iToken; /* Used to iterate through phrase tokens */ char *aPoslist = 0; /* Position list for deferred tokens */ int nPoslist = 0; /* Number of bytes in aPoslist */ int iPrev = -1; /* Token number of previous deferred token */ - char *aFree = (pPhrase->doclist.bFreeList ? pPhrase->doclist.pList : 0); + + assert( pPhrase->doclist.bFreeList==0 ); for(iToken=0; iTokennToken; iToken++){ Fts3PhraseToken *pToken = &pPhrase->aToken[iToken]; Fts3DeferredToken *pDeferred = pToken->pDeferred; @@ -185139,11 +178948,10 @@ int rc = sqlite3Fts3DeferredTokenList(pDeferred, &pList, &nList); if( rc!=SQLITE_OK ) return rc; if( pList==0 ){ sqlite3_free(aPoslist); - sqlite3_free(aFree); pPhrase->doclist.pList = 0; pPhrase->doclist.nList = 0; return SQLITE_OK; }else if( aPoslist==0 ){ @@ -185160,11 +178968,10 @@ sqlite3_free(aPoslist); aPoslist = pList; nPoslist = (int)(aOut - aPoslist); if( nPoslist==0 ){ sqlite3_free(aPoslist); - sqlite3_free(aFree); pPhrase->doclist.pList = 0; pPhrase->doclist.nList = 0; return SQLITE_OK; } } @@ -185193,18 +179000,17 @@ p1 = pPhrase->doclist.pList; p2 = aPoslist; nDistance = iPrev - nMaxUndeferred; } - aOut = (char *)sqlite3Fts3MallocZero(nPoslist+FTS3_BUFFER_PADDING); + aOut = (char *)sqlite3_malloc(nPoslist+8); if( !aOut ){ sqlite3_free(aPoslist); return SQLITE_NOMEM; } pPhrase->doclist.pList = aOut; - assert( p1 && p2 ); if( fts3PoslistPhraseMerge(&aOut, nDistance, 0, 1, &p1, &p2) ){ pPhrase->doclist.bFreeList = 1; pPhrase->doclist.nList = (int)(aOut - pPhrase->doclist.pList); }else{ sqlite3_free(aOut); @@ -185213,11 +179019,10 @@ } sqlite3_free(aPoslist); } } - if( pPhrase->doclist.pList!=aFree ) sqlite3_free(aFree); return SQLITE_OK; } #endif /* SQLITE_DISABLE_FTS4_DEFERRED */ /* @@ -185562,11 +179367,11 @@ /* Check if the current entries really are a phrase match */ if( bEof==0 ){ int nList = 0; int nByte = a[p->nToken-1].nList; - char *aDoclist = sqlite3_malloc64((i64)nByte+FTS3_BUFFER_PADDING); + char *aDoclist = sqlite3_malloc(nByte+FTS3_BUFFER_PADDING); if( !aDoclist ) return SQLITE_NOMEM; memcpy(aDoclist, a[p->nToken-1].pList, nByte+1); memset(&aDoclist[nByte], 0, FTS3_BUFFER_PADDING); for(i=0; i<(p->nToken-1); i++){ @@ -186104,12 +179909,13 @@ static void fts3EvalNextRow( Fts3Cursor *pCsr, /* FTS Cursor handle */ Fts3Expr *pExpr, /* Expr. to advance to next matching row */ int *pRc /* IN/OUT: Error code */ ){ - if( *pRc==SQLITE_OK && pExpr->bEof==0 ){ + if( *pRc==SQLITE_OK ){ int bDescDoclist = pCsr->bDesc; /* Used by DOCID_CMP() macro */ + assert( pExpr->bEof==0 ); pExpr->bStart = 1; switch( pExpr->eType ){ case FTSQUERY_NEAR: case FTSQUERY_AND: { @@ -186387,14 +180193,15 @@ ); break; default: { #ifndef SQLITE_DISABLE_FTS4_DEFERRED - if( pCsr->pDeferred && (pExpr->bDeferred || ( - pExpr->iDocid==pCsr->iPrevId && pExpr->pPhrase->doclist.pList - ))){ + if( pCsr->pDeferred + && (pExpr->iDocid==pCsr->iPrevId || pExpr->bDeferred) + ){ Fts3Phrase *pPhrase = pExpr->pPhrase; + assert( pExpr->bDeferred || pPhrase->doclist.bFreeList==0 ); if( pExpr->bDeferred ){ fts3EvalInvalidatePoslist(pPhrase); } *pRc = fts3EvalDeferredPhrase(pCsr, pPhrase); bHit = (pPhrase->doclist.pList!=0); @@ -186581,26 +180388,10 @@ fts3EvalUpdateCounts(pExpr->pLeft, nCol); fts3EvalUpdateCounts(pExpr->pRight, nCol); } } -/* -** This is an sqlite3Fts3ExprIterate() callback. If the Fts3Expr.aMI[] array -** has not yet been allocated, allocate and zero it. Otherwise, just zero -** it. -*/ -static int fts3AllocateMSI(Fts3Expr *pExpr, int iPhrase, void *pCtx){ - Fts3Table *pTab = (Fts3Table*)pCtx; - UNUSED_PARAMETER(iPhrase); - if( pExpr->aMI==0 ){ - pExpr->aMI = (u32 *)sqlite3_malloc64(pTab->nColumn * 3 * sizeof(u32)); - if( pExpr->aMI==0 ) return SQLITE_NOMEM; - } - memset(pExpr->aMI, 0, pTab->nColumn * 3 * sizeof(u32)); - return SQLITE_OK; -} - /* ** Expression pExpr must be of type FTSQUERY_PHRASE. ** ** If it is not already allocated and populated, this function allocates and ** populates the Fts3Expr.aMI[] array for expression pExpr. If pExpr is part @@ -186618,29 +180409,34 @@ assert( pExpr->eType==FTSQUERY_PHRASE ); if( pExpr->aMI==0 ){ Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; Fts3Expr *pRoot; /* Root of NEAR expression */ + Fts3Expr *p; /* Iterator used for several purposes */ sqlite3_int64 iPrevId = pCsr->iPrevId; sqlite3_int64 iDocid; u8 bEof; /* Find the root of the NEAR expression */ pRoot = pExpr; - while( pRoot->pParent - && (pRoot->pParent->eType==FTSQUERY_NEAR || pRoot->bDeferred) - ){ + while( pRoot->pParent && pRoot->pParent->eType==FTSQUERY_NEAR ){ pRoot = pRoot->pParent; } iDocid = pRoot->iDocid; bEof = pRoot->bEof; assert( pRoot->bStart ); /* Allocate space for the aMSI[] array of each FTSQUERY_PHRASE node */ - rc = sqlite3Fts3ExprIterate(pRoot, fts3AllocateMSI, (void*)pTab); - if( rc!=SQLITE_OK ) return rc; + for(p=pRoot; p; p=p->pLeft){ + Fts3Expr *pE = (p->eType==FTSQUERY_PHRASE?p:p->pRight); + assert( pE->aMI==0 ); + pE->aMI = (u32 *)sqlite3_malloc64(pTab->nColumn * 3 * sizeof(u32)); + if( !pE->aMI ) return SQLITE_NOMEM; + memset(pE->aMI, 0, pTab->nColumn * 3 * sizeof(u32)); + } + fts3EvalRestart(pCsr, pRoot, &rc); while( pCsr->isEof==0 && rc==SQLITE_OK ){ do { @@ -186792,11 +180588,10 @@ int bDescDoclist = pTab->bDescIdx; /* For DOCID_CMP macro */ int bOr = 0; u8 bTreeEof = 0; Fts3Expr *p; /* Used to iterate from pExpr to root */ Fts3Expr *pNear; /* Most senior NEAR ancestor (or pExpr) */ - Fts3Expr *pRun; /* Closest non-deferred ancestor of pNear */ int bMatch; /* Check if this phrase descends from an OR expression node. If not, ** return NULL. Otherwise, the entry that corresponds to docid ** pCsr->iPrevId may lie earlier in the doclist buffer. Or, if the @@ -186807,34 +180602,29 @@ if( p->eType==FTSQUERY_OR ) bOr = 1; if( p->eType==FTSQUERY_NEAR ) pNear = p; if( p->bEof ) bTreeEof = 1; } if( bOr==0 ) return SQLITE_OK; - pRun = pNear; - while( pRun->bDeferred ){ - assert( pRun->pParent ); - pRun = pRun->pParent; - } /* This is the descendent of an OR node. In this case we cannot use ** an incremental phrase. Load the entire doclist for the phrase ** into memory in this case. */ if( pPhrase->bIncr ){ - int bEofSave = pRun->bEof; - fts3EvalRestart(pCsr, pRun, &rc); - while( rc==SQLITE_OK && !pRun->bEof ){ - fts3EvalNextRow(pCsr, pRun, &rc); - if( bEofSave==0 && pRun->iDocid==iDocid ) break; + int bEofSave = pNear->bEof; + fts3EvalRestart(pCsr, pNear, &rc); + while( rc==SQLITE_OK && !pNear->bEof ){ + fts3EvalNextRow(pCsr, pNear, &rc); + if( bEofSave==0 && pNear->iDocid==iDocid ) break; } assert( rc!=SQLITE_OK || pPhrase->bIncr==0 ); - if( rc==SQLITE_OK && pRun->bEof!=bEofSave ){ + if( rc==SQLITE_OK && pNear->bEof!=bEofSave ){ rc = FTS_CORRUPT_VTAB; } } if( bTreeEof ){ - while( rc==SQLITE_OK && !pRun->bEof ){ - fts3EvalNextRow(pCsr, pRun, &rc); + while( rc==SQLITE_OK && !pNear->bEof ){ + fts3EvalNextRow(pCsr, pNear, &rc); } } if( rc!=SQLITE_OK ) return rc; bMatch = 1; @@ -189814,11 +183604,11 @@ if( c->iOffset>iStartOffset ){ int n = c->iOffset-iStartOffset; if( n>c->nAllocated ){ char *pNew; c->nAllocated = n+20; - pNew = sqlite3_realloc64(c->zToken, c->nAllocated); + pNew = sqlite3_realloc(c->zToken, c->nAllocated); if( !pNew ) return SQLITE_NOMEM; c->zToken = pNew; } porter_stemmer(&z[iStartOffset], n, c->zToken, pnBytes); *pzToken = c->zToken; @@ -190566,11 +184356,11 @@ if( c->iOffset>iStartOffset ){ int i, n = c->iOffset-iStartOffset; if( n>c->nTokenAllocated ){ char *pNew; c->nTokenAllocated = n+20; - pNew = sqlite3_realloc64(c->pToken, c->nTokenAllocated); + pNew = sqlite3_realloc(c->pToken, c->nTokenAllocated); if( !pNew ) return SQLITE_NOMEM; c->pToken = pNew; } for(i=0; inSpace = 100; p->aData = (char *)&p[1]; p->nData = 0; } else if( p->nData+FTS3_VARINT_MAX+1>p->nSpace ){ - i64 nNew = p->nSpace * 2; - p = sqlite3_realloc64(p, sizeof(*p) + nNew); + int nNew = p->nSpace * 2; + p = sqlite3_realloc(p, sizeof(*p) + nNew); if( !p ){ sqlite3_free(*pp); *pp = 0; return SQLITE_NOMEM; } - p->nSpace = (int)nNew; + p->nSpace = nNew; p->aData = (char *)&p[1]; } /* Append the new serialized varint to the end of the list. */ p->nData += sqlite3Fts3PutVarint(&p->aData[p->nData], i); @@ -192301,11 +186091,11 @@ if( rc==SQLITE_OK ){ int nByte = sqlite3_blob_bytes(p->pSegments); *pnBlob = nByte; if( paBlob ){ - char *aByte = sqlite3_malloc64((i64)nByte + FTS3_NODE_PADDING); + char *aByte = sqlite3_malloc(nByte + FTS3_NODE_PADDING); if( !aByte ){ rc = SQLITE_NOMEM; }else{ if( pnLoad && nByte>(FTS3_NODE_CHUNK_THRESHOLD) ){ nByte = FTS3_NODE_CHUNKSIZE; @@ -192418,19 +186208,19 @@ int nCopy = pList->nData+1; int nTerm = fts3HashKeysize(pElem); if( (nTerm+1)>pReader->nTermAlloc ){ sqlite3_free(pReader->zTerm); - pReader->zTerm = (char*)sqlite3_malloc64(((i64)nTerm+1)*2); + pReader->zTerm = (char*)sqlite3_malloc((nTerm+1)*2); if( !pReader->zTerm ) return SQLITE_NOMEM; pReader->nTermAlloc = (nTerm+1)*2; } memcpy(pReader->zTerm, fts3HashKey(pElem), nTerm); pReader->zTerm[nTerm] = '\0'; pReader->nTerm = nTerm; - aCopy = (char*)sqlite3_malloc64(nCopy); + aCopy = (char*)sqlite3_malloc(nCopy); if( !aCopy ) return SQLITE_NOMEM; memcpy(aCopy, pList->aData, nCopy); pReader->nNode = pReader->nDoclist = nCopy; pReader->aNode = pReader->aDoclist = aCopy; pReader->ppNextElem++; @@ -192713,11 +186503,11 @@ if( iStartLeaf==0 ){ if( iEndLeaf!=0 ) return FTS_CORRUPT_VTAB; nExtra = nRoot + FTS3_NODE_PADDING; } - pReader = (Fts3SegReader *)sqlite3_malloc64(sizeof(Fts3SegReader) + nExtra); + pReader = (Fts3SegReader *)sqlite3_malloc(sizeof(Fts3SegReader) + nExtra); if( !pReader ){ return SQLITE_NOMEM; } memset(pReader, 0, sizeof(Fts3SegReader)); pReader->iIdx = iAge; @@ -192805,11 +186595,11 @@ int nKey = fts3HashKeysize(pE); if( nTerm==0 || (nKey>=nTerm && 0==memcmp(zKey, zTerm, nTerm)) ){ if( nElem==nAlloc ){ Fts3HashElem **aElem2; nAlloc += 16; - aElem2 = (Fts3HashElem **)sqlite3_realloc64( + aElem2 = (Fts3HashElem **)sqlite3_realloc( aElem, nAlloc*sizeof(Fts3HashElem *) ); if( !aElem2 ){ rc = SQLITE_NOMEM; nElem = 0; @@ -193139,11 +186929,11 @@ ** p->nNodeSize bytes, but since this scenario only comes about when ** the database contain two terms that share a prefix of almost 2KB, ** this is not expected to be a serious problem. */ assert( pTree->aData==(char *)&pTree[1] ); - pTree->aData = (char *)sqlite3_malloc64(nReq); + pTree->aData = (char *)sqlite3_malloc(nReq); if( !pTree->aData ){ return SQLITE_NOMEM; } } @@ -193157,11 +186947,11 @@ pTree->nData = nData + nSuffix; pTree->nEntry++; if( isCopyTerm ){ if( pTree->nMalloczMalloc, (i64)nTerm*2); + char *zNew = sqlite3_realloc(pTree->zMalloc, nTerm*2); if( !zNew ){ return SQLITE_NOMEM; } pTree->nMalloc = nTerm*2; pTree->zMalloc = zNew; @@ -193183,11 +186973,11 @@ ** ** Otherwise, the term is not added to the new node, it is left empty for ** now. Instead, the term is inserted into the parent of pTree. If pTree ** has no parent, one is created here. */ - pNew = (SegmentNode *)sqlite3_malloc64(sizeof(SegmentNode) + p->nNodeSize); + pNew = (SegmentNode *)sqlite3_malloc(sizeof(SegmentNode) + p->nNodeSize); if( !pNew ){ return SQLITE_NOMEM; } memset(pNew, 0, sizeof(SegmentNode)); pNew->nData = 1 + FTS3_VARINT_MAX; @@ -193321,26 +187111,26 @@ const char *aDoclist, /* Pointer to buffer containing doclist */ int nDoclist /* Size of doclist in bytes */ ){ int nPrefix; /* Size of term prefix in bytes */ int nSuffix; /* Size of term suffix in bytes */ - i64 nReq; /* Number of bytes required on leaf page */ + int nReq; /* Number of bytes required on leaf page */ int nData; SegmentWriter *pWriter = *ppWriter; if( !pWriter ){ int rc; sqlite3_stmt *pStmt; /* Allocate the SegmentWriter structure */ - pWriter = (SegmentWriter *)sqlite3_malloc64(sizeof(SegmentWriter)); + pWriter = (SegmentWriter *)sqlite3_malloc(sizeof(SegmentWriter)); if( !pWriter ) return SQLITE_NOMEM; memset(pWriter, 0, sizeof(SegmentWriter)); *ppWriter = pWriter; /* Allocate a buffer in which to accumulate data */ - pWriter->aData = (char *)sqlite3_malloc64(p->nNodeSize); + pWriter->aData = (char *)sqlite3_malloc(p->nNodeSize); if( !pWriter->aData ) return SQLITE_NOMEM; pWriter->nSize = p->nNodeSize; /* Find the next free blockid in the %_segments table */ rc = fts3SqlStmt(p, SQL_NEXT_SEGMENTS_ID, &pStmt, 0); @@ -193411,11 +187201,11 @@ /* If the buffer currently allocated is too small for this entry, realloc ** the buffer to make it large enough. */ if( nReq>pWriter->nSize ){ - char *aNew = sqlite3_realloc64(pWriter->aData, nReq); + char *aNew = sqlite3_realloc(pWriter->aData, nReq); if( !aNew ) return SQLITE_NOMEM; pWriter->aData = aNew; pWriter->nSize = nReq; } assert( nData+nReq<=pWriter->nSize ); @@ -193436,11 +187226,11 @@ ** zTerm is transient, so take a copy of the term data. Otherwise, just ** store a copy of the pointer. */ if( isCopyTerm ){ if( nTerm>pWriter->nMalloc ){ - char *zNew = sqlite3_realloc64(pWriter->zMalloc, (i64)nTerm*2); + char *zNew = sqlite3_realloc(pWriter->zMalloc, nTerm*2); if( !zNew ){ return SQLITE_NOMEM; } pWriter->nMalloc = nTerm*2; pWriter->zMalloc = zNew; @@ -193744,24 +187534,22 @@ ** trying to resize the buffer, return SQLITE_NOMEM. */ static int fts3MsrBufferData( Fts3MultiSegReader *pMsr, /* Multi-segment-reader handle */ char *pList, - i64 nList + int nList ){ - if( (nList+FTS3_NODE_PADDING)>pMsr->nBuffer ){ + if( nList>pMsr->nBuffer ){ char *pNew; - int nNew = nList*2 + FTS3_NODE_PADDING; - pNew = (char *)sqlite3_realloc64(pMsr->aBuffer, nNew); + pMsr->nBuffer = nList*2; + pNew = (char *)sqlite3_realloc(pMsr->aBuffer, pMsr->nBuffer); if( !pNew ) return SQLITE_NOMEM; pMsr->aBuffer = pNew; - pMsr->nBuffer = nNew; } assert( nList>0 ); memcpy(pMsr->aBuffer, pList, nList); - memset(&pMsr->aBuffer[nList], 0, FTS3_NODE_PADDING); return SQLITE_OK; } SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext( Fts3Table *p, /* Virtual table handle */ @@ -193807,11 +187595,11 @@ } if( rc!=SQLITE_OK ) return rc; fts3SegReaderSort(pMsr->apSegment, nMerge, j, xCmp); if( nList>0 && fts3SegReaderIsPending(apSegment[0]) ){ - rc = fts3MsrBufferData(pMsr, pList, (i64)nList+1); + rc = fts3MsrBufferData(pMsr, pList, nList+1); if( rc!=SQLITE_OK ) return rc; assert( (pMsr->aBuffer[nList] & 0xFE)==0x00 ); pList = pMsr->aBuffer; } @@ -193944,15 +187732,15 @@ } return SQLITE_OK; } -static int fts3GrowSegReaderBuffer(Fts3MultiSegReader *pCsr, i64 nReq){ +static int fts3GrowSegReaderBuffer(Fts3MultiSegReader *pCsr, int nReq){ if( nReq>pCsr->nBuffer ){ char *aNew; pCsr->nBuffer = nReq*2; - aNew = sqlite3_realloc64(pCsr->aBuffer, pCsr->nBuffer); + aNew = sqlite3_realloc(pCsr->aBuffer, pCsr->nBuffer); if( !aNew ){ return SQLITE_NOMEM; } pCsr->aBuffer = aNew; } @@ -194039,12 +187827,11 @@ && !isFirst && (p->bDescIdx==0 || fts3SegReaderIsPending(apSegment[0])==0) ){ pCsr->nDoclist = apSegment[0]->nDoclist; if( fts3SegReaderIsPending(apSegment[0]) ){ - rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist, - (i64)pCsr->nDoclist); + rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist, pCsr->nDoclist); pCsr->aDoclist = pCsr->aBuffer; }else{ pCsr->aDoclist = apSegment[0]->aDoclist; } if( rc==SQLITE_OK ) rc = SQLITE_ROW; @@ -194093,12 +187880,11 @@ iDelta = (i64)((u64)iDocid - (u64)iPrev); } nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0); - rc = fts3GrowSegReaderBuffer(pCsr, - (i64)nByte+nDoclist+FTS3_NODE_PADDING); + rc = fts3GrowSegReaderBuffer(pCsr, nByte+nDoclist+FTS3_NODE_PADDING); if( rc ) return rc; if( isFirst ){ char *a = &pCsr->aBuffer[nDoclist]; int nWrite; @@ -194120,11 +187906,11 @@ } fts3SegReaderSort(apSegment, nMerge, j, xCmp); } if( nDoclist>0 ){ - rc = fts3GrowSegReaderBuffer(pCsr, (i64)nDoclist+FTS3_NODE_PADDING); + rc = fts3GrowSegReaderBuffer(pCsr, nDoclist+FTS3_NODE_PADDING); if( rc ) return rc; memset(&pCsr->aBuffer[nDoclist], 0, FTS3_NODE_PADDING); pCsr->aDoclist = pCsr->aBuffer; pCsr->nDoclist = nDoclist; rc = SQLITE_ROW; @@ -194833,11 +188619,11 @@ ** to reflect the new size of the pBlob->a[] buffer. */ static void blobGrowBuffer(Blob *pBlob, int nMin, int *pRc){ if( *pRc==SQLITE_OK && nMin>pBlob->nAlloc ){ int nAlloc = nMin; - char *a = (char *)sqlite3_realloc64(pBlob->a, nAlloc); + char *a = (char *)sqlite3_realloc(pBlob->a, nAlloc); if( a ){ pBlob->nAlloc = nAlloc; pBlob->a = a; }else{ *pRc = SQLITE_NOMEM; @@ -194982,12 +188768,10 @@ if( rc==SQLITE_OK ){ if( pNode->key.n ){ pBlk->n += sqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nPrefix); } pBlk->n += sqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nSuffix); - assert( nPrefix+nSuffix<=nTerm ); - assert( nPrefix>=0 ); memcpy(&pBlk->a[pBlk->n], &zTerm[nPrefix], nSuffix); pBlk->n += nSuffix; memcpy(pNode->key.a, zTerm, nTerm); pNode->key.n = nTerm; @@ -195106,11 +188890,10 @@ NodeWriter *pLeaf; /* Object used to write leaf nodes */ pLeaf = &pWriter->aNodeWriter[0]; nPrefix = fts3PrefixCompress(pLeaf->key.a, pLeaf->key.n, zTerm, nTerm); nSuffix = nTerm - nPrefix; - if(nSuffix<=0 ) return FTS_CORRUPT_VTAB; nSpace = sqlite3Fts3VarintLen(nPrefix); nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist; @@ -195630,11 +189413,11 @@ sqlite3_bind_int64(pSelect, 1, iAbsLevel); while( SQLITE_ROW==sqlite3_step(pSelect) ){ if( nIdx>=nAlloc ){ int *aNew; nAlloc += 16; - aNew = sqlite3_realloc64(aIdx, nAlloc*sizeof(int)); + aNew = sqlite3_realloc(aIdx, nAlloc*sizeof(int)); if( !aNew ){ rc = SQLITE_NOMEM; break; } aIdx = aNew; @@ -196004,11 +189787,11 @@ Blob hint = {0, 0, 0}; /* Hint read from %_stat table */ int bDirtyHint = 0; /* True if blob 'hint' has been modified */ /* Allocate space for the cursor, filter and writer objects */ const int nAlloc = sizeof(*pCsr) + sizeof(*pFilter) + sizeof(*pWriter); - pWriter = (IncrmergeWriter *)sqlite3_malloc64(nAlloc); + pWriter = (IncrmergeWriter *)sqlite3_malloc(nAlloc); if( !pWriter ) return SQLITE_NOMEM; pFilter = (Fts3SegFilter *)&pWriter[1]; pCsr = (Fts3MultiSegReader *)&pFilter[1]; rc = fts3IncrmergeHintLoad(p, &hint); @@ -196640,11 +190423,11 @@ if( p->pList==0 ){ return SQLITE_OK; } - pRet = (char *)sqlite3_malloc64(p->pList->nData); + pRet = (char *)sqlite3_malloc(p->pList->nData); if( !pRet ) return SQLITE_NOMEM; nSkip = sqlite3Fts3GetVarint(p->pList->aData, &dummy); *pnData = p->pList->nData - nSkip; *ppData = pRet; @@ -196660,11 +190443,11 @@ Fts3Cursor *pCsr, /* Fts3 table cursor */ Fts3PhraseToken *pToken, /* Token to defer */ int iCol /* Column that token must appear in (or -1) */ ){ Fts3DeferredToken *pDeferred; - pDeferred = sqlite3_malloc64(sizeof(*pDeferred)); + pDeferred = sqlite3_malloc(sizeof(*pDeferred)); if( !pDeferred ){ return SQLITE_NOMEM; } memset(pDeferred, 0, sizeof(*pDeferred)); pDeferred->pToken = pToken; @@ -196939,11 +190722,11 @@ */ #define FTS3_MATCHINFO_DEFAULT "pcx" /* -** Used as an sqlite3Fts3ExprIterate() context when loading phrase doclists to +** Used as an fts3ExprIterate() context when loading phrase doclists to ** Fts3Expr.aDoclist[]/nDoclist. */ typedef struct LoadDoclistCtx LoadDoclistCtx; struct LoadDoclistCtx { Fts3Cursor *pCsr; /* FTS3 Cursor */ @@ -196983,11 +190766,11 @@ u64 covered; /* Mask of query phrases covered */ u64 hlmask; /* Mask of snippet terms to highlight */ }; /* -** This type is used as an sqlite3Fts3ExprIterate() context object while +** This type is used as an fts3ExprIterate() context object while ** accumulating the data returned by the matchinfo() function. */ typedef struct MatchInfo MatchInfo; struct MatchInfo { Fts3Cursor *pCursor; /* FTS3 Cursor */ @@ -197142,11 +190925,11 @@ *pp += fts3GetVarint32(*pp, &iVal); *piPos += (iVal-2); } /* -** Helper function for sqlite3Fts3ExprIterate() (see below). +** Helper function for fts3ExprIterate() (see below). */ static int fts3ExprIterate2( Fts3Expr *pExpr, /* Expression to iterate phrases of */ int *piPhrase, /* Pointer to phrase counter */ int (*x)(Fts3Expr*,int,void*), /* Callback function to invoke for phrases */ @@ -197176,22 +190959,23 @@ ** If the callback function returns anything other than SQLITE_OK, ** the iteration is abandoned and the error code returned immediately. ** Otherwise, SQLITE_OK is returned after a callback has been made for ** all eligible phrase nodes. */ -SQLITE_PRIVATE int sqlite3Fts3ExprIterate( +static int fts3ExprIterate( Fts3Expr *pExpr, /* Expression to iterate phrases of */ int (*x)(Fts3Expr*,int,void*), /* Callback function to invoke for phrases */ void *pCtx /* Second argument to pass to callback */ ){ int iPhrase = 0; /* Variable used as the phrase counter */ return fts3ExprIterate2(pExpr, &iPhrase, x, pCtx); } + /* -** This is an sqlite3Fts3ExprIterate() callback used while loading the -** doclists for each phrase into Fts3Expr.aDoclist[]/nDoclist. See also +** This is an fts3ExprIterate() callback used while loading the doclists +** for each phrase into Fts3Expr.aDoclist[]/nDoclist. See also ** fts3ExprLoadDoclists(). */ static int fts3ExprLoadDoclistsCb(Fts3Expr *pExpr, int iPhrase, void *ctx){ int rc = SQLITE_OK; Fts3Phrase *pPhrase = pExpr->pPhrase; @@ -197219,13 +191003,13 @@ Fts3Cursor *pCsr, /* Fts3 cursor for current query */ int *pnPhrase, /* OUT: Number of phrases in query */ int *pnToken /* OUT: Number of tokens in query */ ){ int rc; /* Return Code */ - LoadDoclistCtx sCtx = {0,0,0}; /* Context for sqlite3Fts3ExprIterate() */ + LoadDoclistCtx sCtx = {0,0,0}; /* Context for fts3ExprIterate() */ sCtx.pCsr = pCsr; - rc = sqlite3Fts3ExprIterate(pCsr->pExpr,fts3ExprLoadDoclistsCb,(void*)&sCtx); + rc = fts3ExprIterate(pCsr->pExpr, fts3ExprLoadDoclistsCb, (void *)&sCtx); if( pnPhrase ) *pnPhrase = sCtx.nPhrase; if( pnToken ) *pnToken = sCtx.nToken; return rc; } @@ -197234,11 +191018,11 @@ pExpr->iPhrase = iPhrase; return SQLITE_OK; } static int fts3ExprPhraseCount(Fts3Expr *pExpr){ int nPhrase = 0; - (void)sqlite3Fts3ExprIterate(pExpr, fts3ExprPhraseCountCb, (void *)&nPhrase); + (void)fts3ExprIterate(pExpr, fts3ExprPhraseCountCb, (void *)&nPhrase); return nPhrase; } /* ** Advance the position list iterator specified by the first two @@ -197362,13 +191146,12 @@ *pmCover = mCover; *pmHighlight = mHighlight; } /* -** This function is an sqlite3Fts3ExprIterate() callback used by -** fts3BestSnippet(). Each invocation populates an element of the -** SnippetIter.aPhrase[] array. +** This function is an fts3ExprIterate() callback used by fts3BestSnippet(). +** Each invocation populates an element of the SnippetIter.aPhrase[] array. */ static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){ SnippetIter *p = (SnippetIter *)ctx; SnippetPhrase *pPhrase = &p->aPhrase[iPhrase]; char *pCsr; @@ -197454,13 +191237,11 @@ sIter.pCsr = pCsr; sIter.iCol = iCol; sIter.nSnippet = nSnippet; sIter.nPhrase = nList; sIter.iCurrent = -1; - rc = sqlite3Fts3ExprIterate( - pCsr->pExpr, fts3SnippetFindPositions, (void*)&sIter - ); + rc = fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void*)&sIter); if( rc==SQLITE_OK ){ /* Set the *pmSeen output variable. */ for(i=0; ipCursor, pExpr, &p->aMatchinfo[3*iPhrase*p->nCol] ); } /* -** sqlite3Fts3ExprIterate() callback used to collect the "local" part of the +** fts3ExprIterate() callback used to collect the "local" part of the ** FTS3_MATCHINFO_HITS array. The local stats are those elements of the ** array that are different for each row returned by the query. */ static int fts3ExprLocalHitsCb( Fts3Expr *pExpr, /* Phrase expression node */ @@ -198051,11 +191832,11 @@ /* Allocate and populate the array of LcsIterator objects. The array ** contains one element for each matchable phrase in the query. **/ aIter = sqlite3Fts3MallocZero(sizeof(LcsIterator) * pCsr->nPhrase); if( !aIter ) return SQLITE_NOMEM; - (void)sqlite3Fts3ExprIterate(pCsr->pExpr, fts3MatchinfoLcsCb, (void*)aIter); + (void)fts3ExprIterate(pCsr->pExpr, fts3MatchinfoLcsCb, (void*)aIter); for(i=0; inPhrase; i++){ LcsIterator *pIter = &aIter[i]; nToken -= pIter->pExpr->pPhrase->nToken; pIter->iPosOffset = nToken; @@ -198228,15 +192009,15 @@ if( bGlobal ){ if( pCsr->pDeferred ){ rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &pInfo->nDoc,0,0); if( rc!=SQLITE_OK ) break; } - rc = sqlite3Fts3ExprIterate(pExpr, fts3ExprGlobalHitsCb,(void*)pInfo); + rc = fts3ExprIterate(pExpr, fts3ExprGlobalHitsCb,(void*)pInfo); sqlite3Fts3EvalTestDeferred(pCsr, &rc); if( rc!=SQLITE_OK ) break; } - (void)sqlite3Fts3ExprIterate(pExpr, fts3ExprLocalHitsCb,(void*)pInfo); + (void)fts3ExprIterate(pExpr, fts3ExprLocalHitsCb,(void*)pInfo); break; } } pInfo->aMatchinfo += fts3MatchinfoSize(pInfo, zArg[i]); @@ -198455,11 +192236,11 @@ sqlite3_int64 iDocid; TermOffset *aTerm; }; /* -** This function is an sqlite3Fts3ExprIterate() callback used by sqlite3Fts3Offsets(). +** This function is an fts3ExprIterate() callback used by sqlite3Fts3Offsets(). */ static int fts3ExprTermOffsetInit(Fts3Expr *pExpr, int iPhrase, void *ctx){ TermOffsetCtx *p = (TermOffsetCtx *)ctx; int nTerm; /* Number of tokens in phrase */ int iTerm; /* For looping through nTerm phrase terms */ @@ -198537,13 +192318,11 @@ /* Initialize the contents of sCtx.aTerm[] for column iCol. This ** operation may fail if the database contains corrupt records. */ sCtx.iCol = iCol; sCtx.iTerm = 0; - rc = sqlite3Fts3ExprIterate( - pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx - ); + rc = fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx); if( rc!=SQLITE_OK ) goto offsets_out; /* Retreive the text stored in column iCol. If an SQL NULL is stored ** in column iCol, jump immediately to the next iteration of the loop. ** If an OOM occurs while retrieving the data (this can happen if SQLite @@ -199749,15 +193528,12 @@ switch( sqlite3_value_type(pValue) ){ case SQLITE_NULL: { jsonAppendRaw(p, "null", 4); break; } + case SQLITE_INTEGER: case SQLITE_FLOAT: { - jsonPrintf(100, p, "%!0.15g", sqlite3_value_double(pValue)); - break; - } - case SQLITE_INTEGER: { const char *z = (const char*)sqlite3_value_text(pValue); u32 n = (u32)sqlite3_value_bytes(pValue); jsonAppendRaw(p, z, n); break; } @@ -200199,31 +193975,10 @@ int i; for(i=0; i<4; i++) if( !sqlite3Isxdigit(z[i]) ) return 0; return 1; } -#ifdef SQLITE_ENABLE_JSON_NAN_INF -/* -** Extra floating-point literals to allow in JSON. -*/ -static const struct NanInfName { - char c1; - char c2; - char n; - char eType; - char nRepl; - char *zMatch; - char *zRepl; -} aNanInfName[] = { - { 'i', 'I', 3, JSON_REAL, 7, "inf", "9.0e999" }, - { 'i', 'I', 8, JSON_REAL, 7, "infinity", "9.0e999" }, - { 'n', 'N', 3, JSON_NULL, 4, "NaN", "null" }, - { 'q', 'Q', 4, JSON_NULL, 4, "QNaN", "null" }, - { 's', 'S', 4, JSON_NULL, 4, "SNaN", "null" }, -}; -#endif /* SQLITE_ENABLE_JSON_NAN_INF */ - /* ** Parse a single JSON value which begins at pParse->zJson[i]. Return the ** index of the first character past the end of the value parsed. ** ** Return negative for a syntax error. Special cases: return -2 if the @@ -200365,28 +194120,10 @@ c = z[j+1]; } if( c<'0' || c>'9' ) return -1; continue; } -#ifdef SQLITE_ENABLE_JSON_NAN_INF - /* Non-standard JSON: Allow "-Inf" (in any case) - ** to be understood as floating point literals. */ - if( (c=='i' || c=='I') - && j==i+1 - && z[i]=='-' - && sqlite3StrNICmp(&z[j], "inf",3)==0 - ){ - if( !sqlite3Isalnum(z[j+3]) ){ - jsonParseAddNode(pParse, JSON_REAL, 8, "-9.0e999"); - return i+4; - }else if( (sqlite3StrNICmp(&z[j],"infinity",8)==0 && - !sqlite3Isalnum(z[j+8])) ){ - jsonParseAddNode(pParse, JSON_REAL, 8, "-9.0e999"); - return i+9; - } - } -#endif break; } if( z[j-1]<'0' ) return -1; jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT, j - i, &z[i]); @@ -200396,24 +194133,10 @@ }else if( c==']' ){ return -3; /* End of [...] */ }else if( c==0 ){ return 0; /* End of file */ }else{ -#ifdef SQLITE_ENABLE_JSON_NAN_INF - int k, nn; - for(k=0; keType!=JSON_OBJECT ){ return pPatch; } - assert( iTargetnNode ); + assert( iTarget>=0 && iTargetnNode ); pTarget = &pParse->aNode[iTarget]; assert( (pPatch->jnFlags & JNODE_APPEND)==0 ); if( pTarget->eType!=JSON_OBJECT ){ jsonRemoveAllNulls(pPatch); return pPatch; @@ -201971,17 +195694,10 @@ }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){ aIdx[iCol] = i; idxMask |= iMask; } } - if( pIdxInfo->nOrderBy>0 - && pIdxInfo->aOrderBy[0].iColumn<0 - && pIdxInfo->aOrderBy[0].desc==0 - ){ - pIdxInfo->orderByConsumed = 1; - } - if( (unusableMask & ~idxMask)!=0 ){ /* If there are any unusable constraints on JSON or ROOT, then reject ** this entire plan */ return SQLITE_CONSTRAINT; } @@ -202173,14 +195889,14 @@ JFUNCTION(json_parse, 1, 0, jsonParseFunc), JFUNCTION(json_test1, 1, 0, jsonTest1Func), #endif WAGGREGATE(json_group_array, 1, 0, 0, jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse, - SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC), + SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS), WAGGREGATE(json_group_object, 2, 0, 0, jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse, - SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC) + SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS) }; sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc)); #endif } @@ -202708,11 +196424,11 @@ */ static int readInt16(u8 *p){ return (p[0]<<8) + p[1]; } static void readCoord(u8 *p, RtreeCoord *pCoord){ - assert( (((sqlite3_uint64)p)&3)==0 ); /* p is always 4-byte aligned */ + assert( ((((char*)p) - (char*)0)&3)==0 ); /* p is always 4-byte aligned */ #if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 pCoord->u = _byteswap_ulong(*(u32*)p); #elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 pCoord->u = __builtin_bswap32(*(u32*)p); #elif SQLITE_BYTEORDER==4321 @@ -202762,11 +196478,11 @@ p[0] = (i>> 8)&0xFF; p[1] = (i>> 0)&0xFF; } static int writeCoord(u8 *p, RtreeCoord *pCoord){ u32 i; - assert( (((sqlite3_uint64)p)&3)==0 ); /* p is always 4-byte aligned */ + assert( ((((char*)p) - (char*)0)&3)==0 ); /* p is always 4-byte aligned */ assert( sizeof(RtreeCoord)==4 ); assert( sizeof(u32)==4 ); #if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 i = __builtin_bswap32(pCoord->u); memcpy(p, &i, 4); @@ -203490,11 +197206,11 @@ pCellData += 8 + 4*(p->iCoord&0xfe); assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE || p->op==RTREE_FALSE ); - assert( (((sqlite3_uint64)pCellData)&3)==0 ); /* 4-byte aligned */ + assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */ switch( p->op ){ case RTREE_TRUE: return; /* Always satisfied */ case RTREE_FALSE: break; /* Never satisfied */ case RTREE_EQ: RTREE_DECODE_COORD(eInt, pCellData, val); @@ -203543,11 +197259,11 @@ assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE || p->op==RTREE_FALSE ); pCellData += 8 + p->iCoord*4; - assert( (((sqlite3_uint64)pCellData)&3)==0 ); /* 4-byte aligned */ + assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */ RTREE_DECODE_COORD(eInt, pCellData, xN); switch( p->op ){ case RTREE_TRUE: return; /* Always satisfied */ case RTREE_FALSE: break; /* Never satisfied */ case RTREE_LE: if( xN <= p->u.rValue ) return; break; @@ -205442,11 +199158,11 @@ return SQLITE_LOCKED_VTAB; } rtreeReference(pRtree); assert(nData>=1); - memset(&cell, 0, sizeof(cell)); + cell.iRowid = 0; /* Used only to suppress a compiler warning */ /* Constraint handling. A write operation on an r-tree table may return ** SQLITE_CONSTRAINT for two reasons: ** ** 1. A duplicate rowid value, or @@ -206915,11 +200631,11 @@ ){ GeoPoly *p = 0; int nByte; testcase( pCtx==0 ); if( sqlite3_value_type(pVal)==SQLITE_BLOB - && (nByte = sqlite3_value_bytes(pVal))>=(int)(4+6*sizeof(GeoCoord)) + && (nByte = sqlite3_value_bytes(pVal))>=(4+6*sizeof(GeoCoord)) ){ const unsigned char *a = sqlite3_value_blob(pVal); int nVertex; if( a==0 ){ if( pCtx ) sqlite3_result_error_nomem(pCtx); @@ -206973,11 +200689,10 @@ sqlite3_context *context, int argc, sqlite3_value **argv ){ GeoPoly *p = geopolyFuncParam(context, argv[0], 0); - (void)argc; if( p ){ sqlite3_result_blob(context, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT); sqlite3_free(p); } @@ -206993,11 +200708,10 @@ sqlite3_context *context, int argc, sqlite3_value **argv ){ GeoPoly *p = geopolyFuncParam(context, argv[0], 0); - (void)argc; if( p ){ sqlite3 *db = sqlite3_context_db_handle(context); sqlite3_str *x = sqlite3_str_new(db); int i; sqlite3_str_append(x, "[", 1); @@ -207075,11 +200789,10 @@ double D = sqlite3_value_double(argv[4]); double E = sqlite3_value_double(argv[5]); double F = sqlite3_value_double(argv[6]); GeoCoord x1, y1, x0, y0; int ii; - (void)argc; if( p ){ for(ii=0; iinVertex; ii++){ x0 = GeoX(p,ii); y0 = GeoY(p,ii); x1 = (GeoCoord)(A*x0 + B*y0 + E); @@ -207126,11 +200839,10 @@ sqlite3_context *context, int argc, sqlite3_value **argv ){ GeoPoly *p = geopolyFuncParam(context, argv[0], 0); - (void)argc; if( p ){ sqlite3_result_double(context, geopolyArea(p)); sqlite3_free(p); } } @@ -207152,11 +200864,10 @@ sqlite3_context *context, int argc, sqlite3_value **argv ){ GeoPoly *p = geopolyFuncParam(context, argv[0], 0); - (void)argc; if( p ){ if( geopolyArea(p)<0.0 ){ int ii, jj; for(ii=1, jj=p->nVertex-1; ii1000 ) n = 1000; p = sqlite3_malloc64( sizeof(*p) + (n-1)*2*sizeof(GeoCoord) ); if( p==0 ){ @@ -207317,11 +201027,10 @@ sqlite3_context *context, int argc, sqlite3_value **argv ){ GeoPoly *p = geopolyBBox(context, argv[0], 0, 0); - (void)argc; if( p ){ sqlite3_result_blob(context, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT); sqlite3_free(p); } @@ -207345,11 +201054,10 @@ int argc, sqlite3_value **argv ){ RtreeCoord a[4]; int rc = SQLITE_OK; - (void)argc; (void)geopolyBBox(context, argv[0], a, &rc); if( rc==SQLITE_OK ){ GeoBBox *pBBox; pBBox = (GeoBBox*)sqlite3_aggregate_context(context, sizeof(*pBBox)); if( pBBox==0 ) return; @@ -207434,12 +201142,10 @@ double x0 = sqlite3_value_double(argv[1]); double y0 = sqlite3_value_double(argv[2]); int v = 0; int cnt = 0; int ii; - (void)argc; - if( p1==0 ) return; for(ii=0; iinVertex-1; ii++){ v = pointBeneathLine(x0,y0,GeoX(p1,ii), GeoY(p1,ii), GeoX(p1,ii+1),GeoY(p1,ii+1)); if( v==2 ) break; @@ -207475,11 +201181,10 @@ int argc, sqlite3_value **argv ){ GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0); - (void)argc; if( p1 && p2 ){ int x = geopolyOverlap(p1, p2); if( x<0 ){ sqlite3_result_error_nomem(context); }else{ @@ -207806,11 +201511,10 @@ int argc, sqlite3_value **argv ){ GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0); - (void)argc; if( p1 && p2 ){ int x = geopolyOverlap(p1, p2); if( x<0 ){ sqlite3_result_error_nomem(context); }else{ @@ -207827,16 +201531,12 @@ static void geopolyDebugFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ - (void)context; - (void)argc; #ifdef GEOPOLY_ENABLE_DEBUG geo_debug = sqlite3_value_int(argv[0]); -#else - (void)argv; #endif } /* ** This function is the implementation of both the xConnect and xCreate @@ -207860,11 +201560,10 @@ sqlite3_int64 nDb; /* Length of string argv[1] */ sqlite3_int64 nName; /* Length of string argv[2] */ sqlite3_str *pSql; char *zSql; int ii; - (void)pAux; sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); /* Allocate the sqlite3_vtab structure */ nDb = strlen(argv[1]); @@ -207977,11 +201676,10 @@ Rtree *pRtree = (Rtree *)pVtabCursor->pVtab; RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; RtreeNode *pRoot = 0; int rc = SQLITE_OK; int iCell = 0; - (void)idxStr; rtreeReference(pRtree); /* Reset the cursor to the same state as rtreeOpen() leaves it in. */ resetCursor(pCsr); @@ -208104,11 +201802,10 @@ static int geopolyBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ int ii; int iRowidTerm = -1; int iFuncTerm = -1; int idxNum = 0; - (void)tab; for(ii=0; iinConstraint; ii++){ struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii]; if( !p->usable ) continue; if( p->iColumn<0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){ @@ -208325,11 +202022,11 @@ sqlite3_bind_value(pUp, 2, aData[2]); } sqlite3_free(p); nChange = 1; } - for(jj=1; jjnAux; jj++){ nChange++; sqlite3_bind_value(pUp, jj+2, aData[jj+2]); } if( nChange ){ sqlite3_step(pUp); @@ -208351,12 +202048,10 @@ int nArg, const char *zName, void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), void **ppArg ){ - (void)pVtab; - (void)nArg; if( sqlite3_stricmp(zName, "geopoly_overlap")==0 ){ *pxFunc = geopolyOverlapFunc; *ppArg = 0; return SQLITE_INDEX_CONSTRAINT_FUNCTION; } @@ -208422,11 +202117,11 @@ void (*xFinal)(sqlite3_context*); const char *zName; } aAgg[] = { { geopolyBBoxStep, geopolyBBoxFinal, "geopoly_group_bbox" }, }; - unsigned int i; + int i; for(i=0; i naming scheme. +** tables or view named using the data_ naming scheme. ** ** Instead of the plain data_ naming scheme, RBU database tables ** may also be named data_, where is any sequence ** of zero or more numeric characters (0-9). This can be significant because ** tables within the RBU database are always processed in order sorted by @@ -209656,11 +203350,11 @@ ** are processed. This can be useful, for example, to ensure that "external ** content" FTS4 tables are updated before their underlying content tables. ** ** If the target database table is a virtual table or a table that has no ** PRIMARY KEY declaration, the data_% table must also contain a column -** named "rbu_rowid". This column is mapped to the table's implicit primary +** named "rbu_rowid". This column is mapped to the tables implicit primary ** key column - "rowid". Virtual tables for which the "rowid" column does ** not function like a primary key value cannot be updated using RBU. For ** example, if the target db contains either of the following: ** ** CREATE VIRTUAL TABLE x1 USING fts3(a, b); @@ -210088,38 +203782,10 @@ #define SQLITE_RBU_STATE_CHECKPOINT 3 #define SQLITE_RBU_STATE_DONE 4 #define SQLITE_RBU_STATE_ERROR 5 SQLITE_API int sqlite3rbu_state(sqlite3rbu *pRbu); - -/* -** As part of applying an RBU update or performing an RBU vacuum operation, -** the system must at one point move the *-oal file to the equivalent *-wal -** path. Normally, it does this by invoking POSIX function rename(2) directly. -** Except on WINCE platforms, where it uses win32 API MoveFileW(). This -** function may be used to register a callback that the RBU module will invoke -** instead of one of these APIs. -** -** If a callback is registered with an RBU handle, it invokes it instead -** of rename(2) when it needs to move a file within the file-system. The -** first argument passed to the xRename() callback is a copy of the second -** argument (pArg) passed to this function. The second is the full path -** to the file to move and the third the full path to which it should be -** moved. The callback function should return SQLITE_OK to indicate -** success. If an error occurs, it should return an SQLite error code. -** In this case the RBU operation will be abandoned and the error returned -** to the RBU user. -** -** Passing a NULL pointer in place of the xRename argument to this function -** restores the default behaviour. -*/ -SQLITE_API void sqlite3rbu_rename_handler( - sqlite3rbu *pRbu, - void *pArg, - int (*xRename)(void *pArg, const char *zOld, const char *zNew) -); - /* ** Create an RBU VFS named zName that accesses the underlying file-system ** via existing VFS zParent. Or, if the zParent parameter is passed NULL, ** then the new RBU VFS uses the default system VFS to access the file-system. @@ -210484,12 +204150,10 @@ const char *zVfsName; /* Name of automatically created rbu vfs */ rbu_file *pTargetFd; /* File handle open on target db */ int nPagePerSector; /* Pages per sector for pTargetFd */ i64 iOalSz; i64 nPhaseOneStep; - void *pRenameArg; - int (*xRename)(void*, const char*, const char*); /* The following state variables are used as part of the incremental ** checkpoint stage (eStage==RBU_STAGE_CKPT). See comments surrounding ** function rbuSetupCheckpoint() for details. */ u32 iMaxFrame; /* Largest iWalFrame value in aFrame[] */ @@ -212874,11 +206538,11 @@ if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){ sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p); if( p->zState==0 ){ const char *zFile = sqlite3_db_filename(p->dbRbu, "main"); - p->zState = rbuMPrintf(p, "file:///%s-vacuum?modeof=%s", zFile, zFile); + p->zState = rbuMPrintf(p, "file://%s-vacuum?modeof=%s", zFile, zFile); } } /* If using separate RBU and state databases, attach the state database to ** the RBU db handle now. */ @@ -213122,25 +206786,25 @@ ** * Calls to xShmLock(UNLOCK) to release the exclusive shm WRITER, ** READ0 and CHECKPOINT locks taken as part of the checkpoint are ** no-ops. These locks will not be released until the connection ** is closed. ** - ** * Attempting to xSync() the database file causes an SQLITE_NOTICE + ** * Attempting to xSync() the database file causes an SQLITE_INTERNAL ** error. ** ** As a result, unless an error (i.e. OOM or SQLITE_BUSY) occurs, the - ** checkpoint below fails with SQLITE_NOTICE, and leaves the aFrame[] + ** checkpoint below fails with SQLITE_INTERNAL, and leaves the aFrame[] ** array populated with a set of (frame -> page) mappings. Because the ** WRITER, CHECKPOINT and READ0 locks are still held, it is safe to copy ** data from the wal file into the database file according to the ** contents of aFrame[]. */ if( p->rc==SQLITE_OK ){ int rc2; p->eStage = RBU_STAGE_CAPTURE; rc2 = sqlite3_exec(p->dbMain, "PRAGMA main.wal_checkpoint=restart", 0, 0,0); - if( rc2!=SQLITE_NOTICE ) p->rc = rc2; + if( rc2!=SQLITE_INTERNAL ) p->rc = rc2; } if( p->rc==SQLITE_OK && p->nFrame>0 ){ p->eStage = RBU_STAGE_CKPT; p->nStep = (pState ? pState->nRow : 0); @@ -213182,11 +206846,11 @@ const u32 mReq = (1<mLock!=mReq ){ pRbu->rc = SQLITE_BUSY; - return SQLITE_NOTICE_RBU; + return SQLITE_INTERNAL; } pRbu->pgsz = iAmt; if( pRbu->nFrame==pRbu->nFrameAlloc ){ int nNew = (pRbu->nFrameAlloc ? pRbu->nFrameAlloc : 64) * 2; @@ -213232,28 +206896,19 @@ iOff = (i64)(pFrame->iDbPage-1) * p->pgsz; p->rc = pDb->pMethods->xWrite(pDb, p->aBuf, p->pgsz, iOff); } -/* -** This value is copied from the definition of ZIPVFS_CTRL_FILE_POINTER -** in zipvfs.h. -*/ -#define RBU_ZIPVFS_CTRL_FILE_POINTER 230439 /* ** Take an EXCLUSIVE lock on the database file. Return SQLITE_OK if ** successful, or an SQLite error code otherwise. */ static int rbuLockDatabase(sqlite3 *db){ int rc = SQLITE_OK; sqlite3_file *fd = 0; - - sqlite3_file_control(db, "main", RBU_ZIPVFS_CTRL_FILE_POINTER, &fd); - if( fd==0 ){ - sqlite3_file_control(db, "main", SQLITE_FCNTL_FILE_POINTER, &fd); - } + sqlite3_file_control(db, "main", SQLITE_FCNTL_FILE_POINTER, &fd); if( fd->pMethods ){ rc = fd->pMethods->xLock(fd, SQLITE_LOCK_SHARED); if( rc==SQLITE_OK ){ rc = fd->pMethods->xLock(fd, SQLITE_LOCK_EXCLUSIVE); @@ -213343,11 +206998,36 @@ assert( p->rc==SQLITE_OK ); p->rc = rbuLockDatabase(dbMain); } if( p->rc==SQLITE_OK ){ - p->rc = p->xRename(p->pRenameArg, zOal, zWal); +#if defined(_WIN32_WCE) + { + LPWSTR zWideOal; + LPWSTR zWideWal; + + zWideOal = rbuWinUtf8ToUnicode(zOal); + if( zWideOal ){ + zWideWal = rbuWinUtf8ToUnicode(zWal); + if( zWideWal ){ + if( MoveFileW(zWideOal, zWideWal) ){ + p->rc = SQLITE_OK; + }else{ + p->rc = SQLITE_IOERR; + } + sqlite3_free(zWideWal); + }else{ + p->rc = SQLITE_IOERR_NOMEM; + } + sqlite3_free(zWideOal); + }else{ + p->rc = SQLITE_IOERR_NOMEM; + } + } +#else + p->rc = rename(zOal, zWal) ? SQLITE_IOERR : SQLITE_OK; +#endif } if( p->rc!=SQLITE_OK || rbuIsVacuum(p) || rbuExclusiveCheckpoint(dbMain)==0 @@ -213930,12 +207610,11 @@ ** leave an error code and error message in the rbu handle. */ static void rbuDeleteOalFile(sqlite3rbu *p){ char *zOal = rbuMPrintf(p, "%s-oal", p->zTarget); if( zOal ){ - sqlite3_vfs *pVfs = 0; - sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_VFS_POINTER, &pVfs); + sqlite3_vfs *pVfs = sqlite3_vfs_find(0); assert( pVfs && p->rc==SQLITE_OK && p->zErrmsg==0 ); pVfs->xDelete(pVfs, zOal, 0); sqlite3_free(zOal); } } @@ -214083,11 +207762,10 @@ if( p ){ RbuState *pState = 0; /* Create the custom VFS. */ memset(p, 0, sizeof(sqlite3rbu)); - sqlite3rbu_rename_handler(p, 0, 0); rbuCreateVfs(p); /* Open the target, RBU and state databases */ if( p->rc==SQLITE_OK ){ char *pCsr = (char*)&p[1]; @@ -214475,58 +208153,10 @@ p->rc = rc; return rc; } -/* -** Default xRename callback for RBU. -*/ -static int xDefaultRename(void *pArg, const char *zOld, const char *zNew){ - int rc = SQLITE_OK; -#if defined(_WIN32_WCE) - { - LPWSTR zWideOld; - LPWSTR zWideNew; - - zWideOld = rbuWinUtf8ToUnicode(zOld); - if( zWideOld ){ - zWideNew = rbuWinUtf8ToUnicode(zNew); - if( zWideNew ){ - if( MoveFileW(zWideOld, zWideNew) ){ - rc = SQLITE_OK; - }else{ - rc = SQLITE_IOERR; - } - sqlite3_free(zWideNew); - }else{ - rc = SQLITE_IOERR_NOMEM; - } - sqlite3_free(zWideOld); - }else{ - rc = SQLITE_IOERR_NOMEM; - } - } -#else - rc = rename(zOld, zNew) ? SQLITE_IOERR : SQLITE_OK; -#endif - return rc; -} - -SQLITE_API void sqlite3rbu_rename_handler( - sqlite3rbu *pRbu, - void *pArg, - int (*xRename)(void *pArg, const char *zOld, const char *zNew) -){ - if( xRename ){ - pRbu->xRename = xRename; - pRbu->pRenameArg = pArg; - }else{ - pRbu->xRename = xDefaultRename; - pRbu->pRenameArg = 0; - } -} - /************************************************************************** ** Beginning of RBU VFS shim methods. The VFS shim modifies the behaviour ** of a standard VFS in the following ways: ** ** 1. Whenever the first page of a main database file is read or @@ -214579,11 +208209,11 @@ ** are recorded. Additionally, successful attempts to obtain exclusive ** xShmLock() WRITER, CHECKPOINTER and READ0 locks on the target ** database file are recorded. xShmLock() calls to unlock the same ** locks are no-ops (so that once obtained, these locks are never ** relinquished). Finally, calls to xSync() on the target database -** file fail with SQLITE_NOTICE errors. +** file fail with SQLITE_INTERNAL errors. */ static void rbuUnlockShm(rbu_file *p){ assert( p->openFlags & SQLITE_OPEN_MAIN_DB ); if( p->pRbu ){ @@ -214688,16 +208318,13 @@ sqlite3_free(p->apShm); p->apShm = 0; sqlite3_free(p->zDel); if( p->openFlags & SQLITE_OPEN_MAIN_DB ){ - const sqlite3_io_methods *pMeth = p->pReal->pMethods; rbuMainlistRemove(p); rbuUnlockShm(p); - if( pMeth->iVersion>1 && pMeth->xShmUnmap ){ - pMeth->xShmUnmap(p->pReal, 0); - } + p->pReal->pMethods->xShmUnmap(p->pReal, 0); } else if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){ rbuUpdateTempSize(p, 0); } assert( p->pMainNext==0 && p->pRbuVfs->pMain!=p ); @@ -214861,11 +208488,11 @@ */ static int rbuVfsSync(sqlite3_file *pFile, int flags){ rbu_file *p = (rbu_file *)pFile; if( p->pRbu && p->pRbu->eStage==RBU_STAGE_CAPTURE ){ if( p->openFlags & SQLITE_OPEN_MAIN_DB ){ - return SQLITE_NOTICE_RBU; + return SQLITE_INTERNAL; } return SQLITE_OK; } return p->pReal->pMethods->xSync(p->pReal, flags); } @@ -215152,29 +208779,10 @@ rbuVfsShmLock, /* xShmLock */ rbuVfsShmBarrier, /* xShmBarrier */ rbuVfsShmUnmap, /* xShmUnmap */ 0, 0 /* xFetch, xUnfetch */ }; - static sqlite3_io_methods rbuvfs_io_methods1 = { - 1, /* iVersion */ - rbuVfsClose, /* xClose */ - rbuVfsRead, /* xRead */ - rbuVfsWrite, /* xWrite */ - rbuVfsTruncate, /* xTruncate */ - rbuVfsSync, /* xSync */ - rbuVfsFileSize, /* xFileSize */ - rbuVfsLock, /* xLock */ - rbuVfsUnlock, /* xUnlock */ - rbuVfsCheckReservedLock, /* xCheckReservedLock */ - rbuVfsFileControl, /* xFileControl */ - rbuVfsSectorSize, /* xSectorSize */ - rbuVfsDeviceCharacteristics, /* xDeviceCharacteristics */ - 0, 0, 0, 0, 0, 0 - }; - - - rbu_vfs *pRbuVfs = (rbu_vfs*)pVfs; sqlite3_vfs *pRealVfs = pRbuVfs->pRealVfs; rbu_file *pFd = (rbu_file *)pFile; int rc = SQLITE_OK; const char *zOpen = zName; @@ -215225,19 +208833,14 @@ if( rc==SQLITE_OK ){ rc = pRealVfs->xOpen(pRealVfs, zOpen, pFd->pReal, oflags, pOutFlags); } if( pFd->pReal->pMethods ){ - const sqlite3_io_methods *pMeth = pFd->pReal->pMethods; /* The xOpen() operation has succeeded. Set the sqlite3_file.pMethods ** pointer and, if the file is a main database file, link it into the ** mutex protected linked list of all such files. */ - if( pMeth->iVersion<2 || pMeth->xShmLock==0 ){ - pFile->pMethods = &rbuvfs_io_methods1; - }else{ - pFile->pMethods = &rbuvfs_io_methods; - } + pFile->pMethods = &rbuvfs_io_methods; if( flags & SQLITE_OPEN_MAIN_DB ){ rbuMainlistAdd(pFd); } }else{ sqlite3_free(pFd->zDel); @@ -215666,11 +209269,10 @@ char **pzErr ){ StatTable *pTab = 0; int rc = SQLITE_OK; int iDb; - (void)pAux; if( argc>=4 ){ Token nm; sqlite3TokenInit(&nm, (char*)argv[3]); iDb = sqlite3FindDb(db, &nm); @@ -215720,11 +209322,10 @@ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ int i; int iSchema = -1; int iName = -1; int iAgg = -1; - (void)tab; /* Look for a valid schema=? constraint. If found, change the idxNum to ** 1 and request the value of that constraint be sent to xFilter. And ** lower the cost estimate to encourage the constrained version to be ** used. @@ -216246,12 +209847,10 @@ sqlite3_str *pSql; /* Query of btrees to analyze */ char *zSql; /* String value of pSql */ int iArg = 0; /* Count of argv[] parameters used so far */ int rc = SQLITE_OK; /* Result of this operation */ const char *zName = 0; /* Only provide analysis of this table */ - (void)argc; - (void)idxStr; statResetCsr(pCsr); sqlite3_finalize(pCsr->pStmt); pCsr->pStmt = 0; if( idxNum & 0x01 ){ @@ -216331,28 +209930,28 @@ if( !pCsr->isAgg ){ sqlite3_result_text(ctx, pCsr->zPagetype, -1, SQLITE_STATIC); } break; case 4: /* ncell */ - sqlite3_result_int64(ctx, pCsr->nCell); + sqlite3_result_int(ctx, pCsr->nCell); break; case 5: /* payload */ - sqlite3_result_int64(ctx, pCsr->nPayload); + sqlite3_result_int(ctx, pCsr->nPayload); break; case 6: /* unused */ - sqlite3_result_int64(ctx, pCsr->nUnused); + sqlite3_result_int(ctx, pCsr->nUnused); break; case 7: /* mx_payload */ - sqlite3_result_int64(ctx, pCsr->nMxPayload); + sqlite3_result_int(ctx, pCsr->nMxPayload); break; case 8: /* pgoffset */ if( !pCsr->isAgg ){ sqlite3_result_int64(ctx, pCsr->iOffset); } break; case 9: /* pgsize */ - sqlite3_result_int64(ctx, pCsr->szPage); + sqlite3_result_int(ctx, pCsr->szPage); break; case 10: { /* schema */ sqlite3 *db = sqlite3_context_db_handle(ctx); int iDb = pCsr->iDb; sqlite3_result_text(ctx, db->aDb[iDb].zDbSName, -1, SQLITE_STATIC); @@ -216482,17 +210081,12 @@ sqlite3_vtab **ppVtab, char **pzErr ){ DbpageTable *pTab = 0; int rc = SQLITE_OK; - (void)pAux; - (void)argc; - (void)argv; - (void)pzErr; sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY); - sqlite3_vtab_config(db, SQLITE_VTAB_USES_ALL_SCHEMAS); rc = sqlite3_declare_vtab(db, "CREATE TABLE x(pgno INTEGER PRIMARY KEY, data BLOB, schema HIDDEN)"); if( rc==SQLITE_OK ){ pTab = (DbpageTable *)sqlite3_malloc64(sizeof(DbpageTable)); if( pTab==0 ) rc = SQLITE_NOMEM_BKPT; @@ -216525,11 +210119,10 @@ ** 3 schema=?1, pgno=?2 */ static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ int i; int iPlan = 0; - (void)tab; /* If there is a schema= constraint, it must be honored. Report a ** ridiculously large estimated cost if the schema= constraint is ** unavailable */ @@ -216572,10 +210165,11 @@ && pIdxInfo->aOrderBy[0].iColumn<=0 && pIdxInfo->aOrderBy[0].desc==0 ){ pIdxInfo->orderByConsumed = 1; } + sqlite3VtabWriteAll(pIdxInfo); return SQLITE_OK; } /* ** Open a new dbpagevfs cursor. @@ -216640,12 +210234,10 @@ DbpageTable *pTab = (DbpageTable *)pCursor->pVtab; int rc; sqlite3 *db = pTab->db; Btree *pBt; - (void)idxStr; - /* Default setting is no rows of result */ pCsr->pgno = 1; pCsr->mxPgno = 0; if( idxNum & 2 ){ @@ -216656,11 +210248,11 @@ if( pCsr->iDb<0 ) return SQLITE_OK; }else{ pCsr->iDb = 0; } pBt = db->aDb[pCsr->iDb].pBt; - if( NEVER(pBt==0) ) return SQLITE_OK; + if( pBt==0 ) return SQLITE_OK; pCsr->pPager = sqlite3BtreePager(pBt); pCsr->szPage = sqlite3BtreeGetPageSize(pBt); pCsr->mxPgno = sqlite3BtreeLastPage(pBt); if( idxNum & 1 ){ assert( argc>(idxNum>>1) ); @@ -216691,31 +210283,25 @@ sqlite3_result_int(ctx, pCsr->pgno); break; } case 1: { /* data */ DbPage *pDbPage = 0; - if( pCsr->pgno==((PENDING_BYTE/pCsr->szPage)+1) ){ - /* The pending byte page. Assume it is zeroed out. Attempting to - ** request this page from the page is an SQLITE_CORRUPT error. */ - sqlite3_result_zeroblob(ctx, pCsr->szPage); - }else{ - rc = sqlite3PagerGet(pCsr->pPager, pCsr->pgno, (DbPage**)&pDbPage, 0); - if( rc==SQLITE_OK ){ - sqlite3_result_blob(ctx, sqlite3PagerGetData(pDbPage), pCsr->szPage, - SQLITE_TRANSIENT); - } - sqlite3PagerUnref(pDbPage); - } + rc = sqlite3PagerGet(pCsr->pPager, pCsr->pgno, (DbPage**)&pDbPage, 0); + if( rc==SQLITE_OK ){ + sqlite3_result_blob(ctx, sqlite3PagerGetData(pDbPage), pCsr->szPage, + SQLITE_TRANSIENT); + } + sqlite3PagerUnref(pDbPage); break; } default: { /* schema */ sqlite3 *db = sqlite3_context_db_handle(ctx); sqlite3_result_text(ctx, db->aDb[pCsr->iDb].zDbSName, -1, SQLITE_STATIC); break; } } - return rc; + return SQLITE_OK; } static int dbpageRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ DbpageCursor *pCsr = (DbpageCursor *)pCursor; *pRowid = pCsr->pgno; @@ -216737,34 +210323,31 @@ int iDb; Btree *pBt; Pager *pPager; int szPage; - (void)pRowid; if( pTab->db->flags & SQLITE_Defensive ){ zErr = "read-only"; goto update_fail; } if( argc==1 ){ zErr = "cannot delete"; goto update_fail; } pgno = sqlite3_value_int(argv[0]); - if( sqlite3_value_type(argv[0])==SQLITE_NULL - || (Pgno)sqlite3_value_int(argv[1])!=pgno - ){ + if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){ zErr = "cannot insert"; goto update_fail; } zSchema = (const char*)sqlite3_value_text(argv[4]); - iDb = ALWAYS(zSchema) ? sqlite3FindDbName(pTab->db, zSchema) : -1; - if( NEVER(iDb<0) ){ + iDb = zSchema ? sqlite3FindDbName(pTab->db, zSchema) : -1; + if( iDb<0 ){ zErr = "no such schema"; goto update_fail; } pBt = pTab->db->aDb[iDb].pBt; - if( NEVER(pgno<1) || NEVER(pBt==0) || NEVER(pgno>sqlite3BtreeLastPage(pBt)) ){ + if( pgno<1 || pBt==0 || pgno>(int)sqlite3BtreeLastPage(pBt) ){ zErr = "bad page number"; goto update_fail; } szPage = sqlite3BtreeGetPageSize(pBt); if( sqlite3_value_type(argv[3])!=SQLITE_BLOB @@ -216774,16 +210357,15 @@ goto update_fail; } pPager = sqlite3BtreePager(pBt); rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0); if( rc==SQLITE_OK ){ - const void *pData = sqlite3_value_blob(argv[3]); - assert( pData!=0 || pTab->db->mallocFailed ); - if( pData - && (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK - ){ - memcpy(sqlite3PagerGetData(pDbPage), pData, szPage); + rc = sqlite3PagerWrite(pDbPage); + if( rc==SQLITE_OK ){ + memcpy(sqlite3PagerGetData(pDbPage), + sqlite3_value_blob(argv[3]), + szPage); } } sqlite3PagerUnref(pDbPage); return rc; @@ -216801,11 +210383,11 @@ DbpageTable *pTab = (DbpageTable *)pVtab; sqlite3 *db = pTab->db; int i; for(i=0; inDb; i++){ Btree *pBt = db->aDb[i].pBt; - if( pBt ) (void)sqlite3BtreeBeginTrans(pBt, 1, 0); + if( pBt ) sqlite3BtreeBeginTrans(pBt, 1, 0); } return SQLITE_OK; } @@ -218346,12 +211928,10 @@ ){ sqlite3_session *pSession; int nDb = sqlite3Strlen30(zDb); assert( sqlite3_mutex_held(db->mutex) ); - (void)iKey1; - (void)iKey2; for(pSession=(sqlite3_session *)pCtx; pSession; pSession=pSession->pNext){ SessionTable *pTab; /* If this session is attached to a different database ("main", "temp" @@ -218424,11 +212004,10 @@ static int sessionDiffCount(void *pCtx){ SessionDiffCtx *p = (SessionDiffCtx*)pCtx; return p->nOldOff ? p->nOldOff : sqlite3_column_count(p->pStmt); } static int sessionDiffDepth(void *pCtx){ - (void)pCtx; return 0; } /* ** Install the diff hooks on the session object passed as the only @@ -218498,10 +212077,11 @@ return zRet; } static char *sessionSelectFindNew( + int nCol, const char *zDb1, /* Pick rows in this db only */ const char *zDb2, /* But not in this one */ const char *zTbl, /* Table name */ const char *zExpr ){ @@ -218521,11 +212101,11 @@ const char *zDb1, const char *zDb2, char *zExpr ){ int rc = SQLITE_OK; - char *zStmt = sessionSelectFindNew(zDb1, zDb2, pTab->zName,zExpr); + char *zStmt = sessionSelectFindNew(pTab->nCol, zDb1, zDb2, pTab->zName,zExpr); if( zStmt==0 ){ rc = SQLITE_NOMEM; }else{ sqlite3_stmt *pStmt; @@ -218960,14 +212540,13 @@ SessionBuffer *p, const char *zStr, int *pRc ){ int nStr = sqlite3Strlen30(zStr); - if( 0==sessionBufferGrow(p, nStr+1, pRc) ){ + if( 0==sessionBufferGrow(p, nStr, pRc) ){ memcpy(&p->aBuf[p->nBuf], zStr, nStr); p->nBuf += nStr; - p->aBuf[p->nBuf] = 0x00; } } /* ** This function is a no-op if *pRc is other than SQLITE_OK when it is @@ -218985,31 +212564,10 @@ char aBuf[24]; sqlite3_snprintf(sizeof(aBuf)-1, aBuf, "%d", iVal); sessionAppendStr(p, aBuf, pRc); } -static void sessionAppendPrintf( - SessionBuffer *p, /* Buffer to append to */ - int *pRc, - const char *zFmt, - ... -){ - if( *pRc==SQLITE_OK ){ - char *zApp = 0; - va_list ap; - va_start(ap, zFmt); - zApp = sqlite3_vmprintf(zFmt, ap); - if( zApp==0 ){ - *pRc = SQLITE_NOMEM; - }else{ - sessionAppendStr(p, zApp, pRc); - } - va_end(ap); - sqlite3_free(zApp); - } -} - /* ** This function is a no-op if *pRc is other than SQLITE_OK when it is ** called. Otherwise, append the string zStr enclosed in quotes (") and ** with any embedded quote characters escaped to the buffer. No ** nul-terminator byte is written. @@ -219020,11 +212578,11 @@ static void sessionAppendIdent( SessionBuffer *p, /* Buffer to a append to */ const char *zStr, /* String to quote, escape and append */ int *pRc /* IN/OUT: Error code */ ){ - int nStr = sqlite3Strlen30(zStr)*2 + 2 + 2; + int nStr = sqlite3Strlen30(zStr)*2 + 2 + 1; if( 0==sessionBufferGrow(p, nStr, pRc) ){ char *zOut = (char *)&p->aBuf[p->nBuf]; const char *zIn = zStr; *zOut++ = '"'; while( *zIn ){ @@ -219031,11 +212589,10 @@ if( *zIn=='"' ) *zOut++ = '"'; *zOut++ = *(zIn++); } *zOut++ = '"'; p->nBuf = (int)((u8 *)zOut - p->aBuf); - p->aBuf[p->nBuf] = 0x00; } } /* ** This function is a no-op if *pRc is other than SQLITE_OK when it is @@ -219256,82 +212813,33 @@ /* ** Formulate and prepare a SELECT statement to retrieve a row from table ** zTab in database zDb based on its primary key. i.e. ** -** SELECT *, FROM zDb.zTab WHERE (pk1, pk2,...) IS (?1, ?2,...) -** -** where is: -** -** 1 AND (?A OR ?1 IS ) AND ... -** -** for each non-pk . +** SELECT * FROM zDb.zTab WHERE pk1 = ? AND pk2 = ? AND ... */ static int sessionSelectStmt( sqlite3 *db, /* Database handle */ - int bIgnoreNoop, const char *zDb, /* Database name */ const char *zTab, /* Table name */ int nCol, /* Number of columns in table */ const char **azCol, /* Names of table columns */ u8 *abPK, /* PRIMARY KEY array */ sqlite3_stmt **ppStmt /* OUT: Prepared SELECT statement */ ){ int rc = SQLITE_OK; char *zSql = 0; - const char *zSep = ""; - const char *zCols = "*"; int nSql = -1; - int i; - - SessionBuffer nooptest = {0, 0, 0}; - SessionBuffer pkfield = {0, 0, 0}; - SessionBuffer pkvar = {0, 0, 0}; - - sessionAppendStr(&nooptest, ", 1", &rc); - - if( 0==sqlite3_stricmp("sqlite_stat1", zTab) ){ - sessionAppendStr(&nooptest, " AND (?6 OR ?3 IS stat)", &rc); - sessionAppendStr(&pkfield, "tbl, idx", &rc); - sessionAppendStr(&pkvar, - "?1, (CASE WHEN ?2=X'' THEN NULL ELSE ?2 END)", &rc - ); - zCols = "tbl, ?2, stat"; - }else{ - for(i=0; izDb, zName, nCol, azCol, abPK, &pSel - ); + db, pSession->zDb, zName, nCol, azCol, abPK, &pSel); } nNoop = buf.nBuf; for(i=0; inChange && rc==SQLITE_OK; i++){ SessionChange *p; /* Used to iterate through changes */ @@ -220253,26 +213756,10 @@ } }else if( p->bInvert ){ if( p->op==SQLITE_INSERT ) p->op = SQLITE_DELETE; else if( p->op==SQLITE_DELETE ) p->op = SQLITE_INSERT; } - - /* If this is an UPDATE that is part of a changeset, then check that - ** there are no fields in the old.* record that are not (a) PK fields, - ** or (b) also present in the new.* record. - ** - ** Such records are technically corrupt, but the rebaser was at one - ** point generating them. Under most circumstances this is benign, but - ** can cause spurious SQLITE_RANGE errors when applying the changeset. */ - if( p->bPatchset==0 && p->op==SQLITE_UPDATE){ - for(i=0; inCol; i++){ - if( p->abPK[i]==0 && p->apValue[i+p->nCol]==0 ){ - sqlite3ValueFree(p->apValue[i]); - p->apValue[i] = 0; - } - } - } } return SQLITE_ROW; } @@ -220706,11 +214193,10 @@ int bInvertConstraints; /* Invert when iterating constraints buffer */ SessionBuffer constraints; /* Deferred constraints are stored here */ SessionBuffer rebase; /* Rebase information (if any) here */ u8 bRebaseStarted; /* If table header is already in rebase */ u8 bRebase; /* True to collect rebase information */ - u8 bIgnoreNoop; /* True to ignore no-op conflicts */ }; /* Number of prepared UPDATE statements to cache. */ #define SESSION_UPDATE_CACHE_SZ 12 @@ -220957,13 +214443,12 @@ static int sessionSelectRow( sqlite3 *db, /* Database handle */ const char *zTab, /* Table name */ SessionApplyCtx *p /* Session changeset-apply context */ ){ - return sessionSelectStmt(db, p->bIgnoreNoop, - "main", zTab, p->nCol, p->azCol, p->abPK, &p->pSelect - ); + return sessionSelectStmt( + db, "main", zTab, p->nCol, p->azCol, p->abPK, &p->pSelect); } /* ** Formulate and prepare an INSERT statement to add a record to table zTab. ** For example: @@ -221117,38 +214602,26 @@ ** If the iterator currently points to an INSERT record, bind values from the ** new.* record to the SELECT statement. Or, if it points to a DELETE or ** UPDATE, bind values from the old.* record. */ static int sessionSeekToRow( + sqlite3 *db, /* Database handle */ sqlite3_changeset_iter *pIter, /* Changeset iterator */ - SessionApplyCtx *p + u8 *abPK, /* Primary key flags array */ + sqlite3_stmt *pSelect /* SELECT statement from sessionSelectRow() */ ){ - sqlite3_stmt *pSelect = p->pSelect; int rc; /* Return code */ int nCol; /* Number of columns in table */ int op; /* Changset operation (SQLITE_UPDATE etc.) */ const char *zDummy; /* Unused */ - sqlite3_clear_bindings(pSelect); sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0); rc = sessionBindRow(pIter, op==SQLITE_INSERT ? sqlite3changeset_new : sqlite3changeset_old, - nCol, p->abPK, pSelect + nCol, abPK, pSelect ); - if( op!=SQLITE_DELETE && p->bIgnoreNoop ){ - int ii; - for(ii=0; rc==SQLITE_OK && iiabPK[ii]==0 ){ - sqlite3_value *pVal = 0; - sqlite3changeset_new(pIter, ii, &pVal); - sqlite3_bind_int(pSelect, ii+1+nCol, (pVal==0)); - if( pVal ) rc = sessionBindValue(pSelect, ii+1, pVal); - } - } - } - if( rc==SQLITE_OK ){ rc = sqlite3_step(pSelect); if( rc!=SQLITE_ROW ) rc = sqlite3_reset(pSelect); } @@ -221259,26 +214732,20 @@ assert( SQLITE_CHANGESET_CONFLICT+1==SQLITE_CHANGESET_CONSTRAINT ); assert( SQLITE_CHANGESET_DATA+1==SQLITE_CHANGESET_NOTFOUND ); /* Bind the new.* PRIMARY KEY values to the SELECT statement. */ if( pbReplace ){ - rc = sessionSeekToRow(pIter, p); + rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect); }else{ rc = SQLITE_OK; } if( rc==SQLITE_ROW ){ /* There exists another row with the new.* primary key. */ - if( p->bIgnoreNoop - && sqlite3_column_int(p->pSelect, sqlite3_column_count(p->pSelect)-1) - ){ - res = SQLITE_CHANGESET_OMIT; - }else{ - pIter->pConflict = p->pSelect; - res = xConflict(pCtx, eType, pIter); - pIter->pConflict = 0; - } + pIter->pConflict = p->pSelect; + res = xConflict(pCtx, eType, pIter); + pIter->pConflict = 0; rc = sqlite3_reset(p->pSelect); }else if( rc==SQLITE_OK ){ if( p->bDeferConstraints && eType==SQLITE_CHANGESET_CONFLICT ){ /* Instead of invoking the conflict handler, append the change blob ** to the SessionApplyCtx.constraints buffer. */ @@ -221382,11 +214849,11 @@ } if( rc!=SQLITE_OK ) return rc; sqlite3_step(p->pDelete); rc = sqlite3_reset(p->pDelete); - if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 && p->bIgnoreNoop==0 ){ + if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 ){ rc = sessionConflictHandler( SQLITE_CHANGESET_DATA, p, pIter, xConflict, pCtx, pbRetry ); }else if( (rc&0xff)==SQLITE_CONSTRAINT ){ rc = sessionConflictHandler( @@ -221439,11 +214906,11 @@ assert( op==SQLITE_INSERT ); if( p->bStat1 ){ /* Check if there is a conflicting row. For sqlite_stat1, this needs ** to be done using a SELECT, as there is no PRIMARY KEY in the ** database schema to throw an exception if a duplicate is inserted. */ - rc = sessionSeekToRow(pIter, p); + rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect); if( rc==SQLITE_ROW ){ rc = SQLITE_CONSTRAINT; sqlite3_reset(p->pSelect); } } @@ -221616,11 +215083,10 @@ pIter->in.bNoDiscard = 1; memset(&sApply, 0, sizeof(sApply)); sApply.bRebase = (ppRebase && pnRebase); sApply.bInvertConstraints = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); - sApply.bIgnoreNoop = !!(flags & SQLITE_CHANGESETAPPLY_IGNORENOOP); sqlite3_mutex_enter(sqlite3_db_mutex(db)); if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); } if( rc==SQLITE_OK ){ @@ -222486,11 +215952,11 @@ int n2 = sessionSerialLen(a2); if( pIter->abPK[i] || a2[0]==0 ){ if( !pIter->abPK[i] && a1[0] ) bData = 1; memcpy(pOut, a1, n1); pOut += n1; - }else if( a2[0]!=0xFF && a1[0] ){ + }else if( a2[0]!=0xFF ){ bData = 1; memcpy(pOut, a2, n2); pOut += n2; }else{ *pOut++ = '\0'; @@ -223556,34 +217022,29 @@ fts5_tokenizer *pTokApi; int bLock; /* True when table is preparing statement */ int ePattern; /* FTS_PATTERN_XXX constant */ /* Values loaded from the %_config table */ - int iVersion; /* fts5 file format 'version' */ int iCookie; /* Incremented when %_config is modified */ int pgsz; /* Approximate page size used in %_data */ int nAutomerge; /* 'automerge' setting */ int nCrisisMerge; /* Maximum allowed segments per level */ int nUsermerge; /* 'usermerge' setting */ int nHashSize; /* Bytes of memory for in-memory hash */ char *zRank; /* Name of rank function */ char *zRankArgs; /* Arguments to rank function */ - int bSecureDelete; /* 'secure-delete' */ /* If non-NULL, points to sqlite3_vtab.base.zErrmsg. Often NULL. */ char **pzErrmsg; #ifdef SQLITE_DEBUG int bPrefixIndex; /* True to use prefix-indexes */ #endif }; -/* Current expected value of %_config table 'version' field. And -** the expected version if the 'secure-delete' option has ever been -** set on the table. */ -#define FTS5_CURRENT_VERSION 4 -#define FTS5_CURRENT_VERSION_SECUREDELETE 5 +/* Current expected value of %_config table 'version' field */ +#define FTS5_CURRENT_VERSION 4 #define FTS5_CONTENT_NORMAL 0 #define FTS5_CONTENT_NONE 1 #define FTS5_CONTENT_EXTERNAL 2 @@ -223648,11 +217109,11 @@ static void sqlite3Fts5BufferAppendPrintf(int *, Fts5Buffer*, char *zFmt, ...); static char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...); #define fts5BufferZero(x) sqlite3Fts5BufferZero(x) -#define fts5BufferAppendVarint(a,b,c) sqlite3Fts5BufferAppendVarint(a,b,(i64)c) +#define fts5BufferAppendVarint(a,b,c) sqlite3Fts5BufferAppendVarint(a,b,c) #define fts5BufferFree(a) sqlite3Fts5BufferFree(a) #define fts5BufferAppendBlob(a,b,c,d) sqlite3Fts5BufferAppendBlob(a,b,c,d) #define fts5BufferSet(a,b,c,d) sqlite3Fts5BufferSet(a,b,c,d) #define fts5BufferGrow(pRc,pBuf,nn) ( \ @@ -223745,11 +217206,10 @@ /* The following are used internally by the fts5_index.c module. They are ** defined here only to make it easier to avoid clashes with the flags ** above. */ #define FTS5INDEX_QUERY_SKIPEMPTY 0x0010 #define FTS5INDEX_QUERY_NOOUTPUT 0x0020 -#define FTS5INDEX_QUERY_SKIPHASH 0x0040 /* ** Create/destroy an Fts5Index object. */ static int sqlite3Fts5IndexOpen(Fts5Config *pConfig, int bCreate, Fts5Index**, char**); @@ -225879,11 +219339,11 @@ UNUSED_PARAM2(pToken, nToken); if( tflags & FTS5_TOKEN_COLOCATED ) return SQLITE_OK; iPos = p->iPos++; - if( p->iRangeEnd>=0 ){ + if( p->iRangeEnd>0 ){ if( iPosiRangeStart || iPos>p->iRangeEnd ) return SQLITE_OK; if( p->iRangeStart && iPos==p->iRangeStart ) p->iOff = iStartOff; } if( iPos==p->iter.iStart ){ @@ -225891,11 +219351,11 @@ fts5HighlightAppend(&rc, p, p->zOpen, -1); p->iOff = iStartOff; } if( iPos==p->iter.iEnd ){ - if( p->iRangeEnd>=0 && p->iter.iStartiRangeStart ){ + if( p->iRangeEnd && p->iter.iStartiRangeStart ){ fts5HighlightAppend(&rc, p, p->zOpen, -1); } fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff); fts5HighlightAppend(&rc, p, p->zClose, -1); p->iOff = iEndOff; @@ -225902,11 +219362,11 @@ if( rc==SQLITE_OK ){ rc = fts5CInstIterNext(&p->iter); } } - if( p->iRangeEnd>=0 && iPos==p->iRangeEnd ){ + if( p->iRangeEnd>0 && iPos==p->iRangeEnd ){ fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff); p->iOff = iEndOff; if( iPos>=p->iter.iStart && iPositer.iEnd ){ fts5HighlightAppend(&rc, p, p->zClose, -1); } @@ -225937,11 +219397,10 @@ iCol = sqlite3_value_int(apVal[0]); memset(&ctx, 0, sizeof(HighlightContext)); ctx.zOpen = (const char*)sqlite3_value_text(apVal[1]); ctx.zClose = (const char*)sqlite3_value_text(apVal[2]); - ctx.iRangeEnd = -1; rc = pApi->xColumnText(pFts, iCol, &ctx.zIn, &ctx.nIn); if( ctx.zIn ){ if( rc==SQLITE_OK ){ rc = fts5CInstIterInit(pApi, pFts, iCol, &ctx.iter); @@ -226123,11 +219582,10 @@ nCol = pApi->xColumnCount(pFts); memset(&ctx, 0, sizeof(HighlightContext)); iCol = sqlite3_value_int(apVal[0]); ctx.zOpen = fts5ValueToText(apVal[1]); ctx.zClose = fts5ValueToText(apVal[2]); - ctx.iRangeEnd = -1; zEllips = fts5ValueToText(apVal[3]); nToken = sqlite3_value_int(apVal[4]); iBestCol = (iCol>=0 ? iCol : 0); nPhrase = pApi->xPhraseCount(pFts); @@ -227745,22 +221203,10 @@ pConfig->zRankArgs = zRankArgs; }else if( rc==SQLITE_ERROR ){ rc = SQLITE_OK; *pbBadkey = 1; } - } - - else if( 0==sqlite3_stricmp(zKey, "secure-delete") ){ - int bVal = -1; - if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){ - bVal = sqlite3_value_int(pVal); - } - if( bVal<0 ){ - *pbBadkey = 1; - }else{ - pConfig->bSecureDelete = (bVal ? 1 : 0); - } }else{ *pbBadkey = 1; } return rc; } @@ -227801,24 +221247,19 @@ } } rc = sqlite3_finalize(p); } - if( rc==SQLITE_OK - && iVersion!=FTS5_CURRENT_VERSION - && iVersion!=FTS5_CURRENT_VERSION_SECUREDELETE - ){ + if( rc==SQLITE_OK && iVersion!=FTS5_CURRENT_VERSION ){ rc = SQLITE_ERROR; if( pConfig->pzErrmsg ){ assert( 0==*pConfig->pzErrmsg ); - *pConfig->pzErrmsg = sqlite3_mprintf("invalid fts5 file format " - "(found %d, expected %d or %d) - run 'rebuild'", - iVersion, FTS5_CURRENT_VERSION, FTS5_CURRENT_VERSION_SECUREDELETE + *pConfig->pzErrmsg = sqlite3_mprintf( + "invalid fts5 file format (found %d, expected %d) - run 'rebuild'", + iVersion, FTS5_CURRENT_VERSION ); } - }else{ - pConfig->iVersion = iVersion; } if( rc==SQLITE_OK ){ pConfig->iCookie = iCookie; } @@ -228114,23 +221555,10 @@ sqlite3_free(sParse.apPhrase); *pzErr = sParse.zErr; return sParse.rc; } -/* -** Assuming that buffer z is at least nByte bytes in size and contains a -** valid utf-8 string, return the number of characters in the string. -*/ -static int fts5ExprCountChar(const char *z, int nByte){ - int nRet = 0; - int ii; - for(ii=0; ii=3 ){ + if( i-iFirst>=3 ){ int jj; zExpr[iOut++] = '"'; for(jj=iFirst; jjnPhrase>0 ){ Fts5ExprPhrase *pLast = pRet->apPhrase[pRet->nPhrase-1]; - assert( pParse!=0 ); - assert( pParse->apPhrase!=0 ); - assert( pParse->nPhrase>=2 ); assert( pLast==pParse->apPhrase[pParse->nPhrase-2] ); if( pPhrase->nTerm==0 ){ fts5ExprPhraseFree(pPhrase); pRet->nPhrase--; pParse->nPhrase--; @@ -231526,12 +224950,10 @@ #if FTS5_MAX_PREFIX_INDEXES > 31 # error "FTS5_MAX_PREFIX_INDEXES is too large" #endif -#define FTS5_MAX_LEVEL 64 - /* ** Details: ** ** The %_data table managed by this module, ** @@ -231770,16 +225192,14 @@ /* State used by the fts5DataXXX() functions. */ sqlite3_blob *pReader; /* RO incr-blob open on %_data table */ sqlite3_stmt *pWriter; /* "INSERT ... %_data VALUES(?,?)" */ sqlite3_stmt *pDeleter; /* "DELETE FROM %_data ... id>=? AND id<=?" */ sqlite3_stmt *pIdxWriter; /* "INSERT ... %_idx VALUES(?,?,?,?)" */ - sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=?" */ + sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=? */ sqlite3_stmt *pIdxSelect; int nRead; /* Total number of blocks read */ - sqlite3_stmt *pDeleteFromIdx; - sqlite3_stmt *pDataVersion; i64 iStructVersion; /* data_version when pStruct read */ Fts5Structure *pStruct; /* Current db structure (or NULL) */ }; @@ -231868,10 +225288,13 @@ ** Current leaf page number within segment. ** ** iLeafOffset: ** Byte offset within the current leaf that is the first byte of the ** position list data (one byte passed the position-list size field). +** rowid field of the current entry. Usually this is the size field of the +** position list data. The exception is if the rowid for the current entry +** is the last thing on the leaf page. ** ** pLeaf: ** Buffer containing current leaf page data. Set to NULL at EOF. ** ** iTermLeafPgno, iTermLeafOffset: @@ -232914,29 +226337,46 @@ assert( pLvl->bEof==0 ); if( iOff<=pLvl->iFirstOff ){ pLvl->bEof = 1; }else{ u8 *a = pLvl->pData->p; - - pLvl->iOff = 0; - fts5DlidxLvlNext(pLvl); - while( 1 ){ - int nZero = 0; - int ii = pLvl->iOff; - u64 delta = 0; - - while( a[ii]==0 ){ - nZero++; - ii++; - } - ii += sqlite3Fts5GetVarint(&a[ii], &delta); - - if( ii>=iOff ) break; - pLvl->iLeafPgno += nZero+1; - pLvl->iRowid += delta; - pLvl->iOff = ii; - } + i64 iVal; + int iLimit; + int ii; + int nZero = 0; + + /* Currently iOff points to the first byte of a varint. This block + ** decrements iOff until it points to the first byte of the previous + ** varint. Taking care not to read any memory locations that occur + ** before the buffer in memory. */ + iLimit = (iOff>9 ? iOff-9 : 0); + for(iOff--; iOff>iLimit; iOff--){ + if( (a[iOff-1] & 0x80)==0 ) break; + } + + fts5GetVarint(&a[iOff], (u64*)&iVal); + pLvl->iRowid -= iVal; + pLvl->iLeafPgno--; + + /* Skip backwards past any 0x00 varints. */ + for(ii=iOff-1; ii>=pLvl->iFirstOff && a[ii]==0x00; ii--){ + nZero++; + } + if( ii>=pLvl->iFirstOff && (a[ii] & 0x80) ){ + /* The byte immediately before the last 0x00 byte has the 0x80 bit + ** set. So the last 0x00 is only a varint 0 if there are 8 more 0x80 + ** bytes before a[ii]. */ + int bZero = 0; /* True if last 0x00 counts */ + if( (ii-8)>=pLvl->iFirstOff ){ + int j; + for(j=1; j<=8 && (a[ii-j] & 0x80); j++); + bZero = (j>8); + } + if( bZero==0 ) nZero--; + } + pLvl->iLeafPgno -= nZero; + pLvl->iOff = iOff - nZero; } return pLvl->bEof; } @@ -233128,11 +226568,11 @@ static void fts5SegIterLoadRowid(Fts5Index *p, Fts5SegIter *pIter){ u8 *a = pIter->pLeaf->p; /* Buffer to read data from */ i64 iOff = pIter->iLeafOffset; ASSERT_SZLEAF_OK(pIter->pLeaf); - while( iOff>=pIter->pLeaf->szLeaf ){ + if( iOff>=pIter->pLeaf->szLeaf ){ fts5SegIterNextPage(p, pIter); if( pIter->pLeaf==0 ){ if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT; return; } @@ -233227,16 +226667,14 @@ if( p->rc==SQLITE_OK ){ memset(pIter, 0, sizeof(*pIter)); fts5SegIterSetNext(p, pIter); pIter->pSeg = pSeg; pIter->iLeafPgno = pSeg->pgnoFirst-1; - do { - fts5SegIterNextPage(p, pIter); - }while( p->rc==SQLITE_OK && pIter->pLeaf && pIter->pLeaf->nn==4 ); + fts5SegIterNextPage(p, pIter); } - if( p->rc==SQLITE_OK && pIter->pLeaf ){ + if( p->rc==SQLITE_OK ){ pIter->iLeafOffset = 4; assert( pIter->pLeaf!=0 ); assert_nc( pIter->pLeaf->nn>4 ); assert_nc( fts5LeafFirstTermOff(pIter->pLeaf)==4 ); pIter->iPgidxOff = pIter->pLeaf->szLeaf+1; @@ -233426,11 +226864,11 @@ ASSERT_SZLEAF_OK(pIter->pLeaf); iOff = pIter->iLeafOffset; /* Next entry is on the next page */ - while( pIter->pSeg && iOff>=pIter->pLeaf->szLeaf ){ + if( pIter->pSeg && iOff>=pIter->pLeaf->szLeaf ){ fts5SegIterNextPage(p, pIter); if( p->rc || pIter->pLeaf==0 ) return; pIter->iRowid = 0; iOff = 4; } @@ -233619,11 +227057,11 @@ static void fts5SegIterReverse(Fts5Index *p, Fts5SegIter *pIter){ Fts5DlidxIter *pDlidx = pIter->pDlidx; Fts5Data *pLast = 0; int pgnoLast = 0; - if( pDlidx && p->pConfig->iVersion==FTS5_CURRENT_VERSION ){ + if( pDlidx ){ int iSegid = pIter->pSeg->iSegid; pgnoLast = fts5DlidxIterPgno(pDlidx); pLast = fts5LeafRead(p, FTS5_SEGMENT_ROWID(iSegid, pgnoLast)); }else{ Fts5Data *pLeaf = pIter->pLeaf; /* Current leaf data */ @@ -234180,12 +227618,11 @@ return 0; } /* ** Move the seg-iter so that it points to the first rowid on page iLeafPgno. -** It is an error if leaf iLeafPgno does not exist. Unless the db is -** a 'secure-delete' db, if it contains no rowids then this is also an error. +** It is an error if leaf iLeafPgno does not exist or contains no rowids. */ static void fts5SegIterGotoPage( Fts5Index *p, /* FTS5 backend object */ Fts5SegIter *pIter, /* Iterator to advance */ int iLeafPgno @@ -234196,27 +227633,25 @@ p->rc = FTS5_CORRUPT; }else{ fts5DataRelease(pIter->pNextLeaf); pIter->pNextLeaf = 0; pIter->iLeafPgno = iLeafPgno-1; + fts5SegIterNextPage(p, pIter); + assert( p->rc!=SQLITE_OK || pIter->iLeafPgno==iLeafPgno ); - while( p->rc==SQLITE_OK ){ + if( p->rc==SQLITE_OK && ALWAYS(pIter->pLeaf!=0) ){ int iOff; - fts5SegIterNextPage(p, pIter); - if( pIter->pLeaf==0 ) break; + u8 *a = pIter->pLeaf->p; + int n = pIter->pLeaf->szLeaf; + iOff = fts5LeafFirstRowidOff(pIter->pLeaf); - if( iOff>0 ){ - u8 *a = pIter->pLeaf->p; - int n = pIter->pLeaf->szLeaf; - if( iOff<4 || iOff>=n ){ - p->rc = FTS5_CORRUPT; - }else{ - iOff += fts5GetVarint(&a[iOff], (u64*)&pIter->iRowid); - pIter->iLeafOffset = iOff; - fts5SegIterLoadNPos(p, pIter); - } - break; + if( iOff<4 || iOff>=n ){ + p->rc = FTS5_CORRUPT; + }else{ + iOff += fts5GetVarint(&a[iOff], (u64*)&pIter->iRowid); + pIter->iLeafOffset = iOff; + fts5SegIterLoadNPos(p, pIter); } } } } @@ -234927,11 +228362,11 @@ /* Allocate space for the new multi-seg-iterator. */ if( p->rc==SQLITE_OK ){ if( iLevel<0 ){ assert( pStruct->nSegment==fts5StructureCountSegments(pStruct) ); nSeg = pStruct->nSegment; - nSeg += (p->pHash && 0==(flags & FTS5INDEX_QUERY_SKIPHASH)); + nSeg += (p->pHash ? 1 : 0); }else{ nSeg = MIN(pStruct->aLevel[iLevel].nSeg, nSegment); } } *ppOut = pNew = fts5MultiIterAlloc(p, nSeg); @@ -234948,11 +228383,11 @@ /* Initialize each of the component segment iterators. */ if( p->rc==SQLITE_OK ){ if( iLevel<0 ){ Fts5StructureLevel *pEnd = &pStruct->aLevel[pStruct->nLevel]; - if( p->pHash && 0==(flags & FTS5INDEX_QUERY_SKIPHASH) ){ + if( p->pHash ){ /* Add a segment iterator for the current contents of the hash table. */ Fts5SegIter *pIter = &pNew->aSeg[iIter++]; fts5SegIterHashInit(p, pTerm, nTerm, flags, pIter); } for(pLvl=&pStruct->aLevel[0]; pLvlbFirstRowidInDoclist || pWriter->bFirstRowidInPage ){ fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid); }else{ assert_nc( p->rc || iRowid>pWriter->iPrevRowid ); - fts5BufferAppendVarint(&p->rc, &pPage->buf, - (u64)iRowid - (u64)pWriter->iPrevRowid - ); + fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid - pWriter->iPrevRowid); } pWriter->iPrevRowid = iRowid; pWriter->bFirstRowidInDoclist = 0; pWriter->bFirstRowidInPage = 0; } @@ -235703,11 +229136,11 @@ fts5BufferZero(&buf); fts5BufferGrow(&p->rc, &buf, pData->nn); fts5BufferAppendBlob(&p->rc, &buf, sizeof(aHdr), aHdr); fts5BufferAppendVarint(&p->rc, &buf, pSeg->term.n); fts5BufferAppendBlob(&p->rc, &buf, pSeg->term.n, pSeg->term.p); - fts5BufferAppendBlob(&p->rc, &buf,pData->szLeaf-iOff,&pData->p[iOff]); + fts5BufferAppendBlob(&p->rc, &buf, pData->szLeaf-iOff,&pData->p[iOff]); if( p->rc==SQLITE_OK ){ /* Set the szLeaf field */ fts5PutU16(&buf.p[2], (u16)buf.n); } @@ -235981,20 +229414,20 @@ Fts5Index *p, /* FTS5 backend object */ Fts5Structure **ppStruct /* IN/OUT: Current structure of index */ ){ const int nCrisis = p->pConfig->nCrisisMerge; Fts5Structure *pStruct = *ppStruct; - if( pStruct && pStruct->nLevel>0 ){ - int iLvl = 0; - while( p->rc==SQLITE_OK && pStruct->aLevel[iLvl].nSeg>=nCrisis ){ - fts5IndexMergeLevel(p, &pStruct, iLvl, 0); - assert( p->rc!=SQLITE_OK || pStruct->nLevel>(iLvl+1) ); - fts5StructurePromote(p, iLvl+1, pStruct); - iLvl++; - } - *ppStruct = pStruct; - } + int iLvl = 0; + + assert( p->rc!=SQLITE_OK || pStruct->nLevel>0 ); + while( p->rc==SQLITE_OK && pStruct->aLevel[iLvl].nSeg>=nCrisis ){ + fts5IndexMergeLevel(p, &pStruct, iLvl, 0); + assert( p->rc!=SQLITE_OK || pStruct->nLevel>(iLvl+1) ); + fts5StructurePromote(p, iLvl+1, pStruct); + iLvl++; + } + *ppStruct = pStruct; } static int fts5IndexReturn(Fts5Index *p){ int rc = p->rc; p->rc = SQLITE_OK; @@ -236023,415 +229456,10 @@ ret += i; } } return ret; } - -/* -** Execute the SQL statement: -** -** DELETE FROM %_idx WHERE (segid, (pgno/2)) = ($iSegid, $iPgno); -** -** This is used when a secure-delete operation removes the last term -** from a segment leaf page. In that case the %_idx entry is removed -** too. This is done to ensure that if all instances of a token are -** removed from an fts5 database in secure-delete mode, no trace of -** the token itself remains in the database. -*/ -static void fts5SecureDeleteIdxEntry( - Fts5Index *p, /* FTS5 backend object */ - int iSegid, /* Id of segment to delete entry for */ - int iPgno /* Page number within segment */ -){ - if( iPgno!=1 ){ - assert( p->pConfig->iVersion==FTS5_CURRENT_VERSION_SECUREDELETE ); - if( p->pDeleteFromIdx==0 ){ - fts5IndexPrepareStmt(p, &p->pDeleteFromIdx, sqlite3_mprintf( - "DELETE FROM '%q'.'%q_idx' WHERE (segid, (pgno/2)) = (?1, ?2)", - p->pConfig->zDb, p->pConfig->zName - )); - } - if( p->rc==SQLITE_OK ){ - sqlite3_bind_int(p->pDeleteFromIdx, 1, iSegid); - sqlite3_bind_int(p->pDeleteFromIdx, 2, iPgno); - sqlite3_step(p->pDeleteFromIdx); - p->rc = sqlite3_reset(p->pDeleteFromIdx); - } - } -} - -/* -** This is called when a secure-delete operation removes a position-list -** that overflows onto segment page iPgno of segment pSeg. This function -** rewrites node iPgno, and possibly one or more of its right-hand peers, -** to remove this portion of the position list. -** -** Output variable (*pbLastInDoclist) is set to true if the position-list -** removed is followed by a new term or the end-of-segment, or false if -** it is followed by another rowid/position list. -*/ -static void fts5SecureDeleteOverflow( - Fts5Index *p, - Fts5StructureSegment *pSeg, - int iPgno, - int *pbLastInDoclist -){ - const int bDetailNone = (p->pConfig->eDetail==FTS5_DETAIL_NONE); - int pgno; - Fts5Data *pLeaf = 0; - assert( iPgno!=1 ); - - *pbLastInDoclist = 1; - for(pgno=iPgno; p->rc==SQLITE_OK && pgno<=pSeg->pgnoLast; pgno++){ - i64 iRowid = FTS5_SEGMENT_ROWID(pSeg->iSegid, pgno); - int iNext = 0; - u8 *aPg = 0; - - pLeaf = fts5DataRead(p, iRowid); - if( pLeaf==0 ) break; - aPg = pLeaf->p; - - iNext = fts5GetU16(&aPg[0]); - if( iNext!=0 ){ - *pbLastInDoclist = 0; - } - if( iNext==0 && pLeaf->szLeaf!=pLeaf->nn ){ - fts5GetVarint32(&aPg[pLeaf->szLeaf], iNext); - } - - if( iNext==0 ){ - /* The page contains no terms or rowids. Replace it with an empty - ** page and move on to the right-hand peer. */ - const u8 aEmpty[] = {0x00, 0x00, 0x00, 0x04}; - assert_nc( bDetailNone==0 || pLeaf->nn==4 ); - if( bDetailNone==0 ) fts5DataWrite(p, iRowid, aEmpty, sizeof(aEmpty)); - fts5DataRelease(pLeaf); - pLeaf = 0; - }else if( bDetailNone ){ - break; - }else{ - int nShift = iNext - 4; - int nPg; - - int nIdx = 0; - u8 *aIdx = 0; - - /* Unless the current page footer is 0 bytes in size (in which case - ** the new page footer will be as well), allocate and populate a - ** buffer containing the new page footer. Set stack variables aIdx - ** and nIdx accordingly. */ - if( pLeaf->nn>pLeaf->szLeaf ){ - int iFirst = 0; - int i1 = pLeaf->szLeaf; - int i2 = 0; - - aIdx = sqlite3Fts5MallocZero(&p->rc, (pLeaf->nn-pLeaf->szLeaf)+2); - if( aIdx==0 ) break; - i1 += fts5GetVarint32(&aPg[i1], iFirst); - i2 = sqlite3Fts5PutVarint(aIdx, iFirst-nShift); - if( i1nn ){ - memcpy(&aIdx[i2], &aPg[i1], pLeaf->nn-i1); - i2 += (pLeaf->nn-i1); - } - nIdx = i2; - } - - /* Modify the contents of buffer aPg[]. Set nPg to the new size - ** in bytes. The new page is always smaller than the old. */ - nPg = pLeaf->szLeaf - nShift; - memmove(&aPg[4], &aPg[4+nShift], nPg-4); - fts5PutU16(&aPg[2], nPg); - if( fts5GetU16(&aPg[0]) ) fts5PutU16(&aPg[0], 4); - if( nIdx>0 ){ - memcpy(&aPg[nPg], aIdx, nIdx); - nPg += nIdx; - } - sqlite3_free(aIdx); - - /* Write the new page to disk and exit the loop */ - assert( nPg>4 || fts5GetU16(aPg)==0 ); - fts5DataWrite(p, iRowid, aPg, nPg); - break; - } - } - fts5DataRelease(pLeaf); -} - -/* -** Completely remove the entry that pSeg currently points to from -** the database. -*/ -static void fts5DoSecureDelete( - Fts5Index *p, - Fts5Structure *pStruct, - Fts5SegIter *pSeg -){ - const int bDetailNone = (p->pConfig->eDetail==FTS5_DETAIL_NONE); - int iSegid = pSeg->pSeg->iSegid; - u8 *aPg = pSeg->pLeaf->p; - int nPg = pSeg->pLeaf->nn; - int iPgIdx = pSeg->pLeaf->szLeaf; - - u64 iDelta = 0; - u64 iNextDelta = 0; - int iNextOff = 0; - int iOff = 0; - int nIdx = 0; - u8 *aIdx = 0; - int bLastInDoclist = 0; - int iIdx = 0; - int iStart = 0; - int iKeyOff = 0; - int iPrevKeyOff = 0; - int iDelKeyOff = 0; /* Offset of deleted key, if any */ - - nIdx = nPg-iPgIdx; - aIdx = sqlite3Fts5MallocZero(&p->rc, nIdx+16); - if( p->rc ) return; - memcpy(aIdx, &aPg[iPgIdx], nIdx); - - /* At this point segment iterator pSeg points to the entry - ** this function should remove from the b-tree segment. - ** - ** In detail=full or detail=column mode, pSeg->iLeafOffset is the - ** offset of the first byte in the position-list for the entry to - ** remove. Immediately before this comes two varints that will also - ** need to be removed: - ** - ** + the rowid or delta rowid value for the entry, and - ** + the size of the position list in bytes. - ** - ** Or, in detail=none mode, there is a single varint prior to - ** pSeg->iLeafOffset - the rowid or delta rowid value. - ** - ** This block sets the following variables: - ** - ** iStart: - ** iDelta: - */ - { - int iSOP; - if( pSeg->iLeafPgno==pSeg->iTermLeafPgno ){ - iStart = pSeg->iTermLeafOffset; - }else{ - iStart = fts5GetU16(&aPg[0]); - } - - iSOP = iStart + fts5GetVarint(&aPg[iStart], &iDelta); - assert_nc( iSOP<=pSeg->iLeafOffset ); - - if( bDetailNone ){ - while( iSOPiLeafOffset ){ - if( aPg[iSOP]==0x00 ) iSOP++; - if( aPg[iSOP]==0x00 ) iSOP++; - iStart = iSOP; - iSOP = iStart + fts5GetVarint(&aPg[iStart], &iDelta); - } - - iNextOff = iSOP; - if( iNextOffiEndofDoclist && aPg[iNextOff]==0x00 ) iNextOff++; - if( iNextOffiEndofDoclist && aPg[iNextOff]==0x00 ) iNextOff++; - - }else{ - int nPos = 0; - iSOP += fts5GetVarint32(&aPg[iSOP], nPos); - while( iSOPiLeafOffset ){ - iStart = iSOP + (nPos/2); - iSOP = iStart + fts5GetVarint(&aPg[iStart], &iDelta); - iSOP += fts5GetVarint32(&aPg[iSOP], nPos); - } - assert_nc( iSOP==pSeg->iLeafOffset ); - iNextOff = pSeg->iLeafOffset + pSeg->nPos; - } - } - - iOff = iStart; - if( iNextOff>=iPgIdx ){ - int pgno = pSeg->iLeafPgno+1; - fts5SecureDeleteOverflow(p, pSeg->pSeg, pgno, &bLastInDoclist); - iNextOff = iPgIdx; - }else{ - /* Set bLastInDoclist to true if the entry being removed is the last - ** in its doclist. */ - for(iIdx=0, iKeyOff=0; iIdxiTermLeafOffset && pSeg->iLeafPgno==pSeg->iTermLeafPgno - ){ - /* The entry being removed was the only position list in its - ** doclist. Therefore the term needs to be removed as well. */ - int iKey = 0; - for(iIdx=0, iKeyOff=0; iIdxiStart ) break; - iKeyOff += iVal; - } - - iDelKeyOff = iOff = iKeyOff; - if( iNextOff!=iPgIdx ){ - int nPrefix = 0; - int nSuffix = 0; - int nPrefix2 = 0; - int nSuffix2 = 0; - - iDelKeyOff = iNextOff; - iNextOff += fts5GetVarint32(&aPg[iNextOff], nPrefix2); - iNextOff += fts5GetVarint32(&aPg[iNextOff], nSuffix2); - - if( iKey!=1 ){ - iKeyOff += fts5GetVarint32(&aPg[iKeyOff], nPrefix); - } - iKeyOff += fts5GetVarint32(&aPg[iKeyOff], nSuffix); - - nPrefix = MIN(nPrefix, nPrefix2); - nSuffix = (nPrefix2 + nSuffix2) - nPrefix; - - if( (iKeyOff+nSuffix)>iPgIdx || (iNextOff+nSuffix2)>iPgIdx ){ - p->rc = FTS5_CORRUPT; - }else{ - if( iKey!=1 ){ - iOff += sqlite3Fts5PutVarint(&aPg[iOff], nPrefix); - } - iOff += sqlite3Fts5PutVarint(&aPg[iOff], nSuffix); - if( nPrefix2>nPrefix ){ - memcpy(&aPg[iOff], &pSeg->term.p[nPrefix], nPrefix2-nPrefix); - iOff += (nPrefix2-nPrefix); - } - memmove(&aPg[iOff], &aPg[iNextOff], nSuffix2); - iOff += nSuffix2; - iNextOff += nSuffix2; - } - } - }else if( iStart==4 ){ - assert_nc( pSeg->iLeafPgno>pSeg->iTermLeafPgno ); - /* The entry being removed may be the only position list in - ** its doclist. */ - int iPgno = pSeg->iLeafPgno-1; - - for(iPgno=pSeg->iLeafPgno-1; iPgno>pSeg->iTermLeafPgno; iPgno-- ){ - Fts5Data *pPg = fts5DataRead(p, FTS5_SEGMENT_ROWID(iSegid, iPgno)); - int bEmpty = (pPg && pPg->nn==4); - fts5DataRelease(pPg); - if( bEmpty==0 ) break; - } - - if( iPgno==pSeg->iTermLeafPgno ){ - i64 iId = FTS5_SEGMENT_ROWID(iSegid, pSeg->iTermLeafPgno); - Fts5Data *pTerm = fts5DataRead(p, iId); - if( pTerm && pTerm->szLeaf==pSeg->iTermLeafOffset ){ - u8 *aTermIdx = &pTerm->p[pTerm->szLeaf]; - int nTermIdx = pTerm->nn - pTerm->szLeaf; - int iTermIdx = 0; - int iTermOff = 0; - - while( 1 ){ - u32 iVal = 0; - int nByte = fts5GetVarint32(&aTermIdx[iTermIdx], iVal); - iTermOff += iVal; - if( (iTermIdx+nByte)>=nTermIdx ) break; - iTermIdx += nByte; - } - nTermIdx = iTermIdx; - - memmove(&pTerm->p[iTermOff], &pTerm->p[pTerm->szLeaf], nTermIdx); - fts5PutU16(&pTerm->p[2], iTermOff); - - fts5DataWrite(p, iId, pTerm->p, iTermOff+nTermIdx); - if( nTermIdx==0 ){ - fts5SecureDeleteIdxEntry(p, iSegid, pSeg->iTermLeafPgno); - } - } - fts5DataRelease(pTerm); - } - } - - if( p->rc==SQLITE_OK ){ - const int nMove = nPg - iNextOff; - int nShift = 0; - - memmove(&aPg[iOff], &aPg[iNextOff], nMove); - iPgIdx -= (iNextOff - iOff); - nPg = iPgIdx; - fts5PutU16(&aPg[2], iPgIdx); - - nShift = iNextOff - iOff; - for(iIdx=0, iKeyOff=0, iPrevKeyOff=0; iIdxiOff ){ - iKeyOff -= nShift; - nShift = 0; - } - nPg += sqlite3Fts5PutVarint(&aPg[nPg], iKeyOff - iPrevKeyOff); - iPrevKeyOff = iKeyOff; - } - } - - if( iPgIdx==nPg && nIdx>0 && pSeg->iLeafPgno!=1 ){ - fts5SecureDeleteIdxEntry(p, iSegid, pSeg->iLeafPgno); - } - - assert_nc( nPg>4 || fts5GetU16(aPg)==0 ); - fts5DataWrite(p, FTS5_SEGMENT_ROWID(iSegid,pSeg->iLeafPgno), aPg,nPg); - } - sqlite3_free(aIdx); -} - -/* -** This is called as part of flushing a delete to disk in 'secure-delete' -** mode. It edits the segments within the database described by argument -** pStruct to remove the entries for term zTerm, rowid iRowid. -*/ -static void fts5FlushSecureDelete( - Fts5Index *p, - Fts5Structure *pStruct, - const char *zTerm, - i64 iRowid -){ - const int f = FTS5INDEX_QUERY_SKIPHASH; - int nTerm = strlen(zTerm); - Fts5Iter *pIter = 0; /* Used to find term instance */ - - fts5MultiIterNew(p, pStruct, f, 0, (const u8*)zTerm, nTerm, -1, 0, &pIter); - if( fts5MultiIterEof(p, pIter)==0 ){ - i64 iThis = fts5MultiIterRowid(pIter); - if( iThisrc==SQLITE_OK - && fts5MultiIterEof(p, pIter)==0 - && iRowid==fts5MultiIterRowid(pIter) - ){ - Fts5SegIter *pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst]; - fts5DoSecureDelete(p, pStruct, pSeg); - } - } - - fts5MultiIterFree(pIter); -} - /* ** Flush the contents of in-memory hash table iHash to a new level-0 ** segment on disk. Also update the corresponding structure record. ** @@ -236451,11 +229479,10 @@ fts5StructureInvalidate(p); if( iSegid ){ const int pgsz = p->pConfig->pgsz; int eDetail = p->pConfig->eDetail; - int bSecureDelete = p->pConfig->bSecureDelete; Fts5StructureSegment *pSeg; /* New segment within pStruct */ Fts5Buffer *pBuf; /* Buffer in which to assemble leaf page */ Fts5Buffer *pPgidx; /* Buffer in which to assemble pgidx */ Fts5SegWriter writer; @@ -236474,81 +229501,44 @@ if( p->rc==SQLITE_OK ){ p->rc = sqlite3Fts5HashScanInit(pHash, 0, 0); } while( p->rc==SQLITE_OK && 0==sqlite3Fts5HashScanEof(pHash) ){ const char *zTerm; /* Buffer containing term */ - int nTerm; /* Size of zTerm in bytes */ const u8 *pDoclist; /* Pointer to doclist for this term */ int nDoclist; /* Size of doclist in bytes */ - /* Get the term and doclist for this entry. */ + /* Write the term for this entry to disk. */ sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist); - nTerm = (int)strlen(zTerm); - if( bSecureDelete==0 ){ - fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm); - if( p->rc!=SQLITE_OK ) break; - assert( writer.bFirstRowidInPage==0 ); - } - - if( !bSecureDelete && pgsz>=(pBuf->n + pPgidx->n + nDoclist + 1) ){ + fts5WriteAppendTerm(p, &writer, (int)strlen(zTerm), (const u8*)zTerm); + if( p->rc!=SQLITE_OK ) break; + + assert( writer.bFirstRowidInPage==0 ); + if( pgsz>=(pBuf->n + pPgidx->n + nDoclist + 1) ){ /* The entire doclist will fit on the current leaf. */ fts5BufferSafeAppendBlob(pBuf, pDoclist, nDoclist); }else{ - int bTermWritten = !bSecureDelete; i64 iRowid = 0; - i64 iPrev = 0; + u64 iDelta = 0; int iOff = 0; /* The entire doclist will not fit on this leaf. The following ** loop iterates through the poslists that make up the current ** doclist. */ while( p->rc==SQLITE_OK && iOffrc!=SQLITE_OK || pDoclist[iOff]==0x01 ){ - iOff++; - continue; - } - } - } - - if( p->rc==SQLITE_OK && bTermWritten==0 ){ - fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm); - bTermWritten = 1; - assert( p->rc!=SQLITE_OK || writer.bFirstRowidInPage==0 ); - } - if( writer.bFirstRowidInPage ){ fts5PutU16(&pBuf->p[0], (u16)pBuf->n); /* first rowid on page */ pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid); writer.bFirstRowidInPage = 0; fts5WriteDlidxAppend(p, &writer, iRowid); + if( p->rc!=SQLITE_OK ) break; }else{ - pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid-iPrev); + pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iDelta); } - if( p->rc!=SQLITE_OK ) break; assert( pBuf->n<=pBuf->nSpace ); - iPrev = iRowid; if( eDetail==FTS5_DETAIL_NONE ){ if( iOffp[pBuf->n++] = 0; iOff++; @@ -236603,27 +229593,24 @@ if( p->rc==SQLITE_OK ) sqlite3Fts5HashScanNext(pHash); } sqlite3Fts5HashClear(pHash); fts5WriteFinish(p, &writer, &pgnoLast); - assert( p->rc!=SQLITE_OK || bSecureDelete || pgnoLast>0 ); - if( pgnoLast>0 ){ - /* Update the Fts5Structure. It is written back to the database by the - ** fts5StructureRelease() call below. */ - if( pStruct->nLevel==0 ){ - fts5StructureAddLevel(&p->rc, &pStruct); - } - fts5StructureExtendLevel(&p->rc, pStruct, 0, 1, 0); - if( p->rc==SQLITE_OK ){ - pSeg = &pStruct->aLevel[0].aSeg[ pStruct->aLevel[0].nSeg++ ]; - pSeg->iSegid = iSegid; - pSeg->pgnoFirst = 1; - pSeg->pgnoLast = pgnoLast; - pStruct->nSegment++; - } - fts5StructurePromote(p, 0, pStruct); - } + /* Update the Fts5Structure. It is written back to the database by the + ** fts5StructureRelease() call below. */ + if( pStruct->nLevel==0 ){ + fts5StructureAddLevel(&p->rc, &pStruct); + } + fts5StructureExtendLevel(&p->rc, pStruct, 0, 1, 0); + if( p->rc==SQLITE_OK ){ + pSeg = &pStruct->aLevel[0].aSeg[ pStruct->aLevel[0].nSeg++ ]; + pSeg->iSegid = iSegid; + pSeg->pgnoFirst = 1; + pSeg->pgnoLast = pgnoLast; + pStruct->nSegment++; + } + fts5StructurePromote(p, 0, pStruct); } fts5IndexAutomerge(p, &pStruct, pgnoLast); fts5IndexCrisismerge(p, &pStruct); fts5StructureWrite(p, pStruct); @@ -236675,14 +229662,14 @@ pNew = (Fts5Structure*)sqlite3Fts5MallocZero(&p->rc, nByte); if( pNew ){ Fts5StructureLevel *pLvl; nByte = nSeg * sizeof(Fts5StructureSegment); - pNew->nLevel = MIN(pStruct->nLevel+1, FTS5_MAX_LEVEL); + pNew->nLevel = pStruct->nLevel+1; pNew->nRef = 1; pNew->nWriteCounter = pStruct->nWriteCounter; - pLvl = &pNew->aLevel[pNew->nLevel-1]; + pLvl = &pNew->aLevel[pStruct->nLevel]; pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&p->rc, nByte); if( pLvl->aSeg ){ int iLvl, iSeg; int iSegOut = 0; /* Iterate through all segments, from oldest to newest. Add them to @@ -236760,21 +229747,21 @@ return fts5IndexReturn(p); } static void fts5AppendRowid( Fts5Index *p, - u64 iDelta, + i64 iDelta, Fts5Iter *pUnused, Fts5Buffer *pBuf ){ UNUSED_PARAM(pUnused); fts5BufferAppendVarint(&p->rc, pBuf, iDelta); } static void fts5AppendPoslist( Fts5Index *p, - u64 iDelta, + i64 iDelta, Fts5Iter *pMulti, Fts5Buffer *pBuf ){ int nData = pMulti->base.nData; int nByte = nData + 9 + 9 + FTS5_DATA_ZERO_PADDING; @@ -236845,14 +229832,14 @@ fts5BufferSafeAppendVarint(pBuf, iRowid - *piLastRowid); *piLastRowid = iRowid; } #endif -#define fts5MergeAppendDocid(pBuf, iLastRowid, iRowid) { \ - assert( (pBuf)->n!=0 || (iLastRowid)==0 ); \ - fts5BufferSafeAppendVarint((pBuf), (u64)(iRowid) - (u64)(iLastRowid)); \ - (iLastRowid) = (iRowid); \ +#define fts5MergeAppendDocid(pBuf, iLastRowid, iRowid) { \ + assert( (pBuf)->n!=0 || (iLastRowid)==0 ); \ + fts5BufferSafeAppendVarint((pBuf), (iRowid) - (iLastRowid)); \ + (iLastRowid) = (iRowid); \ } /* ** Swap the contents of buffer *p1 with that of *p2. */ @@ -236980,11 +229967,11 @@ i64 iLastRowid = 0; /* Initialize a doclist-iterator for each input buffer. Arrange them in ** a linked-list starting at pHead in ascending order of rowid. Avoid ** linking any iterators already at EOF into the linked list at all. */ - assert( nBuf+1<=(int)(sizeof(aMerger)/sizeof(aMerger[0])) ); + assert( nBuf+1<=sizeof(aMerger)/sizeof(aMerger[0]) ); memset(aMerger, 0, sizeof(PrefixMerger)*(nBuf+1)); pHead = &aMerger[nBuf]; fts5DoclistIterInit(p1, &pHead->iter); for(i=0; ipConfig->eDetail==FTS5_DETAIL_NONE ){ xMerge = fts5MergeRowidLists; xAppend = fts5AppendRowid; }else{ nMerge = FTS5_MERGE_NLIST-1; @@ -237158,11 +230145,11 @@ fts5MultiIterNext2(p, p1, &dummy) ){ Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ]; p1->xSetOutputs(p1, pSeg); if( p1->base.nData ){ - xAppend(p, (u64)p1->base.iRowid-(u64)iLastRowid, p1, &doclist); + xAppend(p, p1->base.iRowid-iLastRowid, p1, &doclist); iLastRowid = p1->base.iRowid; } } fts5MultiIterFree(p1); } @@ -237206,11 +230193,11 @@ } } iLastRowid = 0; } - xAppend(p, (u64)p1->base.iRowid-(u64)iLastRowid, p1, &doclist); + xAppend(p, p1->base.iRowid-iLastRowid, p1, &doclist); iLastRowid = p1->base.iRowid; } assert( (nBuf%nMerge)==0 ); for(i=0; ipDeleter); sqlite3_finalize(p->pIdxWriter); sqlite3_finalize(p->pIdxDeleter); sqlite3_finalize(p->pIdxSelect); sqlite3_finalize(p->pDataVersion); - sqlite3_finalize(p->pDeleteFromIdx); sqlite3Fts5HashFree(p->pHash); sqlite3_free(p->zDataTbl); sqlite3_free(p); } return rc; @@ -237991,11 +230977,10 @@ static void fts5IndexIntegrityCheckSegment( Fts5Index *p, /* FTS5 backend object */ Fts5StructureSegment *pSeg /* Segment to check internal consistency */ ){ Fts5Config *pConfig = p->pConfig; - int bSecureDelete = (pConfig->iVersion==FTS5_CURRENT_VERSION_SECUREDELETE); sqlite3_stmt *pStmt = 0; int rc2; int iIdxPrevLeaf = pSeg->pgnoFirst-1; int iDlidxPrevLeaf = pSeg->pgnoLast; @@ -238027,23 +231012,11 @@ /* Check that the leaf contains at least one term, and that it is equal ** to or larger than the split-key in zIdxTerm. Also check that if there ** is also a rowid pointer within the leaf page header, it points to a ** location before the term. */ if( pLeaf->nn<=pLeaf->szLeaf ){ - - if( nIdxTerm==0 - && pConfig->iVersion==FTS5_CURRENT_VERSION_SECUREDELETE - && pLeaf->nn==pLeaf->szLeaf - && pLeaf->nn==4 - ){ - /* special case - the very first page in a segment keeps its %_idx - ** entry even if all the terms are removed from it by secure-delete - ** operations. */ - }else{ - p->rc = FTS5_CORRUPT; - } - + p->rc = FTS5_CORRUPT; }else{ int iOff; /* Offset of first term on leaf */ int iRowidOff; /* Offset of first rowid on leaf */ int nTerm; /* Size of term on leaf in bytes */ int res; /* Comparison of term and split-key */ @@ -238103,16 +231076,13 @@ i64 iRowid; int iRowidOff = fts5LeafFirstRowidOff(pLeaf); ASSERT_SZLEAF_OK(pLeaf); if( iRowidOff>=pLeaf->szLeaf ){ p->rc = FTS5_CORRUPT; - }else if( bSecureDelete==0 || iRowidOff>0 ){ - i64 iDlRowid = fts5DlidxIterRowid(pDlidx); + }else{ fts5GetVarint(&pLeaf->p[iRowidOff], (u64*)&iRowid); - if( iRowidrc = FTS5_CORRUPT; - } + if( iRowid!=fts5DlidxIterRowid(pDlidx) ) p->rc = FTS5_CORRUPT; } fts5DataRelease(pLeaf); } } @@ -238202,11 +231172,10 @@ i64 iRowid = fts5MultiIterRowid(pIter); char *z = (char*)fts5MultiIterTerm(pIter, &n); /* If this is a new term, query for it. Update cksum3 with the results. */ fts5TestTerm(p, &term, z, n, cksum2, &cksum3); - if( p->rc ) break; if( eDetail==FTS5_DETAIL_NONE ){ if( 0==fts5MultiIterIsEmpty(p, pIter) ){ cksum2 ^= sqlite3Fts5IndexEntryCksum(iRowid, 0, 0, -1, z, n); } @@ -239007,11 +231976,11 @@ p->ts.eState = 1; p->ts.iSavepoint = -1; break; case FTS5_SYNC: - assert( p->ts.eState==1 || p->ts.eState==2 ); + assert( p->ts.eState==1 ); p->ts.eState = 2; break; case FTS5_COMMIT: assert( p->ts.eState==2 ); @@ -239022,25 +231991,25 @@ assert( p->ts.eState==1 || p->ts.eState==2 || p->ts.eState==0 ); p->ts.eState = 0; break; case FTS5_SAVEPOINT: - assert( p->ts.eState>=1 ); + assert( p->ts.eState==1 ); assert( iSavepoint>=0 ); assert( iSavepoint>=p->ts.iSavepoint ); p->ts.iSavepoint = iSavepoint; break; case FTS5_RELEASE: - assert( p->ts.eState>=1 ); + assert( p->ts.eState==1 ); assert( iSavepoint>=0 ); assert( iSavepoint<=p->ts.iSavepoint ); p->ts.iSavepoint = iSavepoint-1; break; case FTS5_ROLLBACKTO: - assert( p->ts.eState>=1 ); + assert( p->ts.eState==1 ); assert( iSavepoint>=-1 ); /* The following assert() can fail if another vtab strikes an error ** within an xSavepoint() call then SQLite calls xRollbackTo() - without ** having called xSavepoint() on this vtab. */ /* assert( iSavepoint<=p->ts.iSavepoint ); */ @@ -240370,27 +233339,20 @@ ){ Fts5FullTable *pTab = (Fts5FullTable*)pVtab; Fts5Config *pConfig = pTab->p.pConfig; int eType0; /* value_type() of apVal[0] */ int rc = SQLITE_OK; /* Return code */ - int bUpdateOrDelete = 0; - /* A transaction must be open when this is called. */ - assert( pTab->ts.eState==1 || pTab->ts.eState==2 ); + assert( pTab->ts.eState==1 ); assert( pVtab->zErrMsg==0 ); assert( nArg==1 || nArg==(2+pConfig->nCol+2) ); assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER || sqlite3_value_type(apVal[0])==SQLITE_NULL ); assert( pTab->p.pConfig->pzErrmsg==0 ); - if( pConfig->pgsz==0 ){ - rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); - if( rc!=SQLITE_OK ) return rc; - } - pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg; /* Put any active cursors into REQUIRE_SEEK state. */ fts5TripCursors(pTab); @@ -240439,11 +233401,10 @@ /* DELETE */ else if( nArg==1 ){ i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0); - bUpdateOrDelete = 1; } /* INSERT or UPDATE */ else{ int eType1 = sqlite3_value_numeric_type(apVal[1]); @@ -240455,11 +233416,10 @@ else if( eType0!=SQLITE_INTEGER ){ /* If this is a REPLACE, first remove the current entry (if any) */ if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){ i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0); - bUpdateOrDelete = 1; } fts5StorageInsert(&rc, pTab, apVal, pRowid); } /* UPDATE */ @@ -240484,25 +233444,11 @@ } }else{ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); fts5StorageInsert(&rc, pTab, apVal, pRowid); } - bUpdateOrDelete = 1; - } - } - } - - if( rc==SQLITE_OK - && bUpdateOrDelete - && pConfig->bSecureDelete - && pConfig->iVersion==FTS5_CURRENT_VERSION - ){ - rc = sqlite3Fts5StorageConfigValue( - pTab->pStorage, "version", 0, FTS5_CURRENT_VERSION_SECUREDELETE - ); - if( rc==SQLITE_OK ){ - pConfig->iVersion = FTS5_CURRENT_VERSION_SECUREDELETE; + } } } pTab->p.pConfig->pzErrmsg = 0; return rc; @@ -241361,11 +234307,10 @@ static int fts5RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ Fts5FullTable *pTab = (Fts5FullTable*)pVtab; UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint); fts5TripCursors(pTab); - pTab->p.pConfig->pgsz = 0; return sqlite3Fts5StorageRollback(pTab->pStorage); } /* ** Register a new auxiliary function with global context pGlobal. @@ -241564,11 +234509,11 @@ int nArg, /* Number of args */ sqlite3_value **apUnused /* Function arguments */ ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2023-04-18 23:05:34 ba8e4378f21d529a248d2d60b60974fef0d6612dcaaa1f6b7f8a6946fc46b39b", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2022-05-06 15:25:27 78d9c993d404cdfaa7fdd2973fa1052e3da9f66215cff9c5540ebe55c407d9fe", -1, SQLITE_TRANSIENT); } /* ** Return true if zName is the extension on one of the shadow tables used ** by this module. @@ -241637,13 +234582,11 @@ db, "fts5", 1, SQLITE_UTF8, p, fts5Fts5Func, 0, 0 ); } if( rc==SQLITE_OK ){ rc = sqlite3_create_function( - db, "fts5_source_id", 0, - SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS, - p, fts5SourceIdFunc, 0, 0 + db, "fts5_source_id", 0, SQLITE_UTF8, p, fts5SourceIdFunc, 0, 0 ); } } /* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file @@ -246237,20 +239180,10 @@ /* #include */ /* #include */ #ifndef SQLITE_OMIT_VIRTUALTABLE - -#define STMT_NUM_INTEGER_COLUMN 10 -typedef struct StmtRow StmtRow; -struct StmtRow { - sqlite3_int64 iRowid; /* Rowid value */ - char *zSql; /* column "sql" */ - int aCol[STMT_NUM_INTEGER_COLUMN+1]; /* all other column values */ - StmtRow *pNext; /* Next row to return */ -}; - /* stmt_vtab is a subclass of sqlite3_vtab which will ** serve as the underlying representation of a stmt virtual table */ typedef struct stmt_vtab stmt_vtab; struct stmt_vtab { @@ -246264,11 +239197,12 @@ */ typedef struct stmt_cursor stmt_cursor; struct stmt_cursor { sqlite3_vtab_cursor base; /* Base class - must be first */ sqlite3 *db; /* Database connection for this cursor */ - StmtRow *pRow; /* Current row */ + sqlite3_stmt *pStmt; /* Statement cursor is currently pointing at */ + sqlite3_int64 iRowid; /* The rowid */ }; /* ** The stmtConnect() method is invoked to create a new ** stmt_vtab that describes the stmt virtual table. @@ -246304,19 +239238,15 @@ #define STMT_COLUMN_REPREP 8 /* SQLITE_STMTSTATUS_REPREPARE */ #define STMT_COLUMN_RUN 9 /* SQLITE_STMTSTATUS_RUN */ #define STMT_COLUMN_MEM 10 /* SQLITE_STMTSTATUS_MEMUSED */ - (void)pAux; - (void)argc; - (void)argv; - (void)pzErr; rc = sqlite3_declare_vtab(db, "CREATE TABLE x(sql,ncol,ro,busy,nscan,nsort,naidx,nstep," "reprep,run,mem)"); if( rc==SQLITE_OK ){ - pNew = sqlite3_malloc64( sizeof(*pNew) ); + pNew = sqlite3_malloc( sizeof(*pNew) ); *ppVtab = (sqlite3_vtab*)pNew; if( pNew==0 ) return SQLITE_NOMEM; memset(pNew, 0, sizeof(*pNew)); pNew->db = db; } @@ -246334,33 +239264,22 @@ /* ** Constructor for a new stmt_cursor object. */ static int stmtOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ stmt_cursor *pCur; - pCur = sqlite3_malloc64( sizeof(*pCur) ); + pCur = sqlite3_malloc( sizeof(*pCur) ); if( pCur==0 ) return SQLITE_NOMEM; memset(pCur, 0, sizeof(*pCur)); pCur->db = ((stmt_vtab*)p)->db; *ppCursor = &pCur->base; return SQLITE_OK; } -static void stmtCsrReset(stmt_cursor *pCur){ - StmtRow *pRow = 0; - StmtRow *pNext = 0; - for(pRow=pCur->pRow; pRow; pRow=pNext){ - pNext = pRow->pNext; - sqlite3_free(pRow); - } - pCur->pRow = 0; -} - /* ** Destructor for a stmt_cursor. */ static int stmtClose(sqlite3_vtab_cursor *cur){ - stmtCsrReset((stmt_cursor*)cur); sqlite3_free(cur); return SQLITE_OK; } @@ -246367,13 +239286,12 @@ /* ** Advance a stmt_cursor to its next row of output. */ static int stmtNext(sqlite3_vtab_cursor *cur){ stmt_cursor *pCur = (stmt_cursor*)cur; - StmtRow *pNext = pCur->pRow->pNext; - sqlite3_free(pCur->pRow); - pCur->pRow = pNext; + pCur->iRowid++; + pCur->pStmt = sqlite3_next_stmt(pCur->db, pCur->pStmt); return SQLITE_OK; } /* ** Return values of columns for the row at which the stmt_cursor @@ -246383,15 +239301,43 @@ sqlite3_vtab_cursor *cur, /* The cursor */ sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ int i /* Which column to return */ ){ stmt_cursor *pCur = (stmt_cursor*)cur; - StmtRow *pRow = pCur->pRow; - if( i==STMT_COLUMN_SQL ){ - sqlite3_result_text(ctx, pRow->zSql, -1, SQLITE_TRANSIENT); - }else{ - sqlite3_result_int(ctx, pRow->aCol[i]); + switch( i ){ + case STMT_COLUMN_SQL: { + sqlite3_result_text(ctx, sqlite3_sql(pCur->pStmt), -1, SQLITE_TRANSIENT); + break; + } + case STMT_COLUMN_NCOL: { + sqlite3_result_int(ctx, sqlite3_column_count(pCur->pStmt)); + break; + } + case STMT_COLUMN_RO: { + sqlite3_result_int(ctx, sqlite3_stmt_readonly(pCur->pStmt)); + break; + } + case STMT_COLUMN_BUSY: { + sqlite3_result_int(ctx, sqlite3_stmt_busy(pCur->pStmt)); + break; + } + default: { + assert( i==STMT_COLUMN_MEM ); + i = SQLITE_STMTSTATUS_MEMUSED + + STMT_COLUMN_NSCAN - SQLITE_STMTSTATUS_FULLSCAN_STEP; + /* Fall thru */ + } + case STMT_COLUMN_NSCAN: + case STMT_COLUMN_NSORT: + case STMT_COLUMN_NAIDX: + case STMT_COLUMN_NSTEP: + case STMT_COLUMN_REPREP: + case STMT_COLUMN_RUN: { + sqlite3_result_int(ctx, sqlite3_stmt_status(pCur->pStmt, + i-STMT_COLUMN_NSCAN+SQLITE_STMTSTATUS_FULLSCAN_STEP, 0)); + break; + } } return SQLITE_OK; } /* @@ -246398,21 +239344,21 @@ ** Return the rowid for the current row. In this implementation, the ** rowid is the same as the output value. */ static int stmtRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ stmt_cursor *pCur = (stmt_cursor*)cur; - *pRowid = pCur->pRow->iRowid; + *pRowid = pCur->iRowid; return SQLITE_OK; } /* ** Return TRUE if the cursor has been moved off of the last ** row of output. */ static int stmtEof(sqlite3_vtab_cursor *cur){ stmt_cursor *pCur = (stmt_cursor*)cur; - return pCur->pRow==0; + return pCur->pStmt==0; } /* ** This method is called to "rewind" the stmt_cursor object back ** to the first row of output. This method is always called at least @@ -246423,61 +239369,13 @@ sqlite3_vtab_cursor *pVtabCursor, int idxNum, const char *idxStr, int argc, sqlite3_value **argv ){ stmt_cursor *pCur = (stmt_cursor *)pVtabCursor; - sqlite3_stmt *p = 0; - sqlite3_int64 iRowid = 1; - StmtRow **ppRow = 0; - - (void)idxNum; - (void)idxStr; - (void)argc; - (void)argv; - stmtCsrReset(pCur); - ppRow = &pCur->pRow; - for(p=sqlite3_next_stmt(pCur->db, 0); p; p=sqlite3_next_stmt(pCur->db, p)){ - const char *zSql = sqlite3_sql(p); - sqlite3_int64 nSql = zSql ? strlen(zSql)+1 : 0; - StmtRow *pNew = (StmtRow*)sqlite3_malloc64(sizeof(StmtRow) + nSql); - - if( pNew==0 ) return SQLITE_NOMEM; - memset(pNew, 0, sizeof(StmtRow)); - if( zSql ){ - pNew->zSql = (char*)&pNew[1]; - memcpy(pNew->zSql, zSql, nSql); - } - pNew->aCol[STMT_COLUMN_NCOL] = sqlite3_column_count(p); - pNew->aCol[STMT_COLUMN_RO] = sqlite3_stmt_readonly(p); - pNew->aCol[STMT_COLUMN_BUSY] = sqlite3_stmt_busy(p); - pNew->aCol[STMT_COLUMN_NSCAN] = sqlite3_stmt_status( - p, SQLITE_STMTSTATUS_FULLSCAN_STEP, 0 - ); - pNew->aCol[STMT_COLUMN_NSORT] = sqlite3_stmt_status( - p, SQLITE_STMTSTATUS_SORT, 0 - ); - pNew->aCol[STMT_COLUMN_NAIDX] = sqlite3_stmt_status( - p, SQLITE_STMTSTATUS_AUTOINDEX, 0 - ); - pNew->aCol[STMT_COLUMN_NSTEP] = sqlite3_stmt_status( - p, SQLITE_STMTSTATUS_VM_STEP, 0 - ); - pNew->aCol[STMT_COLUMN_REPREP] = sqlite3_stmt_status( - p, SQLITE_STMTSTATUS_REPREPARE, 0 - ); - pNew->aCol[STMT_COLUMN_RUN] = sqlite3_stmt_status( - p, SQLITE_STMTSTATUS_RUN, 0 - ); - pNew->aCol[STMT_COLUMN_MEM] = sqlite3_stmt_status( - p, SQLITE_STMTSTATUS_MEMUSED, 0 - ); - pNew->iRowid = iRowid++; - *ppRow = pNew; - ppRow = &pNew->pNext; - } - - return SQLITE_OK; + pCur->pStmt = 0; + pCur->iRowid = 0; + return stmtNext(pVtabCursor); } /* ** SQLite will invoke this method one or more times while planning a query ** that uses the stmt virtual table. This routine needs to create @@ -246486,11 +239384,10 @@ */ static int stmtBestIndex( sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo ){ - (void)tab; pIdxInfo->estimatedCost = (double)500; pIdxInfo->estimatedRows = 500; return SQLITE_OK; } Index: lib/sqlite3.h ================================================================== --- lib/sqlite3.h +++ lib/sqlite3.h @@ -144,13 +144,13 @@ ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.42.0" -#define SQLITE_VERSION_NUMBER 3042000 -#define SQLITE_SOURCE_ID "2023-04-18 23:05:34 ba8e4378f21d529a248d2d60b60974fef0d6612dcaaa1f6b7f8a6946fc46b39b" +#define SQLITE_VERSION "3.38.5" +#define SQLITE_VERSION_NUMBER 3038005 +#define SQLITE_SOURCE_ID "2022-05-06 15:25:27 78d9c993d404cdfaa7fdd2973fa1052e3da9f66215cff9c5540ebe55c407d9fe" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version sqlite3_sourceid ** @@ -561,11 +561,10 @@ #define SQLITE_CONSTRAINT_ROWID (SQLITE_CONSTRAINT |(10<<8)) #define SQLITE_CONSTRAINT_PINNED (SQLITE_CONSTRAINT |(11<<8)) #define SQLITE_CONSTRAINT_DATATYPE (SQLITE_CONSTRAINT |(12<<8)) #define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8)) #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8)) -#define SQLITE_NOTICE_RBU (SQLITE_NOTICE | (3<<8)) #define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8)) #define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8)) #define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8)) #define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal use only */ @@ -669,21 +668,17 @@ /* ** CAPI3REF: File Locking Levels ** ** SQLite uses one of these integer values as the second ** argument to calls it makes to the xLock() and xUnlock() methods -** of an [sqlite3_io_methods] object. These values are ordered from -** lest restrictive to most restrictive. -** -** The argument to xLock() is always SHARED or higher. The argument to -** xUnlock is either SHARED or NONE. +** of an [sqlite3_io_methods] object. */ -#define SQLITE_LOCK_NONE 0 /* xUnlock() only */ -#define SQLITE_LOCK_SHARED 1 /* xLock() or xUnlock() */ -#define SQLITE_LOCK_RESERVED 2 /* xLock() only */ -#define SQLITE_LOCK_PENDING 3 /* xLock() only */ -#define SQLITE_LOCK_EXCLUSIVE 4 /* xLock() only */ +#define SQLITE_LOCK_NONE 0 +#define SQLITE_LOCK_SHARED 1 +#define SQLITE_LOCK_RESERVED 2 +#define SQLITE_LOCK_PENDING 3 +#define SQLITE_LOCK_EXCLUSIVE 4 /* ** CAPI3REF: Synchronization Type Flags ** ** When SQLite invokes the xSync() method of an @@ -757,18 +752,11 @@ **
    6. [SQLITE_LOCK_SHARED], **
    7. [SQLITE_LOCK_RESERVED], **
    8. [SQLITE_LOCK_PENDING], or **
    9. [SQLITE_LOCK_EXCLUSIVE]. ** -** xLock() upgrades the database file lock. In other words, xLock() moves the -** database file lock in the direction NONE toward EXCLUSIVE. The argument to -** xLock() is always on of SHARED, RESERVED, PENDING, or EXCLUSIVE, never -** SQLITE_LOCK_NONE. If the database file lock is already at or above the -** requested lock, then the call to xLock() is a no-op. -** xUnlock() downgrades the database file lock to either SHARED or NONE. -* If the lock is already at or below the requested lock state, then the call -** to xUnlock() is a no-op. +** xLock() increases the lock. xUnlock() decreases the lock. ** The xCheckReservedLock() method checks whether any database connection, ** either in this process or in some other process, is holding a RESERVED, ** PENDING, or EXCLUSIVE lock on the file. It returns true ** if such a lock exists and false otherwise. ** @@ -869,12 +857,13 @@ **
    10. [[SQLITE_FCNTL_LOCKSTATE]] ** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This ** opcode causes the xFileControl method to write the current state of ** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], ** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) -** into an integer that the pArg argument points to. -** This capability is only available if SQLite is compiled with [SQLITE_DEBUG]. +** into an integer that the pArg argument points to. This capability +** is used during testing and is only available when the SQLITE_TEST +** compile-time option is used. ** **
    11. [[SQLITE_FCNTL_SIZE_HINT]] ** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS ** layer a hint of how large the database file will grow to be during the ** current transaction. This hint is not guaranteed to be accurate but it @@ -1174,10 +1163,11 @@ **
    12. [[SQLITE_FCNTL_CKPT_DONE]] ** The [SQLITE_FCNTL_CKPT_DONE] opcode is invoked from within a checkpoint ** in wal mode after the client has finished copying pages from the wal ** file to the database file, but before the *-shm file is updated to ** record the fact that the pages have been checkpointed. +** ** **
    13. [[SQLITE_FCNTL_EXTERNAL_READER]] ** The EXPERIMENTAL [SQLITE_FCNTL_EXTERNAL_READER] opcode is used to detect ** whether or not there is a database client in another process with a wal-mode ** transaction open on the database or not. It is only available on unix.The @@ -1186,20 +1176,14 @@ ** mode database and there exists at least one client in another process that ** currently has an SQL transaction open on the database. It is set to 0 if ** the database is not a wal-mode db, or if there is no such connection in any ** other process. This opcode cannot be used to detect transactions opened ** by clients within the current process, only within other processes. +** ** **
    14. [[SQLITE_FCNTL_CKSM_FILE]] -** The [SQLITE_FCNTL_CKSM_FILE] opcode is for use interally by the -** [checksum VFS shim] only. -** -**
    15. [[SQLITE_FCNTL_RESET_CACHE]] -** If there is currently no transaction open on the database, and the -** database is not a temp db, then the [SQLITE_FCNTL_RESET_CACHE] file-control -** purges the contents of the in-memory page cache. If there is an open -** transaction, or if the db is a temp-db, this opcode is a no-op, not an error. +** Used by the cksmvfs VFS module only. ** */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_FCNTL_GET_LOCKPROXYFILE 2 #define SQLITE_FCNTL_SET_LOCKPROXYFILE 3 @@ -1238,11 +1222,10 @@ #define SQLITE_FCNTL_CKPT_DONE 37 #define SQLITE_FCNTL_RESERVE_BYTES 38 #define SQLITE_FCNTL_CKPT_START 39 #define SQLITE_FCNTL_EXTERNAL_READER 40 #define SQLITE_FCNTL_CKSM_FILE 41 -#define SQLITE_FCNTL_RESET_CACHE 42 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO @@ -1268,30 +1251,10 @@ ** structure must be typedefed in order to work around compiler warnings ** on some platforms. */ typedef struct sqlite3_api_routines sqlite3_api_routines; -/* -** CAPI3REF: File Name -** -** Type [sqlite3_filename] is used by SQLite to pass filenames to the -** xOpen method of a [VFS]. It may be cast to (const char*) and treated -** as a normal, nul-terminated, UTF-8 buffer containing the filename, but -** may also be passed to special APIs such as: -** -**
        -**
      • sqlite3_filename_database() -**
      • sqlite3_filename_journal() -**
      • sqlite3_filename_wal() -**
      • sqlite3_uri_parameter() -**
      • sqlite3_uri_boolean() -**
      • sqlite3_uri_int64() -**
      • sqlite3_uri_key() -**
      -*/ -typedef const char *sqlite3_filename; - /* ** CAPI3REF: OS Interface Object ** ** An instance of the sqlite3_vfs object defines the interface between ** the SQLite core and the underlying operating system. The "vfs" @@ -1466,11 +1429,11 @@ int szOsFile; /* Size of subclassed sqlite3_file */ int mxPathname; /* Maximum file pathname length */ sqlite3_vfs *pNext; /* Next registered VFS */ const char *zName; /* Name of this virtual file system */ void *pAppData; /* Pointer to application-specific data */ - int (*xOpen)(sqlite3_vfs*, sqlite3_filename zName, sqlite3_file*, + int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, int flags, int *pOutFlags); int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut); int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); @@ -1653,27 +1616,24 @@ ** ** The sqlite3_config() interface is not threadsafe. The application ** must ensure that no other SQLite interfaces are invoked by other ** threads while sqlite3_config() is running. ** +** The sqlite3_config() interface +** may only be invoked prior to library initialization using +** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()]. +** ^If sqlite3_config() is called after [sqlite3_initialize()] and before +** [sqlite3_shutdown()] then it will return SQLITE_MISUSE. +** Note, however, that ^sqlite3_config() can be called as part of the +** implementation of an application-defined [sqlite3_os_init()]. +** ** The first argument to sqlite3_config() is an integer ** [configuration option] that determines ** what property of SQLite is to be configured. Subsequent arguments ** vary depending on the [configuration option] ** in the first argument. ** -** For most configuration options, the sqlite3_config() interface -** may only be invoked prior to library initialization using -** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()]. -** The exceptional configuration options that may be invoked at any time -** are called "anytime configuration options". -** ^If sqlite3_config() is called after [sqlite3_initialize()] and before -** [sqlite3_shutdown()] with a first argument that is not an anytime -** configuration option, then the sqlite3_config() call will return SQLITE_MISUSE. -** Note, however, that ^sqlite3_config() can be called as part of the -** implementation of an application-defined [sqlite3_os_init()]. -** ** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK]. ** ^If the option is unknown or SQLite is unable to set the option ** then this routine returns a non-zero [error code]. */ SQLITE_API int sqlite3_config(int, ...); @@ -1777,27 +1737,10 @@ ** KEYWORDS: {configuration option} ** ** These constants are the available integer configuration options that ** can be passed as the first argument to the [sqlite3_config()] interface. ** -** Most of the configuration options for sqlite3_config() -** will only work if invoked prior to [sqlite3_initialize()] or after -** [sqlite3_shutdown()]. The few exceptions to this rule are called -** "anytime configuration options". -** ^Calling [sqlite3_config()] with a first argument that is not an -** anytime configuration option in between calls to [sqlite3_initialize()] and -** [sqlite3_shutdown()] is a no-op that returns SQLITE_MISUSE. -** -** The set of anytime configuration options can change (by insertions -** and/or deletions) from one release of SQLite to the next. -** As of SQLite version 3.42.0, the complete set of anytime configuration -** options is: -**
        -**
      • SQLITE_CONFIG_LOG -**
      • SQLITE_CONFIG_PCACHE_HDRSZ -**
      -** ** New configuration options may be added in future releases of SQLite. ** Existing configuration options might be discontinued. Applications ** should check the return code from [sqlite3_config()] to make sure that ** the call worked. The [sqlite3_config()] interface will return a ** non-zero [error code] if a discontinued or unsupported configuration option @@ -2202,11 +2145,11 @@ ** 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 -** [sqlite3_db_status](D,[SQLITE_DBSTATUS_LOOKASIDE_USED],...) is zero. +** [sqlite3_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].)^ ** ** [[SQLITE_DBCONFIG_ENABLE_FKEY]] @@ -2352,16 +2295,12 @@ **
    16. sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0); **
    17. [sqlite3_exec](db, "[VACUUM]", 0, 0, 0); **
    18. sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0); ** ** Because resetting a database is destructive and irreversible, the -** process requires the use of this obscure API and multiple steps to -** help ensure that it does not happen by accident. Because this -** feature must be capable of resetting corrupt databases, and -** shutting down virtual tables may require access to that corrupt -** storage, the library must abandon any installed virtual tables -** without calling their xDestroy() methods. +** process requires the use of this obscure API and multiple steps to help +** ensure that it does not happen by accident. ** ** [[SQLITE_DBCONFIG_DEFENSIVE]]
      SQLITE_DBCONFIG_DEFENSIVE
      **
      The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the ** "defensive" flag for a database connection. When the defensive ** flag is enabled, language features that allow ordinary SQL to @@ -2368,11 +2307,10 @@ ** deliberately corrupt the database file are disabled. The disabled ** features include but are not limited to the following: **
        **
      • The [PRAGMA writable_schema=ON] statement. **
      • The [PRAGMA journal_mode=OFF] statement. -**
      • The [PRAGMA schema_version=N] statement. **
      • Writes to the [sqlite_dbpage] virtual table. **
      • Direct writes to [shadow tables]. **
      **
      ** @@ -2454,30 +2392,10 @@ ** the [VACUUM] command will fail with an obscure error when attempting to ** process a table with generated columns and a descending index. This is ** not considered a bug since SQLite versions 3.3.0 and earlier do not support ** either generated columns or decending indexes. ** -** -** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]] -**
      SQLITE_DBCONFIG_STMT_SCANSTATUS -**
      The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in -** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears -** a flag that enables collection of the sqlite3_stmt_scanstatus_v2() -** statistics. For statistics to be collected, the flag must be set on -** the database handle both when the SQL statement is prepared and when it -** is stepped. The flag is set (collection of statistics is enabled) -** by default.
      -** -** [[SQLITE_DBCONFIG_REVERSE_SCANORDER]] -**
      SQLITE_DBCONFIG_REVERSE_SCANORDER -**
      The SQLITE_DBCONFIG_REVERSE_SCANORDER option change the default order -** in which tables and indexes are scanned so that the scans start at the end -** and work toward the beginning rather than starting at the beginning and -** working toward the end. Setting SQLITE_DBCONFIG_REVERSE_SCANORDER is the -** same as setting [PRAGMA reverse_unordered_selects]. This configuration option -** is useful for application testing.
      -** ** */ #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ #define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ @@ -2494,13 +2412,11 @@ #define SQLITE_DBCONFIG_DQS_DML 1013 /* int int* */ #define SQLITE_DBCONFIG_DQS_DDL 1014 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */ #define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 1016 /* int int* */ #define SQLITE_DBCONFIG_TRUSTED_SCHEMA 1017 /* int int* */ -#define SQLITE_DBCONFIG_STMT_SCANSTATUS 1018 /* int int* */ -#define SQLITE_DBCONFIG_REVERSE_SCANORDER 1019 /* int int* */ -#define SQLITE_DBCONFIG_MAX 1019 /* Largest DBCONFIG */ +#define SQLITE_DBCONFIG_MAX 1017 /* Largest DBCONFIG */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes ** METHOD: sqlite3 ** @@ -2718,16 +2634,12 @@ ** that are started after the running statement count reaches zero are ** not effected by the sqlite3_interrupt(). ** ^A call to sqlite3_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 sqlite3_interrupt() call returns. -** -** ^The [sqlite3_is_interrupted(D)] interface can be used to determine whether -** or not an interrupt is currently in effect for [database connection] D. */ SQLITE_API void sqlite3_interrupt(sqlite3*); -SQLITE_API int sqlite3_is_interrupted(sqlite3*); /* ** CAPI3REF: Determine If An SQL Statement Is Complete ** ** These routines are useful during command-line input to determine if the @@ -3341,12 +3253,12 @@ ** ** [[SQLITE_TRACE_PROFILE]]
      SQLITE_TRACE_PROFILE
      **
      ^An SQLITE_TRACE_PROFILE callback provides approximately the same ** information as is provided by the [sqlite3_profile()] callback. ** ^The P argument is a pointer to the [prepared statement] and the -** X argument points to a 64-bit integer which is approximately -** the number of nanoseconds that the prepared statement took to run. +** X argument points to a 64-bit integer which is the estimated of +** the number of nanosecond that the prepared statement took to run. ** ^The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes. ** ** [[SQLITE_TRACE_ROW]]
      SQLITE_TRACE_ROW
      **
      ^An SQLITE_TRACE_ROW callback is invoked whenever a prepared ** statement generates a single row of result. @@ -3405,11 +3317,11 @@ ** CAPI3REF: Query Progress Callbacks ** METHOD: sqlite3 ** ** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback ** function X to be invoked periodically during long running calls to -** [sqlite3_step()] and [sqlite3_prepare()] and similar for +** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] 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 approximate number of @@ -3430,17 +3342,10 @@ ** The progress handler callback must not do anything that will modify ** the database connection that invoked the progress handler. ** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their ** database connections for the meaning of "modify" in this paragraph. ** -** The progress handler callback would originally only be invoked from the -** bytecode engine. It still might be invoked during [sqlite3_prepare()] -** and similar because those routines might force a reparse of the schema -** which involves running the bytecode engine. However, beginning with -** SQLite version 3.41.0, the progress handler callback might also be -** invoked directly from [sqlite3_prepare()] while analyzing and generating -** code for complex queries. */ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); /* ** CAPI3REF: Opening A New Database Connection @@ -3473,22 +3378,17 @@ ** sqlite3_open_v2() must include, at a minimum, one of the following ** three flag combinations:)^ ** **
      ** ^(
      [SQLITE_OPEN_READONLY]
      -**
      The database is opened in read-only mode. If the database does -** not already exist, an error is returned.
      )^ +**
      The database is opened in read-only mode. If the database does not +** already exist, an error is returned.
      )^ ** ** ^(
      [SQLITE_OPEN_READWRITE]
      -**
      The database is opened for reading and writing if possible, or -** reading only if the file is write protected by the operating -** system. In either case the database must already exist, otherwise -** an error is returned. For historical reasons, if opening in -** read-write mode fails due to OS-level permissions, an attempt is -** made to open it in read-only mode. [sqlite3_db_readonly()] can be -** used to determine whether the database is actually -** read-write.
      )^ +**
      The database is opened for reading and writing if possible, or reading +** only if the file is write protected by the operating system. In either +** case the database must already exist, otherwise an error is returned.
      )^ ** ** ^(
      [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]
      **
      The database is opened for reading and writing, and is created if ** it does not already exist. This is the behavior that is always used for ** sqlite3_open() and sqlite3_open16().
      )^ @@ -3522,13 +3422,10 @@ ** ** ^(
      [SQLITE_OPEN_SHAREDCACHE]
      **
      The database is opened [shared cache] enabled, overriding ** the default shared cache setting provided by ** [sqlite3_enable_shared_cache()].)^ -** The [use of shared cache mode is discouraged] and hence shared cache -** capabilities may be omitted from many builds of SQLite. In such cases, -** this option is a no-op. ** ** ^(
      [SQLITE_OPEN_PRIVATECACHE]
      **
      The database is opened [shared cache] disabled, overriding ** the default shared cache setting provided by ** [sqlite3_enable_shared_cache()].)^ @@ -3540,11 +3437,11 @@ ** connection as soon as the connection is created. In addition to setting ** the extended result code mode, this flag also causes [sqlite3_open_v2()] ** to return an extended result code.
      ** ** [[OPEN_NOFOLLOW]] ^(
      [SQLITE_OPEN_NOFOLLOW]
      -**
      The database filename is not allowed to contain a symbolic link
      +**
      The database filename is not allowed to be a symbolic link
      **
      )^ ** ** If the 3rd parameter to sqlite3_open_v2() is not one of the ** required combinations shown above optionally combined with other ** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits] @@ -3799,14 +3696,14 @@ ** it has access to all the same query parameters as were found on the ** main database file. ** ** See the [URI filename] documentation for additional information. */ -SQLITE_API const char *sqlite3_uri_parameter(sqlite3_filename z, const char *zParam); -SQLITE_API int sqlite3_uri_boolean(sqlite3_filename z, const char *zParam, int bDefault); -SQLITE_API sqlite3_int64 sqlite3_uri_int64(sqlite3_filename, const char*, sqlite3_int64); -SQLITE_API const char *sqlite3_uri_key(sqlite3_filename z, int N); +SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam); +SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); +SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64); +SQLITE_API const char *sqlite3_uri_key(const char *zFilename, int N); /* ** CAPI3REF: Translate filenames ** ** These routines are available to [VFS|custom VFS implementations] for @@ -3831,13 +3728,13 @@ ** In all of the above, if F is not the name of a database, journal or WAL ** filename passed into the VFS from the SQLite core and F is not the ** return value from [sqlite3_db_filename()], then the result is ** undefined and is likely a memory access violation. */ -SQLITE_API const char *sqlite3_filename_database(sqlite3_filename); -SQLITE_API const char *sqlite3_filename_journal(sqlite3_filename); -SQLITE_API const char *sqlite3_filename_wal(sqlite3_filename); +SQLITE_API const char *sqlite3_filename_database(const char*); +SQLITE_API const char *sqlite3_filename_journal(const char*); +SQLITE_API const char *sqlite3_filename_wal(const char*); /* ** CAPI3REF: Database File Corresponding To A Journal ** ** ^If X is the name of a rollback or WAL-mode journal file that is @@ -3899,18 +3796,18 @@ ** used again after sqlite3_free_filename(Y) has been called. This means ** that if the [sqlite3_vfs.xOpen()] method of a VFS has been called using Y, ** then the corresponding [sqlite3_module.xClose() method should also be ** invoked prior to calling sqlite3_free_filename(Y). */ -SQLITE_API sqlite3_filename sqlite3_create_filename( +SQLITE_API char *sqlite3_create_filename( const char *zDatabase, const char *zJournal, const char *zWal, int nParam, const char **azParam ); -SQLITE_API void sqlite3_free_filename(sqlite3_filename); +SQLITE_API void sqlite3_free_filename(char*); /* ** CAPI3REF: Error Codes And Messages ** METHOD: sqlite3 ** @@ -5465,25 +5362,14 @@ ** [[SQLITE_DIRECTONLY]]
      SQLITE_DIRECTONLY
      ** The SQLITE_DIRECTONLY flag means that the function may only be invoked ** from top-level SQL, and cannot be used in VIEWs or TRIGGERs nor in ** schema structures such as [CHECK constraints], [DEFAULT clauses], ** [expression indexes], [partial indexes], or [generated columns]. -**

      -** The SQLITE_DIRECTONLY flag is recommended for any -** [application-defined SQL function] -** that has side-effects or that could potentially leak sensitive information. -** This will prevent attacks in which an application is tricked -** into using a database file that has had its schema surreptiously -** modified to invoke the application-defined function in ways that are -** harmful. -**

      -** Some people say it is good practice to set SQLITE_DIRECTONLY on all -** [application-defined SQL functions], regardless of whether or not they -** are security sensitive, as doing so prevents those functions from being used -** inside of the database schema, and thus ensures that the database -** can be inspected and modified using generic tools (such as the [CLI]) -** that do not have access to the application-defined functions. +** The SQLITE_DIRECTONLY flags is a security feature which is recommended +** for all [application-defined SQL functions], and especially for functions +** that have side-effects or that could potentially leak sensitive +** information. **

      ** ** [[SQLITE_INNOCUOUS]]
      SQLITE_INNOCUOUS
      ** The SQLITE_INNOCUOUS flag means that the function is unlikely ** to cause problems even if misused. An innocuous function should have @@ -5685,32 +5571,10 @@ SQLITE_API int sqlite3_value_type(sqlite3_value*); SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); SQLITE_API int sqlite3_value_nochange(sqlite3_value*); SQLITE_API int sqlite3_value_frombind(sqlite3_value*); -/* -** CAPI3REF: Report the internal text encoding state of an sqlite3_value object -** METHOD: sqlite3_value -** -** ^(The sqlite3_value_encoding(X) interface returns one of [SQLITE_UTF8], -** [SQLITE_UTF16BE], or [SQLITE_UTF16LE] according to the current text encoding -** of the value X, assuming that X has type TEXT.)^ If sqlite3_value_type(X) -** returns something other than SQLITE_TEXT, then the return value from -** sqlite3_value_encoding(X) is meaningless. ^Calls to -** [sqlite3_value_text(X)], [sqlite3_value_text16(X)], [sqlite3_value_text16be(X)], -** [sqlite3_value_text16le(X)], [sqlite3_value_bytes(X)], or -** [sqlite3_value_bytes16(X)] might change the encoding of the value X and -** thus change the return from subsequent calls to sqlite3_value_encoding(X). -** -** This routine is intended for used by applications that test and validate -** the SQLite implementation. This routine is inquiring about the opaque -** internal state of an [sqlite3_value] object. Ordinary applications should -** not need to know what the internal state of an sqlite3_value object is and -** hence should not need to use this interface. -*/ -SQLITE_API int sqlite3_value_encoding(sqlite3_value*); - /* ** CAPI3REF: Finding The Subtype Of SQL Values ** METHOD: sqlite3_value ** ** The sqlite3_value_subtype(V) function returns the subtype for @@ -5727,12 +5591,11 @@ ** ** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value] ** object D and returns a pointer to that copy. ^The [sqlite3_value] returned ** is a [protected sqlite3_value] object even if the input is not. ** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a -** memory allocation fails. ^If V is a [pointer value], then the result -** of sqlite3_value_dup(V) is a NULL value. +** memory allocation fails. ** ** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object ** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer ** then sqlite3_value_free(V) is a harmless no-op. */ @@ -5759,11 +5622,11 @@ ** In those cases, sqlite3_aggregate_context() might be called for the ** first time from within xFinal().)^ ** ** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer ** when first called if N is less than or equal to zero or if a memory -** allocation error occurs. +** allocate error occurs. ** ** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is ** determined by the N parameter on first successful call. Changing the ** value of N in any subsequent call to sqlite3_aggregate_context() within ** the same aggregate function instance will not resize the memory @@ -5964,14 +5827,13 @@ ** application-defined function to be a text string in an encoding ** specified by the fifth (and last) parameter, which must be one ** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]. ** ^SQLite takes the text result from the application from ** the 2nd parameter of the sqlite3_result_text* interfaces. -** ^If the 3rd parameter to any of the sqlite3_result_text* interfaces -** other than sqlite3_result_text64() is negative, then SQLite computes -** the string length itself by searching the 2nd parameter for the first -** zero character. +** ^If the 3rd parameter to the sqlite3_result_text* interfaces +** is negative, then SQLite takes result text from the 2nd parameter +** through the first zero character. ** ^If the 3rd parameter to the sqlite3_result_text* interfaces ** is non-negative, then as many bytes (not characters) of the text ** pointed to by the 2nd parameter are taken as the application-defined ** function result. If the 3rd parameter is non-negative, then it ** must be the byte offset into the string where the NUL terminator would @@ -6411,32 +6273,10 @@ ** to the [sqlite3_prepare_v2()] call (or its variants) that was used to ** create the statement in the first place. */ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); -/* -** CAPI3REF: Return The Schema Name For A Database Connection -** METHOD: sqlite3 -** -** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name -** for the N-th database on database connection D, or a NULL pointer of N is -** out of range. An N value of 0 means the main database file. An N of 1 is -** the "temp" schema. Larger values of N correspond to various ATTACH-ed -** databases. -** -** Space to hold the string that is returned by sqlite3_db_name() is managed -** by SQLite itself. The string might be deallocated by any operation that -** changes the schema, including [ATTACH] or [DETACH] or calls to -** [sqlite3_serialize()] or [sqlite3_deserialize()], even operations that -** occur on a different thread. Applications that need to -** remember the string long-term should make their own copy. Applications that -** are accessing the same database connection simultaneously on multiple -** threads should mutex-protect calls to this API and should make their own -** private copy of the result prior to releasing the mutex. -*/ -SQLITE_API const char *sqlite3_db_name(sqlite3 *db, int N); - /* ** CAPI3REF: Return The Filename For A Database Connection ** METHOD: sqlite3 ** ** ^The sqlite3_db_filename(D,N) interface returns a pointer to the filename @@ -6463,11 +6303,11 @@ **
    19. [sqlite3_filename_database()] **
    20. [sqlite3_filename_journal()] **
    21. [sqlite3_filename_wal()] ** */ -SQLITE_API sqlite3_filename sqlite3_db_filename(sqlite3 *db, const char *zDbName); +SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); /* ** CAPI3REF: Determine if a database is read-only ** METHOD: sqlite3 ** @@ -6600,11 +6440,11 @@ ** ** ^The sqlite3_autovacuum_pages(D,C,P,X) interface registers a callback ** function C that is invoked prior to each autovacuum of the database ** file. ^The callback is passed a copy of the generic data pointer (P), ** the schema-name of the attached database that is being autovacuumed, -** the size of the database file in pages, the number of free pages, +** the the size of the database file in pages, the number of free pages, ** and the number of bytes per page, respectively. The callback should ** return the number of free pages that should be removed by the ** autovacuum. ^If the callback returns zero, then no autovacuum happens. ** ^If the value returned is greater than or equal to the number of ** free pages, then a complete autovacuum happens. @@ -6721,15 +6561,10 @@ ** ^(This routine enables or disables the sharing of the database cache ** and schema data structures between [database connection | connections] ** to the same database. Sharing is enabled if the argument is true ** and disabled if the argument is false.)^ ** -** This interface is omitted if SQLite is compiled with -** [-DSQLITE_OMIT_SHARED_CACHE]. The [-DSQLITE_OMIT_SHARED_CACHE] -** compile-time option is recommended because the -** [use of shared cache mode is discouraged]. -** ** ^Cache sharing is enabled and disabled for an entire process. ** This is a change as of SQLite [version 3.5.0] ([dateof:3.5.0]). ** In prior versions of SQLite, ** sharing was enabled or disabled for each thread separately. ** @@ -6824,11 +6659,11 @@ ** ^Setting the heap limits to zero disables the heap limiter mechanism. ** ** ^The soft heap limit may not be greater than the hard heap limit. ** ^If the hard heap limit is enabled and if sqlite3_soft_heap_limit(N) ** is invoked with a value of N that is greater than the hard heap limit, -** the soft heap limit is set to the value of the hard heap limit. +** the the soft heap limit is set to the value of the hard heap limit. ** ^The soft heap limit is automatically enabled whenever the hard heap ** limit is enabled. ^When sqlite3_hard_heap_limit64(N) is invoked and ** the soft heap limit is outside the range of 1..N, then the soft heap ** limit is set to N. ^Invoking sqlite3_soft_heap_limit64(0) when the ** hard heap limit is enabled makes the soft heap limit equal to the @@ -7085,10 +6920,19 @@ ** ^This interface disables all automatic extensions previously ** registered using [sqlite3_auto_extension()]. */ SQLITE_API void sqlite3_reset_auto_extension(void); +/* +** 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 sqlite3_vtab sqlite3_vtab; typedef struct sqlite3_index_info sqlite3_index_info; @@ -7203,14 +7047,14 @@ ** checked separately in byte code. If the omit flag is change to true, then ** the constraint may or may not be checked in byte code. In other words, ** when the omit flag is true there is no guarantee that the constraint will ** not be checked again using byte code.)^ ** -** ^The idxNum and idxStr values are recorded and passed into the +** ^The idxNum and idxPtr values are recorded and passed into the ** [xFilter] method. -** ^[sqlite3_free()] is used to free idxStr if and only if -** needToFreeIdxStr is true. +** ^[sqlite3_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. ** @@ -7326,11 +7170,11 @@ ** ** The collating sequence to be used for comparison can be found using ** the [sqlite3_vtab_collation()] interface. For most real-world virtual ** tables, the collating sequence of constraints does not matter (for example ** because the constraints are numeric) and so the sqlite3_vtab_collation() -** interface is not commonly needed. +** interface is no commonly needed. */ #define SQLITE_INDEX_CONSTRAINT_EQ 2 #define SQLITE_INDEX_CONSTRAINT_GT 4 #define SQLITE_INDEX_CONSTRAINT_LE 8 #define SQLITE_INDEX_CONSTRAINT_LT 16 @@ -7484,10 +7328,20 @@ ** 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 sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); + +/* +** The interface to the virtual-table mechanism defined above (back up +** to a comment remarkably similar to this one) 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. +*/ /* ** CAPI3REF: A Handle To An Open BLOB ** KEYWORDS: {BLOB handle} {BLOB handles} ** @@ -9100,11 +8954,11 @@ ** sqlite3_backup_init() is called and before the corresponding call to ** sqlite3_backup_finish(). SQLite does not currently check to see ** if the application incorrectly accesses the destination [database connection] ** and so no error code is reported, but the operations may malfunction ** nevertheless. Use of the destination database connection while a -** backup is in progress might also cause a mutex deadlock. +** backup is in progress might also also cause a mutex deadlock. ** ** If running in [shared cache mode], the application must ** guarantee that the shared cache used by the destination database ** is not accessed while the backup is running. In practice this means ** that the application must guarantee that the disk file being @@ -9528,11 +9382,11 @@ ** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the ** meaning of each of these checkpoint modes. */ #define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */ #define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */ -#define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for readers */ +#define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for for readers */ #define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */ /* ** CAPI3REF: Virtual Table Interface Configuration ** @@ -9604,32 +9458,22 @@ **
    22. ** ** [[SQLITE_VTAB_INNOCUOUS]]
      SQLITE_VTAB_INNOCUOUS
      **
      Calls of the form ** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the -** the [xConnect] or [xCreate] methods of a [virtual table] implementation +** the [xConnect] or [xCreate] methods of a [virtual table] implmentation ** identify that virtual table as being safe to use from within triggers ** and views. Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the ** virtual table can do no serious harm even if it is controlled by a ** malicious hacker. Developers should avoid setting the SQLITE_VTAB_INNOCUOUS ** flag unless absolutely necessary. **
      -** -** [[SQLITE_VTAB_USES_ALL_SCHEMAS]]
      SQLITE_VTAB_USES_ALL_SCHEMAS
      -**
      Calls of the form -** [sqlite3_vtab_config](db,SQLITE_VTAB_USES_ALL_SCHEMA) from within the -** the [xConnect] or [xCreate] methods of a [virtual table] implementation -** instruct the query planner to begin at least a read transaction on -** all schemas ("main", "temp", and any ATTACH-ed databases) whenever the -** virtual table is used. -**
      ** */ #define SQLITE_VTAB_CONSTRAINT_SUPPORT 1 #define SQLITE_VTAB_INNOCUOUS 2 #define SQLITE_VTAB_DIRECTONLY 3 -#define SQLITE_VTAB_USES_ALL_SCHEMAS 4 /* ** CAPI3REF: Determine The Virtual Table Conflict Policy ** ** This function may only be called from within a call to the [xUpdate] method @@ -9698,22 +9542,22 @@ ** statement that was passed into [sqlite3_declare_vtab()], then the ** name of that alternative collating sequence is returned. **
    23. Otherwise, "BINARY" is returned. ** */ -SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int); +SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int); /* ** CAPI3REF: Determine if a virtual table query is DISTINCT ** METHOD: sqlite3_index_info ** ** This API may only be used from within an [xBestIndex|xBestIndex method] ** of a [virtual table] implementation. The result of calling this ** interface from outside of xBestIndex() is undefined and probably harmful. ** -** ^The sqlite3_vtab_distinct() interface returns an integer between 0 and -** 3. The integer returned by sqlite3_vtab_distinct() +** ^The sqlite3_vtab_distinct() interface returns an integer that is +** either 0, 1, or 2. The integer returned by sqlite3_vtab_distinct() ** gives the virtual table additional information about how the query ** planner wants the output to be ordered. As long as the virtual table ** can meet the ordering requirements of the query planner, it may set ** the "orderByConsumed" flag. ** @@ -9741,17 +9585,10 @@ ** values in all "aOrderBy" columns to be returned, as long as all such rows ** are adjacent. ^The virtual table may, if it chooses, omit extra rows ** that have the same value for all columns identified by "aOrderBy". ** ^However omitting the extra rows is optional. ** This mode is used for a DISTINCT query. -**

    24. -** ^(If the sqlite3_vtab_distinct() interface returns 3, that means -** that the query planner needs only distinct rows but it does need the -** rows to be sorted.)^ ^The virtual table implementation is free to omit -** rows that are identical in all aOrderBy columns, if it wants to, but -** it is not required to omit any rows. This mode is used for queries -** that have both DISTINCT and ORDER BY clauses. ** ** ** ^For the purposes of comparing virtual table output values to see if the ** values are same value for sorting purposes, two NULL values are considered ** to be the same. In other words, the comparison operator is "IS" @@ -9855,24 +9692,25 @@ ** [xFilter|xFilter() method] of a [virtual table] implementation. ** The result of invoking these interfaces from any other context ** is undefined and probably harmful. ** ** The X parameter in a call to sqlite3_vtab_in_first(X,P) or -** sqlite3_vtab_in_next(X,P) should be one of the parameters to the +** sqlite3_vtab_in_next(X,P) must be one of the parameters to the ** xFilter method which invokes these routines, and specifically ** a parameter that was previously selected for all-at-once IN constraint ** processing use the [sqlite3_vtab_in()] interface in the ** [xBestIndex|xBestIndex method]. ^(If the X parameter is not ** an xFilter argument that was selected for all-at-once IN constraint -** processing, then these routines return [SQLITE_ERROR].)^ +** processing, then these routines return [SQLITE_MISUSE])^ or perhaps +** exhibit some other undefined or harmful behavior. ** ** ^(Use these routines to access all values on the right-hand side ** of the IN constraint using code like the following: ** **

       **    for(rc=sqlite3_vtab_in_first(pList, &pVal);
      -**        rc==SQLITE_OK && pVal;
      +**        rc==SQLITE_OK && pVal
       **        rc=sqlite3_vtab_in_next(pList, &pVal)
       **    ){
       **      // do something with pVal
       **    }
       **    if( rc!=SQLITE_OK ){
      @@ -9966,14 +9804,10 @@
       **
       ** When the value returned to V is a string, space to hold that string is
       ** managed by the prepared statement S and will be automatically freed when
       ** S is finalized.
       **
      -** Not all values are available for all query elements. When a value is
      -** not available, the output variable is set to -1 if the value is numeric,
      -** or to NULL if it is a string (SQLITE_SCANSTAT_NAME).
      -**
       ** 
      ** [[SQLITE_SCANSTAT_NLOOP]]
      SQLITE_SCANSTAT_NLOOP
      **
      ^The [sqlite3_int64] variable pointed to by the V parameter will be ** set to the total number of times that the X-th loop has run.
      ** @@ -9997,44 +9831,30 @@ ** [[SQLITE_SCANSTAT_EXPLAIN]]
      SQLITE_SCANSTAT_EXPLAIN
      **
      ^The "const char *" variable pointed to by the V parameter will be set ** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] ** description for the X-th loop. ** -** [[SQLITE_SCANSTAT_SELECTID]]
      SQLITE_SCANSTAT_SELECTID
      +** [[SQLITE_SCANSTAT_SELECTID]]
      SQLITE_SCANSTAT_SELECT
      **
      ^The "int" variable pointed to by the V parameter will be set to the -** id for the X-th query plan element. The id value is unique within the -** statement. The select-id is the same value as is output in the first -** column of an [EXPLAIN QUERY PLAN] query. -** -** [[SQLITE_SCANSTAT_PARENTID]]
      SQLITE_SCANSTAT_PARENTID
      -**
      The "int" variable pointed to by the V parameter will be set to the -** the id of the parent of the current query element, if applicable, or -** to zero if the query element has no parent. This is the same value as -** returned in the second column of an [EXPLAIN QUERY PLAN] query. -** -** [[SQLITE_SCANSTAT_NCYCLE]]
      SQLITE_SCANSTAT_NCYCLE
      -**
      The sqlite3_int64 output value is set to the number of cycles, -** according to the processor time-stamp counter, that elapsed while the -** query element was being processed. This value is not available for -** all query elements - if it is unavailable the output variable is -** set to -1. +** "select-id" for the X-th loop. The select-id identifies which query or +** subquery the loop is part of. The main query has a select-id of zero. +** The select-id is the same value as is output in the first column +** of an [EXPLAIN QUERY PLAN] query. **
      */ #define SQLITE_SCANSTAT_NLOOP 0 #define SQLITE_SCANSTAT_NVISIT 1 #define SQLITE_SCANSTAT_EST 2 #define SQLITE_SCANSTAT_NAME 3 #define SQLITE_SCANSTAT_EXPLAIN 4 #define SQLITE_SCANSTAT_SELECTID 5 -#define SQLITE_SCANSTAT_PARENTID 6 -#define SQLITE_SCANSTAT_NCYCLE 7 /* ** CAPI3REF: Prepared Statement Scan Status ** METHOD: sqlite3_stmt ** -** These interfaces return information about the predicted and measured +** This interface returns information about the predicted and measured ** performance for pStmt. Advanced applications can use this ** interface to compare the predicted and the measured performance and ** issue warnings and/or rerun [ANALYZE] if discrepancies are found. ** ** Since this interface is expected to be rarely used, it is only @@ -10041,51 +9861,32 @@ ** available if SQLite is compiled using the [SQLITE_ENABLE_STMT_SCANSTATUS] ** compile-time option. ** ** The "iScanStatusOp" parameter determines which status information to return. ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior -** of this interface is undefined. ^The requested measurement is written into -** a variable pointed to by the "pOut" parameter. -** -** The "flags" parameter must be passed a mask of flags. At present only -** one flag is defined - SQLITE_SCANSTAT_COMPLEX. If SQLITE_SCANSTAT_COMPLEX -** is specified, then status information is available for all elements -** of a query plan that are reported by "EXPLAIN QUERY PLAN" output. If -** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements -** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of -** the EXPLAIN QUERY PLAN output) are available. Invoking API -** sqlite3_stmt_scanstatus() is equivalent to calling -** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter. -** -** Parameter "idx" identifies the specific query element to retrieve statistics -** for. Query elements are numbered starting from zero. A value of -1 may be -** to query for statistics regarding the entire query. ^If idx is out of range -** - less than -1 or greater than or equal to the total number of query -** elements used to implement the statement - a non-zero value is returned and -** the variable that pOut points to is unchanged. +** of this interface is undefined. +** ^The requested measurement is written into a variable pointed to by +** the "pOut" parameter. +** Parameter "idx" identifies the specific loop to retrieve statistics for. +** Loops are numbered starting from zero. ^If idx is out of range - less than +** zero or greater than or equal to the total number of loops used to implement +** the statement - a non-zero value is returned and the variable that pOut +** points to is unchanged. +** +** ^Statistics might not be available for all loops in all statements. ^In cases +** where there exist loops with no available statistics, this function behaves +** as if the loop did not exist - it returns non-zero and leave the variable +** that pOut points to unchanged. ** ** See also: [sqlite3_stmt_scanstatus_reset()] */ SQLITE_API int sqlite3_stmt_scanstatus( sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ int idx, /* Index of loop to report on */ int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ void *pOut /* Result written here */ ); -SQLITE_API int sqlite3_stmt_scanstatus_v2( - sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ - int idx, /* Index of loop to report on */ - int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ - int flags, /* Mask of flags defined below */ - void *pOut /* Result written here */ -); - -/* -** CAPI3REF: Prepared Statement Scan Status -** KEYWORDS: {scan status flags} -*/ -#define SQLITE_SCANSTAT_COMPLEX 0x0001 /* ** CAPI3REF: Zero Scan-Status Counters ** METHOD: sqlite3_stmt ** @@ -10172,14 +9973,10 @@ ** seventh parameter is the final rowid value of the row being inserted ** or updated. The value of the seventh parameter passed to the callback ** function is not defined for operations on WITHOUT ROWID tables, or for ** DELETE operations on rowid tables. ** -** ^The sqlite3_preupdate_hook(D,C,P) function returns the P argument from -** the previous call on the same [database connection] D, or NULL for -** the first call on D. -** ** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()], ** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces ** provide additional information about a preupdate event. These routines ** may only be called from within a preupdate callback. Invoking any of ** these routines from outside of a preupdate callback or with a @@ -10581,23 +10378,10 @@ */ #ifdef SQLITE_OMIT_FLOATING_POINT # undef double #endif -#if defined(__wasi__) -# undef SQLITE_WASI -# define SQLITE_WASI 1 -# undef SQLITE_OMIT_WAL -# define SQLITE_OMIT_WAL 1/* because it requires shared memory APIs */ -# ifndef SQLITE_OMIT_LOAD_EXTENSION -# define SQLITE_OMIT_LOAD_EXTENSION -# endif -# ifndef SQLITE_THREADSAFE -# define SQLITE_THREADSAFE 0 -# endif -#endif - #ifdef __cplusplus } /* End of the 'extern "C"' block */ #endif #endif /* SQLITE3_H */ @@ -11963,27 +11747,13 @@ ** **
      SQLITE_CHANGESETAPPLY_INVERT
      ** Invert the changeset before applying it. This is equivalent to inverting ** a changeset using sqlite3changeset_invert() before applying it. It is ** an error to specify this flag with a patchset. -** -**
      SQLITE_CHANGESETAPPLY_IGNORENOOP
      -** Do not invoke the conflict handler callback for any changes that -** would not actually modify the database even if they were applied. -** Specifically, this means that the conflict handler is not invoked -** for: -**
        -**
      • a delete change if the row being deleted cannot be found, -**
      • an update change if the modified fields are already set to -** their new values in the conflicting row, or -**
      • an insert change if all fields of the conflicting row match -** the row being inserted. -**
      */ #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001 #define SQLITE_CHANGESETAPPLY_INVERT 0x0002 -#define SQLITE_CHANGESETAPPLY_IGNORENOOP 0x0004 /* ** CAPI3REF: Constants Passed To The Conflict Handler ** ** Values that may be passed as the second argument to a conflict-handler. Index: lib/sqlite3ext.h ================================================================== --- lib/sqlite3ext.h +++ lib/sqlite3ext.h @@ -329,13 +329,13 @@ const char *(*uri_key)(const char*,int); const char *(*filename_database)(const char*); const char *(*filename_journal)(const char*); const char *(*filename_wal)(const char*); /* Version 3.32.0 and later */ - const char *(*create_filename)(const char*,const char*,const char*, + char *(*create_filename)(const char*,const char*,const char*, int,const char**); - void (*free_filename)(const char*); + void (*free_filename)(char*); sqlite3_file *(*database_file_object)(const char*); /* Version 3.34.0 and later */ int (*txn_state)(sqlite3*,const char*); /* Version 3.36.1 and later */ sqlite3_int64 (*changes64)(sqlite3*); @@ -349,20 +349,10 @@ int (*vtab_rhs_value)(sqlite3_index_info*,int,sqlite3_value**); int (*vtab_distinct)(sqlite3_index_info*); int (*vtab_in)(sqlite3_index_info*,int,int); int (*vtab_in_first)(sqlite3_value*,sqlite3_value**); int (*vtab_in_next)(sqlite3_value*,sqlite3_value**); - /* Version 3.39.0 and later */ - int (*deserialize)(sqlite3*,const char*,unsigned char*, - sqlite3_int64,sqlite3_int64,unsigned); - unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*, - unsigned int); - const char *(*db_name)(sqlite3*,int); - /* Version 3.40.0 and later */ - int (*value_encoding)(sqlite3_value*); - /* Version 3.41.0 and later */ - int (*is_interrupted)(sqlite3*); }; /* ** This is the function signature used for all extension entry points. It ** is also defined in the file "loadext.c". @@ -677,20 +667,10 @@ #define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value #define sqlite3_vtab_distinct sqlite3_api->vtab_distinct #define sqlite3_vtab_in sqlite3_api->vtab_in #define sqlite3_vtab_in_first sqlite3_api->vtab_in_first #define sqlite3_vtab_in_next sqlite3_api->vtab_in_next -/* Version 3.39.0 and later */ -#ifndef SQLITE_OMIT_DESERIALIZE -#define sqlite3_deserialize sqlite3_api->deserialize -#define sqlite3_serialize sqlite3_api->serialize -#endif -#define sqlite3_db_name sqlite3_api->db_name -/* Version 3.40.0 and later */ -#define sqlite3_value_encoding sqlite3_api->value_encoding -/* Version 3.41.0 and later */ -#define sqlite3_is_interrupted sqlite3_api->is_interrupted #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) /* This case when the file really is being compiled as a loadable ** extension */ ADDED signify/fnc-13-release.pub Index: signify/fnc-13-release.pub ================================================================== --- signify/fnc-13-release.pub +++ signify/fnc-13-release.pub @@ -0,0 +1,2 @@ +untrusted comment: fnc 0.13 public key +RWRBkQNnoj1IBcgbH7YSJa2155xwSKh7+TGI3jW8KwraJ/GGgXtJPp0I DELETED signify/fnc-15-release.pub Index: signify/fnc-15-release.pub ================================================================== --- signify/fnc-15-release.pub +++ signify/fnc-15-release.pub @@ -1,2 +0,0 @@ -untrusted comment: fnc 0.15 public key -RWQS5B3A9In6ctvJKfzZiJlWCSsUeuaxBIJZQ9tw6TLyGBqfkL9vTCRR