Overview
SHA1 Hash: | 0e82ba024cb8c46c32ff6c0fa051397634c6de84 |
---|---|
Date: | 2009-06-25 13:00:36 |
User: | drh |
Comment: | Update the SQLite implementation to the latest from CVS. |
Timelines: | ancestors | descendants | both | trunk |
Other Links: | files | ZIP archive | manifest |
Tags And Properties
- branch=trunk inherited from [a28c83647d]
- sym-trunk inherited from [a28c83647d]
Changes
[hide diffs]Modified src/sqlite3.c from [2829ea120f] to [f0d6caf19a].
@@ -1,8 +1,8 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.6.14. By combining all the individual C code files into this +** version 3.6.15. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a one translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements ** of 5% are more are commonly seen when SQLite is compiled as a single ** translation unit. @@ -9,17 +9,17 @@ ** ** This file is all you need to compile SQLite. To use SQLite in other ** programs, you need this file and the "sqlite3.h" header file that defines ** the programming interface to the SQLite library. (If you do not have ** the "sqlite3.h" header file at hand, you will find a copy in the first -** 5605 lines past this header comment.) Additional code files may be +** 5626 lines past this header comment.) Additional code files may be ** needed if you want a wrapper to interface SQLite with your choice of ** programming language. The code for the "sqlite3" command-line shell ** is also in a separate file. This file contains only code for the core ** SQLite library. ** -** This amalgamation was generated on 2009-06-07 12:34:52 UTC. +** This amalgamation was generated on 2009-06-23 14:42:37 UTC. */ #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 #ifndef SQLITE_PRIVATE # define SQLITE_PRIVATE static @@ -39,11 +39,11 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.882 2009/06/05 14:17:23 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.886 2009/06/19 14:06:03 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* @@ -545,11 +545,11 @@ ** The name of this file under configuration management is "sqlite.h.in". ** The makefile makes some minor changes to this file (such as inserting ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. ** -** @(#) $Id: sqlite.h.in,v 1.455 2009/05/24 21:59:28 drh Exp $ +** @(#) $Id: sqlite.h.in,v 1.458 2009/06/19 22:50:31 drh Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ #include <stdarg.h> /* Needed for the definition of va_list */ @@ -614,12 +614,12 @@ ** ** See also: [sqlite3_libversion()] and [sqlite3_libversion_number()]. ** ** Requirements: [H10011] [H10014] */ -#define SQLITE_VERSION "3.6.14" -#define SQLITE_VERSION_NUMBER 3006014 +#define SQLITE_VERSION "3.6.15" +#define SQLITE_VERSION_NUMBER 3006015 /* ** CAPI3REF: Run-Time Library Version Numbers {H10020} <S60100> ** KEYWORDS: sqlite3_version ** @@ -1009,10 +1009,16 @@ ** [sqlite3_file] object (or, more commonly, a subclass of the ** [sqlite3_file] object) with a pointer to an instance of this object. ** This object defines the methods used to perform various operations ** against the open file represented by the [sqlite3_file] object. ** +** If the xOpen method sets the sqlite3_file.pMethods element +** to a non-NULL pointer, then the sqlite3_io_methods.xClose method +** may be invoked even if the xOpen reported that it failed. The +** only way to prevent a call to xClose following a failed xOpen +** is for the xOpen to set the sqlite3_file.pMethods element to NULL. +** ** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or ** [SQLITE_SYNC_FULL]. The first choice is the normal fsync(). ** The second choice is a Mac OS X style fullsync. The [SQLITE_SYNC_DATAONLY] ** flag may be ORed in to indicate that only the data of the file ** and not its inode needs to be synced. @@ -1169,15 +1175,15 @@ ** ** SQLite will guarantee that the zFilename parameter to xOpen ** is either a NULL pointer or string obtained ** from xFullPathname(). SQLite further guarantees that ** the string will be valid and unchanged until xClose() is -** called. Because of the previous sentense, +** called. Because of the previous sentence, ** the [sqlite3_file] can safely store a pointer to the ** filename if it needs to remember the filename for some reason. ** If the zFilename parameter is xOpen is a NULL pointer then xOpen -** must invite its own temporary name for the file. Whenever the +** must invent its own temporary name for the file. Whenever the ** xFilename parameter is NULL it will also be the case that the ** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE]. ** ** The flags argument to xOpen() includes all bits set in ** the flags argument to [sqlite3_open_v2()]. Or if [sqlite3_open()] @@ -1229,11 +1235,16 @@ ** for exclusive access. ** ** At least szOsFile bytes of memory are allocated by SQLite ** to hold the [sqlite3_file] structure passed as the third ** argument to xOpen. The xOpen method does not have to -** allocate the structure; it should just fill it in. +** allocate the structure; it should just fill it in. Note that +** the xOpen method must set the sqlite3_file.pMethods to either +** a valid [sqlite3_io_methods] object or to NULL. xOpen must do +** this even if the open fails. SQLite expects that the sqlite3_file.pMethods +** element will be valid after xOpen returns regardless of the success +** or failure of the xOpen call. ** ** The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] ** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to ** test whether a file is readable and writable, or [SQLITE_ACCESS_READ] ** to test whether a file is at least readable. The file can be a @@ -1551,16 +1562,18 @@ ** </ul> ** </dd> ** ** <dt>SQLITE_CONFIG_SCRATCH</dt> ** <dd>This option specifies a static memory buffer that SQLite can use for -** scratch memory. There are three arguments: A pointer to the memory, the -** size of each scratch buffer (sz), and the number of buffers (N). The sz +** scratch memory. There are three arguments: A pointer an 8-byte +** aligned memory buffer from which the scrach allocations will be +** drawn, the size of each scratch allocation (sz), +** and the maximum number of scratch allocations (N). The sz ** argument must be a multiple of 16. The sz parameter should be a few bytes -** larger than the actual scratch space required due internal overhead. -** The first -** argument should point to an allocation of at least sz*N bytes of memory. +** larger than the actual scratch space required due to internal overhead. +** The first argument should pointer to an 8-byte aligned buffer +** of at least sz*N bytes of memory. ** SQLite will use no more than one scratch buffer at once per thread, so ** N should be set to the expected maximum number of threads. The sz ** parameter should be 6 times the size of the largest database page size. ** Scratch buffers are used as part of the btree balance operation. If ** The btree balancer needs additional memory beyond what is provided by @@ -1570,33 +1583,41 @@ ** <dt>SQLITE_CONFIG_PAGECACHE</dt> ** <dd>This option specifies a static memory buffer that SQLite can use for ** the database page cache with the default page cache implemenation. ** This configuration should not be used if an application-define page ** cache implementation is loaded using the SQLITE_CONFIG_PCACHE option. -** There are three arguments to this option: A pointer to the +** There are three arguments to this option: A pointer to 8-byte aligned ** memory, the size of each page buffer (sz), and the number of pages (N). -** The sz argument must be a power of two between 512 and 32768. The first +** The sz argument should be the size of the largest database page +** (a power of two between 512 and 32768) plus a little extra for each +** page header. The page header size is 20 to 40 bytes depending on +** the host architecture. It is harmless, apart from the wasted memory, +** to make sz a little too large. The first ** argument should point to an allocation of at least sz*N bytes of memory. ** SQLite will use the memory provided by the first argument to satisfy its ** memory needs for the first N pages that it adds to cache. If additional ** page cache memory is needed beyond what is provided by this option, then ** SQLite goes to [sqlite3_malloc()] for the additional storage space. ** The implementation might use one or more of the N buffers to hold -** memory accounting information. </dd> +** memory accounting information. The pointer in the first argument must +** be aligned to an 8-byte boundary or subsequent behavior of SQLite +** will be undefined.</dd> ** ** <dt>SQLITE_CONFIG_HEAP</dt> ** <dd>This option specifies a static memory buffer that SQLite will use ** for all of its dynamic memory allocation needs beyond those provided ** for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE]. -** There are three arguments: A pointer to the memory, the number of -** bytes in the memory buffer, and the minimum allocation size. If -** the first pointer (the memory pointer) is NULL, then SQLite reverts +** There are three arguments: An 8-byte aligned pointer to the memory, +** the number of bytes in the memory buffer, and the minimum allocation size. +** If the first pointer (the memory pointer) is NULL, then SQLite reverts ** to using its default memory allocator (the system malloc() implementation), ** undoing any prior invocation of [SQLITE_CONFIG_MALLOC]. If the ** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or ** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory -** allocator is engaged to handle all of SQLites memory allocation needs.</dd> +** allocator is engaged to handle all of SQLites memory allocation needs. +** The first pointer (the memory pointer) must be aligned to an 8-byte +** boundary or subsequent behavior of SQLite will be undefined.</dd> ** ** <dt>SQLITE_CONFIG_MUTEX</dt> ** <dd>This option takes a single argument which is a pointer to an ** instance of the [sqlite3_mutex_methods] structure. The argument specifies ** alternative low-level mutex routines to be used in place @@ -1663,13 +1684,13 @@ ** <dl> ** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt> ** <dd>This option takes three additional arguments that determine the ** [lookaside memory allocator] configuration for the [database connection]. ** The first argument (the third parameter to [sqlite3_db_config()] is a -** pointer to a memory buffer to use for lookaside memory. The first -** argument may be NULL in which case SQLite will allocate the lookaside -** buffer itself using [sqlite3_malloc()]. The second argument is the +** pointer to an 8-byte aligned memory buffer to use for lookaside memory. +** The first argument may be NULL in which case SQLite will allocate the +** lookaside buffer itself using [sqlite3_malloc()]. The second argument is the ** size of each lookaside buffer slot and the third argument is the number of ** slots. The size of the buffer in the first argument must be greater than ** or equal to the product of the second and third arguments.</dd> ** ** </dl> @@ -6397,15 +6418,16 @@ */ #ifdef SQLITE_OMIT_FLOATING_POINT # define double sqlite_int64 # define LONGDOUBLE_TYPE sqlite_int64 # ifndef SQLITE_BIG_DBL -# define SQLITE_BIG_DBL (0x7fffffffffffffff) +# define SQLITE_BIG_DBL (((sqlite3_int64)1)<<60) # endif # define SQLITE_OMIT_DATETIME_FUNCS 1 # define SQLITE_OMIT_TRACE 1 # undef SQLITE_MIXED_ENDIAN_64BIT_FLOAT +# undef SQLITE_HAVE_ISNAN #endif #ifndef SQLITE_BIG_DBL # define SQLITE_BIG_DBL (1e99) #endif @@ -7375,11 +7397,11 @@ ************************************************************************* ** This header file defines the interface that the sqlite page cache ** subsystem. The page cache subsystem reads and writes a file a page ** at a time and provides a journal for rollback. ** -** @(#) $Id: pager.h,v 1.101 2009/04/30 09:10:38 danielk1977 Exp $ +** @(#) $Id: pager.h,v 1.102 2009/06/18 17:22:39 drh Exp $ */ #ifndef _PAGER_H_ #define _PAGER_H_ @@ -7455,11 +7477,11 @@ SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager*, int, unsigned char*); /* Functions used to configure a Pager object. */ SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *); SQLITE_PRIVATE void sqlite3PagerSetReiniter(Pager*, void(*)(DbPage*)); -SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u16*); +SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u16*, int); SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager*, int); SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int); SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(Pager*,int,int); SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *, int); SQLITE_PRIVATE int sqlite3PagerJournalMode(Pager *, int); @@ -7502,15 +7524,10 @@ SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*); SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*); /* Functions used to truncate the database file. */ SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno); - -/* Used by encryption extensions. */ -#ifdef SQLITE_HAS_CODEC -SQLITE_PRIVATE void sqlite3PagerSetCodec(Pager*,void*(*)(void*,void*,Pgno,int),void*); -#endif /* Functions to support testing and debugging. */ #if !defined(NDEBUG) || defined(SQLITE_TEST) SQLITE_PRIVATE Pgno sqlite3PagerPagenumber(DbPage*); SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage*); @@ -8259,13 +8276,10 @@ FuncDefHash aFunc; /* Hash table of connection functions */ Hash aCollSeq; /* All collating sequences */ BusyHandler busyHandler; /* Busy callback */ int busyTimeout; /* Busy handler timeout, in msec */ Db aDbStatic[2]; /* Static space for the 2 default backends */ -#ifdef SQLITE_SSE - sqlite3_stmt *pFetch; /* Used by SSE to fetch stored statements */ -#endif Savepoint *pSavepoint; /* List of active savepoints */ int nSavepoint; /* Number of non-transaction savepoints */ int nStatement; /* Number of nested statement-transactions */ u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */ @@ -10299,15 +10313,10 @@ SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db); #else #define sqlite3ConnectionBlocked(x,y) #define sqlite3ConnectionUnlocked(x) #define sqlite3ConnectionClosed(x) -#endif - - -#ifdef SQLITE_SSE -#include "sseInt.h" #endif #ifdef SQLITE_DEBUG SQLITE_PRIVATE void sqlite3ParserTrace(FILE*, char *); #endif @@ -17073,22 +17082,14 @@ ** VDBE. This information used to all be at the top of the single ** source code file "vdbe.c". When that file became too big (over ** 6000 lines long) it was split up into several smaller files and ** this header information was factored out. ** -** $Id: vdbeInt.h,v 1.171 2009/06/05 14:17:25 drh Exp $ +** $Id: vdbeInt.h,v 1.174 2009/06/23 14:15:04 drh Exp $ */ #ifndef _VDBEINT_H_ #define _VDBEINT_H_ - -/* -** intToKey() and keyToInt() used to transform the rowid. But with -** the latest versions of the design they are no-ops. -*/ -#define keyToInt(X) (X) -#define intToKey(X) (X) - /* ** SQL is translated into a sequence of instructions to be ** executed by a virtual machine. Each instruction is an instance ** of the following structure. @@ -17320,66 +17321,57 @@ ** "DROP TABLE" statements and to prevent some nasty side effects of ** malloc failure when SQLite is invoked recursively by a virtual table ** method function. */ struct Vdbe { - sqlite3 *db; /* The whole database */ - Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ - int nOp; /* Number of instructions in the program */ - int nOpAlloc; /* Number of slots allocated for aOp[] */ - Op *aOp; /* Space to hold the virtual machine's program */ - int nLabel; /* Number of labels used */ - int nLabelAlloc; /* Number of slots allocated in aLabel[] */ - int *aLabel; /* Space to hold the labels */ - Mem **apArg; /* Arguments to currently executing user function */ - Mem *aColName; /* Column names to return */ - int nCursor; /* Number of slots in apCsr[] */ - VdbeCursor **apCsr; /* One element of this array for each open cursor */ - int nVar; /* Number of entries in aVar[] */ - Mem *aVar; /* Values for the OP_Variable opcode. */ - char **azVar; /* Name of variables */ - int okVar; /* True if azVar[] has been initialized */ + sqlite3 *db; /* The database connection that owns this statement */ + Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ + int nOp; /* Number of instructions in the program */ + int nOpAlloc; /* Number of slots allocated for aOp[] */ + Op *aOp; /* Space to hold the virtual machine's program */ + int nLabel; /* Number of labels used */ + int nLabelAlloc; /* Number of slots allocated in aLabel[] */ + int *aLabel; /* Space to hold the labels */ + Mem **apArg; /* Arguments to currently executing user function */ + Mem *aColName; /* Column names to return */ + Mem *pResultSet; /* Pointer to an array of results */ + u16 nResColumn; /* Number of columns in one row of the result set */ + u16 nCursor; /* Number of slots in apCsr[] */ + VdbeCursor **apCsr; /* One element of this array for each open cursor */ + u8 errorAction; /* Recovery action to do in case of an error */ + u8 okVar; /* True if azVar[] has been initialized */ + u16 nVar; /* Number of entries in aVar[] */ + Mem *aVar; /* Values for the OP_Variable opcode. */ + char **azVar; /* Name of variables */ u32 magic; /* Magic number for sanity checking */ int nMem; /* Number of memory locations currently allocated */ Mem *aMem; /* The memory locations */ int cacheCtr; /* VdbeCursor row cache generation counter */ int contextStackTop; /* Index of top element in the context stack */ int contextStackDepth; /* The size of the "context" stack */ Context *contextStack; /* Stack used by opcodes ContextPush & ContextPop*/ int pc; /* The program counter */ int rc; /* Value to return */ - int errorAction; /* Recovery action to do in case of an error */ - int nResColumn; /* Number of columns in one row of the result set */ - char **azResColumn; /* Values for one row of result */ - char *zErrMsg; /* Error message written here */ - Mem *pResultSet; /* Pointer to an array of results */ + char *zErrMsg; /* Error message written here */ u8 explain; /* True if EXPLAIN present on SQL command */ u8 changeCntOn; /* True to update the change-counter */ u8 expired; /* True if the VM needs to be recompiled */ u8 minWriteFileFormat; /* Minimum file format for writable database files */ u8 inVtabMethod; /* See comments above */ u8 usesStmtJournal; /* True if uses a statement journal */ u8 readOnly; /* True for read-only statements */ u8 isPrepareV2; /* True if prepared with prepare_v2() */ int nChange; /* Number of db changes made since last reset */ - i64 startTime; /* Time when query started - used for profiling */ int btreeMask; /* Bitmask of db->aDb[] entries referenced */ + i64 startTime; /* Time when query started - used for profiling */ BtreeMutexArray aMutex; /* An array of Btree used here and needing locks */ int aCounter[2]; /* Counters used by sqlite3_stmt_status() */ - char *zSql; /* Text of the SQL statement that generated this */ - void *pFree; /* Free this when deleting the vdbe */ -#ifdef SQLITE_DEBUG - FILE *trace; /* Write an execution trace here, if not NULL */ -#endif + char *zSql; /* Text of the SQL statement that generated this */ + void *pFree; /* Free this when deleting the vdbe */ int iStatement; /* Statement number (or 0 if has not opened stmt) */ -#ifdef SQLITE_SSE - int fetchId; /* Statement number used by sqlite3_fetch_statement */ - int lru; /* Counter used for LRU cache replacement */ -#endif -#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT - Vdbe *pLruPrev; - Vdbe *pLruNext; +#ifdef SQLITE_DEBUG + FILE *trace; /* Write an execution trace here, if not NULL */ #endif }; /* ** The following are allowed values for Vdbe.magic @@ -17404,11 +17396,11 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc*, int); int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*); -SQLITE_PRIVATE int sqlite3VdbeIdxRowid(BtCursor *, i64 *); +SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor *, i64 *); SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*); SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*); SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*); SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int); @@ -17985,11 +17977,11 @@ ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** -** $Id: util.c,v 1.258 2009/06/05 14:17:23 drh Exp $ +** $Id: util.c,v 1.260 2009/06/17 16:20:04 drh Exp $ */ #ifdef SQLITE_HAVE_ISNAN # include <math.h> #endif @@ -18077,11 +18069,11 @@ ** than the actual length of the string. For very long strings (greater ** than 1GiB) the value returned might be less than the true string length. */ SQLITE_PRIVATE int sqlite3Strlen30(const char *z){ const char *z2 = z; - if( NEVER(z==0) ) return 0; + if( z==0 ) return 0; while( *z2 ){ z2++; } return 0x3fffffff & (int)(z2 - z); } /* @@ -18361,11 +18353,11 @@ ** ** will return -8. */ static int compare2pow63(const char *zNum){ int c; - c = memcmp(zNum,"922337203685477580",18); + c = memcmp(zNum,"922337203685477580",18)*10; if( c==0 ){ c = zNum[18] - '8'; } return c; } @@ -20864,11 +20856,11 @@ ** * sqlite3_vfs method implementations. ** * Locking primitives for the proxy uber-locking-method. (MacOSX only) ** * Definitions of sqlite3_vfs objects for all locking methods ** plus implementations of sqlite3_os_init() and sqlite3_os_end(). ** -** $Id: os_unix.c,v 1.251 2009/05/08 11:34:37 danielk1977 Exp $ +** $Id: os_unix.c,v 1.253 2009/06/17 13:09:39 drh Exp $ */ #if SQLITE_OS_UNIX /* This file is used on unix only */ /* ** There are various methods for file locking used for concurrency @@ -21952,11 +21944,11 @@ int rc; /* System call return code */ int fd; /* The file descriptor for pFile */ struct unixLockKey lockKey; /* Lookup key for the unixLockInfo structure */ struct unixFileId fileId; /* Lookup key for the unixOpenCnt struct */ struct stat statbuf; /* Low-level file information */ - struct unixLockInfo *pLock; /* Candidate unixLockInfo object */ + struct unixLockInfo *pLock = 0;/* Candidate unixLockInfo object */ struct unixOpenCnt *pOpen; /* Candidate unixOpenCnt object */ /* Get low-level information about the file that we can used to ** create a unique name for the file. */ @@ -22856,11 +22848,12 @@ } /* To fully unlock the database, delete the lock file */ assert( locktype==NO_LOCK ); if( unlink(zLockFile) ){ - int rc, tErrno = errno; + int rc = 0; + int tErrno = errno; if( ENOENT != tErrno ){ rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); } if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; @@ -25106,11 +25099,15 @@ ** Find the current time (in Universal Coordinated Time). Write the ** current time and date as a Julian Day number into *prNow and ** return 0. Return 1 if the time and date cannot be found. */ static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){ -#if defined(NO_GETTOD) +#if defined(SQLITE_OMIT_FLOATING_POINT) + time_t t; + time(&t); + *prNow = (((sqlite3_int64)t)/8640 + 24405875)/10; +#elif defined(NO_GETTOD) time_t t; time(&t); *prNow = t/86400.0 + 2440587.5; #elif OS_VXWORKS struct timespec sNow; @@ -29299,11 +29296,11 @@ ** sqlite3_pcache interface). It also contains part of the implementation ** of the SQLITE_CONFIG_PAGECACHE and sqlite3_release_memory() features. ** If the default page cache implementation is overriden, then neither of ** these two features are available. ** -** @(#) $Id: pcache1.c,v 1.16 2009/06/03 21:04:36 drh Exp $ +** @(#) $Id: pcache1.c,v 1.17 2009/06/09 18:58:53 shane Exp $ */ typedef struct PCache1 PCache1; typedef struct PgHdr1 PgHdr1; @@ -29650,11 +29647,11 @@ */ static void pcache1TruncateUnsafe( PCache1 *pCache, unsigned int iLimit ){ - TESTONLY( int nPage = 0; ) /* Used to assert pCache->nPage is correct */ + TESTONLY( unsigned int nPage = 0; ) /* Used to assert pCache->nPage is correct */ unsigned int h; assert( sqlite3_mutex_held(pcache1.mutex) ); for(h=0; h<pCache->nHash; h++){ PgHdr1 **pp = &pCache->apHash[h]; PgHdr1 *pPage; @@ -30498,11 +30495,11 @@ ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.591 2009/06/02 21:31:39 drh Exp $ +** @(#) $Id: pager.c,v 1.601 2009/06/22 05:43:24 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_DISKIO /* ** Macros for troubleshooting. Normally turned off @@ -30582,15 +30579,18 @@ /* ** A macro used for invoking the codec if there is one */ #ifdef SQLITE_HAS_CODEC -# define CODEC1(P,D,N,X) if( P->xCodec!=0 ){ P->xCodec(P->pCodecArg,D,N,X); } -# define CODEC2(P,D,N,X) ((char*)(P->xCodec!=0?P->xCodec(P->pCodecArg,D,N,X):D)) -#else -# define CODEC1(P,D,N,X) /* NO-OP */ -# define CODEC2(P,D,N,X) ((char*)D) +# define CODEC1(P,D,N,X,E) \ + if( P->xCodec && P->xCodec(P->pCodec,D,N,X)==0 ){ E; } +# define CODEC2(P,D,N,X,E,O) \ + if( P->xCodec==0 ){ O=(char*)D; }else \ + if( (O=(char*)(P->xCodec(P->pCodec,D,N,X)))==0 ){ E; } +#else +# define CODEC1(P,D,N,X,E) /* NO-OP */ +# define CODEC2(P,D,N,X,E,O) O=(char*)D #endif /* ** The maximum allowed sector size. 16MB. If the xSectorsize() method ** returns a value larger than this, then MAX_SECTOR_SIZE is used instead. @@ -30766,11 +30766,12 @@ PagerSavepoint *aSavepoint; /* Array of active savepoints */ int nSavepoint; /* Number of elements in aSavepoint[] */ char dbFileVers[16]; /* Changes whenever database file changes */ u32 sectorSize; /* Assumed sector size during rollback */ - int nExtra; /* Add this many bytes to each in-memory page */ + 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() */ int pageSize; /* Number of bytes in a page */ Pgno mxPgno; /* Maximum allowed size of the database */ char *zFilename; /* Name of the database file */ char *zJournal; /* Name of the journal file */ @@ -30781,11 +30782,13 @@ int nRead, nWrite; /* Database pages read/written */ #endif void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */ #ifdef SQLITE_HAS_CODEC void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */ - void *pCodecArg; /* First argument to xCodec() */ + void (*xCodecSizeChng)(void*,int,int); /* Notify of page size changes */ + void (*xCodecFree)(void*); /* Destructor for the codec */ + void *pCodec; /* First argument to xCodec... methods */ #endif char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ i64 journalSizeLimit; /* Size limit for persistent journal files */ PCache *pPCache; /* Pointer to page cache object */ sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */ @@ -31403,11 +31406,11 @@ /* Update the page-size to match the value read from the journal. ** Use a testcase() macro to make sure that malloc failure within ** PagerSetPagesize() is tested. */ iPageSize16 = (u16)iPageSize; - rc = sqlite3PagerSetPagesize(pPager, &iPageSize16); + rc = sqlite3PagerSetPagesize(pPager, &iPageSize16, -1); testcase( rc!=SQLITE_OK ); assert( rc!=SQLITE_OK || iPageSize16==(u16)iPageSize ); /* Update the assumed sector-size to match the value used by ** the process that created this journal. If this journal was @@ -32005,11 +32008,15 @@ i64 ofst = (pgno-1)*(i64)pPager->pageSize; rc = sqlite3OsWrite(pPager->fd, aData, pPager->pageSize, ofst); if( pgno>pPager->dbFileSize ){ pPager->dbFileSize = pgno; } - sqlite3BackupUpdate(pPager->pBackup, pgno, aData); + if( pPager->pBackup ){ + CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM); + sqlite3BackupUpdate(pPager->pBackup, pgno, aData); + CODEC1(pPager, aData, pgno, 0, rc=SQLITE_NOMEM); + } }else if( !isMainJrnl && pPg==0 ){ /* If this is a rollback of a savepoint and data was not written to ** the database and the page is not in-memory, there is a potential ** problem. When the page is next fetched by the b-tree layer, it ** will be read from the database file, which may or may not be @@ -32074,11 +32081,11 @@ if( pgno==1 ){ memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers)); } /* Decode the page just read from disk */ - CODEC1(pPager, pData, pPg->pgno, 3); + CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM); sqlite3PcacheRelease(pPg); } return rc; } @@ -32838,10 +32845,25 @@ SQLITE_PRIVATE void sqlite3PagerSetReiniter(Pager *pPager, void (*xReinit)(DbPage*)){ pPager->xReiniter = xReinit; } /* +** Report the current page size and number of reserved bytes back +** to the codec. +*/ +#ifdef SQLITE_HAS_CODEC +static void pagerReportSize(Pager *pPager){ + if( pPager->xCodecSizeChng ){ + pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize, + (int)pPager->nReserve); + } +} +#else +# define pagerReportSize(X) /* No-op if we do not support a codec */ +#endif + +/* ** Change the page size used by the Pager object. The new page size ** is passed in *pPageSize. ** ** If the pager is in the error state when this function is called, it ** is a no-op. The value returned is the error state error code (i.e. @@ -32867,11 +32889,11 @@ ** If the page size is not changed, either because one of the enumerated ** conditions above is not true, the pager was in error state when this ** function was called, or because the memory allocation attempt failed, ** then *pPageSize is set to the old, retained page size before returning. */ -SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u16 *pPageSize){ +SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u16 *pPageSize, int nReserve){ int rc = pPager->errCode; if( rc==SQLITE_OK ){ u16 pageSize = *pPageSize; assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) ); if( pageSize && pageSize!=pPager->pageSize @@ -32888,10 +32910,14 @@ pPager->pTmpSpace = pNew; sqlite3PcacheSetPageSize(pPager->pPCache, pageSize); } } *pPageSize = (u16)pPager->pageSize; + if( nReserve<0 ) nReserve = pPager->nReserve; + assert( nReserve>=0 && nReserve<1000 ); + pPager->nReserve = (i16)nReserve; + pagerReportSize(pPager); } return rc; } /* @@ -33136,10 +33162,14 @@ IOTRACE(("CLOSE %p\n", pPager)) sqlite3OsClose(pPager->fd); sqlite3PageFree(pPager->pTmpSpace); sqlite3PcacheClose(pPager->pPCache); +#ifdef SQLITE_HAS_CODEC + if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec); +#endif + assert( !pPager->aSavepoint && !pPager->pInJournal ); assert( !isOpen(pPager->jfd) && !isOpen(pPager->sjfd) ); sqlite3_free(pPager); return SQLITE_OK; @@ -33366,12 +33396,15 @@ ** ** Also, do not write out any page that has the PGHDR_DONT_WRITE flag ** set (set by sqlite3PagerDontWrite()). */ if( pgno<=pPager->dbSize && 0==(pList->flags&PGHDR_DONT_WRITE) ){ - i64 offset = (pgno-1)*(i64)pPager->pageSize; /* Offset to write */ - char *pData = CODEC2(pPager, pList->pData, pgno, 6); /* Data to write */ + i64 offset = (pgno-1)*(i64)pPager->pageSize; /* Offset to write */ + char *pData; /* Data to write */ + + /* Encode the database */ + CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM, pData); /* Write out the page data. */ rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset); /* If page 1 was just written, update Pager.dbFileVers to match @@ -33384,11 +33417,11 @@ if( pgno>pPager->dbFileSize ){ pPager->dbFileSize = pgno; } /* Update any backup objects copying the contents of this pager. */ - sqlite3BackupUpdate(pPager->pBackup, pgno, (u8 *)pData); + sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)pList->pData); PAGERTRACE(("STORE %d page %d hash(%08x)\n", PAGERID(pPager), pgno, pager_pagehash(pList))); IOTRACE(("PGOUT %p %d\n", pPager, pgno)); PAGER_INCR(sqlite3_pager_writedb_count); @@ -33422,12 +33455,13 @@ int rc = SQLITE_OK; Pager *pPager = pPg->pPager; if( isOpen(pPager->sjfd) ){ void *pData = pPg->pData; i64 offset = pPager->nSubRec*(4+pPager->pageSize); - char *pData2 = CODEC2(pPager, pData, pPg->pgno, 7); - + char *pData2; + + CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2); PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno)); assert( pageInJournal(pPg) || pPg->pgno>pPager->dbOrigSize ); rc = write32bits(pPager->sjfd, offset, pPg->pgno); if( rc==SQLITE_OK ){ @@ -33745,18 +33779,19 @@ ** database is the same as a temp-file that is never written out to ** disk and uses an in-memory rollback journal. */ tempFile = 1; pPager->state = PAGER_EXCLUSIVE; + readOnly = (vfsFlags&SQLITE_OPEN_READONLY); } /* The following call to PagerSetPagesize() serves to set the value of ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer. */ if( rc==SQLITE_OK ){ assert( pPager->memDb==0 ); - rc = sqlite3PagerSetPagesize(pPager, &szPageDflt); + rc = sqlite3PagerSetPagesize(pPager, &szPageDflt, -1); testcase( rc!=SQLITE_OK ); } /* If an error occurred in either of the blocks above, free the ** Pager structure and close the file. @@ -33767,10 +33802,11 @@ sqlite3_free(pPager); return rc; } /* Initialize the PCache object. */ + assert( nExtra<1000 ); nExtra = ROUND8(nExtra); sqlite3PcacheOpen(szPageDflt, nExtra, !memDb, !memDb?pagerStress:0, (void *)pPager, pPager->pPCache); PAGERTRACE(("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename)); @@ -33802,11 +33838,11 @@ pPager->fullSync = pPager->noSync ?0:1; pPager->sync_flags = SQLITE_SYNC_NORMAL; /* pPager->pFirst = 0; */ /* pPager->pFirstSynced = 0; */ /* pPager->pLast = 0; */ - pPager->nExtra = nExtra; + pPager->nExtra = (u16)nExtra; pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT; assert( isOpen(pPager->fd) || tempFile ); setSectorSize(pPager); if( memDb ){ pPager->journalMode = PAGER_JOURNALMODE_MEMORY; @@ -33966,11 +34002,11 @@ } if( pgno==1 ){ u8 *dbFileVers = &((u8*)pPg->pData)[24]; memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers)); } - CODEC1(pPager, pPg->pData, pgno, 3); + CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM); PAGER_INCR(sqlite3_pager_readdb_count); PAGER_INCR(pPager->nRead); IOTRACE(("PGIN %p %d\n", pPager, pgno)); PAGERTRACE(("FETCH %d page %d hash(%08x)\n", @@ -34011,19 +34047,17 @@ */ static int pagerSharedLock(Pager *pPager){ int rc = SQLITE_OK; /* Return code */ int isErrorReset = 0; /* True if recovering from error state */ - /* If this database is opened for exclusive access, has no outstanding - ** page references and is in an error-state, this is a chance to clear - ** the error. Discard the contents of the pager-cache and treat any - ** open journal file as a hot-journal. - */ - if( !MEMDB && pPager->exclusiveMode - && sqlite3PcacheRefCount(pPager->pPCache)==0 && pPager->errCode - ){ - if( isOpen(pPager->jfd) ){ + /* If this database has no outstanding page references and is in an + ** error-state, this is a chance to clear the error. Discard the + ** contents of the pager-cache and rollback any hot journal in the + ** file-system. + */ + if( !MEMDB && sqlite3PcacheRefCount(pPager->pPCache)==0 && pPager->errCode ){ + if( isOpen(pPager->jfd) || pPager->zJournal ){ isErrorReset = 1; } pPager->errCode = SQLITE_OK; pager_reset(pPager); } @@ -34102,13 +34136,16 @@ if( rc==SQLITE_OK && fout&SQLITE_OPEN_READONLY ){ rc = SQLITE_CANTOPEN; sqlite3OsClose(pPager->jfd); } }else{ - /* If the journal does not exist, that means some other process - ** has already rolled it back */ - rc = SQLITE_BUSY; + /* If the journal does not exist, it usually means that some + ** other connection managed to get in and roll it back before + ** this connection obtained the exclusive lock above. Or, it + ** may mean that the pager was in the error-state when this + ** function was called and the journal file does not exist. */ + rc = pager_end_transaction(pPager, 0); } } } if( rc!=SQLITE_OK ){ goto failed; @@ -34123,14 +34160,16 @@ /* Playback and delete the journal. Drop the database write ** lock and reacquire the read lock. Purge the cache before ** playing back the hot-journal so that we don't end up with ** an inconsistent cache. */ - rc = pager_playback(pPager, 1); - if( rc!=SQLITE_OK ){ - rc = pager_error(pPager, rc); - goto failed; + if( isOpen(pPager->jfd) ){ + rc = pager_playback(pPager, 1); + if( rc!=SQLITE_OK ){ + rc = pager_error(pPager, rc); + goto failed; + } } assert( (pPager->state==PAGER_SHARED) || (pPager->exclusiveMode && pPager->state>PAGER_SHARED) ); } @@ -34306,10 +34345,11 @@ } assert( pPager->state!=PAGER_UNLOCK ); rc = sqlite3PcacheFetch(pPager->pPCache, pgno, 1, &pPg); if( rc!=SQLITE_OK ){ + pagerUnlockIfUnused(pPager); return rc; } assert( pPg->pgno==pgno ); assert( pPg->pPager==pPager || pPg->pPager==0 ); if( pPg->pPager==0 ){ @@ -34664,11 +34704,11 @@ /* 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_MJ_PGNO(pPager) ); - pData2 = CODEC2(pPager, pData, pPg->pgno, 7); + CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2); cksum = pager_cksum(pPager, (u8*)pData2); rc = write32bits(pPager->jfd, pPager->journalOff, pPg->pgno); if( rc==SQLITE_OK ){ rc = sqlite3OsWrite(pPager->jfd, pData2, pPager->pageSize, pPager->journalOff + 4); @@ -35515,19 +35555,28 @@ return pPager->noSync; } #ifdef SQLITE_HAS_CODEC /* -** Set the codec for this pager -*/ -SQLITE_PRIVATE void sqlite3PagerSetCodec( +** Set or retrieve the codec for this pager +*/ +static void sqlite3PagerSetCodec( Pager *pPager, void *(*xCodec)(void*,void*,Pgno,int), - void *pCodecArg -){ + void (*xCodecSizeChng)(void*,int,int), + void (*xCodecFree)(void*), + void *pCodec +){ + if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec); pPager->xCodec = xCodec; - pPager->pCodecArg = pCodecArg; + pPager->xCodecSizeChng = xCodecSizeChng; + pPager->xCodecFree = xCodecFree; + pPager->pCodec = pCodec; + pagerReportSize(pPager); +} +static void *sqlite3PagerGetCodec(Pager *pPager){ + return pPager->pCodec; } #endif #ifndef SQLITE_OMIT_AUTOVACUUM /* @@ -35815,11 +35864,11 @@ ** 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. ** ************************************************************************* -** $Id: btreeInt.h,v 1.46 2009/03/20 14:18:52 danielk1977 Exp $ +** $Id: btreeInt.h,v 1.48 2009/06/22 12:05:10 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to ** ** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3: @@ -35876,10 +35925,21 @@ ** 24 4 File change counter ** 28 4 Reserved for future use ** 32 4 First freelist page ** 36 4 Number of freelist pages in the file ** 40 60 15 4-byte meta values passed to higher layers +** +** 40 4 Schema cookie +** 44 4 File format of schema layer +** 48 4 Size of page cache +** 52 4 Largest root-page (auto/incr_vacuum) +** 56 4 1=UTF-8 2=UTF16le 3=UTF16be +** 60 4 User version +** 64 4 Incremental vacuum mode +** 68 4 unused +** 72 4 unused +** 76 4 unused ** ** All of the integer values are big-endian (most significant byte first). ** ** The file change counter is incremented when the database is changed ** This counter allows other processes to know when the file has changed @@ -36441,13 +36501,16 @@ SQLITE_PRIVATE int sqlite3BtreeGetPage(BtShared*, Pgno, MemPage**, int); SQLITE_PRIVATE int sqlite3BtreeInitPage(MemPage *pPage); SQLITE_PRIVATE void sqlite3BtreeParseCellPtr(MemPage*, u8*, CellInfo*); SQLITE_PRIVATE void sqlite3BtreeParseCell(MemPage*, int, CellInfo*); SQLITE_PRIVATE int sqlite3BtreeRestoreCursorPosition(BtCursor *pCur); +SQLITE_PRIVATE void sqlite3BtreeMoveToParent(BtCursor *pCur); + +#ifdef SQLITE_TEST SQLITE_PRIVATE void sqlite3BtreeGetTempCursor(BtCursor *pCur, BtCursor *pTempCur); SQLITE_PRIVATE void sqlite3BtreeReleaseTempCursor(BtCursor *pCur); -SQLITE_PRIVATE void sqlite3BtreeMoveToParent(BtCursor *pCur); +#endif /************** End of btreeInt.h ********************************************/ /************** Continuing where we left off in btmutex.c ********************/ #ifndef SQLITE_OMIT_SHARED_CACHE #if SQLITE_THREADSAFE @@ -36795,11 +36858,11 @@ ** 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. ** ************************************************************************* -** $Id: btree.c,v 1.619 2009/06/05 18:44:15 drh Exp $ +** $Id: btree.c,v 1.639 2009/06/23 11:22:29 danielk1977 Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. ** Including a description of file format and an overview of operation. */ @@ -36813,11 +36876,11 @@ /* ** Set this global variable to 1 to enable tracing using the TRACE ** macro. */ #if 0 -int sqlite3BtreeTrace=0; /* True to enable tracing */ +int sqlite3BtreeTrace=1; /* True to enable tracing */ # define TRACE(X) if(sqlite3BtreeTrace){printf X;fflush(stdout);} #else # define TRACE(X) #endif @@ -37423,11 +37486,10 @@ } #else /* if defined SQLITE_OMIT_AUTOVACUUM */ #define ptrmapPut(w,x,y,z) SQLITE_OK #define ptrmapGet(w,x,y,z) SQLITE_OK - #define ptrmapPutOvfl(y,z) SQLITE_OK #endif /* ** Given a btree page and a cell index (0 means the first cell on ** the page, 1 means the second cell, and so forth) return a pointer @@ -37588,11 +37650,11 @@ if( nSize>pPage->maxLocal ){ nSize = minLocal; } nSize += 4; } - nSize += (pIter - pCell); + nSize += (u32)(pIter - pCell); /* The minimum size of any cell is 4 bytes. */ if( nSize<4 ){ nSize = 4; } @@ -37615,26 +37677,15 @@ static int ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell){ CellInfo info; assert( pCell!=0 ); sqlite3BtreeParseCellPtr(pPage, pCell, &info); assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload ); - if( (info.nData+(pPage->intKey?0:info.nKey))>info.nLocal ){ + if( info.iOverflow ){ Pgno ovfl = get4byte(&pCell[info.iOverflow]); return ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno); } return SQLITE_OK; -} -/* -** If the cell with index iCell on page pPage contains a pointer -** to an overflow page, insert an entry into the pointer-map -** for the overflow page. -*/ -static int ptrmapPutOvfl(MemPage *pPage, int iCell){ - u8 *pCell; - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - pCell = findOverflowCell(pPage, iCell); - return ptrmapPutOvflPtr(pPage, pCell); } #endif /* @@ -37938,11 +37989,11 @@ ** ** The following block of code checks early to see if a cell extends ** past the end of a page boundary and causes SQLITE_CORRUPT to be ** returned if it does. */ -#if defined(SQLITE_OVERREAD_CHECK) || 1 +#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK) { int iCellFirst; /* First allowable cell index */ int iCellLast; /* Last possible cell index */ int i; /* Index into the cell pointer array */ int sz; /* Size of a cell */ @@ -37976,11 +38027,11 @@ size = get2byte(&data[pc+2]); if( next>0 && next<=pc+size+3 ){ /* Free blocks must be in accending order */ return SQLITE_CORRUPT_BKPT; } - nFree += size; + nFree = nFree + size; pc = next; } /* At this point, nFree contains the sum of the offset to the start ** of the cell-content area plus the number of free bytes within @@ -38386,11 +38437,11 @@ #ifndef SQLITE_OMIT_AUTOVACUUM pBt->autoVacuum = (get4byte(&zDbHeader[36 + 4*4])?1:0); pBt->incrVacuum = (get4byte(&zDbHeader[36 + 7*4])?1:0); #endif } - rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize); + rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve); if( rc ) goto btree_open_out; pBt->usableSize = pBt->pageSize - nReserve; assert( (pBt->pageSize & 7)==0 ); /* 8-byte alignment of pageSize */ #if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) @@ -38677,12 +38728,12 @@ ((pageSize-1)&pageSize)==0 ){ assert( (pageSize & 7)==0 ); assert( !pBt->pPage1 && !pBt->pCursor ); pBt->pageSize = (u16)pageSize; freeTempSpace(pBt); - rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize); - } + } + rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve); pBt->usableSize = pBt->pageSize - (u16)nReserve; if( iFix ) pBt->pageSizeFixed = 1; sqlite3BtreeLeave(p); return rc; } @@ -38833,15 +38884,16 @@ */ releasePage(pPage1); pBt->usableSize = (u16)usableSize; pBt->pageSize = (u16)pageSize; freeTempSpace(pBt); - rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize); + rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, + pageSize-usableSize); if( rc ) goto page1_init_failed; return SQLITE_OK; } - if( usableSize<500 ){ + if( usableSize<480 ){ goto page1_init_failed; } pBt->pageSize = (u16)pageSize; pBt->usableSize = (u16)usableSize; #ifndef SQLITE_OMIT_AUTOVACUUM @@ -39494,11 +39546,13 @@ assert( nRef==sqlite3PagerRefcount(pPager) ); return rc; } -#endif /* ifndef SQLITE_OMIT_AUTOVACUUM */ +#else /* ifndef SQLITE_OMIT_AUTOVACUUM */ +# define setChildPtrmaps(x) SQLITE_OK +#endif /* ** This routine does the first phase of a two-phase commit. This routine ** causes a rollback journal to be created (if it does not already exist) ** and populated with enough information so that if a power loss occurs @@ -39991,10 +40045,11 @@ sqlite3BtreeLeave(pBtree); } return SQLITE_OK; } +#ifdef SQLITE_TEST /* ** Make a temporary cursor by filling in the fields of pTempCur. ** The temporary cursor is not on the cursor list for the Btree. */ SQLITE_PRIVATE void sqlite3BtreeGetTempCursor(BtCursor *pCur, BtCursor *pTempCur){ @@ -40006,11 +40061,13 @@ for(i=0; i<=pTempCur->iPage; i++){ sqlite3PagerRef(pTempCur->apPage[i]->pDbPage); } assert( pTempCur->pKey==0 ); } - +#endif /* SQLITE_TEST */ + +#ifdef SQLITE_TEST /* ** Delete a temporary cursor such as was made by the CreateTemporaryCursor() ** function above. */ SQLITE_PRIVATE void sqlite3BtreeReleaseTempCursor(BtCursor *pCur){ @@ -40019,12 +40076,11 @@ for(i=0; i<=pCur->iPage; i++){ sqlite3PagerUnref(pCur->apPage[i]->pDbPage); } sqlite3_free(pCur->pKey); } - - +#endif /* SQLITE_TEST */ /* ** Make sure the BtCursor* given in the argument has a valid ** BtCursor.info structure. If it is not already valid, call ** sqlite3BtreeParseCell() to fill it in. @@ -41182,11 +41238,11 @@ u8 exact ){ MemPage *pPage1; int rc; u32 n; /* Number of pages on the freelist */ - int k; /* Number of leaves on the trunk of the freelist */ + u32 k; /* Number of leaves on the trunk of the freelist */ MemPage *pTrunk = 0; MemPage *pPrevTrunk = 0; Pgno mxPage; /* Total size of the database file */ assert( sqlite3_mutex_held(pBt->mutex) ); @@ -41260,11 +41316,11 @@ *pPgno = iTrunk; memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); *ppPage = pTrunk; pTrunk = 0; TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); - }else if( k>pBt->usableSize/4 - 2 ){ + }else if( k>(u32)(pBt->usableSize/4 - 2) ){ /* Value of k is out of range. Database corruption */ rc = SQLITE_CORRUPT_BKPT; goto end_allocate_page; #ifndef SQLITE_OMIT_AUTOVACUUM }else if( searchList && nearby==iTrunk ){ @@ -41320,21 +41376,22 @@ } } pTrunk = 0; TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); #endif - }else{ + }else if( k>0 ){ /* Extract a leaf from the trunk */ - int closest; + u32 closest; Pgno iPage; unsigned char *aData = pTrunk->aData; rc = sqlite3PagerWrite(pTrunk->pDbPage); if( rc ){ goto end_allocate_page; } if( nearby>0 ){ - int i, dist; + u32 i; + int dist; closest = 0; dist = get4byte(&aData[8]) - nearby; if( dist<0 ) dist = -dist; for(i=1; i<k; i++){ int d2 = get4byte(&aData[8+i*4]) - nearby; @@ -41356,11 +41413,11 @@ if( !searchList || iPage==nearby ){ int noContent; Pgno nPage; *pPgno = iPage; nPage = pagerPagecount(pBt); - if( *pPgno>nPage ){ + if( iPage>nPage ){ /* Free page off the end of the file */ rc = SQLITE_CORRUPT_BKPT; goto end_allocate_page; } TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d" @@ -41434,10 +41491,12 @@ if( sqlite3PagerPageRefcount((*ppPage)->pDbPage)>1 ){ releasePage(*ppPage); return SQLITE_CORRUPT_BKPT; } (*ppPage)->isInit = 0; + }else{ + *ppPage = 0; } return rc; } /* @@ -41844,11 +41903,11 @@ 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 */ - u8 nSkip /* Do not write the first nSkip bytes of the cell */ + Pgno iChild /* If non-zero, replace first 4 bytes with this value */ ){ int idx; /* Where to write new cell content in data[] */ int j; /* Loop counter */ int top; /* First byte of content for any cell in data[] */ int end; /* First byte past the last cell pointer in data[] */ @@ -41855,10 +41914,12 @@ int ins; /* Index in data[] where new cell pointer is inserted */ int hdr; /* Offset into data[] of the page header */ int cellOffset; /* Address of first cell pointer in data[] */ u8 *data; /* The content of the whole page */ u8 *ptr; /* Used for moving information around in data[] */ + + int nSkip = (iChild ? 4 : 0); assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); assert( pPage->nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=5460 ); assert( pPage->nOverflow<=ArraySize(pPage->aOvfl) ); assert( sz==cellSizePtr(pPage, pCell) ); @@ -41866,15 +41927,17 @@ if( pPage->nOverflow || sz+2>pPage->nFree ){ if( pTemp ){ memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip); pCell = pTemp; } + if( iChild ){ + put4byte(pCell, iChild); + } j = pPage->nOverflow++; assert( j<(int)(sizeof(pPage->aOvfl)/sizeof(pPage->aOvfl[0])) ); pPage->aOvfl[j].pCell = pCell; pPage->aOvfl[j].idx = (u16)i; - pPage->nFree = 0; }else{ int rc = sqlite3PagerWrite(pPage->pDbPage); if( rc!=SQLITE_OK ){ return rc; } @@ -41900,10 +41963,13 @@ return SQLITE_CORRUPT_BKPT; } pPage->nCell++; pPage->nFree -= 2; memcpy(&data[idx+nSkip], pCell+nSkip, sz-nSkip); + if( iChild ){ + put4byte(&data[idx], iChild); + } for(j=end-2, ptr=&data[j]; j>ins; j-=2, ptr-=2){ ptr[0] = ptr[-2]; ptr[1] = ptr[-1]; } put2byte(&data[ins], idx); @@ -41911,18 +41977,11 @@ #ifndef SQLITE_OMIT_AUTOVACUUM if( pPage->pBt->autoVacuum ){ /* The cell may contain a pointer to an overflow page. If so, write ** the entry for the overflow page into the pointer map. */ - CellInfo info; - sqlite3BtreeParseCellPtr(pPage, pCell, &info); - assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload ); - if( info.iOverflow ){ - Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]); - rc = ptrmapPut(pPage->pBt, pgnoOvfl, PTRMAP_OVERFLOW1, pPage->pgno); - if( rc!=SQLITE_OK ) return rc; - } + rc = ptrmapPutOvflPtr(pPage, pCell); } #endif } return SQLITE_OK; @@ -41981,12 +42040,10 @@ ** The value of NN appears to give the best results overall. */ #define NN 1 /* Number of neighbors on either side of pPage */ #define NB (NN*2+1) /* Total pages involved in the balance */ -/* Forward reference */ -static int balance(BtCursor*, int); #ifndef SQLITE_OMIT_QUICKBALANCE /* ** This version of balance() handles the common special case where ** a new entry is being inserted on the extreme right-end of the @@ -42001,42 +42058,62 @@ ** fill up. On average. ** ** pPage is the leaf page which is the right-most page in the tree. ** pParent is its parent. pPage must have a single overflow entry ** which is also the right-most entry on the page. -*/ -static int balance_quick(BtCursor *pCur){ - MemPage *const pPage = pCur->apPage[pCur->iPage]; - BtShared *const pBt = pCur->pBt; - MemPage *pNew = 0; /* Newly allocated page */ +** +** The pSpace buffer is used to store a temporary copy of the divider +** cell that will be inserted into pParent. Such a cell consists of a 4 +** byte page number followed by a variable length integer. In other +** words, at most 13 bytes. Hence the pSpace buffer must be at +** least 13 bytes in size. +*/ +static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ + BtShared *const pBt = pPage->pBt; /* B-Tree Database */ + MemPage *pNew; /* Newly allocated page */ int rc; /* Return Code */ Pgno pgnoNew; /* Page number of pNew */ assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); + assert( pPage->nOverflow==1 ); + if( pPage->nCell<=0 ) return SQLITE_CORRUPT_BKPT; - /* Allocate a new page. This page will become the right-sibling of pPage */ + /* Allocate a new page. This page will become the right-sibling of + ** pPage. Make the parent page writable, so that the new divider cell + ** may be inserted. If both these operations are successful, proceed. + */ rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0); if( rc==SQLITE_OK ){ - /* The parentCell buffer is used to store a temporary copy of the divider - ** cell that will be inserted into pParent. Such a cell consists of a 4 - ** byte page number followed by a variable length integer. In other - ** words, at most 13 bytes. Hence the parentCell buffer must be at - ** least 13 bytes in size. - */ - MemPage * const pParent = pCur->apPage[pCur->iPage-1]; - u8 parentCell[13]; - u8 *pOut = &parentCell[4]; + + u8 *pOut = &pSpace[4]; u8 *pCell = pPage->aOvfl[0].pCell; u16 szCell = cellSizePtr(pPage, pCell); u8 *pStop; assert( sqlite3PagerIswriteable(pNew->pDbPage) ); - zeroPage(pNew, pPage->aData[0]); + assert( pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) ); + zeroPage(pNew, PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF); assemblePage(pNew, 1, &pCell, &szCell); - pPage->nOverflow = 0; + + /* If this is an auto-vacuum database, update the pointer map + ** with entries for the new page, and any pointer from the + ** cell on the page to an overflow page. If either of these + ** operations fails, the return code is set, but the contents + ** of the parent page are still manipulated by thh code below. + ** That is Ok, at this point the parent page is guaranteed to + ** be marked as dirty. Returning an error code will cause a + ** rollback, undoing any changes made to the parent page. + */ + if( ISAUTOVACUUM ){ + rc = ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno); + if( szCell>pNew->minLocal && rc==SQLITE_OK ){ + rc = ptrmapPutOvflPtr(pNew, pCell); + } + } /* Create a divider cell to insert into pParent. The divider cell ** consists of a 4-byte page number (the page number of pPage) and ** a variable length key value (which must be the same value as the ** largest key on pPage). @@ -42045,278 +42122,263 @@ ** cell on pPage. The first two fields of this cell are the ** record-length (a variable length integer at most 32-bits in size) ** and the key value (a variable length integer, may have any value). ** The first of the while(...) loops below skips over the record-length ** field. The second while(...) loop copies the key value from the - ** cell on pPage into the parentCell buffer. - */ - put4byte(parentCell, pPage->pgno); + ** cell on pPage into the pSpace buffer. + */ pCell = findCell(pPage, pPage->nCell-1); pStop = &pCell[9]; while( (*(pCell++)&0x80) && pCell<pStop ); pStop = &pCell[9]; while( ((*(pOut++) = *(pCell++))&0x80) && pCell<pStop ); - /* Insert the new divider cell into pParent */ - insertCell(pParent, pParent->nCell, parentCell, pOut-parentCell, 0, 0); + /* Insert the new divider cell into pParent. */ + insertCell(pParent,pParent->nCell,pSpace,(int)(pOut-pSpace),0,pPage->pgno); /* Set the right-child pointer of pParent to point to the new page. */ put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew); - - /* If this is an auto-vacuum database, update the pointer map - ** with entries for the new page, and any pointer from the - ** cell on the page to an overflow page. - */ - if( ISAUTOVACUUM ){ - rc = ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno); - if( rc==SQLITE_OK ){ - rc = ptrmapPutOvfl(pNew, 0); - } - } /* Release the reference to the new page. */ releasePage(pNew); } - /* At this point the pPage->nFree variable is not set correctly with - ** respect to the content of the page (because it was set to 0 by - ** insertCell). So call sqlite3BtreeInitPage() to make sure it is - ** correct. - ** - ** This has to be done even if an error will be returned. Normally, if - ** an error occurs during tree balancing, the contents of MemPage are - ** not important, as they will be recalculated when the page is rolled - ** back. But here, in balance_quick(), it is possible that pPage has - ** not yet been marked dirty or written into the journal file. Therefore - ** it will not be rolled back and so it is important to make sure that - ** the page data and contents of MemPage are consistent. - */ - pPage->isInit = 0; - sqlite3BtreeInitPage(pPage); - assert( pPage->nOverflow==0 ); - - /* If everything else succeeded, balance the parent page, in - ** case the divider cell inserted caused it to become overfull. - */ - if( rc==SQLITE_OK ){ - releasePage(pPage); - pCur->iPage--; - rc = balance(pCur, 0); - } return rc; } #endif /* SQLITE_OMIT_QUICKBALANCE */ -/* -** This routine redistributes Cells on pPage and up to NN*2 siblings -** of pPage so that all pages have about the same amount of free space. -** Usually NN siblings on either side of pPage is used in the balancing, -** though more siblings might come from one side if pPage is the first -** or last child of its parent. If pPage has fewer than 2*NN siblings -** (something which can only happen if pPage is the root page or a -** child of root) then all available siblings participate in the balancing. -** -** The number of siblings of pPage might be increased or decreased by one or -** two in an effort to keep pages nearly full but not over full. The root page -** is special and is allowed to be nearly empty. If pPage is -** the root page, then the depth of the tree might be increased -** or decreased by one, as necessary, to keep the root page from being -** overfull or completely empty. -** -** Note that when this routine is called, some of the Cells on pPage -** might not actually be stored in pPage->aData[]. This can happen -** if the page is overfull. Part of the job of this routine is to -** make sure all Cells for pPage once again fit in pPage->aData[]. -** -** In the course of balancing the siblings of pPage, the parent of pPage -** might become overfull or underfull. If that happens, then this routine -** is called recursively on the parent. +#if 0 +/* +** This function does not contribute anything to the operation of SQLite. +** it is sometimes activated temporarily while debugging code responsible +** for setting pointer-map entries. +*/ +static int ptrmapCheckPages(MemPage **apPage, int nPage){ + int i, j; + for(i=0; i<nPage; i++){ + Pgno n; + u8 e; + MemPage *pPage = apPage[i]; + BtShared *pBt = pPage->pBt; + assert( pPage->isInit ); + + for(j=0; j<pPage->nCell; j++){ + CellInfo info; + u8 *z; + + z = findCell(pPage, j); + sqlite3BtreeParseCellPtr(pPage, z, &info); + if( info.iOverflow ){ + Pgno ovfl = get4byte(&z[info.iOverflow]); + ptrmapGet(pBt, ovfl, &e, &n); + assert( n==pPage->pgno && e==PTRMAP_OVERFLOW1 ); + } + if( !pPage->leaf ){ + Pgno child = get4byte(z); + ptrmapGet(pBt, child, &e, &n); + assert( n==pPage->pgno && e==PTRMAP_BTREE ); + } + } + if( !pPage->leaf ){ + Pgno child = get4byte(&pPage->aData[pPage->hdrOffset+8]); + ptrmapGet(pBt, child, &e, &n); + assert( n==pPage->pgno && e==PTRMAP_BTREE ); + } + } + return 1; +} +#endif + + +/* +** This routine redistributes cells on the iParentIdx'th child of pParent +** (hereafter "the page") and up to 2 siblings so that all pages have about the +** same amount of free space. Usually a single sibling on either side of the +** page are used in the balancing, though both siblings might come from one +** side if the page is the first or last child of its parent. If the page +** has fewer than 2 siblings (something which can only happen if the page +** is a root page or a child of a root page) then all available siblings +** participate in the balancing. +** +** The number of siblings of the page might be increased or decreased by +** one or two in an effort to keep pages nearly full but not over full. +** +** Note that when this routine is called, some of the cells on the page +** might not actually be stored in MemPage.aData[]. This can happen +** if the page is overfull. This routine ensures that all cells allocated +** to the page and its siblings fit into MemPage.aData[] before returning. +** +** In the course of balancing the page and its siblings, cells may be +** inserted into or removed from the parent page (pParent). Doing so +** may cause the parent page to become overfull or underfull. If this +** happens, it is the responsibility of the caller to invoke the correct +** balancing routine to fix this problem (see the balance() routine). ** ** If this routine fails for any reason, it might leave the database -** in a corrupted state. So if this routine fails, the database should +** in a corrupted state. So if this routine fails, the database should ** be rolled back. -*/ -static int balance_nonroot(BtCursor *pCur){ - MemPage *pPage; /* The over or underfull page to balance */ - MemPage *pParent; /* The parent of pPage */ +** +** The third argument to this function, aOvflSpace, is a pointer to a +** buffer page-size bytes in size. If, in inserting cells into the parent +** page (pParent), the parent page becomes overfull, this buffer is +** used to store the parents overflow cells. Because this function inserts +** a maximum of four divider cells into the parent page, and the maximum +** size of a cell stored within an internal node is always less than 1/4 +** of the page-size, the aOvflSpace[] buffer is guaranteed to be large +** enough for all overflow cells. +** +** If aOvflSpace is set to a null pointer, this function returns +** SQLITE_NOMEM. +*/ +static int balance_nonroot( + MemPage *pParent, /* Parent page of siblings being balanced */ + int iParentIdx, /* Index of "the page" in pParent */ + u8 *aOvflSpace /* page-size bytes of space for parent ovfl */ +){ BtShared *pBt; /* The whole database */ int nCell = 0; /* Number of cells in apCell[] */ int nMaxCells = 0; /* Allocated size of apCell, szCell, aFrom. */ - int nOld = 0; /* Number of pages in apOld[] */ int nNew = 0; /* Number of pages in apNew[] */ - int nDiv; /* Number of cells in apDiv[] */ + int nOld; /* Number of pages in apOld[] */ int i, j, k; /* Loop counters */ - int idx; /* Index of pPage in pParent->aCell[] */ int nxDiv; /* Next divider slot in pParent->aCell[] */ - int rc; /* The return code */ + int rc = SQLITE_OK; /* The return code */ int leafCorrection; /* 4 if pPage is a leaf. 0 if not */ int leafData; /* True if pPage is a leaf of a LEAFDATA tree */ int usableSpace; /* Bytes in pPage beyond the header */ int pageFlags; /* Value of pPage->aData[0] */ int subtotal; /* Subtotal of bytes in cells on one page */ int iSpace1 = 0; /* First unused byte of aSpace1[] */ - int iSpace2 = 0; /* First unused byte of aSpace2[] */ + int iOvflSpace = 0; /* First unused byte of aOvflSpace[] */ int szScratch; /* Size of scratch memory requested */ MemPage *apOld[NB]; /* pPage and up to two siblings */ - Pgno pgnoOld[NB]; /* Page numbers for each page in apOld[] */ MemPage *apCopy[NB]; /* Private copies of apOld[] pages */ MemPage *apNew[NB+2]; /* pPage and up to NB siblings after balancing */ - Pgno pgnoNew[NB+2]; /* Page numbers for each page in apNew[] */ - u8 *apDiv[NB]; /* Divider cells in pParent */ + u8 *pRight; /* Location in parent of right-sibling pointer */ + u8 *apDiv[NB-1]; /* Divider cells in pParent */ int cntNew[NB+2]; /* Index in aCell[] of cell after i-th page */ int szNew[NB+2]; /* Combined size of cells place on i-th page */ u8 **apCell = 0; /* All cells begin balanced */ u16 *szCell; /* Local size of all cells in apCell[] */ - u8 *aCopy[NB]; /* Space for holding data of apCopy[] */ - u8 *aSpace1; /* Space for copies of dividers cells before balance */ - u8 *aSpace2 = 0; /* Space for overflow dividers cells after balance */ - u8 *aFrom = 0; - - pPage = pCur->apPage[pCur->iPage]; - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - VVA_ONLY( pCur->pagesShuffled = 1 ); - - /* - ** Find the parent page. - */ - assert( pCur->iPage>0 ); - assert( pPage->isInit ); - assert( sqlite3PagerIswriteable(pPage->pDbPage) || pPage->nOverflow==1 ); - pBt = pPage->pBt; - pParent = pCur->apPage[pCur->iPage-1]; - assert( pParent ); - if( SQLITE_OK!=(rc = sqlite3PagerWrite(pParent->pDbPage)) ){ - goto balance_cleanup; - } - + u8 *aSpace1; /* Space for copies of dividers cells */ + Pgno pgno; /* Temp var to store a page number in */ + + pBt = pParent->pBt; + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); + +#if 0 TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno)); - -#ifndef SQLITE_OMIT_QUICKBALANCE - /* - ** A special case: If a new entry has just been inserted into a - ** table (that is, a btree with integer keys and all data at the leaves) - ** and the new entry is the right-most entry in the tree (it has the - ** largest key) then use the special balance_quick() routine for - ** balancing. balance_quick() is much faster and results in a tighter - ** packing of data in the common case. - */ - if( pPage->leaf && - pPage->intKey && - pPage->nOverflow==1 && - pPage->aOvfl[0].idx==pPage->nCell && - pParent->pgno!=1 && - get4byte(&pParent->aData[pParent->hdrOffset+8])==pPage->pgno - ){ - assert( pPage->intKey ); - /* - ** TODO: Check the siblings to the left of pPage. It may be that - ** they are not full and no new page is required. - */ - return balance_quick(pCur); - } -#endif - - if( SQLITE_OK!=(rc = sqlite3PagerWrite(pPage->pDbPage)) ){ - goto balance_cleanup; - } - - /* - ** Find the cell in the parent page whose left child points back - ** to pPage. The "idx" variable is the index of that cell. If pPage - ** is the rightmost child of pParent then set idx to pParent->nCell - */ - idx = pCur->aiIdx[pCur->iPage-1]; - assertParentIndex(pParent, idx, pPage->pgno); - - /* - ** Find sibling pages to pPage and the cells in pParent that divide - ** the siblings. An attempt is made to find NN siblings on either - ** side of pPage. More siblings are taken from one side, however, if - ** pPage there are fewer than NN siblings on the other side. If pParent +#endif + + /* At this point pParent may have at most one overflow cell. And if + ** this overflow cell is present, it must be the cell with + ** index iParentIdx. This scenario comes about when this function + ** is called (indirectly) from sqlite3BtreeDelete(). */ + assert( pParent->nOverflow==0 || pParent->nOverflow==1 ); + assert( pParent->nOverflow==0 || pParent->aOvfl[0].idx==iParentIdx ); + + if( !aOvflSpace ){ + return SQLITE_NOMEM; + } + + /* Find the sibling pages to balance. Also locate the cells in pParent + ** that divide the siblings. An attempt is made to find NN siblings on + ** either side of pPage. More siblings are taken from one side, however, + ** if there are fewer than NN siblings on the other side. If pParent ** has NB or fewer children then all children of pParent are taken. - */ - nxDiv = idx - NN; - if( nxDiv + NB > pParent->nCell ){ - nxDiv = pParent->nCell - NB + 1; - } - if( nxDiv<0 ){ + ** + ** This loop also drops the divider cells from the parent page. This + ** way, the remainder of the function does not have to deal with any + ** overflow cells in the parent page, as if one existed it has already + ** been removed. */ + i = pParent->nOverflow + pParent->nCell; + if( i<2 ){ nxDiv = 0; - } - nDiv = 0; - for(i=0, k=nxDiv; i<NB; i++, k++){ - if( k<pParent->nCell ){ - apDiv[i] = findCell(pParent, k); - nDiv++; - assert( !pParent->leaf ); - pgnoOld[i] = get4byte(apDiv[i]); - }else if( k==pParent->nCell ){ - pgnoOld[i] = get4byte(&pParent->aData[pParent->hdrOffset+8]); - }else{ - break; - } - rc = getAndInitPage(pBt, pgnoOld[i], &apOld[i]); - if( rc ) goto balance_cleanup; - /* apOld[i]->idxParent = k; */ - apCopy[i] = 0; - assert( i==nOld ); - nOld++; + nOld = i+1; + }else{ + nOld = 3; + if( iParentIdx==0 ){ + nxDiv = 0; + }else if( iParentIdx==i ){ + nxDiv = i-2; + }else{ + nxDiv = iParentIdx-1; + } + i = 2; + } + if( (i+nxDiv-pParent->nOverflow)==pParent->nCell ){ + pRight = &pParent->aData[pParent->hdrOffset+8]; + }else{ + pRight = findCell(pParent, i+nxDiv-pParent->nOverflow); + } + pgno = get4byte(pRight); + while( 1 ){ + rc = getAndInitPage(pBt, pgno, &apOld[i]); + if( rc ){ + memset(apOld, 0, i*sizeof(MemPage*)); + goto balance_cleanup; + } nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow; + if( (i--)==0 ) break; + + if( pParent->nOverflow && i+nxDiv==pParent->aOvfl[0].idx ){ + apDiv[i] = pParent->aOvfl[0].pCell; + pgno = get4byte(apDiv[i]); + szNew[i] = cellSizePtr(pParent, apDiv[i]); + pParent->nOverflow = 0; + }else{ + apDiv[i] = findCell(pParent, i+nxDiv-pParent->nOverflow); + pgno = get4byte(apDiv[i]); + szNew[i] = cellSizePtr(pParent, apDiv[i]); + + /* Drop the cell from the parent page. apDiv[i] still points to + ** the cell within the parent, even though it has been dropped. + ** This is safe because dropping a cell only overwrites the first + ** four bytes of it, and this function does not need the first + ** four bytes of the divider cell. So the pointer is safe to use + ** later on. + ** + ** Unless SQLite is compiled in secure-delete mode. In this case, + ** the dropCell() routine will overwrite the entire cell with zeroes. + ** In this case, temporarily copy the cell into the aOvflSpace[] + ** buffer. It will be copied out again as soon as the aSpace[] buffer + ** is allocated. */ +#ifdef SQLITE_SECURE_DELETE + memcpy(&aOvflSpace[apDiv[i]-pParent->aData], apDiv[i], szNew[i]); + apDiv[i] = &aOvflSpace[apDiv[i]-pParent->aData]; +#endif + dropCell(pParent, i+nxDiv-pParent->nOverflow, szNew[i]); + } } /* Make nMaxCells a multiple of 4 in order to preserve 8-byte ** alignment */ nMaxCells = (nMaxCells + 3)&~3; /* ** Allocate space for memory structures */ + k = pBt->pageSize + ROUND8(sizeof(MemPage)); szScratch = nMaxCells*sizeof(u8*) /* apCell */ + nMaxCells*sizeof(u16) /* szCell */ - + (ROUND8(sizeof(MemPage))+pBt->pageSize)*NB /* aCopy */ + pBt->pageSize /* aSpace1 */ - + (ISAUTOVACUUM ? nMaxCells : 0); /* aFrom */ + + k*nOld; /* Page copies (apCopy) */ apCell = sqlite3ScratchMalloc( szScratch ); if( apCell==0 ){ rc = SQLITE_NOMEM; goto balance_cleanup; } szCell = (u16*)&apCell[nMaxCells]; - aCopy[0] = (u8*)&szCell[nMaxCells]; - assert( EIGHT_BYTE_ALIGNMENT(aCopy[0]) ); - for(i=1; i<NB; i++){ - aCopy[i] = &aCopy[i-1][pBt->pageSize+ROUND8(sizeof(MemPage))]; - assert( ((aCopy[i] - (u8*)0) & 7)==0 ); /* 8-byte alignment required */ - } - aSpace1 = &aCopy[NB-1][pBt->pageSize+ROUND8(sizeof(MemPage))]; - assert( EIGHT_BYTE_ALIGNMENT(aSpace1) ); - if( ISAUTOVACUUM ){ - aFrom = &aSpace1[pBt->pageSize]; - } - aSpace2 = sqlite3PageMalloc(pBt->pageSize); - if( aSpace2==0 ){ - rc = SQLITE_NOMEM; - goto balance_cleanup; - } - - /* - ** Make copies of the content of pPage and its siblings into aOld[]. - ** The rest of this function will use data from the copies rather - ** that the original pages since the original pages will be in the - ** process of being overwritten. - */ - for(i=0; i<nOld; i++){ - MemPage *p = apCopy[i] = (MemPage*)aCopy[i]; - memcpy(p, apOld[i], sizeof(MemPage)); - p->aData = (void*)&p[1]; - memcpy(p->aData, apOld[i]->aData, pBt->pageSize); - } + aSpace1 = (u8*)&szCell[nMaxCells]; + assert( EIGHT_BYTE_ALIGNMENT(aSpace1) ); /* ** Load pointers to all cells on sibling pages and the divider cells ** into the local apCell[] array. Make copies of the divider cells - ** into space obtained form aSpace1[] and remove the the divider Cells + ** into space obtained from aSpace1[] and remove the the divider Cells ** from pParent. ** ** If the siblings are on leaf pages, then the child pointers of the ** divider cells are stripped from the cells before they are copied ** into aSpace1[]. In this way, all cells in apCell[] are without @@ -42325,72 +42387,58 @@ ** are alike. ** ** leafCorrection: 4 if pPage is a leaf. 0 if pPage is not a leaf. ** leafData: 1 if pPage holds key+data and pParent holds only keys. */ - nCell = 0; - leafCorrection = pPage->leaf*4; - leafData = pPage->hasData; + leafCorrection = apOld[0]->leaf*4; + leafData = apOld[0]->hasData; for(i=0; i<nOld; i++){ - MemPage *pOld = apCopy[i]; - int limit = pOld->nCell+pOld->nOverflow; + int limit; + + /* Before doing anything else, take a copy of the i'th original sibling + ** The rest of this function will use data from the copies rather + ** that the original pages since the original pages will be in the + ** process of being overwritten. */ + MemPage *pOld = apCopy[i] = (MemPage*)&aSpace1[pBt->pageSize + k*i]; + memcpy(pOld, apOld[i], sizeof(MemPage)); + pOld->aData = (void*)&pOld[1]; + memcpy(pOld->aData, apOld[i]->aData, pBt->pageSize); + + limit = pOld->nCell+pOld->nOverflow; for(j=0; j<limit; j++){ assert( nCell<nMaxCells ); apCell[nCell] = findOverflowCell(pOld, j); szCell[nCell] = cellSizePtr(pOld, apCell[nCell]); - if( ISAUTOVACUUM ){ - int a; - aFrom[nCell] = (u8)i; assert( i>=0 && i<6 ); - for(a=0; a<pOld->nOverflow; a++){ - if( pOld->aOvfl[a].pCell==apCell[nCell] ){ - aFrom[nCell] = 0xFF; - break; - } - } - } nCell++; } - if( i<nOld-1 ){ - u16 sz = cellSizePtr(pParent, apDiv[i]); - if( leafData ){ - /* With the LEAFDATA flag, pParent cells hold only INTKEYs that - ** are duplicates of keys on the child pages. We need to remove - ** the divider cells from pParent, but the dividers cells are not - ** added to apCell[] because they are duplicates of child cells. - */ - dropCell(pParent, nxDiv, sz); - }else{ - u8 *pTemp; - assert( nCell<nMaxCells ); - szCell[nCell] = sz; - pTemp = &aSpace1[iSpace1]; - iSpace1 += sz; - assert( sz<=pBt->pageSize/4 ); - assert( iSpace1<=pBt->pageSize ); - memcpy(pTemp, apDiv[i], sz); - apCell[nCell] = pTemp+leafCorrection; - if( ISAUTOVACUUM ){ - aFrom[nCell] = 0xFF; - } - dropCell(pParent, nxDiv, sz); - assert( leafCorrection==0 || leafCorrection==4 ); - szCell[nCell] -= (u16)leafCorrection; - assert( get4byte(pTemp)==pgnoOld[i] ); - if( !pOld->leaf ){ - assert( leafCorrection==0 ); - /* The right pointer of the child page pOld becomes the left - ** pointer of the divider cell */ - memcpy(apCell[nCell], &pOld->aData[pOld->hdrOffset+8], 4); - }else{ - assert( leafCorrection==4 ); - if( szCell[nCell]<4 ){ - /* Do not allow any cells smaller than 4 bytes. */ - szCell[nCell] = 4; - } - } - nCell++; - } + if( i<nOld-1 && !leafData){ + u16 sz = szNew[i]; + u8 *pTemp; + assert( nCell<nMaxCells ); + szCell[nCell] = sz; + pTemp = &aSpace1[iSpace1]; + iSpace1 += sz; + assert( sz<=pBt->pageSize/4 ); + assert( iSpace1<=pBt->pageSize ); + memcpy(pTemp, apDiv[i], sz); + apCell[nCell] = pTemp+leafCorrection; + assert( leafCorrection==0 || leafCorrection==4 ); + szCell[nCell] -= (u16)leafCorrection; + if( !pOld->leaf ){ + assert( leafCorrection==0 ); + assert( pOld->hdrOffset==0 ); + /* The right pointer of the child page pOld becomes the left + ** pointer of the divider cell */ + memcpy(apCell[nCell], &pOld->aData[8], 4); + }else{ + assert( leafCorrection==4 ); + if( szCell[nCell]<4 ){ + /* Do not allow any cells smaller than 4 bytes. */ + szCell[nCell] = 4; + } + } + nCell++; } } /* ** Figure out the number of pages needed to hold all nCell cells. @@ -42416,10 +42464,11 @@ szNew[k] = subtotal - szCell[i]; cntNew[k] = i; if( leafData ){ i--; } subtotal = 0; k++; + if( k>NB+1 ){ rc = SQLITE_CORRUPT; goto balance_cleanup; } } } szNew[k] = subtotal; cntNew[k] = nCell; k++; @@ -42459,30 +42508,46 @@ ** 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) ); + TRACE(("BALANCE: old: %d %d %d ", + apOld[0]->pgno, + nOld>=2 ? apOld[1]->pgno : 0, + nOld>=3 ? apOld[2]->pgno : 0 + )); + /* ** Allocate k new pages. Reuse old pages where possible. */ - assert( pPage->pgno>1 ); - pageFlags = pPage->aData[0]; + if( apOld[0]->pgno<=1 ){ + rc = SQLITE_CORRUPT; + goto balance_cleanup; + } + pageFlags = apOld[0]->aData[0]; for(i=0; i<k; i++){ MemPage *pNew; if( i<nOld ){ pNew = apNew[i] = apOld[i]; - pgnoNew[i] = pgnoOld[i]; apOld[i] = 0; rc = sqlite3PagerWrite(pNew->pDbPage); nNew++; if( rc ) goto balance_cleanup; }else{ assert( i>0 ); - rc = allocateBtreePage(pBt, &pNew, &pgnoNew[i], pgnoNew[i-1], 0); + rc = allocateBtreePage(pBt, &pNew, &pgno, pgno, 0); if( rc ) goto balance_cleanup; apNew[i] = pNew; nNew++; + + /* Set the pointer-map entry for the new sibling page. */ + if( ISAUTOVACUUM ){ + rc = ptrmapPut(pBt, pNew->pgno, PTRMAP_BTREE, pParent->pgno); + if( rc!=SQLITE_OK ){ + goto balance_cleanup; + } + } } } /* Free any old pages that were not reused as new pages. */ @@ -42507,38 +42572,36 @@ ** ** When NB==3, this one optimization makes the database ** about 25% faster for large insertions and deletions. */ for(i=0; i<k-1; i++){ - int minV = pgnoNew[i]; + int minV = apNew[i]->pgno; int minI = i; for(j=i+1; j<k; j++){ - if( pgnoNew[j]<(unsigned)minV ){ + if( apNew[j]->pgno<(unsigned)minV ){ minI = j; - minV = pgnoNew[j]; + minV = apNew[j]->pgno; } } if( minI>i ){ int t; MemPage *pT; - t = pgnoNew[i]; + t = apNew[i]->pgno; pT = apNew[i]; - pgnoNew[i] = pgnoNew[minI]; - apNew[i] = apNew[minI]; - pgnoNew[minI] = t; + apNew[i] = apNew[minI]; apNew[minI] = pT; } } - TRACE(("BALANCE: old: %d %d %d new: %d(%d) %d(%d) %d(%d) %d(%d) %d(%d)\n", - pgnoOld[0], - nOld>=2 ? pgnoOld[1] : 0, - nOld>=3 ? pgnoOld[2] : 0, - pgnoNew[0], szNew[0], - nNew>=2 ? pgnoNew[1] : 0, nNew>=2 ? szNew[1] : 0, - nNew>=3 ? pgnoNew[2] : 0, nNew>=3 ? szNew[2] : 0, - nNew>=4 ? pgnoNew[3] : 0, nNew>=4 ? szNew[3] : 0, - nNew>=5 ? pgnoNew[4] : 0, nNew>=5 ? szNew[4] : 0)); + TRACE(("new: %d(%d) %d(%d) %d(%d) %d(%d) %d(%d)\n", + apNew[0]->pgno, szNew[0], + nNew>=2 ? apNew[1]->pgno : 0, nNew>=2 ? szNew[1] : 0, + nNew>=3 ? apNew[2]->pgno : 0, nNew>=3 ? szNew[2] : 0, + nNew>=4 ? apNew[3]->pgno : 0, nNew>=4 ? szNew[3] : 0, + nNew>=5 ? apNew[4]->pgno : 0, nNew>=5 ? szNew[4] : 0)); + + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); + put4byte(pRight, apNew[nNew-1]->pgno); /* ** Evenly distribute the data in apCell[] across the new pages. ** Insert divider cells into pParent as necessary. */ @@ -42545,35 +42608,14 @@ j = 0; for(i=0; i<nNew; i++){ /* Assemble the new sibling page. */ MemPage *pNew = apNew[i]; assert( j<nMaxCells ); - assert( pNew->pgno==pgnoNew[i] ); zeroPage(pNew, pageFlags); assemblePage(pNew, cntNew[i]-j, &apCell[j], &szCell[j]); assert( pNew->nCell>0 || (nNew==1 && cntNew[0]==0) ); assert( pNew->nOverflow==0 ); - - /* If this is an auto-vacuum database, update the pointer map entries - ** that point to the siblings that were rearranged. These can be: left - ** children of cells, the right-child of the page, or overflow pages - ** pointed to by cells. - */ - if( ISAUTOVACUUM ){ - for(k=j; k<cntNew[i]; k++){ - assert( k<nMaxCells ); - if( aFrom[k]==0xFF || apCopy[aFrom[k]]->pgno!=pNew->pgno ){ - rc = ptrmapPutOvfl(pNew, k-j); - if( rc==SQLITE_OK && leafCorrection==0 ){ - rc = ptrmapPut(pBt, get4byte(apCell[k]), PTRMAP_BTREE, pNew->pgno); - } - if( rc!=SQLITE_OK ){ - goto balance_cleanup; - } - } - } - } j = cntNew[i]; /* If the sibling page assembled above was not the right-most sibling, ** insert a divider cell into the parent page. @@ -42584,21 +42626,13 @@ int sz; assert( j<nMaxCells ); pCell = apCell[j]; sz = szCell[j] + leafCorrection; - pTemp = &aSpace2[iSpace2]; + pTemp = &aOvflSpace[iOvflSpace]; if( !pNew->leaf ){ memcpy(&pNew->aData[8], pCell, 4); - if( ISAUTOVACUUM - && (aFrom[j]==0xFF || apCopy[aFrom[j]]->pgno!=pNew->pgno) - ){ - rc = ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno); - if( rc!=SQLITE_OK ){ - goto balance_cleanup; - } - } }else if( leafData ){ /* If the tree is a leaf-data tree, and the siblings are leaves, ** then there is no divider cell in apCell[]. Instead, the divider ** cell consists of the integer key for the right-most cell of ** the sibling-page assembled above only. @@ -42605,14 +42639,11 @@ */ CellInfo info; j--; sqlite3BtreeParseCellPtr(pNew, apCell[j], &info); pCell = pTemp; - rc = fillInCell(pParent, pCell, 0, info.nKey, 0, 0, 0, &sz); - if( rc!=SQLITE_OK ){ - goto balance_cleanup; - } + sz = 4 + putVarint(&pCell[4], info.nKey); pTemp = 0; }else{ pCell -= 4; /* Obscure case for non-leaf-data trees: If the cell at pCell was ** previously stored on a leaf node, and its reported size was 4 @@ -42628,300 +42659,457 @@ if( szCell[j]==4 ){ assert(leafCorrection==4); sz = cellSizePtr(pParent, pCell); } } - iSpace2 += sz; + iOvflSpace += sz; assert( sz<=pBt->pageSize/4 ); - assert( iSpace2<=pBt->pageSize ); - rc = insertCell(pParent, nxDiv, pCell, sz, pTemp, 4); + assert( iOvflSpace<=pBt->pageSize ); + rc = insertCell(pParent, nxDiv, pCell, sz, pTemp, pNew->pgno); if( rc!=SQLITE_OK ) goto balance_cleanup; assert( sqlite3PagerIswriteable(pParent->pDbPage) ); - put4byte(findOverflowCell(pParent,nxDiv), pNew->pgno); - - /* If this is an auto-vacuum database, and not a leaf-data tree, - ** then update the pointer map with an entry for the overflow page - ** that the cell just inserted points to (if any). - */ - if( ISAUTOVACUUM && !leafData ){ - rc = ptrmapPutOvfl(pParent, nxDiv); - if( rc!=SQLITE_OK ){ - goto balance_cleanup; - } - } + j++; nxDiv++; - } - - /* Set the pointer-map entry for the new sibling page. */ - if( ISAUTOVACUUM ){ - rc = ptrmapPut(pBt, pNew->pgno, PTRMAP_BTREE, pParent->pgno); - if( rc!=SQLITE_OK ){ - goto balance_cleanup; - } } } assert( j==nCell ); assert( nOld>0 ); assert( nNew>0 ); if( (pageFlags & PTF_LEAF)==0 ){ u8 *zChild = &apCopy[nOld-1]->aData[8]; memcpy(&apNew[nNew-1]->aData[8], zChild, 4); - if( ISAUTOVACUUM ){ - rc = ptrmapPut(pBt, get4byte(zChild), PTRMAP_BTREE, apNew[nNew-1]->pgno); - if( rc!=SQLITE_OK ){ - goto balance_cleanup; - } - } - } - assert( sqlite3PagerIswriteable(pParent->pDbPage) ); - if( nxDiv==pParent->nCell+pParent->nOverflow ){ - /* Right-most sibling is the right-most child of pParent */ - put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew[nNew-1]); - }else{ - /* Right-most sibling is the left child of the first entry in pParent - ** past the right-most divider entry */ - put4byte(findOverflowCell(pParent, nxDiv), pgnoNew[nNew-1]); - } - - /* - ** Balance the parent page. Note that the current page (pPage) might - ** have been added to the freelist so it might no longer be initialized. - ** But the parent page will always be initialized. - */ + } + + /* Fix the pointer-map entries for all the cells that were shifted around. + ** There are several different types of pointer-map entries that need to + ** be dealt with by this routine. Some of these have been set already, but + ** many have not. The following is a summary: + ** + ** 1) The entries associated with new sibling pages that were not + ** siblings when this function was called. These have already + ** been set. We don't need to worry about old siblings that were + ** moved to the free-list - the freePage() code has taken care + ** of those. + ** + ** 2) The pointer-map entries associated with the first overflow + ** page in any overflow chains used by new divider cells. These + ** have also already been taken care of by the insertCell() code. + ** + ** 3) If the sibling pages are not leaves, then the child pages of + ** cells stored on the sibling pages may need to be updated. + ** + ** 4) If the sibling pages are not internal intkey nodes, then any + ** overflow pages used by these cells may need to be updated + ** (internal intkey nodes never contain pointers to overflow pages). + ** + ** 5) If the sibling pages are not leaves, then the pointer-map + ** entries for the right-child pages of each sibling may need + ** to be updated. + ** + ** Cases 1 and 2 are dealt with above by other code. The following + ** block deals with cases 3 and 4. Since setting a pointer map entry + ** is a relatively expensive operation, this code only sets pointer + ** map entries for child or overflow pages that have actually moved + ** between pages. */ + if( ISAUTOVACUUM ){ + MemPage *pNew = apNew[0]; + MemPage *pOld = apCopy[0]; + int nOverflow = pOld->nOverflow; + int iNextOld = pOld->nCell + nOverflow; + int iOverflow = (nOverflow ? pOld->aOvfl[0].idx : -1); + j = 0; /* Current 'old' sibling page */ + k = 0; /* Current 'new' sibling page */ + for(i=0; i<nCell && rc==SQLITE_OK; i++){ + int isDivider = 0; + while( i==iNextOld ){ + /* Cell i is the cell immediately following the last cell on old + ** sibling page j. If the siblings are not leaf pages of an + ** intkey b-tree, then cell i was a divider cell. */ + pOld = apCopy[++j]; + iNextOld = i + !leafData + pOld->nCell + pOld->nOverflow; + if( pOld->nOverflow ){ + nOverflow = pOld->nOverflow; + iOverflow = i + !leafData + pOld->aOvfl[0].idx; + } + isDivider = !leafData; + } + + assert(nOverflow>0 || iOverflow<i ); + assert(nOverflow<2 || pOld->aOvfl[0].idx==pOld->aOvfl[1].idx-1); + assert(nOverflow<3 || pOld->aOvfl[1].idx==pOld->aOvfl[2].idx-1); + if( i==iOverflow ){ + isDivider = 1; + if( (--nOverflow)>0 ){ + iOverflow++; + } + } + + if( i==cntNew[k] ){ + /* Cell i is the cell immediately following the last cell on new + ** sibling page k. If the siblings are not leaf pages of an + ** intkey b-tree, then cell i is a divider cell. */ + pNew = apNew[++k]; + if( !leafData ) continue; + } + assert( rc==SQLITE_OK ); + assert( j<nOld ); + assert( k<nNew ); + + /* If the cell was originally divider cell (and is not now) or + ** an overflow cell, or if the cell was located on a different sibling + ** page before the balancing, then the pointer map entries associated + ** with any child or overflow pages need to be updated. */ + if( isDivider || pOld->pgno!=pNew->pgno ){ + if( !leafCorrection ){ + rc = ptrmapPut(pBt, get4byte(apCell[i]), PTRMAP_BTREE, pNew->pgno); + } + if( szCell[i]>pNew->minLocal && rc==SQLITE_OK ){ + rc = ptrmapPutOvflPtr(pNew, apCell[i]); + } + } + } + + if( !leafCorrection ){ + for(i=0; rc==SQLITE_OK && i<nNew; i++){ + rc = ptrmapPut( + pBt, get4byte(&apNew[i]->aData[8]), PTRMAP_BTREE, apNew[i]->pgno); + } + } + +#if 0 + /* 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); + ptrmapCheckPages(&pParent, 1); +#endif + } + assert( pParent->isInit ); - sqlite3ScratchFree(apCell); - apCell = 0; - TRACE(("BALANCE: finished with %d: old=%d new=%d cells=%d\n", - pPage->pgno, nOld, nNew, nCell)); - pPage->nOverflow = 0; - releasePage(pPage); - pCur->iPage--; - rc = balance(pCur, 0); + TRACE(("BALANCE: finished: old=%d new=%d cells=%d\n", + nOld, nNew, nCell)); /* ** Cleanup before returning. */ balance_cleanup: - sqlite3PageFree(aSpace2); sqlite3ScratchFree(apCell); for(i=0; i<nOld; i++){ releasePage(apOld[i]); } for(i=0; i<nNew; i++){ releasePage(apNew[i]); } - pCur->apPage[pCur->iPage]->nOverflow = 0; - - return rc; -} - -/* -** This routine is called for the root page of a btree when the root -** page contains no cells. This is an opportunity to make the tree + + return rc; +} + +/* +** This function is used to copy the contents of the b-tree node stored +** on page pFrom to page pTo. If page pFrom was not a leaf page, then +** the pointer-map entries for each child page are updated so that the +** parent page stored in the pointer map is page pTo. If pFrom contained +** any cells with overflow page pointers, then the corresponding pointer +** map entries are also updated so that the parent page is page pTo. +** +** If pFrom is currently carrying any overflow cells (entries in the +** MemPage.aOvfl[] array), they are not copied to pTo. +** +** Before returning, page pTo is reinitialized using sqlite3BtreeInitPage(). +** +** The performance of this function is not critical. It is only used by +** the balance_shallower() and balance_deeper() procedures, neither of +** which are called often under normal circumstances. +*/ +static int copyNodeContent(MemPage *pFrom, MemPage *pTo){ + BtShared * const pBt = pFrom->pBt; + u8 * const aFrom = pFrom->aData; + u8 * const aTo = pTo->aData; + int const iFromHdr = pFrom->hdrOffset; + int const iToHdr = ((pTo->pgno==1) ? 100 : 0); + int rc = SQLITE_OK; + int iData; + + assert( pFrom->isInit ); + assert( pFrom->nFree>=iToHdr ); + assert( get2byte(&aFrom[iFromHdr+5])<=pBt->usableSize ); + + /* Copy the b-tree node content from page pFrom to page pTo. */ + iData = get2byte(&aFrom[iFromHdr+5]); + memcpy(&aTo[iData], &aFrom[iData], pBt->usableSize-iData); + memcpy(&aTo[iToHdr], &aFrom[iFromHdr], pFrom->cellOffset + 2*pFrom->nCell); + + /* Reinitialize page pTo so that the contents of the MemPage structure + ** match the new data. The initialization of pTo "cannot" fail, as the + ** data copied from pFrom is known to be valid. */ + pTo->isInit = 0; + TESTONLY(rc = ) sqlite3BtreeInitPage(pTo); + assert( rc==SQLITE_OK ); + + /* 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 ){ + rc = setChildPtrmaps(pTo); + } + return rc; +} + +/* +** This routine is called on the root page of a btree when the root +** page contains no cells. This is an opportunity to make the tree ** shallower by one level. */ -static int balance_shallower(BtCursor *pCur){ - MemPage *pPage; /* Root page of B-Tree */ - MemPage *pChild; /* The only child page of pPage */ - Pgno pgnoChild; /* Page number for pChild */ - int rc = SQLITE_OK; /* Return code from subprocedures */ - BtShared *pBt; /* The main BTree structure */ - int mxCellPerPage; /* Maximum number of cells per page */ - u8 **apCell; /* All cells from pages being balanced */ - u16 *szCell; /* Local size of all cells */ - - assert( pCur->iPage==0 ); - pPage = pCur->apPage[0]; - - assert( pPage->nCell==0 ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - pBt = pPage->pBt; - mxCellPerPage = MX_CELL(pBt); - apCell = sqlite3Malloc( mxCellPerPage*(sizeof(u8*)+sizeof(u16)) ); - if( apCell==0 ) return SQLITE_NOMEM; - szCell = (u16*)&apCell[mxCellPerPage]; - if( pPage->leaf ){ - /* The table is completely empty */ - TRACE(("BALANCE: empty table %d\n", pPage->pgno)); - }else{ - /* The root page is empty but has one child. Transfer the - ** information from that one child into the root page if it - ** will fit. This reduces the depth of the tree by one. - ** - ** If the root page is page 1, it has less space available than - ** its child (due to the 100 byte header that occurs at the beginning - ** of the database fle), so it might not be able to hold all of the - ** information currently contained in the child. If this is the - ** case, then do not do the transfer. Leave page 1 empty except - ** for the right-pointer to the child page. The child page becomes - ** the virtual root of the tree. - */ - VVA_ONLY( pCur->pagesShuffled = 1 ); - pgnoChild = get4byte(&pPage->aData[pPage->hdrOffset+8]); - assert( pgnoChild>0 ); - assert( pgnoChild<=pagerPagecount(pPage->pBt) ); - rc = sqlite3BtreeGetPage(pPage->pBt, pgnoChild, &pChild, 0); - if( rc ) goto end_shallow_balance; - if( pPage->pgno==1 ){ - rc = sqlite3BtreeInitPage(pChild); - if( rc ) goto end_shallow_balance; - assert( pChild->nOverflow==0 ); - if( pChild->nFree>=100 ){ - /* The child information will fit on the root page, so do the - ** copy */ - int i; - zeroPage(pPage, pChild->aData[0]); - for(i=0; i<pChild->nCell; i++){ - apCell[i] = findCell(pChild,i); - szCell[i] = cellSizePtr(pChild, apCell[i]); - } - assemblePage(pPage, pChild->nCell, apCell, szCell); - /* Copy the right-pointer of the child to the parent. */ - assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - put4byte(&pPage->aData[pPage->hdrOffset+8], - get4byte(&pChild->aData[pChild->hdrOffset+8])); +static int balance_shallower(MemPage *pRoot){ + /* The root page is empty but has one child. Transfer the + ** information from that one child into the root page if it + ** will fit. This reduces the depth of the tree by one. + ** + ** If the root page is page 1, it has less space available than + ** its child (due to the 100 byte header that occurs at the beginning + ** of the database fle), so it might not be able to hold all of the + ** information currently contained in the child. If this is the + ** case, then do not do the transfer. Leave page 1 empty except + ** for the right-pointer to the child page. The child page becomes + ** the virtual root of the tree. + */ + int rc = SQLITE_OK; /* Return code */ + int const hdr = pRoot->hdrOffset; /* Offset of root page header */ + MemPage *pChild; /* Only child of pRoot */ + Pgno const pgnoChild = get4byte(&pRoot->aData[pRoot->hdrOffset+8]); + + assert( pRoot->nCell==0 ); + assert( sqlite3_mutex_held(pRoot->pBt->mutex) ); + assert( !pRoot->leaf ); + assert( pgnoChild>0 ); + assert( pgnoChild<=pagerPagecount(pRoot->pBt) ); + assert( hdr==0 || pRoot->pgno==1 ); + + rc = sqlite3BtreeGetPage(pRoot->pBt, pgnoChild, &pChild, 0); + if( rc==SQLITE_OK ){ + if( pChild->nFree>=hdr ){ + if( hdr ){ + rc = defragmentPage(pChild); + } + if( rc==SQLITE_OK ){ + rc = copyNodeContent(pChild, pRoot); + } + if( rc==SQLITE_OK ){ rc = freePage(pChild); - TRACE(("BALANCE: child %d transfer to page 1\n", pChild->pgno)); - }else{ - /* The child has more information that will fit on the root. - ** The tree is already balanced. Do nothing. */ - TRACE(("BALANCE: child %d will not fit on page 1\n", pChild->pgno)); - } - }else{ - memcpy(pPage->aData, pChild->aData, pPage->pBt->usableSize); - pPage->isInit = 0; - rc = sqlite3BtreeInitPage(pPage); - assert( rc==SQLITE_OK ); - freePage(pChild); - TRACE(("BALANCE: transfer child %d into root %d\n", - pChild->pgno, pPage->pgno)); - } - assert( pPage->nOverflow==0 ); -#ifndef SQLITE_OMIT_AUTOVACUUM - if( ISAUTOVACUUM && rc==SQLITE_OK ){ - rc = setChildPtrmaps(pPage); - } -#endif + } + }else{ + /* The child has more information that will fit on the root. + ** The tree is already balanced. Do nothing. */ + TRACE(("BALANCE: child %d will not fit on page 1\n", pChild->pgno)); + } + releasePage(pChild); + } + + return rc; +} + + +/* +** This function is called when the root page of a b-tree structure is +** overfull (has one or more overflow pages). +** +** A new child page is allocated and the contents of the current root +** page, including overflow cells, are copied into the child. The root +** page is then overwritten to make it an empty page with the right-child +** pointer pointing to the new page. +** +** Before returning, all pointer-map entries corresponding to pages +** that the new child-page now contains pointers to are updated. The +** entry corresponding to the new right-child pointer of the root +** page is also updated. +** +** If successful, *ppChild is set to contain a reference to the child +** page and SQLITE_OK is returned. In this case the caller is required +** to call releasePage() on *ppChild exactly once. If an error occurs, +** an error code is returned and *ppChild is set to 0. +*/ +static int balance_deeper(MemPage *pRoot, MemPage **ppChild){ + int rc; /* Return value from subprocedures */ + MemPage *pChild = 0; /* Pointer to a new child page */ + Pgno pgnoChild; /* Page number of the new child page */ + BtShared *pBt = pRoot->pBt; /* The BTree */ + + assert( pRoot->nOverflow>0 ); + assert( sqlite3_mutex_held(pBt->mutex) ); + + /* Make pRoot, the root page of the b-tree, writable. Allocate a new + ** page that will become the new right-child of pPage. Copy the contents + ** of the node stored on pRoot into the new child page. + */ + if( SQLITE_OK!=(rc = sqlite3PagerWrite(pRoot->pDbPage)) + || SQLITE_OK!=(rc = allocateBtreePage(pBt,&pChild,&pgnoChild,pRoot->pgno,0)) + || SQLITE_OK!=(rc = copyNodeContent(pRoot, pChild)) + || (ISAUTOVACUUM && + SQLITE_OK!=(rc = ptrmapPut(pBt, pgnoChild, PTRMAP_BTREE, pRoot->pgno))) + ){ + *ppChild = 0; releasePage(pChild); - } -end_shallow_balance: - sqlite3_free(apCell); - return rc; -} - - -/* -** The root page is overfull -** -** When this happens, Create a new child page and copy the -** contents of the root into the child. Then make the root -** page an empty page with rightChild pointing to the new -** child. Finally, call balance_internal() on the new child -** to cause it to split. -*/ -static int balance_deeper(BtCursor *pCur){ - int rc; /* Return value from subprocedures */ - MemPage *pPage; /* Pointer to the root page */ - MemPage *pChild; /* Pointer to a new child page */ - Pgno pgnoChild; /* Page number of the new child page */ - BtShared *pBt; /* The BTree */ - int usableSize; /* Total usable size of a page */ - u8 *data; /* Content of the parent page */ - u8 *cdata; /* Content of the child page */ - int hdr; /* Offset to page header in parent */ - int cbrk; /* Offset to content of first cell in parent */ - - assert( pCur->iPage==0 ); - assert( pCur->apPage[0]->nOverflow>0 ); - - VVA_ONLY( pCur->pagesShuffled = 1 ); - pPage = pCur->apPage[0]; - pBt = pPage->pBt; - assert( sqlite3_mutex_held(pBt->mutex) ); - assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - rc = allocateBtreePage(pBt, &pChild, &pgnoChild, pPage->pgno, 0); - if( rc ) return rc; + return rc; + } assert( sqlite3PagerIswriteable(pChild->pDbPage) ); - usableSize = pBt->usableSize; - data = pPage->aData; - hdr = pPage->hdrOffset; - cbrk = get2byte(&data[hdr+5]); - cdata = pChild->aData; - memcpy(cdata, &data[hdr], pPage->cellOffset+2*pPage->nCell-hdr); - memcpy(&cdata[cbrk], &data[cbrk], usableSize-cbrk); - - assert( pChild->isInit==0 ); - rc = sqlite3BtreeInitPage(pChild); - if( rc==SQLITE_OK ){ - int nCopy = pPage->nOverflow*sizeof(pPage->aOvfl[0]); - memcpy(pChild->aOvfl, pPage->aOvfl, nCopy); - pChild->nOverflow = pPage->nOverflow; - if( pChild->nOverflow ){ - pChild->nFree = 0; - } - assert( pChild->nCell==pPage->nCell ); - assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - zeroPage(pPage, pChild->aData[0] & ~PTF_LEAF); - put4byte(&pPage->aData[pPage->hdrOffset+8], pgnoChild); - TRACE(("BALANCE: copy root %d into %d\n", pPage->pgno, pChild->pgno)); - if( ISAUTOVACUUM ){ - rc = ptrmapPut(pBt, pChild->pgno, PTRMAP_BTREE, pPage->pgno); -#ifndef SQLITE_OMIT_AUTOVACUUM - if( rc==SQLITE_OK ){ - rc = setChildPtrmaps(pChild); - } - if( rc ){ - pChild->nOverflow = 0; - } -#endif - } - } - - if( rc==SQLITE_OK ){ - pCur->iPage++; - pCur->apPage[1] = pChild; - pCur->aiIdx[0] = 0; - rc = balance_nonroot(pCur); - }else{ - releasePage(pChild); - } - - return rc; + assert( sqlite3PagerIswriteable(pRoot->pDbPage) ); + assert( pChild->nCell==pRoot->nCell ); + + TRACE(("BALANCE: copy root %d into %d\n", pRoot->pgno, pChild->pgno)); + + /* Copy the overflow cells from pRoot to pChild */ + memcpy(pChild->aOvfl, pRoot->aOvfl, pRoot->nOverflow*sizeof(pRoot->aOvfl[0])); + pChild->nOverflow = pRoot->nOverflow; + + /* Zero the contents of pRoot. Then install pChild as the right-child. */ + zeroPage(pRoot, pChild->aData[0] & ~PTF_LEAF); + put4byte(&pRoot->aData[pRoot->hdrOffset+8], pgnoChild); + + *ppChild = pChild; + return SQLITE_OK; } /* ** The page that pCur currently points to has just been modified in ** some way. This function figures out if this modification means the ** tree needs to be balanced, and if so calls the appropriate balancing -** routine. -** -** Parameter isInsert is true if a new cell was just inserted into the -** page, or false otherwise. -*/ -static int balance(BtCursor *pCur, int isInsert){ - int rc = SQLITE_OK; - MemPage *pPage = pCur->apPage[pCur->iPage]; - - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - if( pCur->iPage==0 ){ - rc = sqlite3PagerWrite(pPage->pDbPage); - if( rc==SQLITE_OK && pPage->nOverflow>0 ){ - rc = balance_deeper(pCur); - assert( pCur->apPage[0]==pPage ); - assert( pPage->nOverflow==0 || rc!=SQLITE_OK ); - } - if( rc==SQLITE_OK && pPage->nCell==0 ){ - rc = balance_shallower(pCur); - assert( pCur->apPage[0]==pPage ); - assert( pPage->nOverflow==0 || rc!=SQLITE_OK ); - } - }else{ - if( pPage->nOverflow>0 || - (!isInsert && pPage->nFree>pPage->pBt->usableSize*2/3) ){ - rc = balance_nonroot(pCur); - } +** routine. Balancing routines are: +** +** balance_quick() +** balance_shallower() +** balance_deeper() +** balance_nonroot() +** +** If built with SQLITE_DEBUG, pCur->pagesShuffled is set to true if +** balance_shallower(), balance_deeper() or balance_nonroot() is called. +** If none of these functions are invoked, pCur->pagesShuffled is left +** unmodified. +*/ +static int balance(BtCursor *pCur){ + int rc = SQLITE_OK; + const int nMin = pCur->pBt->usableSize * 2 / 3; + u8 aBalanceQuickSpace[13]; + u8 *pFree = 0; + + TESTONLY( int balance_quick_called = 0 ); + TESTONLY( int balance_deeper_called = 0 ); + + do { + int iPage = pCur->iPage; + MemPage *pPage = pCur->apPage[iPage]; + + if( iPage==0 ){ + if( pPage->nOverflow ){ + /* 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 + ** and copy the current contents of the root-page to it. The + ** next iteration of the do-loop will balance the child page. + */ + assert( (balance_deeper_called++)==0 ); + rc = balance_deeper(pPage, &pCur->apPage[1]); + if( rc==SQLITE_OK ){ + pCur->iPage = 1; + pCur->aiIdx[0] = 0; + pCur->aiIdx[1] = 0; + assert( pCur->apPage[1]->nOverflow ); + } + VVA_ONLY( pCur->pagesShuffled = 1 ); + }else{ + /* The root page of the b-tree is now empty. If the root-page is not + ** also a leaf page, it will have a single child page. Call + ** balance_shallower to attempt to copy the contents of the single + ** child-page into the root page (this may not be possible if the + ** root page is page 1). + ** + ** Whether or not this is possible , the tree is now balanced. + ** Therefore is no next iteration of the do-loop. + */ + if( pPage->nCell==0 && !pPage->leaf ){ + rc = balance_shallower(pPage); + VVA_ONLY( pCur->pagesShuffled = 1 ); + } + break; + } + }else if( pPage->nOverflow==0 && pPage->nFree<=nMin ){ + break; + }else{ + MemPage * const pParent = pCur->apPage[iPage-1]; + int const iIdx = pCur->aiIdx[iPage-1]; + + rc = sqlite3PagerWrite(pParent->pDbPage); + if( rc==SQLITE_OK ){ +#ifndef SQLITE_OMIT_QUICKBALANCE + if( pPage->hasData + && pPage->nOverflow==1 + && pPage->aOvfl[0].idx==pPage->nCell + && pParent->pgno!=1 + && pParent->nCell==iIdx + ){ + /* Call balance_quick() to create a new sibling of pPage on which + ** to store the overflow cell. balance_quick() inserts a new cell + ** into pParent, which may cause pParent overflow. If this + ** happens, the next interation of the do-loop will balance pParent + ** use either balance_nonroot() or balance_deeper(). Until this + ** happens, the overflow cell is stored in the aBalanceQuickSpace[] + ** buffer. + ** + ** The purpose of the following assert() is to check that only a + ** single call to balance_quick() is made for each call to this + ** function. If this were not verified, a subtle bug involving reuse + ** of the aBalanceQuickSpace[] might sneak in. + */ + assert( (balance_quick_called++)==0 ); + rc = balance_quick(pParent, pPage, aBalanceQuickSpace); + }else +#endif + { + /* In this case, call balance_nonroot() to redistribute cells + ** between pPage and up to 2 of its sibling pages. This involves + ** modifying the contents of pParent, which may cause pParent to + ** become overfull or underfull. The next iteration of the do-loop + ** will balance the parent page to correct this. + ** + ** If the parent page becomes overfull, the overflow cell or cells + ** are stored in the pSpace buffer allocated immediately below. + ** A subsequent iteration of the do-loop will deal with this by + ** calling balance_nonroot() (balance_deeper() may be called first, + ** but it doesn't deal with overflow cells - just moves them to a + ** different page). Once this subsequent call to balance_nonroot() + ** has completed, it is safe to release the pSpace buffer used by + ** the previous call, as the overflow cell data will have been + ** copied either into the body of a database page or into the new + ** pSpace buffer passed to the latter call to balance_nonroot(). + */ + u8 *pSpace = sqlite3PageMalloc(pCur->pBt->pageSize); + rc = balance_nonroot(pParent, iIdx, pSpace); + if( pFree ){ + /* If pFree is not NULL, it points to the pSpace buffer used + ** by a previous call to balance_nonroot(). Its contents are + ** now stored either on real database pages or within the + ** new pSpace buffer, so it may be safely freed here. */ + sqlite3PageFree(pFree); + } + + /* The pSpace buffer will be freed after the next call to + ** balance_nonroot(), or just before this function returns, whichever + ** comes first. */ + pFree = pSpace; + VVA_ONLY( pCur->pagesShuffled = 1 ); + } + } + + pPage->nOverflow = 0; + + /* The next iteration of the do-loop balances the parent page. */ + releasePage(pPage); + pCur->iPage--; + } + }while( rc==SQLITE_OK ); + + if( pFree ){ + sqlite3PageFree(pFree); } return rc; } /* @@ -43061,10 +43249,11 @@ SQLITE_OK!=(rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur)) || (!loc && SQLITE_OK!=(rc = sqlite3BtreeMoveto(pCur, pKey, nKey, appendBias, &loc)) )){ return rc; } + assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) ); pPage = pCur->apPage[pCur->iPage]; assert( pPage->intKey || nKey>=0 ); assert( pPage->leaf || !pPage->intKey ); TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n", @@ -43077,11 +43266,11 @@ rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, nZero, &szNew); if( rc ) goto end_insert; assert( szNew==cellSizePtr(pPage, newCell) ); assert( szNew<=MX_CELL_SIZE(pBt) ); idx = pCur->aiIdx[pCur->iPage]; - if( loc==0 && CURSOR_VALID==pCur->eState ){ + if( loc==0 ){ u16 szOld; assert( idx<pPage->nCell ); rc = sqlite3PagerWrite(pPage->pDbPage); if( rc ){ goto end_insert; @@ -43098,51 +43287,49 @@ goto end_insert; } }else if( loc<0 && pPage->nCell>0 ){ assert( pPage->leaf ); idx = ++pCur->aiIdx[pCur->iPage]; - pCur->info.nSize = 0; - pCur->validNKey = 0; }else{ assert( pPage->leaf ); } rc = insertCell(pPage, idx, newCell, szNew, 0, 0); assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 ); - /* If no error has occured, call balance() to deal with any overflow and - ** move the cursor to point at the root of the table (since balance may - ** have rearranged the table in such a way as to invalidate BtCursor.apPage[] - ** or BtCursor.aiIdx[]). - ** - ** Except, if all of the following are true, do nothing: - ** - ** * Inserting the new cell did not cause overflow, - ** - ** * Before inserting the new cell the cursor was pointing at the - ** largest key in an intkey B-Tree, and - ** - ** * The key value associated with the new cell is now the largest - ** in the B-Tree. - ** - ** In this case the cursor can be safely left pointing at the (new) - ** largest key value in the B-Tree. Doing so speeds up inserting a set - ** of entries with increasing integer key values via a single cursor - ** (comes up with "INSERT INTO ... SELECT ..." statements), as - ** the next insert operation is not required to seek the cursor. - */ - if( rc==SQLITE_OK - && (pPage->nOverflow || !pCur->atLast || loc>=0 || !pCur->apPage[0]->intKey) - ){ - rc = balance(pCur, 1); - if( rc==SQLITE_OK ){ - moveToRoot(pCur); - } - } - - /* Must make sure nOverflow is reset to zero even if the balance() - ** fails. Internal data structure corruption will result otherwise. */ - pCur->apPage[pCur->iPage]->nOverflow = 0; + /* If no error has occured and pPage has an overflow cell, call balance() + ** to redistribute the cells within the tree. Since balance() may move + ** the cursor, zero the BtCursor.info.nSize and BtCursor.validNKey + ** variables. + ** + ** Previous versions of SQLite called moveToRoot() to move the cursor + ** back to the root page as balance() used to invalidate the contents + ** of BtCursor.apPage[] and BtCursor.aiIdx[]. Instead of doing that, + ** set the cursor state to "invalid". This makes common insert operations + ** slightly faster. + ** + ** There is a subtle but important optimization here too. When inserting + ** multiple records into an intkey b-tree using a single cursor (as can + ** happen while processing an "INSERT INTO ... SELECT" statement), it + ** is advantageous to leave the cursor pointing to the last entry in + ** 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; + pCur->validNKey = 0; + if( rc==SQLITE_OK && pPage->nOverflow ){ + rc = balance(pCur); + + /* Must make sure nOverflow is reset to zero even if the balance() + ** fails. Internal data structure corruption will result otherwise. + ** Also, set the cursor state to invalid. This stops saveCursorPosition() + ** from trying to save the current position of the cursor. */ + pCur->apPage[pCur->iPage]->nOverflow = 0; + pCur->eState = CURSOR_INVALID; + } + assert( pCur->apPage[pCur->iPage]->nOverflow==0 ); end_insert: return rc; } @@ -43149,202 +43336,114 @@ /* ** Delete the entry that the cursor is pointing to. The cursor ** is left pointing at a arbitrary location. */ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){ - MemPage *pPage = pCur->apPage[pCur->iPage]; - int idx; - unsigned char *pCell; - int rc; - Pgno pgnoChild = 0; Btree *p = pCur->pBtree; BtShared *pBt = p->pBt; + int rc; /* Return code */ + MemPage *pPage; /* Page to delete cell from */ + unsigned char *pCell; /* Pointer to cell to delete */ + int iCellIdx; /* Index of cell to delete */ + int iCellDepth; /* Depth of node containing pCell */ assert( cursorHoldsMutex(pCur) ); - assert( pPage->isInit ); assert( pBt->inTransaction==TRANS_WRITE ); assert( !pBt->readOnly ); - if( pCur->eState==CURSOR_FAULT ){ - return pCur->skip; - } - if( NEVER(pCur->aiIdx[pCur->iPage]>=pPage->nCell) ){ - return SQLITE_ERROR; /* The cursor is not pointing to anything */ - } assert( pCur->wrFlag ); + if( NEVER(pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell) + || NEVER(pCur->eState!=CURSOR_VALID) + ){ + return SQLITE_ERROR; /* Something has gone awry. */ + } + rc = checkForReadConflicts(p, pCur->pgnoRoot, pCur, pCur->info.nKey); if( rc!=SQLITE_OK ){ - /* The table pCur points to has a read lock */ assert( rc==SQLITE_LOCKED_SHAREDCACHE ); - return rc; - } - - /* Restore the current cursor position (a no-op if the cursor is not in - ** CURSOR_REQUIRESEEK state) and save the positions of any other cursors - ** open on the same table. Then call sqlite3PagerWrite() on the page - ** that the entry will be deleted from. - */ - if( - (rc = restoreCursorPosition(pCur))!=0 || - (rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur))!=0 || - (rc = sqlite3PagerWrite(pPage->pDbPage))!=0 - ){ - return rc; - } - - /* Locate the cell within its page and leave pCell pointing to the - ** data. The clearCell() call frees any overflow pages associated with the - ** cell. The cell itself is still intact. - */ - idx = pCur->aiIdx[pCur->iPage]; - pCell = findCell(pPage, idx); + return rc; /* The table pCur points to has a read lock */ + } + + iCellDepth = pCur->iPage; + iCellIdx = pCur->aiIdx[iCellDepth]; + pPage = pCur->apPage[iCellDepth]; + pCell = findCell(pPage, iCellIdx); + + /* If the page containing the entry to delete is not a leaf page, move + ** the cursor to the largest entry in the tree that is smaller than + ** the entry being deleted. This cell will replace the cell being deleted + ** from the internal node. The 'previous' entry is used for this instead + ** of the 'next' entry, as the previous entry is always a part of the + ** sub-tree headed by the child page of the cell being deleted. This makes + ** balancing the tree following the delete operation easier. */ if( !pPage->leaf ){ - pgnoChild = get4byte(pCell); - } - rc = clearCell(pPage, pCell); - if( rc ){ - return rc; - } - + int notUsed; + if( SQLITE_OK!=(rc = sqlite3BtreePrevious(pCur, ¬Used)) ){ + return rc; + } + } + + /* Save the positions of any other cursors open on this table before + ** making any modifications. Make the page containing the entry to be + ** deleted writable. Then free any overflow pages associated with the + ** entry and finally remove the cell itself from within the page. */ + if( SQLITE_OK!=(rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur)) + || SQLITE_OK!=(rc = sqlite3PagerWrite(pPage->pDbPage)) + || SQLITE_OK!=(rc = clearCell(pPage, pCell)) + || SQLITE_OK!=(rc = dropCell(pPage, iCellIdx, cellSizePtr(pPage, pCell))) + ){ + return rc; + } + + /* If the cell deleted was not located on a leaf page, then the cursor + ** is currently pointing to the largest entry in the sub-tree headed + ** by the child-page of the cell that was just deleted from an internal + ** node. The cell from the leaf node needs to be moved to the internal + ** node to replace the deleted cell. */ if( !pPage->leaf ){ - /* - ** The entry we are about to delete is not a leaf so if we do not - ** do something we will leave a hole on an internal page. - ** We have to fill the hole by moving in a cell from a leaf. The - ** next Cell after the one to be deleted is guaranteed to exist and - ** to be a leaf so we can use it. - */ - BtCursor leafCur; - MemPage *pLeafPage = 0; - - unsigned char *pNext; - int notUsed; - unsigned char *tempCell = 0; - assert( !pPage->intKey ); - sqlite3BtreeGetTempCursor(pCur, &leafCur); - rc = sqlite3BtreeNext(&leafCur, ¬Used); - if( rc==SQLITE_OK ){ - assert( leafCur.aiIdx[leafCur.iPage]==0 ); - pLeafPage = leafCur.apPage[leafCur.iPage]; - rc = sqlite3PagerWrite(pLeafPage->pDbPage); - } - if( rc==SQLITE_OK ){ - int leafCursorInvalid = 0; - u16 szNext; - TRACE(("DELETE: table=%d delete internal from %d replace from leaf %d\n", - pCur->pgnoRoot, pPage->pgno, pLeafPage->pgno)); - dropCell(pPage, idx, cellSizePtr(pPage, pCell)); - pNext = findCell(pLeafPage, 0); - szNext = cellSizePtr(pLeafPage, pNext); - assert( MX_CELL_SIZE(pBt)>=szNext+4 ); - allocateTempSpace(pBt); - tempCell = pBt->pTmpSpace; - if( tempCell==0 ){ - rc = SQLITE_NOMEM; - } - if( rc==SQLITE_OK ){ - rc = insertCell(pPage, idx, pNext-4, szNext+4, tempCell, 0); - } - - - /* The "if" statement in the next code block is critical. The - ** slightest error in that statement would allow SQLite to operate - ** correctly most of the time but produce very rare failures. To - ** guard against this, the following macros help to verify that - ** the "if" statement is well tested. - */ - testcase( pPage->nOverflow==0 && pPage->nFree<pBt->usableSize*2/3 - && pLeafPage->nFree+2+szNext > pBt->usableSize*2/3 ); - testcase( pPage->nOverflow==0 && pPage->nFree==pBt->usableSize*2/3 - && pLeafPage->nFree+2+szNext > pBt->usableSize*2/3 ); - testcase( pPage->nOverflow==0 && pPage->nFree==pBt->usableSize*2/3+1 - && pLeafPage->nFree+2+szNext > pBt->usableSize*2/3 ); - testcase( pPage->nOverflow>0 && pPage->nFree<=pBt->usableSize*2/3 - && pLeafPage->nFree+2+szNext > pBt->usableSize*2/3 ); - testcase( (pPage->nOverflow>0 || (pPage->nFree > pBt->usableSize*2/3)) - && pLeafPage->nFree+2+szNext == pBt->usableSize*2/3 ); - - - if( (pPage->nOverflow>0 || (pPage->nFree > pBt->usableSize*2/3)) && - (pLeafPage->nFree+2+szNext > pBt->usableSize*2/3) - ){ - /* This branch is taken if the internal node is now either overflowing - ** or underfull and the leaf node will be underfull after the just cell - ** copied to the internal node is deleted from it. This is a special - ** case because the call to balance() to correct the internal node - ** may change the tree structure and invalidate the contents of - ** the leafCur.apPage[] and leafCur.aiIdx[] arrays, which will be - ** used by the balance() required to correct the underfull leaf - ** node. - ** - ** The formula used in the expression above are based on facets of - ** the SQLite file-format that do not change over time. - */ - testcase( pPage->nFree==pBt->usableSize*2/3+1 ); - testcase( pLeafPage->nFree+2+szNext==pBt->usableSize*2/3+1 ); - leafCursorInvalid = 1; - } - - if( rc==SQLITE_OK ){ - assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - put4byte(findOverflowCell(pPage, idx), pgnoChild); - VVA_ONLY( pCur->pagesShuffled = 0 ); - rc = balance(pCur, 0); - } - - if( rc==SQLITE_OK && leafCursorInvalid ){ - /* The leaf-node is now underfull and so the tree needs to be - ** rebalanced. However, the balance() operation on the internal - ** node above may have modified the structure of the B-Tree and - ** so the current contents of leafCur.apPage[] and leafCur.aiIdx[] - ** may not be trusted. - ** - ** It is not possible to copy the ancestry from pCur, as the same - ** balance() call has invalidated the pCur->apPage[] and aiIdx[] - ** arrays. - ** - ** The call to saveCursorPosition() below internally saves the - ** key that leafCur is currently pointing to. Currently, there - ** are two copies of that key in the tree - one here on the leaf - ** page and one on some internal node in the tree. The copy on - ** the leaf node is always the next key in tree-order after the - ** copy on the internal node. So, the call to sqlite3BtreeNext() - ** calls restoreCursorPosition() to point the cursor to the copy - ** stored on the internal node, then advances to the next entry, - ** which happens to be the copy of the key on the internal node. - ** Net effect: leafCur is pointing back to the duplicate cell - ** that needs to be removed, and the leafCur.apPage[] and - ** leafCur.aiIdx[] arrays are correct. - */ - VVA_ONLY( Pgno leafPgno = pLeafPage->pgno ); - rc = saveCursorPosition(&leafCur); - if( rc==SQLITE_OK ){ - rc = sqlite3BtreeNext(&leafCur, ¬Used); - } - pLeafPage = leafCur.apPage[leafCur.iPage]; - assert( rc!=SQLITE_OK || pLeafPage->pgno==leafPgno ); - assert( rc!=SQLITE_OK || leafCur.aiIdx[leafCur.iPage]==0 ); - } - - if( SQLITE_OK==rc - && SQLITE_OK==(rc = sqlite3PagerWrite(pLeafPage->pDbPage)) - ){ - dropCell(pLeafPage, 0, szNext); - VVA_ONLY( leafCur.pagesShuffled = 0 ); - rc = balance(&leafCur, 0); - assert( leafCursorInvalid || !leafCur.pagesShuffled - || !pCur->pagesShuffled ); - } - } - sqlite3BtreeReleaseTempCursor(&leafCur); - }else{ - TRACE(("DELETE: table=%d delete from leaf %d\n", - pCur->pgnoRoot, pPage->pgno)); - rc = dropCell(pPage, idx, cellSizePtr(pPage, pCell)); - if( rc==SQLITE_OK ){ - rc = balance(pCur, 0); - } - } + MemPage *pLeaf = pCur->apPage[pCur->iPage]; + int nCell; + Pgno n = pCur->apPage[iCellDepth+1]->pgno; + unsigned char *pTmp; + + pCell = findCell(pLeaf, pLeaf->nCell-1); + nCell = cellSizePtr(pLeaf, pCell); + assert( MX_CELL_SIZE(pBt)>=nCell ); + + allocateTempSpace(pBt); + pTmp = pBt->pTmpSpace; + + if( SQLITE_OK!=(rc = sqlite3PagerWrite(pLeaf->pDbPage)) + || SQLITE_OK!=(rc = insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n)) + || SQLITE_OK!=(rc = dropCell(pLeaf, pLeaf->nCell-1, nCell)) + ){ + return rc; + } + } + + /* Balance the tree. If the entry deleted was located on a leaf page, + ** then the cursor still points to that page. In this case the first + ** call to balance() repairs the tree, and the if(...) condition is + ** never true. + ** + ** Otherwise, if the entry deleted was on an internal node page, then + ** pCur is pointing to the leaf page from which a cell was removed to + ** replace the cell deleted from the internal node. This is slightly + ** tricky as the leaf node may be underfull, and the internal node may + ** be either under or overfull. In this case run the balancing algorithm + ** 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. */ + rc = balance(pCur); + if( rc==SQLITE_OK && pCur->iPage>iCellDepth ){ + while( pCur->iPage>iCellDepth ){ + releasePage(pCur->apPage[pCur->iPage--]); + } + rc = balance(pCur); + } + if( rc==SQLITE_OK ){ moveToRoot(pCur); } return rc; } @@ -43431,11 +43530,14 @@ rc = sqlite3BtreeGetPage(pBt, pgnoRoot, &pRoot, 0); if( rc!=SQLITE_OK ){ return rc; } rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage); - if( rc!=SQLITE_OK || eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){ + if( eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){ + rc = SQLITE_CORRUPT_BKPT; + } + if( rc!=SQLITE_OK ){ releasePage(pRoot); return rc; } assert( eType!=PTRMAP_ROOTPAGE ); assert( eType!=PTRMAP_FREEPAGE ); @@ -45188,11 +45290,11 @@ ** This file contains code use to manipulate "Mem" structure. A "Mem" ** stores a single value in the VDBE. Mem is an opaque structure visible ** only within the VDBE. Interface routines refer to a Mem using the ** name sqlite_value ** -** $Id: vdbemem.c,v 1.147 2009/05/28 11:05:57 danielk1977 Exp $ +** $Id: vdbemem.c,v 1.149 2009/06/22 19:05:41 drh Exp $ */ /* ** Call sqlite3VdbeMemExpandBlob() on the supplied value (type Mem*) ** P if required. @@ -45582,11 +45684,22 @@ assert( (pMem->flags & MEM_RowSet)==0 ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); pMem->u.i = doubleToInt64(pMem->r); - if( pMem->r==(double)pMem->u.i ){ + + /* 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 term in the following conditional enforces the second + ** condition under the assumption that additional overflow causes + ** values to wrap around. + */ + if( pMem->r==(double)pMem->u.i && (pMem->u.i-1) < (pMem->u.i+1) ){ pMem->flags |= MEM_Int; } } /* @@ -45797,10 +45910,16 @@ ** The memory management strategy depends on the value of the xDel ** parameter. If the value passed is SQLITE_TRANSIENT, then the ** string is copied into a (possibly existing) buffer managed by the ** Mem structure. Otherwise, any existing buffer is freed and the ** pointer copied. +** +** If the string is too large (if it exceeds the SQLITE_LIMIT_LENGTH +** size limit) then no memory allocation occurs. If the string can be +** stored without allocating memory, then it is. If a memory allocation +** is required to store the string, then value of pMem is unchanged. In +** either case, SQLITE_TOOBIG is returned. */ SQLITE_PRIVATE int sqlite3VdbeMemSetStr( Mem *pMem, /* Memory cell to set to string value */ const char *z, /* String pointer */ int n, /* Bytes in string, or negative */ @@ -45860,13 +45979,10 @@ sqlite3VdbeMemRelease(pMem); pMem->z = (char *)z; pMem->xDel = xDel; flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn); } - if( nByte>iLimit ){ - return SQLITE_TOOBIG; - } pMem->n = nByte; pMem->flags = flags; pMem->enc = (enc==0 ? SQLITE_UTF8 : enc); pMem->type = (enc==0 ? SQLITE_BLOB : SQLITE_TEXT); @@ -45874,10 +45990,14 @@ #ifndef SQLITE_OMIT_UTF16 if( pMem->enc!=SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){ return SQLITE_NOMEM; } #endif + + if( nByte>iLimit ){ + return SQLITE_TOOBIG; + } return SQLITE_OK; } /* @@ -46250,11 +46370,11 @@ ** This file contains code used for creating, destroying, and populating ** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) Prior ** to version 2.8.7, all this code was combined into the vdbe.c source file. ** But that file was getting too big so this subroutines were split out. ** -** $Id: vdbeaux.c,v 1.459 2009/06/05 14:17:25 drh Exp $ +** $Id: vdbeaux.c,v 1.464 2009/06/23 14:15:04 drh Exp $ */ /* @@ -46860,15 +46980,28 @@ ** 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 and writable, but it has no effect. The return of a dummy ** opcode allows the call to continue functioning after a OOM fault without ** having to check to see if the return from this routine is a valid pointer. +** +** About the #ifdef SQLITE_OMIT_TRACE: Normally, this routine is never called +** unless p->nOp>0. This is because in the absense of SQLITE_OMIT_TRACE, +** an OP_Trace instruction is always inserted by sqlite3VdbeGet() as soon as +** a new VDBE is created. So we are free to set addr to p->nOp-1 without +** having to double-check to make sure that the result is non-negative. But +** if SQLITE_OMIT_TRACE is defined, the OP_Trace is omitted and we do need to +** check the value of p->nOp-1 before continuing. */ SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ static VdbeOp dummy; assert( p->magic==VDBE_MAGIC_INIT ); - if( addr<0 ) addr = p->nOp - 1; + if( addr<0 ){ +#ifdef SQLITE_OMIT_TRACE + if( p->nOp==0 ) return &dummy; +#endif + addr = p->nOp - 1; + } assert( (addr>=0 && addr<p->nOp) || p->db->mallocFailed ); if( p->db->mallocFailed ){ return &dummy; }else{ return &p->aOp[addr]; @@ -48235,13 +48368,21 @@ sqlite3DbFree(db, p->pFree); sqlite3DbFree(db, p); } /* +** 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. Return an error code. If no MoveTo is pending, this -** routine does nothing and returns SQLITE_OK. +** 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 *p){ if( p->deferredMoveto ){ int res, rc; #ifdef SQLITE_TEST @@ -48248,11 +48389,11 @@ extern int sqlite3_search_count; #endif assert( p->isTable ); rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res); if( rc ) return rc; - p->lastRowid = keyToInt(p->movetoTarget); + p->lastRowid = p->movetoTarget; p->rowidIsValid = ALWAYS(res==0) ?1:0; if( NEVER(res<0) ){ rc = sqlite3BtreeNext(p->pCursor, &res); if( rc ) return rc; } @@ -48450,11 +48591,11 @@ swapMixedEndianFloat(v); }else{ v = pMem->u.i; } len = i = sqlite3VdbeSerialTypeLen(serial_type); - assert( len<=nBuf ); + assert( len<=(u32)nBuf ); while( i-- ){ buf[i] = (u8)(v&0xFF); v >>= 8; } return len; @@ -48461,11 +48602,11 @@ } /* String or blob */ if( serial_type>=12 ){ assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.nZero:0) - == sqlite3VdbeSerialTypeLen(serial_type) ); + == (int)sqlite3VdbeSerialTypeLen(serial_type) ); assert( pMem->n<=nBuf ); len = pMem->n; memcpy(buf, pMem->z, len); if( pMem->flags & MEM_Zero ){ len += pMem->u.nZero; @@ -48790,11 +48931,11 @@ ** Return SQLITE_OK if everything works, or an error code otherwise. ** ** pCur might be pointing to text obtained from a corrupt database file. ** So the content cannot be trusted. Do appropriate checks on the content. */ -SQLITE_PRIVATE int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){ +SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){ i64 nCellKey = 0; int rc; u32 szHdr; /* Size of the header */ u32 typeRowid; /* Serial type of the rowid */ u32 lenRowid; /* Size of the rowid */ @@ -48807,11 +48948,11 @@ return SQLITE_CORRUPT_BKPT; } /* Read in the complete content of the index entry */ m.flags = 0; - m.db = 0; + m.db = db; m.zMalloc = 0; rc = sqlite3VdbeMemFromBtree(pCur, 0, (int)nCellKey, 1, &m); if( rc ){ return rc; } @@ -48957,168 +49098,12 @@ ************************************************************************* ** ** This file contains code use to implement APIs that are part of the ** VDBE. ** -** $Id: vdbeapi.c,v 1.165 2009/06/06 14:13:27 danielk1977 Exp $ -*/ - -#if 0 && defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) -/* -** The following structure contains pointers to the end points of a -** doubly-linked list of all compiled SQL statements that may be holding -** buffers eligible for release when the sqlite3_release_memory() interface is -** invoked. Access to this list is protected by the SQLITE_MUTEX_STATIC_LRU2 -** mutex. -** -** Statements are added to the end of this list when sqlite3_reset() is -** called. They are removed either when sqlite3_step() or sqlite3_finalize() -** is called. When statements are added to this list, the associated -** register array (p->aMem[1..p->nMem]) may contain dynamic buffers that -** can be freed using sqlite3VdbeReleaseMemory(). -** -** When statements are added or removed from this list, the mutex -** associated with the Vdbe being added or removed (Vdbe.db->mutex) is -** already held. The LRU2 mutex is then obtained, blocking if necessary, -** the linked-list pointers manipulated and the LRU2 mutex relinquished. -*/ -struct StatementLruList { - Vdbe *pFirst; - Vdbe *pLast; -}; -static struct StatementLruList sqlite3LruStatements; - -/* -** Check that the list looks to be internally consistent. This is used -** as part of an assert() statement as follows: -** -** assert( stmtLruCheck() ); -*/ -#ifndef NDEBUG -static int stmtLruCheck(){ - Vdbe *p; - for(p=sqlite3LruStatements.pFirst; p; p=p->pLruNext){ - assert(p->pLruNext || p==sqlite3LruStatements.pLast); - assert(!p->pLruNext || p->pLruNext->pLruPrev==p); - assert(p->pLruPrev || p==sqlite3LruStatements.pFirst); - assert(!p->pLruPrev || p->pLruPrev->pLruNext==p); - } - return 1; -} -#endif - -/* -** Add vdbe p to the end of the statement lru list. It is assumed that -** p is not already part of the list when this is called. The lru list -** is protected by the SQLITE_MUTEX_STATIC_LRU mutex. -*/ -static void stmtLruAdd(Vdbe *p){ - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2)); - - if( p->pLruPrev || p->pLruNext || sqlite3LruStatements.pFirst==p ){ - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2)); - return; - } - - assert( stmtLruCheck() ); - - if( !sqlite3LruStatements.pFirst ){ - assert( !sqlite3LruStatements.pLast ); - sqlite3LruStatements.pFirst = p; - sqlite3LruStatements.pLast = p; - }else{ - assert( !sqlite3LruStatements.pLast->pLruNext ); - p->pLruPrev = sqlite3LruStatements.pLast; - sqlite3LruStatements.pLast->pLruNext = p; - sqlite3LruStatements.pLast = p; - } - - assert( stmtLruCheck() ); - - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2)); -} - -/* -** Assuming the SQLITE_MUTEX_STATIC_LRU2 mutext is already held, remove -** statement p from the least-recently-used statement list. If the -** statement is not currently part of the list, this call is a no-op. -*/ -static void stmtLruRemoveNomutex(Vdbe *p){ - if( p->pLruPrev || p->pLruNext || p==sqlite3LruStatements.pFirst ){ - assert( stmtLruCheck() ); - if( p->pLruNext ){ - p->pLruNext->pLruPrev = p->pLruPrev; - }else{ - sqlite3LruStatements.pLast = p->pLruPrev; - } - if( p->pLruPrev ){ - p->pLruPrev->pLruNext = p->pLruNext; - }else{ - sqlite3LruStatements.pFirst = p->pLruNext; - } - p->pLruNext = 0; - p->pLruPrev = 0; - assert( stmtLruCheck() ); - } -} - -/* -** Assuming the SQLITE_MUTEX_STATIC_LRU2 mutext is not held, remove -** statement p from the least-recently-used statement list. If the -** statement is not currently part of the list, this call is a no-op. -*/ -static void stmtLruRemove(Vdbe *p){ - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2)); - stmtLruRemoveNomutex(p); - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2)); -} - -/* -** Try to release n bytes of memory by freeing buffers associated -** with the memory registers of currently unused vdbes. -*/ -SQLITE_PRIVATE int sqlite3VdbeReleaseMemory(int n){ - Vdbe *p; - Vdbe *pNext; - int nFree = 0; - - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2)); - for(p=sqlite3LruStatements.pFirst; p && nFree<n; p=pNext){ - pNext = p->pLruNext; - - /* For each statement handle in the lru list, attempt to obtain the - ** associated database mutex. If it cannot be obtained, continue - ** to the next statement handle. It is not possible to block on - ** the database mutex - that could cause deadlock. - */ - if( SQLITE_OK==sqlite3_mutex_try(p->db->mutex) ){ - nFree += sqlite3VdbeReleaseBuffers(p); - stmtLruRemoveNomutex(p); - sqlite3_mutex_leave(p->db->mutex); - } - } - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2)); - - return nFree; -} - -/* -** Call sqlite3Reprepare() on the statement. Remove it from the -** lru list before doing so, as Reprepare() will free all the -** memory register buffers anyway. -*/ -int vdbeReprepare(Vdbe *p){ - stmtLruRemove(p); - return sqlite3Reprepare(p); -} - -#else /* !SQLITE_ENABLE_MEMORY_MANAGEMENT */ - #define stmtLruRemove(x) - #define stmtLruAdd(x) - #define vdbeReprepare(x) sqlite3Reprepare(x) -#endif - +** $Id: vdbeapi.c,v 1.166 2009/06/19 14:06:03 drh Exp $ +*/ #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 @@ -49151,11 +49136,10 @@ sqlite3 *db = v->db; #if SQLITE_THREADSAFE sqlite3_mutex *mutex = v->db->mutex; #endif sqlite3_mutex_enter(mutex); - stmtLruRemove(v); rc = sqlite3VdbeFinalize(v); rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(mutex); } return rc; @@ -49175,11 +49159,10 @@ rc = SQLITE_OK; }else{ Vdbe *v = (Vdbe*)pStmt; sqlite3_mutex_enter(v->db->mutex); rc = sqlite3VdbeReset(v); - stmtLruAdd(v); sqlite3VdbeMakeReady(v, -1, 0, 0, 0); assert( (rc & (v->db->errMask))==rc ); rc = sqlite3ApiExit(v->db, rc); sqlite3_mutex_leave(v->db->mutex); } @@ -49419,11 +49402,10 @@ #endif db->activeVdbeCnt++; if( p->readOnly==0 ) db->writeVdbeCnt++; p->pc = 0; - stmtLruRemove(p); } #ifndef SQLITE_OMIT_EXPLAIN if( p->explain ){ rc = sqlite3VdbeList(p); }else @@ -49479,33 +49461,20 @@ /* ** This is the top-level implementation of sqlite3_step(). Call ** sqlite3Step() to do most of the work. If a schema error occurs, ** call sqlite3Reprepare() and try again. */ -#ifdef SQLITE_OMIT_PARSER -SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){ - int rc = SQLITE_MISUSE; - if( pStmt ){ - Vdbe *v; - v = (Vdbe*)pStmt; - sqlite3_mutex_enter(v->db->mutex); - rc = sqlite3Step(v); - sqlite3_mutex_leave(v->db->mutex); - } - return rc; -} -#else SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){ int rc = SQLITE_MISUSE; if( pStmt ){ int cnt = 0; Vdbe *v = (Vdbe*)pStmt; sqlite3 *db = v->db; sqlite3_mutex_enter(db->mutex); while( (rc = sqlite3Step(v))==SQLITE_SCHEMA && cnt++ < 5 - && (rc = vdbeReprepare(v))==SQLITE_OK ){ + && (rc = sqlite3Reprepare(v))==SQLITE_OK ){ sqlite3_reset(pStmt); v->expired = 0; } if( rc==SQLITE_SCHEMA && ALWAYS(v->isPrepareV2) && ALWAYS(db->pErr) ){ /* This case occurs after failing to recompile an sql statement. @@ -49528,11 +49497,10 @@ rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); } return rc; } -#endif /* ** Extract the user data from a sqlite3_context structure and return a ** pointer to it. */ @@ -50351,11 +50319,11 @@ ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.848 2009/06/05 16:46:53 drh Exp $ +** $Id: vdbe.c,v 1.862 2009/06/23 14:15:04 drh Exp $ */ /* ** The following global variable is incremented every time a cursor ** moves, either by the OP_SeekXX, OP_Next, or OP_Prev opcodes. The test @@ -50495,11 +50463,11 @@ static VdbeCursor *allocateCursor( Vdbe *p, /* The virtual machine */ int iCur, /* Index of the new VdbeCursor */ int nField, /* Number of fields in the table or index */ int iDb, /* When database the cursor belongs to, or -1 */ - int isBtreeCursor /* */ + int isBtreeCursor /* True for B-Tree vs. pseudo-table or vtab */ ){ /* Find the memory cell that will be used to store the blob of memory ** required for this VdbeCursor structure. It is convenient to use a ** vdbe memory cell to manage the memory allocation required for a ** VdbeCursor structure for the following reasons: @@ -50732,12 +50700,14 @@ fprintf(out, " NULL"); }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){ fprintf(out, " si:%lld", p->u.i); }else if( p->flags & MEM_Int ){ fprintf(out, " i:%lld", p->u.i); +#ifndef SQLITE_OMIT_FLOATING_POINT }else if( p->flags & MEM_Real ){ fprintf(out, " r:%g", p->r); +#endif }else if( p->flags & MEM_RowSet ){ fprintf(out, " (rowset)"); }else{ char zBuf[200]; sqlite3VdbeMemPrettyPrint(p, zBuf); @@ -51032,13 +51002,10 @@ int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ } ak; struct OP_IfNot_stack_vars { int c; } al; - struct OP_IsNull_stack_vars { - int n; - } am; struct OP_Column_stack_vars { u32 payloadSize; /* Number of bytes in the record */ i64 payloadSize64; /* Number of bytes in the record */ int p1; /* P1 value of the opcode */ int p2; /* column number to retrieve */ @@ -51057,17 +51024,17 @@ u8 *zEndHdr; /* Pointer to first byte after the header */ u32 offset; /* Offset into the data */ u64 offset64; /* 64-bit offset. 64 bits needed to catch overflow */ int szHdr; /* Size of the header size field at start of record */ int avail; /* Number of bytes of available data */ - } an; + } am; struct OP_Affinity_stack_vars { char *zAffinity; /* The affinity to be applied */ Mem *pData0; /* First register to which to apply affinity */ Mem *pLast; /* Last register to which to apply affinity */ Mem *pRec; /* Current register */ - } ao; + } an; struct OP_MakeRecord_stack_vars { u8 *zNewRecord; /* A buffer to hold the data for the new record */ Mem *pRec; /* The new record */ u64 nData; /* Number of bytes of data space */ int nHdr; /* Number of bytes of header space */ @@ -51080,270 +51047,246 @@ 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 */ int i; /* Space used in zNewRecord[] */ int len; /* Length of a field */ - } ap; + } ao; struct OP_Count_stack_vars { i64 nEntry; BtCursor *pCrsr; - } aq; + } ap; struct OP_Statement_stack_vars { - int i; Btree *pBt; - } ar; + } aq; struct OP_Savepoint_stack_vars { int p1; /* Value of P1 operand */ char *zName; /* Name of savepoint */ int nName; Savepoint *pNew; Savepoint *pSavepoint; Savepoint *pTmp; int iSavepoint; int ii; - } as; + } ar; struct OP_AutoCommit_stack_vars { int desiredAutoCommit; - int rollback; + int iRollback; int turnOnAC; - } at; + } as; struct OP_Transaction_stack_vars { - int i; Btree *pBt; - } au; + } at; struct OP_ReadCookie_stack_vars { int iMeta; int iDb; int iCookie; - } av; + } au; struct OP_SetCookie_stack_vars { Db *pDb; - } aw; + } av; struct OP_VerifyCookie_stack_vars { int iMeta; Btree *pBt; - } ax; + } aw; struct OP_OpenWrite_stack_vars { int nField; KeyInfo *pKeyInfo; - int i; int p2; int iDb; int wrFlag; Btree *pX; VdbeCursor *pCur; Db *pDb; int flags; - } ay; + } ax; struct OP_OpenEphemeral_stack_vars { - int i; + VdbeCursor *pCx; + } ay; + struct OP_OpenPseudo_stack_vars { VdbeCursor *pCx; } az; - struct OP_OpenPseudo_stack_vars { - int i; - VdbeCursor *pCx; - } ba; - struct OP_Close_stack_vars { - int i; - } bb; - struct OP_SeekGt_stack_vars { - int i; + struct OP_SeekGt_stack_vars { int res; int oc; VdbeCursor *pC; UnpackedRecord r; int nField; i64 iKey; /* The rowid we are to seek to */ - } bc; + } ba; struct OP_Seek_stack_vars { - int i; - VdbeCursor *pC; - } bd; - struct OP_Found_stack_vars { - int i; + VdbeCursor *pC; + } bb; + struct OP_Found_stack_vars { int alreadyExists; VdbeCursor *pC; int res; UnpackedRecord *pIdxKey; char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7]; - } be; + } bc; struct OP_IsUnique_stack_vars { u16 ii; VdbeCursor *pCx; BtCursor *pCrsr; u16 nField; Mem *aMem; UnpackedRecord r; /* B-Tree index search key */ i64 R; /* Rowid stored in register P3 */ - } bf; - struct OP_NotExists_stack_vars { - int i; + } bd; + struct OP_NotExists_stack_vars { VdbeCursor *pC; BtCursor *pCrsr; int res; u64 iKey; - } bg; + } be; struct OP_NewRowid_stack_vars { - int i; - i64 v; - VdbeCursor *pC; - int res; - int rx; - int cnt; - i64 x; - Mem *pMem; - } bh; + i64 v; /* The new rowid */ + VdbeCursor *pC; /* Cursor of table to get the new rowid */ + int res; /* Result of an sqlite3BtreeLast() */ + int cnt; /* Counter to limit the number of searches */ + Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ + } bf; struct OP_Insert_stack_vars { Mem *pData; Mem *pKey; i64 iKey; /* The integer ROWID or key for the record to be inserted */ - int i; VdbeCursor *pC; int nZero; int seekResult; const char *zDb; const char *zTbl; int op; - } bi; - struct OP_Delete_stack_vars { - int i; + } bg; + struct OP_Delete_stack_vars { i64 iKey; VdbeCursor *pC; - } bj; - struct OP_RowData_stack_vars { - int i; + } bh; + struct OP_RowData_stack_vars { VdbeCursor *pC; BtCursor *pCrsr; u32 n; i64 n64; - } bk; - struct OP_Rowid_stack_vars { - int i; + } bi; + struct OP_Rowid_stack_vars { VdbeCursor *pC; i64 v; sqlite3_vtab *pVtab; const sqlite3_module *pModule; - } bl; + } bj; struct OP_NullRow_stack_vars { - int i; VdbeCursor *pC; - } bm; + } bk; struct OP_Last_stack_vars { - int i; + VdbeCursor *pC; + BtCursor *pCrsr; + int res; + } bl; + struct OP_Rewind_stack_vars { VdbeCursor *pC; BtCursor *pCrsr; int res; - } bn; - struct OP_Rewind_stack_vars { - int i; - VdbeCursor *pC; - BtCursor *pCrsr; - int res; - } bo; + } bm; struct OP_Next_stack_vars { VdbeCursor *pC; BtCursor *pCrsr; int res; - } bp; - struct OP_IdxInsert_stack_vars { - int i; + } bn; + struct OP_IdxInsert_stack_vars { VdbeCursor *pC; BtCursor *pCrsr; int nKey; const char *zKey; - } bq; - struct OP_IdxDelete_stack_vars { - int i; + } bo; + struct OP_IdxDelete_stack_vars { VdbeCursor *pC; BtCursor *pCrsr; - } br; - struct OP_IdxRowid_stack_vars { - int i; + int res; + UnpackedRecord r; + } bp; + struct OP_IdxRowid_stack_vars { BtCursor *pCrsr; VdbeCursor *pC; i64 rowid; - } bs; - struct OP_IdxGE_stack_vars { - int i; + } bq; + struct OP_IdxGE_stack_vars { VdbeCursor *pC; int res; UnpackedRecord r; - } bt; + } br; struct OP_Destroy_stack_vars { int iMoved; int iCnt; Vdbe *pVdbe; int iDb; - } bu; + } bs; struct OP_Clear_stack_vars { int nChange; - } bv; + } bt; struct OP_CreateTable_stack_vars { int pgno; int flags; Db *pDb; - } bw; + } bu; struct OP_ParseSchema_stack_vars { int iDb; const char *zMaster; char *zSql; InitData initData; - } bx; + } bv; struct OP_IntegrityCk_stack_vars { int nRoot; /* Number of tables to check. (Number of root pages.) */ int *aRoot; /* Array of rootpage numbers for tables to be checked */ int j; /* Loop counter */ int nErr; /* Number of errors reported */ char *z; /* Text of the error report */ Mem *pnErr; /* Register keeping track of errors remaining */ - } by; + } bw; struct OP_RowSetAdd_stack_vars { Mem *pIdx; Mem *pVal; - } bz; + } bx; struct OP_RowSetRead_stack_vars { Mem *pIdx; i64 val; - } ca; + } by; struct OP_RowSetTest_stack_vars { int iSet; int exists; - } cb; + } bz; struct OP_ContextPush_stack_vars { int i; Context *pContext; - } cc; + } ca; struct OP_ContextPop_stack_vars { Context *pContext; - } cd; + } cb; struct OP_AggStep_stack_vars { int n; int i; Mem *pMem; Mem *pRec; sqlite3_context ctx; sqlite3_value **apVal; - } ce; + } cc; struct OP_AggFinal_stack_vars { Mem *pMem; - } cf; + } cd; struct OP_IncrVacuum_stack_vars { Btree *pBt; - } cg; + } ce; struct OP_TableLock_stack_vars { int p1; u8 isWriteLock; - } ch; + } cf; struct OP_VBegin_stack_vars { sqlite3_vtab *pVtab; - } ci; + } cg; struct OP_VOpen_stack_vars { VdbeCursor *pCur; sqlite3_vtab_cursor *pVtabCursor; sqlite3_vtab *pVtab; sqlite3_module *pModule; - } cj; + } ch; struct OP_VFilter_stack_vars { int nArg; int iQuery; const sqlite3_module *pModule; Mem *pQuery; @@ -51352,44 +51295,44 @@ sqlite3_vtab *pVtab; VdbeCursor *pCur; int res; int i; Mem **apArg; - } ck; + } ci; struct OP_VColumn_stack_vars { sqlite3_vtab *pVtab; const sqlite3_module *pModule; Mem *pDest; sqlite3_context sContext; - } cl; + } cj; struct OP_VNext_stack_vars { sqlite3_vtab *pVtab; const sqlite3_module *pModule; int res; VdbeCursor *pCur; - } cm; + } ck; struct OP_VRename_stack_vars { sqlite3_vtab *pVtab; Mem *pName; - } cn; + } cl; struct OP_VUpdate_stack_vars { sqlite3_vtab *pVtab; sqlite3_module *pModule; int nArg; int i; sqlite_int64 rowid; Mem **apArg; Mem *pX; - } co; + } cm; struct OP_Pagecount_stack_vars { int p1; int nPage; Pager *pPager; - } cp; + } cn; struct OP_Trace_stack_vars { char *zTrace; - } cq; + } co; } u; /* End automatically generated code ********************************************************************/ assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */ @@ -51732,27 +51675,24 @@ pOp->opcode = OP_String; pOp->p1 = sqlite3Strlen30(pOp->p4.z); #ifndef SQLITE_OMIT_UTF16 if( encoding!=SQLITE_UTF8 ){ - sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC); + rc = sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC); + if( rc==SQLITE_TOOBIG ) goto too_big; if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem; - if( SQLITE_OK!=sqlite3VdbeMemMakeWriteable(pOut) ) goto no_mem; + assert( pOut->zMalloc==pOut->z ); + assert( pOut->flags & MEM_Dyn ); pOut->zMalloc = 0; pOut->flags |= MEM_Static; pOut->flags &= ~MEM_Dyn; if( pOp->p4type==P4_DYNAMIC ){ sqlite3DbFree(db, pOp->p4.z); } pOp->p4type = P4_DYNAMIC; pOp->p4.z = pOut->z; pOp->p1 = pOut->n; - if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ - goto too_big; - } - UPDATE_MAX_BLOBSIZE(pOut); - break; } #endif if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } @@ -51940,13 +51880,17 @@ ** opened by this VM before returning control to the user. This is to ** ensure that statement-transactions are always nested, not overlapping. ** If the open statement-transaction is not closed here, then the user ** may step another VM that opens its own statement transaction. This ** may lead to overlapping statement transactions. + ** + ** The statement transaction is never a top-level transaction. Hence + ** the RELEASE call below can never fail. */ assert( p->iStatement==0 || db->flags&SQLITE_CountRows ); - if( SQLITE_OK!=(rc = sqlite3VdbeCloseStatement(p, SAVEPOINT_RELEASE)) ){ + rc = sqlite3VdbeCloseStatement(p, SAVEPOINT_RELEASE); + if( NEVER(rc!=SQLITE_OK) ){ break; } /* Invalidate all ephemeral cursor row caches */ p->cacheCtr = (p->cacheCtr + 2)|1; @@ -51990,13 +51934,12 @@ assert( pIn1!=pOut ); if( (pIn1->flags | pIn2->flags) & MEM_Null ){ sqlite3VdbeMemSetNull(pOut); break; } - ExpandBlob(pIn1); - Stringify(pIn1, encoding); - ExpandBlob(pIn2); + if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem; + Stringify(pIn1, encoding); Stringify(pIn2, encoding); u.ae.nByte = pIn1->n + pIn2->n; if( u.ae.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } @@ -52108,12 +52051,12 @@ if( u.af.rA==(double)0 ) goto arithmetic_result_is_null; u.af.rB /= u.af.rA; break; } default: { - u.af.iA = u.af.rA; - u.af.iB = u.af.rB; + u.af.iA = (i64)u.af.rA; + u.af.iB = (i64)u.af.rB; if( u.af.iA==0 ) goto arithmetic_result_is_null; if( u.af.iA==-1 ) u.af.iA = 1; u.af.rB = (double)(u.af.iB % u.af.iA); break; } @@ -52781,30 +52724,18 @@ pc = pOp->p2-1; } break; } -/* Opcode: IsNull P1 P2 P3 * * -** -** Jump to P2 if the value in register P1 is NULL. If P3 is greater -** than zero, then check all values reg(P1), reg(P1+1), -** reg(P1+2), ..., reg(P1+P3-1). +/* Opcode: IsNull P1 P2 * * * +** +** Jump to P2 if the value in register P1 is NULL. */ case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */ -#if 0 /* local variables moved into u.am */ - int n; -#endif /* local variables moved into u.am */ - - u.am.n = pOp->p3; - assert( pOp->p3==0 || pOp->p1>0 ); - do{ - if( (pIn1->flags & MEM_Null)!=0 ){ - pc = pOp->p2 - 1; - break; - } - pIn1++; - }while( --u.am.n > 0 ); + if( (pIn1->flags & MEM_Null)!=0 ){ + pc = pOp->p2 - 1; + } break; } /* Opcode: NotNull P1 P2 * * * ** @@ -52852,11 +52783,11 @@ ** If the column contains fewer than P2 fields, then extract a NULL. Or, ** if the P4 argument is a P4_MEM use the value of the P4 argument as ** the result. */ case OP_Column: { -#if 0 /* local variables moved into u.an */ +#if 0 /* local variables moved into u.am */ u32 payloadSize; /* Number of bytes in the record */ i64 payloadSize64; /* Number of bytes in the record */ int p1; /* P1 value of the opcode */ int p2; /* column number to retrieve */ VdbeCursor *pC; /* The VDBE cursor */ @@ -52874,123 +52805,125 @@ u8 *zEndHdr; /* Pointer to first byte after the header */ u32 offset; /* Offset into the data */ u64 offset64; /* 64-bit offset. 64 bits needed to catch overflow */ int szHdr; /* Size of the header size field at start of record */ int avail; /* Number of bytes of available data */ -#endif /* local variables moved into u.an */ - - - u.an.p1 = pOp->p1; - u.an.p2 = pOp->p2; - u.an.pC = 0; - memset(&u.an.sMem, 0, sizeof(u.an.sMem)); - assert( u.an.p1<p->nCursor ); +#endif /* local variables moved into u.am */ + + + u.am.p1 = pOp->p1; + u.am.p2 = pOp->p2; + u.am.pC = 0; + memset(&u.am.sMem, 0, sizeof(u.am.sMem)); + assert( u.am.p1<p->nCursor ); assert( pOp->p3>0 && pOp->p3<=p->nMem ); - u.an.pDest = &p->aMem[pOp->p3]; - MemSetTypeFlag(u.an.pDest, MEM_Null); - - /* This block sets the variable u.an.payloadSize to be the total number of + u.am.pDest = &p->aMem[pOp->p3]; + MemSetTypeFlag(u.am.pDest, MEM_Null); + + /* This block sets the variable u.am.payloadSize to be the total number of ** bytes in the record. ** - ** u.an.zRec is set to be the complete text of the record if it is available. + ** u.am.zRec is set to be the complete text of the record if it is available. ** The complete record text is always available for pseudo-tables ** If the record is stored in a cursor, the complete record text - ** might be available in the u.an.pC->aRow cache. Or it might not be. - ** If the data is unavailable, u.an.zRec is set to NULL. + ** might be available in the u.am.pC->aRow cache. Or it might not be. + ** If the data is unavailable, u.am.zRec is set to NULL. ** ** We also compute the number of columns in the record. For cursors, ** the number of columns is stored in the VdbeCursor.nField element. */ - u.an.pC = p->apCsr[u.an.p1]; - assert( u.an.pC!=0 ); -#ifndef SQLITE_OMIT_VIRTUALTABLE - assert( u.an.pC->pVtabCursor==0 ); -#endif - if( u.an.pC->pCursor!=0 ){ + u.am.pC = p->apCsr[u.am.p1]; + assert( u.am.pC!=0 ); +#ifndef SQLITE_OMIT_VIRTUALTABLE + assert( u.am.pC->pVtabCursor==0 ); +#endif + if( u.am.pC->pCursor!=0 ){ /* The record is stored in a B-Tree */ - rc = sqlite3VdbeCursorMoveto(u.an.pC); + rc = sqlite3VdbeCursorMoveto(u.am.pC); if( rc ) goto abort_due_to_error; - u.an.zRec = 0; - u.an.pCrsr = u.an.pC->pCursor; - if( u.an.pC->nullRow ){ - u.an.payloadSize = 0; - }else if( u.an.pC->cacheStatus==p->cacheCtr ){ - u.an.payloadSize = u.an.pC->payloadSize; - u.an.zRec = (char*)u.an.pC->aRow; - }else if( u.an.pC->isIndex ){ - sqlite3BtreeKeySize(u.an.pCrsr, &u.an.payloadSize64); - if( (u.an.payloadSize64 & SQLITE_MAX_U32)!=(u64)u.an.payloadSize64 ){ - rc = SQLITE_CORRUPT_BKPT; - goto abort_due_to_error; - } - u.an.payloadSize = (u32)u.an.payloadSize64; - }else{ - sqlite3BtreeDataSize(u.an.pCrsr, &u.an.payloadSize); - } - u.an.nField = u.an.pC->nField; - }else{ - assert( u.an.pC->pseudoTable ); + u.am.zRec = 0; + u.am.pCrsr = u.am.pC->pCursor; + if( u.am.pC->nullRow ){ + u.am.payloadSize = 0; + }else if( u.am.pC->cacheStatus==p->cacheCtr ){ + u.am.payloadSize = u.am.pC->payloadSize; + u.am.zRec = (char*)u.am.pC->aRow; + }else if( u.am.pC->isIndex ){ + sqlite3BtreeKeySize(u.am.pCrsr, &u.am.payloadSize64); + /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the + ** payload size, so it is impossible for u.am.payloadSize64 to be + ** larger than 32 bits. */ + assert( (u.am.payloadSize64 & SQLITE_MAX_U32)==(u64)u.am.payloadSize64 ); + u.am.payloadSize = (u32)u.am.payloadSize64; + }else{ + sqlite3BtreeDataSize(u.am.pCrsr, &u.am.payloadSize); + } + u.am.nField = u.am.pC->nField; + }else if( u.am.pC->pseudoTable ){ /* The record is the sole entry of a pseudo-table */ - u.an.payloadSize = u.an.pC->nData; - u.an.zRec = u.an.pC->pData; - u.an.pC->cacheStatus = CACHE_STALE; - assert( u.an.payloadSize==0 || u.an.zRec!=0 ); - u.an.nField = u.an.pC->nField; - u.an.pCrsr = 0; - } - - /* If u.an.payloadSize is 0, then just store a NULL */ - if( u.an.payloadSize==0 ){ - assert( u.an.pDest->flags&MEM_Null ); + u.am.payloadSize = u.am.pC->nData; + u.am.zRec = u.am.pC->pData; + u.am.pC->cacheStatus = CACHE_STALE; + assert( u.am.payloadSize==0 || u.am.zRec!=0 ); + u.am.nField = u.am.pC->nField; + u.am.pCrsr = 0; + }else{ + /* Consider the row to be NULL */ + u.am.payloadSize = 0; + } + + /* If u.am.payloadSize is 0, then just store a NULL */ + if( u.am.payloadSize==0 ){ + assert( u.am.pDest->flags&MEM_Null ); goto op_column_out; } assert( db->aLimit[SQLITE_LIMIT_LENGTH]>=0 ); - if( u.an.payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ + if( u.am.payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } - assert( u.an.p2<u.an.nField ); + assert( u.am.p2<u.am.nField ); /* Read and parse the table header. Store the results of the parse ** into the record header cache fields of the cursor. */ - u.an.aType = u.an.pC->aType; - if( u.an.pC->cacheStatus==p->cacheCtr ){ - u.an.aOffset = u.an.pC->aOffset; - }else{ - assert(u.an.aType); - u.an.avail = 0; - u.an.pC->aOffset = u.an.aOffset = &u.an.aType[u.an.nField]; - u.an.pC->payloadSize = u.an.payloadSize; - u.an.pC->cacheStatus = p->cacheCtr; + u.am.aType = u.am.pC->aType; + if( u.am.pC->cacheStatus==p->cacheCtr ){ + u.am.aOffset = u.am.pC->aOffset; + }else{ + assert(u.am.aType); + u.am.avail = 0; + u.am.pC->aOffset = u.am.aOffset = &u.am.aType[u.am.nField]; + u.am.pC->payloadSize = u.am.payloadSize; + u.am.pC->cacheStatus = p->cacheCtr; /* Figure out how many bytes are in the header */ - if( u.an.zRec ){ - u.an.zData = u.an.zRec; - }else{ - if( u.an.pC->isIndex ){ - u.an.zData = (char*)sqlite3BtreeKeyFetch(u.an.pCrsr, &u.an.avail); - }else{ - u.an.zData = (char*)sqlite3BtreeDataFetch(u.an.pCrsr, &u.an.avail); + if( u.am.zRec ){ + u.am.zData = u.am.zRec; + }else{ + if( u.am.pC->isIndex ){ + u.am.zData = (char*)sqlite3BtreeKeyFetch(u.am.pCrsr, &u.am.avail); + }else{ + u.am.zData = (char*)sqlite3BtreeDataFetch(u.am.pCrsr, &u.am.avail); } /* If KeyFetch()/DataFetch() managed to get the entire payload, - ** save the payload in the u.an.pC->aRow cache. That will save us from + ** save the payload in the u.am.pC->aRow cache. That will save us from ** having to make additional calls to fetch the content portion of ** the record. */ - assert( u.an.avail>=0 ); - if( u.an.payloadSize <= (u32)u.an.avail ){ - u.an.zRec = u.an.zData; - u.an.pC->aRow = (u8*)u.an.zData; - }else{ - u.an.pC->aRow = 0; + assert( u.am.avail>=0 ); + if( u.am.payloadSize <= (u32)u.am.avail ){ + u.am.zRec = u.am.zData; + u.am.pC->aRow = (u8*)u.am.zData; + }else{ + u.am.pC->aRow = 0; } } /* The following assert is true in all cases accept when ** the database file has been corrupted externally. - ** assert( u.an.zRec!=0 || u.an.avail>=u.an.payloadSize || u.an.avail>=9 ); */ - u.an.szHdr = getVarint32((u8*)u.an.zData, u.an.offset); + ** assert( u.am.zRec!=0 || u.am.avail>=u.am.payloadSize || u.am.avail>=9 ); */ + u.am.szHdr = getVarint32((u8*)u.am.zData, u.am.offset); /* Make sure a corrupt database has not given us an oversize header. ** Do this now to avoid an oversize memory allocation. ** ** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte @@ -52997,136 +52930,136 @@ ** types use so much data space that there can only be 4096 and 32 of ** them, respectively. So the maximum header length results from a ** 3-byte type for each of the maximum of 32768 columns plus three ** extra bytes for the header length itself. 32768*3 + 3 = 98307. */ - if( u.an.offset > 98307 ){ + if( u.am.offset > 98307 ){ rc = SQLITE_CORRUPT_BKPT; goto op_column_out; } - /* Compute in u.an.len the number of bytes of data we need to read in order - ** to get u.an.nField type values. u.an.offset is an upper bound on this. But - ** u.an.nField might be significantly less than the true number of columns - ** in the table, and in that case, 5*u.an.nField+3 might be smaller than u.an.offset. - ** We want to minimize u.an.len in order to limit the size of the memory - ** allocation, especially if a corrupt database file has caused u.an.offset + /* Compute in u.am.len the number of bytes of data we need to read in order + ** to get u.am.nField type values. u.am.offset is an upper bound on this. But + ** u.am.nField might be significantly less than the true number of columns + ** in the table, and in that case, 5*u.am.nField+3 might be smaller than u.am.offset. + ** We want to minimize u.am.len in order to limit the size of the memory + ** allocation, especially if a corrupt database file has caused u.am.offset ** to be oversized. Offset is limited to 98307 above. But 98307 might ** still exceed Robson memory allocation limits on some configurations. - ** On systems that cannot tolerate large memory allocations, u.an.nField*5+3 - ** will likely be much smaller since u.an.nField will likely be less than + ** On systems that cannot tolerate large memory allocations, u.am.nField*5+3 + ** will likely be much smaller since u.am.nField will likely be less than ** 20 or so. This insures that Robson memory allocation limits are ** not exceeded even for corrupt database files. */ - u.an.len = u.an.nField*5 + 3; - if( u.an.len > u.an.offset ) u.an.len = u.an.offset; + u.am.len = u.am.nField*5 + 3; + if( u.am.len > (int)u.am.offset ) u.am.len = (int)u.am.offset; /* The KeyFetch() or DataFetch() above are fast and will get the entire ** record header in most cases. But they will fail to get the complete ** record header if the record header does not fit on a single page ** in the B-Tree. When that happens, use sqlite3VdbeMemFromBtree() to ** acquire the complete header text. */ - if( !u.an.zRec && u.an.avail<u.an.len ){ - u.an.sMem.flags = 0; - u.an.sMem.db = 0; - rc = sqlite3VdbeMemFromBtree(u.an.pCrsr, 0, u.an.len, u.an.pC->isIndex, &u.an.sMem); + if( !u.am.zRec && u.am.avail<u.am.len ){ + u.am.sMem.flags = 0; + u.am.sMem.db = 0; + rc = sqlite3VdbeMemFromBtree(u.am.pCrsr, 0, u.am.len, u.am.pC->isIndex, &u.am.sMem); if( rc!=SQLITE_OK ){ goto op_column_out; } - u.an.zData = u.an.sMem.z; - } - u.an.zEndHdr = (u8 *)&u.an.zData[u.an.len]; - u.an.zIdx = (u8 *)&u.an.zData[u.an.szHdr]; - - /* Scan the header and use it to fill in the u.an.aType[] and u.an.aOffset[] - ** arrays. u.an.aType[u.an.i] will contain the type integer for the u.an.i-th - ** column and u.an.aOffset[u.an.i] will contain the u.an.offset from the beginning - ** of the record to the start of the data for the u.an.i-th column - */ - u.an.offset64 = u.an.offset; - for(u.an.i=0; u.an.i<u.an.nField; u.an.i++){ - if( u.an.zIdx<u.an.zEndHdr ){ - u.an.aOffset[u.an.i] = (u32)u.an.offset64; - u.an.zIdx += getVarint32(u.an.zIdx, u.an.aType[u.an.i]); - u.an.offset64 += sqlite3VdbeSerialTypeLen(u.an.aType[u.an.i]); - }else{ - /* If u.an.i is less that u.an.nField, then there are less fields in this + u.am.zData = u.am.sMem.z; + } + u.am.zEndHdr = (u8 *)&u.am.zData[u.am.len]; + u.am.zIdx = (u8 *)&u.am.zData[u.am.szHdr]; + + /* Scan the header and use it to fill in the u.am.aType[] and u.am.aOffset[] + ** arrays. u.am.aType[u.am.i] will contain the type integer for the u.am.i-th + ** column and u.am.aOffset[u.am.i] will contain the u.am.offset from the beginning + ** of the record to the start of the data for the u.am.i-th column + */ + u.am.offset64 = u.am.offset; + for(u.am.i=0; u.am.i<u.am.nField; u.am.i++){ + if( u.am.zIdx<u.am.zEndHdr ){ + u.am.aOffset[u.am.i] = (u32)u.am.offset64; + u.am.zIdx += getVarint32(u.am.zIdx, u.am.aType[u.am.i]); + u.am.offset64 += sqlite3VdbeSerialTypeLen(u.am.aType[u.am.i]); + }else{ + /* If u.am.i is less that u.am.nField, then there are less fields in this ** record than SetNumColumns indicated there are columns in the - ** table. Set the u.an.offset for any extra columns not present in + ** table. Set the u.am.offset for any extra columns not present in ** the record to 0. This tells code below to store a NULL ** instead of deserializing a value from the record. */ - u.an.aOffset[u.an.i] = 0; - } - } - sqlite3VdbeMemRelease(&u.an.sMem); - u.an.sMem.flags = MEM_Null; + u.am.aOffset[u.am.i] = 0; + } + } + sqlite3VdbeMemRelease(&u.am.sMem); + u.am.sMem.flags = MEM_Null; /* If we have read more header data than was contained in the header, ** or if the end of the last field appears to be past the end of the ** record, or if the end of the last field appears to be before the end ** of the record (when all fields present), then we must be dealing ** with a corrupt database. */ - if( (u.an.zIdx > u.an.zEndHdr)|| (u.an.offset64 > u.an.payloadSize) - || (u.an.zIdx==u.an.zEndHdr && u.an.offset64!=(u64)u.an.payloadSize) ){ + if( (u.am.zIdx > u.am.zEndHdr)|| (u.am.offset64 > u.am.payloadSize) + || (u.am.zIdx==u.am.zEndHdr && u.am.offset64!=(u64)u.am.payloadSize) ){ rc = SQLITE_CORRUPT_BKPT; goto op_column_out; } } - /* Get the column information. If u.an.aOffset[u.an.p2] is non-zero, then - ** deserialize the value from the record. If u.an.aOffset[u.an.p2] is zero, + /* Get the column information. If u.am.aOffset[u.am.p2] is non-zero, then + ** deserialize the value from the record. If u.am.aOffset[u.am.p2] is zero, ** then there are not enough fields in the record to satisfy the ** request. In this case, set the value NULL or to P4 if P4 is ** a pointer to a Mem object. */ - if( u.an.aOffset[u.an.p2] ){ + if( u.am.aOffset[u.am.p2] ){ assert( rc==SQLITE_OK ); - if( u.an.zRec ){ - sqlite3VdbeMemReleaseExternal(u.an.pDest); - sqlite3VdbeSerialGet((u8 *)&u.an.zRec[u.an.aOffset[u.an.p2]], u.an.aType[u.an.p2], u.an.pDest); - }else{ - u.an.len = sqlite3VdbeSerialTypeLen(u.an.aType[u.an.p2]); - sqlite3VdbeMemMove(&u.an.sMem, u.an.pDest); - rc = sqlite3VdbeMemFromBtree(u.an.pCrsr, u.an.aOffset[u.an.p2], u.an.len, u.an.pC->isIndex, &u.an.sMem); + if( u.am.zRec ){ + sqlite3VdbeMemReleaseExternal(u.am.pDest); + sqlite3VdbeSerialGet((u8 *)&u.am.zRec[u.am.aOffset[u.am.p2]], u.am.aType[u.am.p2], u.am.pDest); + }else{ + u.am.len = sqlite3VdbeSerialTypeLen(u.am.aType[u.am.p2]); + sqlite3VdbeMemMove(&u.am.sMem, u.am.pDest); + rc = sqlite3VdbeMemFromBtree(u.am.pCrsr, u.am.aOffset[u.am.p2], u.am.len, u.am.pC->isIndex, &u.am.sMem); if( rc!=SQLITE_OK ){ goto op_column_out; } - u.an.zData = u.an.sMem.z; - sqlite3VdbeSerialGet((u8*)u.an.zData, u.an.aType[u.an.p2], u.an.pDest); - } - u.an.pDest->enc = encoding; + u.am.zData = u.am.sMem.z; + sqlite3VdbeSerialGet((u8*)u.am.zData, u.am.aType[u.am.p2], u.am.pDest); + } + u.am.pDest->enc = encoding; }else{ if( pOp->p4type==P4_MEM ){ - sqlite3VdbeMemShallowCopy(u.an.pDest, pOp->p4.pMem, MEM_Static); - }else{ - assert( u.an.pDest->flags&MEM_Null ); + sqlite3VdbeMemShallowCopy(u.am.pDest, pOp->p4.pMem, MEM_Static); + }else{ + assert( u.am.pDest->flags&MEM_Null ); } } /* If we dynamically allocated space to hold the data (in the ** sqlite3VdbeMemFromBtree() call above) then transfer control of that - ** dynamically allocated space over to the u.an.pDest structure. + ** dynamically allocated space over to the u.am.pDest structure. ** This prevents a memory copy. */ - if( u.an.sMem.zMalloc ){ - assert( u.an.sMem.z==u.an.sMem.zMalloc ); - assert( !(u.an.pDest->flags & MEM_Dyn) ); - assert( !(u.an.pDest->flags & (MEM_Blob|MEM_Str)) || u.an.pDest->z==u.an.sMem.z ); - u.an.pDest->flags &= ~(MEM_Ephem|MEM_Static); - u.an.pDest->flags |= MEM_Term; - u.an.pDest->z = u.an.sMem.z; - u.an.pDest->zMalloc = u.an.sMem.zMalloc; - } - - rc = sqlite3VdbeMemMakeWriteable(u.an.pDest); + if( u.am.sMem.zMalloc ){ + assert( u.am.sMem.z==u.am.sMem.zMalloc ); + assert( !(u.am.pDest->flags & MEM_Dyn) ); + assert( !(u.am.pDest->flags & (MEM_Blob|MEM_Str)) || u.am.pDest->z==u.am.sMem.z ); + u.am.pDest->flags &= ~(MEM_Ephem|MEM_Static); + u.am.pDest->flags |= MEM_Term; + u.am.pDest->z = u.am.sMem.z; + u.am.pDest->zMalloc = u.am.sMem.zMalloc; + } + + rc = sqlite3VdbeMemMakeWriteable(u.am.pDest); op_column_out: - UPDATE_MAX_BLOBSIZE(u.an.pDest); - REGISTER_TRACE(pOp->p3, u.an.pDest); + UPDATE_MAX_BLOBSIZE(u.am.pDest); + REGISTER_TRACE(pOp->p3, u.am.pDest); break; } /* Opcode: Affinity P1 P2 * P4 * ** @@ -53135,23 +53068,23 @@ ** P4 is a string that is P2 characters long. The nth character of the ** string indicates the column affinity that should be used for the nth ** memory cell in the range. */ case OP_Affinity: { -#if 0 /* local variables moved into u.ao */ +#if 0 /* local variables moved into u.an */ char *zAffinity; /* The affinity to be applied */ Mem *pData0; /* First register to which to apply affinity */ Mem *pLast; /* Last register to which to apply affinity */ Mem *pRec; /* Current register */ -#endif /* local variables moved into u.ao */ - - u.ao.zAffinity = pOp->p4.z; - u.ao.pData0 = &p->aMem[pOp->p1]; - u.ao.pLast = &u.ao.pData0[pOp->p2-1]; - for(u.ao.pRec=u.ao.pData0; u.ao.pRec<=u.ao.pLast; u.ao.pRec++){ - ExpandBlob(u.ao.pRec); - applyAffinity(u.ao.pRec, u.ao.zAffinity[u.ao.pRec-u.ao.pData0], encoding); +#endif /* local variables moved into u.an */ + + u.an.zAffinity = pOp->p4.z; + u.an.pData0 = &p->aMem[pOp->p1]; + u.an.pLast = &u.an.pData0[pOp->p2-1]; + for(u.an.pRec=u.an.pData0; u.an.pRec<=u.an.pLast; u.an.pRec++){ + ExpandBlob(u.an.pRec); + applyAffinity(u.an.pRec, u.an.zAffinity[u.an.pRec-u.an.pData0], encoding); } break; } /* Opcode: MakeRecord P1 P2 P3 P4 * @@ -53171,11 +53104,11 @@ ** macros defined in sqliteInt.h. ** ** If P4 is NULL then all index fields have the affinity NONE. */ case OP_MakeRecord: { -#if 0 /* local variables moved into u.ap */ +#if 0 /* local variables moved into u.ao */ u8 *zNewRecord; /* A buffer to hold the data for the new record */ Mem *pRec; /* The new record */ u64 nData; /* Number of bytes of data space */ int nHdr; /* Number of bytes of header space */ i64 nByte; /* Data space required for this record */ @@ -53187,11 +53120,11 @@ 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 */ int i; /* Space used in zNewRecord[] */ int len; /* Length of a field */ -#endif /* local variables moved into u.ap */ +#endif /* local variables moved into u.ao */ /* Assuming the record contains N fields, the record format looks ** like this: ** ** ------------------------------------------------------------------------ @@ -53204,52 +53137,52 @@ ** Each type field is a varint representing the serial type of the ** corresponding data element (see sqlite3VdbeSerialType()). The ** hdr-size field is also a varint which is the offset from the beginning ** of the record to data0. */ - u.ap.nData = 0; /* Number of bytes of data space */ - u.ap.nHdr = 0; /* Number of bytes of header space */ - u.ap.nByte = 0; /* Data space required for this record */ - u.ap.nZero = 0; /* Number of zero bytes at the end of the record */ - u.ap.nField = pOp->p1; - u.ap.zAffinity = pOp->p4.z; - assert( u.ap.nField>0 && pOp->p2>0 && pOp->p2+u.ap.nField<=p->nMem+1 ); - u.ap.pData0 = &p->aMem[u.ap.nField]; - u.ap.nField = pOp->p2; - u.ap.pLast = &u.ap.pData0[u.ap.nField-1]; - u.ap.file_format = p->minWriteFileFormat; + u.ao.nData = 0; /* Number of bytes of data space */ + u.ao.nHdr = 0; /* Number of bytes of header space */ + u.ao.nByte = 0; /* Data space required for this record */ + u.ao.nZero = 0; /* Number of zero bytes at the end of the record */ + u.ao.nField = pOp->p1; + u.ao.zAffinity = pOp->p4.z; + assert( u.ao.nField>0 && pOp->p2>0 && pOp->p2+u.ao.nField<=p->nMem+1 ); + u.ao.pData0 = &p->aMem[u.ao.nField]; + u.ao.nField = pOp->p2; + u.ao.pLast = &u.ao.pData0[u.ao.nField-1]; + u.ao.file_format = p->minWriteFileFormat; /* Loop through the elements that will make up the record to figure ** out how much space is required for the new record. */ - for(u.ap.pRec=u.ap.pData0; u.ap.pRec<=u.ap.pLast; u.ap.pRec++){ - if( u.ap.zAffinity ){ - applyAffinity(u.ap.pRec, u.ap.zAffinity[u.ap.pRec-u.ap.pData0], encoding); - } - if( u.ap.pRec->flags&MEM_Zero && u.ap.pRec->n>0 ){ - sqlite3VdbeMemExpandBlob(u.ap.pRec); - } - u.ap.serial_type = sqlite3VdbeSerialType(u.ap.pRec, u.ap.file_format); - u.ap.len = sqlite3VdbeSerialTypeLen(u.ap.serial_type); - u.ap.nData += u.ap.len; - u.ap.nHdr += sqlite3VarintLen(u.ap.serial_type); - if( u.ap.pRec->flags & MEM_Zero ){ + for(u.ao.pRec=u.ao.pData0; u.ao.pRec<=u.ao.pLast; u.ao.pRec++){ + if( u.ao.zAffinity ){ + applyAffinity(u.ao.pRec, u.ao.zAffinity[u.ao.pRec-u.ao.pData0], encoding); + } + if( u.ao.pRec->flags&MEM_Zero && u.ao.pRec->n>0 ){ + sqlite3VdbeMemExpandBlob(u.ao.pRec); + } + u.ao.serial_type = sqlite3VdbeSerialType(u.ao.pRec, u.ao.file_format); + u.ao.len = sqlite3VdbeSerialTypeLen(u.ao.serial_type); + u.ao.nData += u.ao.len; + u.ao.nHdr += sqlite3VarintLen(u.ao.serial_type); + if( u.ao.pRec->flags & MEM_Zero ){ /* Only pure zero-filled BLOBs can be input to this Opcode. ** We do not allow blobs with a prefix and a zero-filled tail. */ - u.ap.nZero += u.ap.pRec->u.nZero; - }else if( u.ap.len ){ - u.ap.nZero = 0; + u.ao.nZero += u.ao.pRec->u.nZero; + }else if( u.ao.len ){ + u.ao.nZero = 0; } } /* Add the initial header varint and total the size */ - u.ap.nHdr += u.ap.nVarint = sqlite3VarintLen(u.ap.nHdr); - if( u.ap.nVarint<sqlite3VarintLen(u.ap.nHdr) ){ - u.ap.nHdr++; - } - u.ap.nByte = u.ap.nHdr+u.ap.nData-u.ap.nZero; - if( u.ap.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + u.ao.nHdr += u.ao.nVarint = sqlite3VarintLen(u.ao.nHdr); + if( u.ao.nVarint<sqlite3VarintLen(u.ao.nHdr) ){ + u.ao.nHdr++; + } + u.ao.nByte = u.ao.nHdr+u.ao.nData-u.ao.nZero; + if( u.ao.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } /* Make sure the output register has a buffer large enough to store ** the new record. The output register (pOp->p3) is not allowed to @@ -53256,32 +53189,32 @@ ** be one of the input registers (because the following call to ** sqlite3VdbeMemGrow() could clobber the value before it is used). */ assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 ); pOut = &p->aMem[pOp->p3]; - if( sqlite3VdbeMemGrow(pOut, (int)u.ap.nByte, 0) ){ + if( sqlite3VdbeMemGrow(pOut, (int)u.ao.nByte, 0) ){ goto no_mem; } - u.ap.zNewRecord = (u8 *)pOut->z; + u.ao.zNewRecord = (u8 *)pOut->z; /* Write the record */ - u.ap.i = putVarint32(u.ap.zNewRecord, u.ap.nHdr); - for(u.ap.pRec=u.ap.pData0; u.ap.pRec<=u.ap.pLast; u.ap.pRec++){ - u.ap.serial_type = sqlite3VdbeSerialType(u.ap.pRec, u.ap.file_format); - u.ap.i += putVarint32(&u.ap.zNewRecord[u.ap.i], u.ap.serial_type); /* serial type */ - } - for(u.ap.pRec=u.ap.pData0; u.ap.pRec<=u.ap.pLast; u.ap.pRec++){ /* serial data */ - u.ap.i += sqlite3VdbeSerialPut(&u.ap.zNewRecord[u.ap.i], (int)(u.ap.nByte-u.ap.i), u.ap.pRec,u.ap.file_format); - } - assert( u.ap.i==u.ap.nByte ); + u.ao.i = putVarint32(u.ao.zNewRecord, u.ao.nHdr); + for(u.ao.pRec=u.ao.pData0; u.ao.pRec<=u.ao.pLast; u.ao.pRec++){ + u.ao.serial_type = sqlite3VdbeSerialType(u.ao.pRec, u.ao.file_format); + u.ao.i += putVarint32(&u.ao.zNewRecord[u.ao.i], u.ao.serial_type); /* serial type */ + } + for(u.ao.pRec=u.ao.pData0; u.ao.pRec<=u.ao.pLast; u.ao.pRec++){ /* serial data */ + u.ao.i += sqlite3VdbeSerialPut(&u.ao.zNewRecord[u.ao.i], (int)(u.ao.nByte-u.ao.i), u.ao.pRec,u.ao.file_format); + } + assert( u.ao.i==u.ao.nByte ); assert( pOp->p3>0 && pOp->p3<=p->nMem ); - pOut->n = (int)u.ap.nByte; + pOut->n = (int)u.ao.nByte; pOut->flags = MEM_Blob | MEM_Dyn; pOut->xDel = 0; - if( u.ap.nZero ){ - pOut->u.nZero = u.ap.nZero; + if( u.ao.nZero ){ + pOut->u.nZero = u.ao.nZero; pOut->flags |= MEM_Zero; } pOut->enc = SQLITE_UTF8; /* In case the blob is ever converted to text */ REGISTER_TRACE(pOp->p3, pOut); UPDATE_MAX_BLOBSIZE(pOut); @@ -53293,23 +53226,23 @@ ** Store the number of entries (an integer value) in the table or index ** opened by cursor P1 in register P2 */ #ifndef SQLITE_OMIT_BTREECOUNT case OP_Count: { /* out2-prerelease */ -#if 0 /* local variables moved into u.aq */ +#if 0 /* local variables moved into u.ap */ i64 nEntry; BtCursor *pCrsr; -#endif /* local variables moved into u.aq */ - - u.aq.pCrsr = p->apCsr[pOp->p1]->pCursor; - if( u.aq.pCrsr ){ - rc = sqlite3BtreeCount(u.aq.pCrsr, &u.aq.nEntry); - }else{ - u.aq.nEntry = 0; +#endif /* local variables moved into u.ap */ + + u.ap.pCrsr = p->apCsr[pOp->p1]->pCursor; + if( u.ap.pCrsr ){ + rc = sqlite3BtreeCount(u.ap.pCrsr, &u.ap.nEntry); + }else{ + u.ap.nEntry = 0; } pOut->flags = MEM_Int; - pOut->u.i = u.aq.nEntry; + pOut->u.i = u.ap.nEntry; break; } #endif /* Opcode: Statement P1 * * * * @@ -53333,27 +53266,25 @@ ** The statement is begun on the database file with index P1. The main ** database file has an index of 0 and the file used for temporary tables ** has an index of 1. */ case OP_Statement: { -#if 0 /* local variables moved into u.ar */ - int i; +#if 0 /* local variables moved into u.aq */ Btree *pBt; -#endif /* local variables moved into u.ar */ +#endif /* local variables moved into u.aq */ if( db->autoCommit==0 || db->activeVdbeCnt>1 ){ - u.ar.i = pOp->p1; - assert( u.ar.i>=0 && u.ar.i<db->nDb ); - assert( db->aDb[u.ar.i].pBt!=0 ); - u.ar.pBt = db->aDb[u.ar.i].pBt; - assert( sqlite3BtreeIsInTrans(u.ar.pBt) ); - assert( (p->btreeMask & (1<<u.ar.i))!=0 ); + assert( pOp->p1>=0 && pOp->p1<db->nDb ); + assert( db->aDb[pOp->p1].pBt!=0 ); + u.aq.pBt = db->aDb[pOp->p1].pBt; + assert( sqlite3BtreeIsInTrans(u.aq.pBt) ); + assert( (p->btreeMask & (1<<pOp->p1))!=0 ); if( p->iStatement==0 ){ assert( db->nStatement>=0 && db->nSavepoint>=0 ); db->nStatement++; p->iStatement = db->nSavepoint + db->nStatement; } - rc = sqlite3BtreeBeginStmt(u.ar.pBt, p->iStatement); + rc = sqlite3BtreeBeginStmt(u.aq.pBt, p->iStatement); } break; } /* Opcode: Savepoint P1 * * P4 * @@ -53361,48 +53292,48 @@ ** Open, release or rollback the savepoint named by parameter P4, depending ** on the value of P1. To open a new savepoint, P1==0. To release (commit) an ** existing savepoint, P1==1, or to rollback an existing savepoint P1==2. */ case OP_Savepoint: { -#if 0 /* local variables moved into u.as */ +#if 0 /* local variables moved into u.ar */ int p1; /* Value of P1 operand */ char *zName; /* Name of savepoint */ int nName; Savepoint *pNew; Savepoint *pSavepoint; Savepoint *pTmp; int iSavepoint; int ii; -#endif /* local variables moved into u.as */ - - u.as.p1 = pOp->p1; - u.as.zName = pOp->p4.z; - - /* Assert that the u.as.p1 parameter is valid. Also that if there is no open +#endif /* local variables moved into u.ar */ + + u.ar.p1 = pOp->p1; + u.ar.zName = pOp->p4.z; + + /* Assert that the u.ar.p1 parameter is valid. Also that if there is no open ** transaction, then there cannot be any savepoints. */ assert( db->pSavepoint==0 || db->autoCommit==0 ); - assert( u.as.p1==SAVEPOINT_BEGIN||u.as.p1==SAVEPOINT_RELEASE||u.as.p1==SAVEPOINT_ROLLBACK ); + assert( u.ar.p1==SAVEPOINT_BEGIN||u.ar.p1==SAVEPOINT_RELEASE||u.ar.p1==SAVEPOINT_ROLLBACK ); assert( db->pSavepoint || db->isTransactionSavepoint==0 ); assert( checkSavepointCount(db) ); - if( u.as.p1==SAVEPOINT_BEGIN ){ + if( u.ar.p1==SAVEPOINT_BEGIN ){ if( db->writeVdbeCnt>0 ){ /* A new savepoint cannot be created if there are active write ** statements (i.e. open read/write incremental blob handles). */ sqlite3SetString(&p->zErrMsg, db, "cannot open savepoint - " "SQL statements in progress"); rc = SQLITE_BUSY; }else{ - u.as.nName = sqlite3Strlen30(u.as.zName); + u.ar.nName = sqlite3Strlen30(u.ar.zName); /* Create a new savepoint structure. */ - u.as.pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+u.as.nName+1); - if( u.as.pNew ){ - u.as.pNew->zName = (char *)&u.as.pNew[1]; - memcpy(u.as.pNew->zName, u.as.zName, u.as.nName+1); + u.ar.pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+u.ar.nName+1); + if( u.ar.pNew ){ + u.ar.pNew->zName = (char *)&u.ar.pNew[1]; + memcpy(u.ar.pNew->zName, u.ar.zName, u.ar.nName+1); /* If there is no open transaction, then mark this as a special ** "transaction savepoint". */ if( db->autoCommit ){ db->autoCommit = 0; @@ -53410,49 +53341,49 @@ }else{ db->nSavepoint++; } /* Link the new savepoint into the database handle's list. */ - u.as.pNew->pNext = db->pSavepoint; - db->pSavepoint = u.as.pNew; - } - } - }else{ - u.as.iSavepoint = 0; + u.ar.pNew->pNext = db->pSavepoint; + db->pSavepoint = u.ar.pNew; + } + } + }else{ + u.ar.iSavepoint = 0; /* Find the named savepoint. If there is no such savepoint, then an ** an error is returned to the user. */ for( - u.as.pSavepoint = db->pSavepoint; - u.as.pSavepoint && sqlite3StrICmp(u.as.pSavepoint->zName, u.as.zName); - u.as.pSavepoint = u.as.pSavepoint->pNext - ){ - u.as.iSavepoint++; - } - if( !u.as.pSavepoint ){ - sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", u.as.zName); + u.ar.pSavepoint = db->pSavepoint; + u.ar.pSavepoint && sqlite3StrICmp(u.ar.pSavepoint->zName, u.ar.zName); + u.ar.pSavepoint = u.ar.pSavepoint->pNext + ){ + u.ar.iSavepoint++; + } + if( !u.ar.pSavepoint ){ + sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", u.ar.zName); rc = SQLITE_ERROR; }else if( - db->writeVdbeCnt>0 || (u.as.p1==SAVEPOINT_ROLLBACK && db->activeVdbeCnt>1) + db->writeVdbeCnt>0 || (u.ar.p1==SAVEPOINT_ROLLBACK && db->activeVdbeCnt>1) ){ /* It is not possible to release (commit) a savepoint if there are ** active write statements. It is not possible to rollback a savepoint ** if there are any active statements at all. */ sqlite3SetString(&p->zErrMsg, db, "cannot %s savepoint - SQL statements in progress", - (u.as.p1==SAVEPOINT_ROLLBACK ? "rollback": "release") + (u.ar.p1==SAVEPOINT_ROLLBACK ? "rollback": "release") ); rc = SQLITE_BUSY; }else{ /* Determine whether or not this is a transaction savepoint. If so, ** and this is a RELEASE command, then the current transaction ** is committed. */ - int isTransaction = u.as.pSavepoint->pNext==0 && db->isTransactionSavepoint; - if( isTransaction && u.as.p1==SAVEPOINT_RELEASE ){ + int isTransaction = u.ar.pSavepoint->pNext==0 && db->isTransactionSavepoint; + if( isTransaction && u.ar.p1==SAVEPOINT_RELEASE ){ db->autoCommit = 1; if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ p->pc = pc; db->autoCommit = 0; p->rc = rc = SQLITE_BUSY; @@ -53459,37 +53390,37 @@ goto vdbe_return; } db->isTransactionSavepoint = 0; rc = p->rc; }else{ - u.as.iSavepoint = db->nSavepoint - u.as.iSavepoint - 1; - for(u.as.ii=0; u.as.ii<db->nDb; u.as.ii++){ - rc = sqlite3BtreeSavepoint(db->aDb[u.as.ii].pBt, u.as.p1, u.as.iSavepoint); + u.ar.iSavepoint = db->nSavepoint - u.ar.iSavepoint - 1; + for(u.ar.ii=0; u.ar.ii<db->nDb; u.ar.ii++){ + rc = sqlite3BtreeSavepoint(db->aDb[u.ar.ii].pBt, u.ar.p1, u.ar.iSavepoint); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } } - if( u.as.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){ + if( u.ar.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){ sqlite3ExpirePreparedStatements(db); sqlite3ResetInternalSchema(db, 0); } } /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all ** savepoints nested inside of the savepoint being operated on. */ - while( db->pSavepoint!=u.as.pSavepoint ){ - u.as.pTmp = db->pSavepoint; - db->pSavepoint = u.as.pTmp->pNext; - sqlite3DbFree(db, u.as.pTmp); + while( db->pSavepoint!=u.ar.pSavepoint ){ + u.ar.pTmp = db->pSavepoint; + db->pSavepoint = u.ar.pTmp->pNext; + sqlite3DbFree(db, u.ar.pTmp); db->nSavepoint--; } /* If it is a RELEASE, then destroy the savepoint being operated on too */ - if( u.as.p1==SAVEPOINT_RELEASE ){ - assert( u.as.pSavepoint==db->pSavepoint ); - db->pSavepoint = u.as.pSavepoint->pNext; - sqlite3DbFree(db, u.as.pSavepoint); + if( u.ar.p1==SAVEPOINT_RELEASE ){ + assert( u.ar.pSavepoint==db->pSavepoint ); + db->pSavepoint = u.ar.pSavepoint->pNext; + sqlite3DbFree(db, u.ar.pSavepoint); if( !isTransaction ){ db->nSavepoint--; } } } @@ -53506,48 +53437,48 @@ ** there are active writing VMs or active VMs that use shared cache. ** ** This instruction causes the VM to halt. */ case OP_AutoCommit: { -#if 0 /* local variables moved into u.at */ +#if 0 /* local variables moved into u.as */ int desiredAutoCommit; - int rollback; + int iRollback; int turnOnAC; -#endif /* local variables moved into u.at */ - - u.at.desiredAutoCommit = pOp->p1; - u.at.rollback = pOp->p2; - u.at.turnOnAC = u.at.desiredAutoCommit && !db->autoCommit; - assert( u.at.desiredAutoCommit==1 || u.at.desiredAutoCommit==0 ); - assert( u.at.desiredAutoCommit==1 || u.at.rollback==0 ); +#endif /* local variables moved into u.as */ + + u.as.desiredAutoCommit = pOp->p1; + u.as.iRollback = pOp->p2; + u.as.turnOnAC = u.as.desiredAutoCommit && !db->autoCommit; + assert( u.as.desiredAutoCommit==1 || u.as.desiredAutoCommit==0 ); + assert( u.as.desiredAutoCommit==1 || u.as.iRollback==0 ); assert( db->activeVdbeCnt>0 ); /* At least this one VM is active */ - if( u.at.turnOnAC && u.at.rollback && db->activeVdbeCnt>1 ){ + if( u.as.turnOnAC && u.as.iRollback && db->activeVdbeCnt>1 ){ /* If this instruction implements a ROLLBACK and other VMs are ** still running, and a transaction is active, return an error indicating ** that the other VMs must complete first. */ - sqlite3SetString(&p->zErrMsg, db, "cannot u.at.rollback transaction - " + sqlite3SetString(&p->zErrMsg, db, "cannot rollback transaction - " "SQL statements in progress"); rc = SQLITE_BUSY; - }else if( u.at.turnOnAC && !u.at.rollback && db->writeVdbeCnt>1 ){ + }else if( u.as.turnOnAC && !u.as.iRollback && db->writeVdbeCnt>0 ){ /* If this instruction implements a COMMIT and other VMs are writing ** return an error indicating that the other VMs must complete first. */ sqlite3SetString(&p->zErrMsg, db, "cannot commit transaction - " "SQL statements in progress"); rc = SQLITE_BUSY; - }else if( u.at.desiredAutoCommit!=db->autoCommit ){ - if( u.at.rollback ){ - assert( u.at.desiredAutoCommit==1 ); + }else if( u.as.desiredAutoCommit!=db->autoCommit ){ + if( u.as.iRollback ){ + assert( u.as.desiredAutoCommit==1 ); sqlite3RollbackAll(db); db->autoCommit = 1; }else{ - db->autoCommit = (u8)u.at.desiredAutoCommit; + db->autoCommit = (u8)u.as.desiredAutoCommit; if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ p->pc = pc; - db->autoCommit = (u8)(1-u.at.desiredAutoCommit); + db->autoCommit = (u8)(1-u.as.desiredAutoCommit); p->rc = rc = SQLITE_BUSY; goto vdbe_return; } } assert( db->nStatement==0 ); @@ -53558,12 +53489,12 @@ rc = SQLITE_ERROR; } goto vdbe_return; }else{ sqlite3SetString(&p->zErrMsg, db, - (!u.at.desiredAutoCommit)?"cannot start a transaction within a transaction":( - (u.at.rollback)?"cannot u.at.rollback - no transaction is active": + (!u.as.desiredAutoCommit)?"cannot start a transaction within a transaction":( + (u.as.iRollback)?"cannot rollback - no transaction is active": "cannot commit - no transaction is active")); rc = SQLITE_ERROR; } break; @@ -53589,22 +53520,20 @@ ** on the file. ** ** If P2 is zero, then a read-lock is obtained on the database file. */ case OP_Transaction: { -#if 0 /* local variables moved into u.au */ - int i; +#if 0 /* local variables moved into u.at */ Btree *pBt; -#endif /* local variables moved into u.au */ - - u.au.i = pOp->p1; - assert( u.au.i>=0 && u.au.i<db->nDb ); - assert( (p->btreeMask & (1<<u.au.i))!=0 ); - u.au.pBt = db->aDb[u.au.i].pBt; - - if( u.au.pBt ){ - rc = sqlite3BtreeBeginTrans(u.au.pBt, pOp->p2); +#endif /* local variables moved into u.at */ + + assert( pOp->p1>=0 && pOp->p1<db->nDb ); + assert( (p->btreeMask & (1<<pOp->p1))!=0 ); + u.at.pBt = db->aDb[pOp->p1].pBt; + + if( u.at.pBt ){ + rc = sqlite3BtreeBeginTrans(u.at.pBt, pOp->p2); if( rc==SQLITE_BUSY ){ p->pc = pc; p->rc = rc = SQLITE_BUSY; goto vdbe_return; } @@ -53626,25 +53555,25 @@ ** There must be a read-lock on the database (either a transaction ** must be started or there must be an open cursor) before ** executing this instruction. */ case OP_ReadCookie: { /* out2-prerelease */ -#if 0 /* local variables moved into u.av */ +#if 0 /* local variables moved into u.au */ int iMeta; int iDb; int iCookie; -#endif /* local variables moved into u.av */ - - u.av.iDb = pOp->p1; - u.av.iCookie = pOp->p3; +#endif /* local variables moved into u.au */ + + u.au.iDb = pOp->p1; + u.au.iCookie = pOp->p3; assert( pOp->p3<SQLITE_N_BTREE_META ); - assert( u.av.iDb>=0 && u.av.iDb<db->nDb ); - assert( db->aDb[u.av.iDb].pBt!=0 ); - assert( (p->btreeMask & (1<<u.av.iDb))!=0 ); - - rc = sqlite3BtreeGetMeta(db->aDb[u.av.iDb].pBt, u.av.iCookie, (u32 *)&u.av.iMeta); - pOut->u.i = u.av.iMeta; + assert( u.au.iDb>=0 && u.au.iDb<db->nDb ); + assert( db->aDb[u.au.iDb].pBt!=0 ); + assert( (p->btreeMask & (1<<u.au.iDb))!=0 ); + + rc = sqlite3BtreeGetMeta(db->aDb[u.au.iDb].pBt, u.au.iCookie, (u32 *)&u.au.iMeta); + pOut->u.i = u.au.iMeta; MemSetTypeFlag(pOut, MEM_Int); break; } /* Opcode: SetCookie P1 P2 P3 * * @@ -53656,28 +53585,28 @@ ** database file used to store temporary tables. ** ** A transaction must be started before executing this opcode. */ case OP_SetCookie: { /* in3 */ -#if 0 /* local variables moved into u.aw */ +#if 0 /* local variables moved into u.av */ Db *pDb; -#endif /* local variables moved into u.aw */ +#endif /* local variables moved into u.av */ assert( pOp->p2<SQLITE_N_BTREE_META ); assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( (p->btreeMask & (1<<pOp->p1))!=0 ); - u.aw.pDb = &db->aDb[pOp->p1]; - assert( u.aw.pDb->pBt!=0 ); + u.av.pDb = &db->aDb[pOp->p1]; + assert( u.av.pDb->pBt!=0 ); sqlite3VdbeMemIntegerify(pIn3); /* See note about index shifting on OP_ReadCookie */ - rc = sqlite3BtreeUpdateMeta(u.aw.pDb->pBt, pOp->p2, (int)pIn3->u.i); + rc = sqlite3BtreeUpdateMeta(u.av.pDb->pBt, pOp->p2, (int)pIn3->u.i); if( pOp->p2==BTREE_SCHEMA_VERSION ){ /* When the schema cookie changes, record the new cookie internally */ - u.aw.pDb->pSchema->schema_cookie = (int)pIn3->u.i; + u.av.pDb->pSchema->schema_cookie = (int)pIn3->u.i; db->flags |= SQLITE_InternChanges; }else if( pOp->p2==BTREE_FILE_FORMAT ){ /* Record changes in the file format */ - u.aw.pDb->pSchema->file_format = (u8)pIn3->u.i; + u.av.pDb->pSchema->file_format = (u8)pIn3->u.i; } if( pOp->p1==1 ){ /* Invalidate all prepared statements whenever the TEMP database ** schema is changed. Ticket #1644 */ sqlite3ExpirePreparedStatements(db); @@ -53700,24 +53629,24 @@ ** Either a transaction needs to have been started or an OP_Open needs ** to be executed (to establish a read lock) before this opcode is ** invoked. */ case OP_VerifyCookie: { -#if 0 /* local variables moved into u.ax */ +#if 0 /* local variables moved into u.aw */ int iMeta; Btree *pBt; -#endif /* local variables moved into u.ax */ +#endif /* local variables moved into u.aw */ assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( (p->btreeMask & (1<<pOp->p1))!=0 ); - u.ax.pBt = db->aDb[pOp->p1].pBt; - if( u.ax.pBt ){ - rc = sqlite3BtreeGetMeta(u.ax.pBt, BTREE_SCHEMA_VERSION, (u32 *)&u.ax.iMeta); + u.aw.pBt = db->aDb[pOp->p1].pBt; + if( u.aw.pBt ){ + rc = sqlite3BtreeGetMeta(u.aw.pBt, BTREE_SCHEMA_VERSION, (u32 *)&u.aw.iMeta); }else{ rc = SQLITE_OK; - u.ax.iMeta = 0; - } - if( rc==SQLITE_OK && u.ax.iMeta!=pOp->p2 ){ + u.aw.iMeta = 0; + } + if( rc==SQLITE_OK && u.aw.iMeta!=pOp->p2 ){ sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); /* If the schema-cookie from the database file matches the cookie ** stored with the in-memory representation of the schema, do ** not reload the schema from the database file. @@ -53729,11 +53658,11 @@ ** discard the database schema, as the user code implementing the ** v-table would have to be ready for the sqlite3_vtab structure itself ** to be invalidated whenever sqlite3_step() is called from within ** a v-table method. */ - if( db->aDb[pOp->p1].pSchema->schema_cookie!=u.ax.iMeta ){ + if( db->aDb[pOp->p1].pSchema->schema_cookie!=u.aw.iMeta ){ sqlite3ResetInternalSchema(db, pOp->p1); } sqlite3ExpirePreparedStatements(db); rc = SQLITE_SCHEMA; @@ -53790,105 +53719,104 @@ ** ** See also OpenRead. */ case OP_OpenRead: case OP_OpenWrite: { -#if 0 /* local variables moved into u.ay */ +#if 0 /* local variables moved into u.ax */ int nField; KeyInfo *pKeyInfo; - int i; int p2; int iDb; int wrFlag; Btree *pX; VdbeCursor *pCur; Db *pDb; int flags; -#endif /* local variables moved into u.ay */ - - u.ay.nField = 0; - u.ay.pKeyInfo = 0; - u.ay.i = pOp->p1; - u.ay.p2 = pOp->p2; - u.ay.iDb = pOp->p3; - assert( u.ay.iDb>=0 && u.ay.iDb<db->nDb ); - assert( (p->btreeMask & (1<<u.ay.iDb))!=0 ); - u.ay.pDb = &db->aDb[u.ay.iDb]; - u.ay.pX = u.ay.pDb->pBt; - assert( u.ay.pX!=0 ); +#endif /* local variables moved into u.ax */ + + u.ax.nField = 0; + u.ax.pKeyInfo = 0; + u.ax.p2 = pOp->p2; + u.ax.iDb = pOp->p3; + assert( u.ax.iDb>=0 && u.ax.iDb<db->nDb ); + assert( (p->btreeMask & (1<<u.ax.iDb))!=0 ); + u.ax.pDb = &db->aDb[u.ax.iDb]; + u.ax.pX = u.ax.pDb->pBt; + assert( u.ax.pX!=0 ); if( pOp->opcode==OP_OpenWrite ){ - u.ay.wrFlag = 1; - if( u.ay.pDb->pSchema->file_format < p->minWriteFileFormat ){ - p->minWriteFileFormat = u.ay.pDb->pSchema->file_format; - } - }else{ - u.ay.wrFlag = 0; + u.ax.wrFlag = 1; + if( u.ax.pDb->pSchema->file_format < p->minWriteFileFormat ){ + p->minWriteFileFormat = u.ax.pDb->pSchema->file_format; + } + }else{ + u.ax.wrFlag = 0; } if( pOp->p5 ){ - assert( u.ay.p2>0 ); - assert( u.ay.p2<=p->nMem ); - pIn2 = &p->aMem[u.ay.p2]; + assert( u.ax.p2>0 ); + assert( u.ax.p2<=p->nMem ); + pIn2 = &p->aMem[u.ax.p2]; sqlite3VdbeMemIntegerify(pIn2); - u.ay.p2 = (int)pIn2->u.i; - if( u.ay.p2<2 ) { + u.ax.p2 = (int)pIn2->u.i; + /* The u.ax.p2 value always comes from a prior OP_CreateTable opcode and + ** that opcode will always set the u.ax.p2 value to 2 or more or else fail. + ** If there were a failure, the prepared statement would have halted + ** before reaching this instruction. */ + if( NEVER(u.ax.p2<2) ) { rc = SQLITE_CORRUPT_BKPT; goto abort_due_to_error; } } - assert( u.ay.i>=0 ); if( pOp->p4type==P4_KEYINFO ){ - u.ay.pKeyInfo = pOp->p4.pKeyInfo; - u.ay.pKeyInfo->enc = ENC(p->db); - u.ay.nField = u.ay.pKeyInfo->nField+1; + u.ax.pKeyInfo = pOp->p4.pKeyInfo; + u.ax.pKeyInfo->enc = ENC(p->db); + u.ax.nField = u.ax.pKeyInfo->nField+1; }else if( pOp->p4type==P4_INT32 ){ - u.ay.nField = pOp->p4.i; - } - u.ay.pCur = allocateCursor(p, u.ay.i, u.ay.nField, u.ay.iDb, 1); - if( u.ay.pCur==0 ) goto no_mem; - u.ay.pCur->nullRow = 1; - rc = sqlite3BtreeCursor(u.ay.pX, u.ay.p2, u.ay.wrFlag, u.ay.pKeyInfo, u.ay.pCur->pCursor); - u.ay.pCur->pKeyInfo = u.ay.pKeyInfo; + u.ax.nField = pOp->p4.i; + } + assert( pOp->p1>=0 ); + u.ax.pCur = allocateCursor(p, pOp->p1, u.ax.nField, u.ax.iDb, 1); + if( u.ax.pCur==0 ) goto no_mem; + u.ax.pCur->nullRow = 1; + rc = sqlite3BtreeCursor(u.ax.pX, u.ax.p2, u.ax.wrFlag, u.ax.pKeyInfo, u.ax.pCur->pCursor); + u.ax.pCur->pKeyInfo = u.ax.pKeyInfo; switch( rc ){ - case SQLITE_BUSY: { - p->pc = pc; - p->rc = rc = SQLITE_BUSY; - goto vdbe_return; - } case SQLITE_OK: { - u.ay.flags = sqlite3BtreeFlags(u.ay.pCur->pCursor); - /* Sanity checking. Only the lower four bits of the u.ay.flags byte should + u.ax.flags = sqlite3BtreeFlags(u.ax.pCur->pCursor); + + /* Sanity checking. Only the lower four bits of the u.ax.flags byte should ** be used. Bit 3 (mask 0x08) is unpredictable. The lower 3 bits ** (mask 0x07) should be either 5 (intkey+leafdata for tables) or ** 2 (zerodata for indices). If these conditions are not met it can - ** only mean that we are dealing with a corrupt database file - */ - if( (u.ay.flags & 0xf0)!=0 || ((u.ay.flags & 0x07)!=5 && (u.ay.flags & 0x07)!=2) ){ - rc = SQLITE_CORRUPT_BKPT; - goto abort_due_to_error; - } - u.ay.pCur->isTable = (u.ay.flags & BTREE_INTKEY)!=0 ?1:0; - u.ay.pCur->isIndex = (u.ay.flags & BTREE_ZERODATA)!=0 ?1:0; + ** only mean that we are dealing with a corrupt database file. + ** Note: All of the above is checked already in sqlite3BtreeCursor(). + */ + assert( (u.ax.flags & 0xf0)==0 ); + assert( (u.ax.flags & 0x07)==5 || (u.ax.flags & 0x07)==2 ); + + u.ax.pCur->isTable = (u.ax.flags & BTREE_INTKEY)!=0 ?1:0; + u.ax.pCur->isIndex = (u.ax.flags & BTREE_ZERODATA)!=0 ?1:0; /* If P4==0 it means we are expected to open a table. If P4!=0 then ** we expect to be opening an index. If this is not what happened, ** then the database is corrupt */ - if( (u.ay.pCur->isTable && pOp->p4type==P4_KEYINFO) - || (u.ay.pCur->isIndex && pOp->p4type!=P4_KEYINFO) ){ + if( (u.ax.pCur->isTable && pOp->p4type==P4_KEYINFO) + || (u.ax.pCur->isIndex && pOp->p4type!=P4_KEYINFO) ){ rc = SQLITE_CORRUPT_BKPT; goto abort_due_to_error; } break; } case SQLITE_EMPTY: { - u.ay.pCur->isTable = pOp->p4type!=P4_KEYINFO; - u.ay.pCur->isIndex = !u.ay.pCur->isTable; - u.ay.pCur->pCursor = 0; + u.ax.pCur->isTable = pOp->p4type!=P4_KEYINFO; + u.ax.pCur->isIndex = !u.ax.pCur->isTable; + u.ax.pCur->pCursor = 0; rc = SQLITE_OK; break; } default: { + assert( rc!=SQLITE_BUSY ); /* Busy conditions detected earlier */ goto abort_due_to_error; } } break; } @@ -53910,30 +53838,28 @@ ** to a TEMP table at the SQL level, or to a table opened by ** this opcode. Then this opcode was call OpenVirtual. But ** that created confusion with the whole virtual-table idea. */ case OP_OpenEphemeral: { -#if 0 /* local variables moved into u.az */ - int i; +#if 0 /* local variables moved into u.ay */ VdbeCursor *pCx; -#endif /* local variables moved into u.az */ +#endif /* local variables moved into u.ay */ static const int openFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE | SQLITE_OPEN_TRANSIENT_DB; - u.az.i = pOp->p1; - assert( u.az.i>=0 ); - u.az.pCx = allocateCursor(p, u.az.i, pOp->p2, -1, 1); - if( u.az.pCx==0 ) goto no_mem; - u.az.pCx->nullRow = 1; + assert( pOp->p1>=0 ); + u.ay.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); + if( u.ay.pCx==0 ) goto no_mem; + u.ay.pCx->nullRow = 1; rc = sqlite3BtreeFactory(db, 0, 1, SQLITE_DEFAULT_TEMP_CACHE_SIZE, openFlags, - &u.az.pCx->pBt); - if( rc==SQLITE_OK ){ - rc = sqlite3BtreeBeginTrans(u.az.pCx->pBt, 1); + &u.ay.pCx->pBt); + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeBeginTrans(u.ay.pCx->pBt, 1); } if( rc==SQLITE_OK ){ /* If a transient index is required, create it by calling ** sqlite3BtreeCreateTable() with the BTREE_ZERODATA flag before ** opening it. If a transient table is required, just use the @@ -53940,25 +53866,25 @@ ** automatically created table with root-page 1 (an INTKEY table). */ if( pOp->p4.pKeyInfo ){ int pgno; assert( pOp->p4type==P4_KEYINFO ); - rc = sqlite3BtreeCreateTable(u.az.pCx->pBt, &pgno, BTREE_ZERODATA); + rc = sqlite3BtreeCreateTable(u.ay.pCx->pBt, &pgno, BTREE_ZERODATA); if( rc==SQLITE_OK ){ assert( pgno==MASTER_ROOT+1 ); - rc = sqlite3BtreeCursor(u.az.pCx->pBt, pgno, 1, - (KeyInfo*)pOp->p4.z, u.az.pCx->pCursor); - u.az.pCx->pKeyInfo = pOp->p4.pKeyInfo; - u.az.pCx->pKeyInfo->enc = ENC(p->db); - } - u.az.pCx->isTable = 0; - }else{ - rc = sqlite3BtreeCursor(u.az.pCx->pBt, MASTER_ROOT, 1, 0, u.az.pCx->pCursor); - u.az.pCx->isTable = 1; - } - } - u.az.pCx->isIndex = !u.az.pCx->isTable; + rc = sqlite3BtreeCursor(u.ay.pCx->pBt, pgno, 1, + (KeyInfo*)pOp->p4.z, u.ay.pCx->pCursor); + u.ay.pCx->pKeyInfo = pOp->p4.pKeyInfo; + u.ay.pCx->pKeyInfo->enc = ENC(p->db); + } + u.ay.pCx->isTable = 0; + }else{ + rc = sqlite3BtreeCursor(u.ay.pCx->pBt, MASTER_ROOT, 1, 0, u.ay.pCx->pCursor); + u.ay.pCx->isTable = 1; + } + } + u.ay.pCx->isIndex = !u.ay.pCx->isTable; break; } /* Opcode: OpenPseudo P1 P2 P3 * * ** @@ -53982,40 +53908,34 @@ ** ** P3 is the number of fields in the records that will be stored by ** the pseudo-table. */ case OP_OpenPseudo: { -#if 0 /* local variables moved into u.ba */ - int i; +#if 0 /* local variables moved into u.az */ VdbeCursor *pCx; -#endif /* local variables moved into u.ba */ - - u.ba.i = pOp->p1; - assert( u.ba.i>=0 ); - u.ba.pCx = allocateCursor(p, u.ba.i, pOp->p3, -1, 0); - if( u.ba.pCx==0 ) goto no_mem; - u.ba.pCx->nullRow = 1; - u.ba.pCx->pseudoTable = 1; - u.ba.pCx->ephemPseudoTable = (u8)pOp->p2; - u.ba.pCx->isTable = 1; - u.ba.pCx->isIndex = 0; +#endif /* local variables moved into u.az */ + + assert( pOp->p1>=0 ); + u.az.pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0); + if( u.az.pCx==0 ) goto no_mem; + u.az.pCx->nullRow = 1; + u.az.pCx->pseudoTable = 1; + u.az.pCx->ephemPseudoTable = (u8)pOp->p2; + u.az.pCx->isTable = 1; + u.az.pCx->isIndex = 0; break; } /* Opcode: Close P1 * * * * ** ** Close a cursor previously opened as P1. If P1 is not ** currently open, this instruction is a no-op. */ case OP_Close: { -#if 0 /* local variables moved into u.bb */ - int i; -#endif /* local variables moved into u.bb */ - u.bb.i = pOp->p1; - assert( u.bb.i>=0 && u.bb.i<p->nCursor ); - sqlite3VdbeFreeCursor(p, p->apCsr[u.bb.i]); - p->apCsr[u.bb.i] = 0; + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + sqlite3VdbeFreeCursor(p, p->apCsr[pOp->p1]); + p->apCsr[pOp->p1] = 0; break; } /* Opcode: SeekGe P1 P2 P3 P4 * ** @@ -54071,35 +53991,33 @@ */ case OP_SeekLt: /* jump, in3 */ case OP_SeekLe: /* jump, in3 */ case OP_SeekGe: /* jump, in3 */ case OP_SeekGt: { /* jump, in3 */ -#if 0 /* local variables moved into u.bc */ - int i; +#if 0 /* local variables moved into u.ba */ int res; int oc; VdbeCursor *pC; UnpackedRecord r; int nField; i64 iKey; /* The rowid we are to seek to */ -#endif /* local variables moved into u.bc */ - - u.bc.i = pOp->p1; - assert( u.bc.i>=0 && u.bc.i<p->nCursor ); +#endif /* local variables moved into u.ba */ + + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p2!=0 ); - u.bc.pC = p->apCsr[u.bc.i]; - assert( u.bc.pC!=0 ); - if( u.bc.pC->pCursor!=0 ){ - u.bc.oc = pOp->opcode; - u.bc.pC->nullRow = 0; - if( u.bc.pC->isTable ){ + u.ba.pC = p->apCsr[pOp->p1]; + assert( u.ba.pC!=0 ); + if( u.ba.pC->pCursor!=0 ){ + u.ba.oc = pOp->opcode; + u.ba.pC->nullRow = 0; + if( u.ba.pC->isTable ){ /* The input value in P3 might be of any type: integer, real, string, ** blob, or NULL. But it needs to be an integer before we can do ** the seek, so covert it. */ applyNumericAffinity(pIn3); - u.bc.iKey = sqlite3VdbeIntValue(pIn3); - u.bc.pC->rowidIsValid = 0; + u.ba.iKey = sqlite3VdbeIntValue(pIn3); + u.ba.pC->rowidIsValid = 0; /* If the P3 value could not be converted into an integer without ** loss of information, then special processing is required... */ if( (pIn3->flags & MEM_Int)==0 ){ if( (pIn3->flags & MEM_Real)==0 ){ @@ -54110,99 +54028,100 @@ } /* If we reach this point, then the P3 value must be a floating ** point number. */ assert( (pIn3->flags & MEM_Real)!=0 ); - if( u.bc.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.bc.iKey || pIn3->r>0) ){ - /* The P3 value is to large in magnitude to be expressed as an + if( u.ba.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.ba.iKey || pIn3->r>0) ){ + /* The P3 value is too large in magnitude to be expressed as an ** integer. */ - u.bc.res = 1; + u.ba.res = 1; if( pIn3->r<0 ){ - if( u.bc.oc==OP_SeekGt || u.bc.oc==OP_SeekGe ){ - rc = sqlite3BtreeFirst(u.bc.pC->pCursor, &u.bc.res); + if( u.ba.oc==OP_SeekGt || u.ba.oc==OP_SeekGe ){ + rc = sqlite3BtreeFirst(u.ba.pC->pCursor, &u.ba.res); if( rc!=SQLITE_OK ) goto abort_due_to_error; } }else{ - if( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekLe ){ - rc = sqlite3BtreeLast(u.bc.pC->pCursor, &u.bc.res); + if( u.ba.oc==OP_SeekLt || u.ba.oc==OP_SeekLe ){ + rc = sqlite3BtreeLast(u.ba.pC->pCursor, &u.ba.res); if( rc!=SQLITE_OK ) goto abort_due_to_error; } } - if( u.bc.res ){ + if( u.ba.res ){ pc = pOp->p2 - 1; } break; - }else if( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekGe ){ + }else if( u.ba.oc==OP_SeekLt || u.ba.oc==OP_SeekGe ){ /* Use the ceiling() function to convert real->int */ - if( pIn3->r > (double)u.bc.iKey ) u.bc.iKey++; + if( pIn3->r > (double)u.ba.iKey ) u.ba.iKey++; }else{ /* Use the floor() function to convert real->int */ - assert( u.bc.oc==OP_SeekLe || u.bc.oc==OP_SeekGt ); - if( pIn3->r < (double)u.bc.iKey ) u.bc.iKey--; - } - } - rc = sqlite3BtreeMovetoUnpacked(u.bc.pC->pCursor, 0, (u64)u.bc.iKey, 0, &u.bc.res); + assert( u.ba.oc==OP_SeekLe || u.ba.oc==OP_SeekGt ); + if( pIn3->r < (double)u.ba.iKey ) u.ba.iKey--; + } + } + rc = sqlite3BtreeMovetoUnpacked(u.ba.pC->pCursor, 0, (u64)u.ba.iKey, 0, &u.ba.res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } - if( u.bc.res==0 ){ - u.bc.pC->rowidIsValid = 1; - u.bc.pC->lastRowid = u.bc.iKey; - } - }else{ - u.bc.nField = pOp->p4.i; + if( u.ba.res==0 ){ + u.ba.pC->rowidIsValid = 1; + u.ba.pC->lastRowid = u.ba.iKey; + } + }else{ + u.ba.nField = pOp->p4.i; assert( pOp->p4type==P4_INT32 ); - assert( u.bc.nField>0 ); - u.bc.r.pKeyInfo = u.bc.pC->pKeyInfo; - u.bc.r.nField = (u16)u.bc.nField; - if( u.bc.oc==OP_SeekGt || u.bc.oc==OP_SeekLe ){ - u.bc.r.flags = UNPACKED_INCRKEY; - }else{ - u.bc.r.flags = 0; - } - u.bc.r.aMem = &p->aMem[pOp->p3]; - rc = sqlite3BtreeMovetoUnpacked(u.bc.pC->pCursor, &u.bc.r, 0, 0, &u.bc.res); + assert( u.ba.nField>0 ); + u.ba.r.pKeyInfo = u.ba.pC->pKeyInfo; + u.ba.r.nField = (u16)u.ba.nField; + if( u.ba.oc==OP_SeekGt || u.ba.oc==OP_SeekLe ){ + u.ba.r.flags = UNPACKED_INCRKEY; + }else{ + u.ba.r.flags = 0; + } + u.ba.r.aMem = &p->aMem[pOp->p3]; + rc = sqlite3BtreeMovetoUnpacked(u.ba.pC->pCursor, &u.ba.r, 0, 0, &u.ba.res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } - u.bc.pC->rowidIsValid = 0; - } - u.bc.pC->deferredMoveto = 0; - u.bc.pC->cacheStatus = CACHE_STALE; + u.ba.pC->rowidIsValid = 0; + } + u.ba.pC->deferredMoveto = 0; + u.ba.pC->cacheStatus = CACHE_STALE; #ifdef SQLITE_TEST sqlite3_search_count++; #endif - if( u.bc.oc==OP_SeekGe || u.bc.oc==OP_SeekGt ){ - if( u.bc.res<0 || (u.bc.res==0 && u.bc.oc==OP_SeekGt) ){ - rc = sqlite3BtreeNext(u.bc.pC->pCursor, &u.bc.res); + if( u.ba.oc==OP_SeekGe || u.ba.oc==OP_SeekGt ){ + if( u.ba.res<0 || (u.ba.res==0 && u.ba.oc==OP_SeekGt) ){ + rc = sqlite3BtreeNext(u.ba.pC->pCursor, &u.ba.res); if( rc!=SQLITE_OK ) goto abort_due_to_error; - u.bc.pC->rowidIsValid = 0; - }else{ - u.bc.res = 0; - } - }else{ - assert( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekLe ); - if( u.bc.res>0 || (u.bc.res==0 && u.bc.oc==OP_SeekLt) ){ - rc = sqlite3BtreePrevious(u.bc.pC->pCursor, &u.bc.res); + u.ba.pC->rowidIsValid = 0; + }else{ + u.ba.res = 0; + } + }else{ + assert( u.ba.oc==OP_SeekLt || u.ba.oc==OP_SeekLe ); + if( u.ba.res>0 || (u.ba.res==0 && u.ba.oc==OP_SeekLt) ){ + rc = sqlite3BtreePrevious(u.ba.pC->pCursor, &u.ba.res); if( rc!=SQLITE_OK ) goto abort_due_to_error; - u.bc.pC->rowidIsValid = 0; - }else{ - /* u.bc.res might be negative because the table is empty. Check to + u.ba.pC->rowidIsValid = 0; + }else{ + /* u.ba.res might be negative because the table is empty. Check to ** see if this is the case. */ - u.bc.res = sqlite3BtreeEof(u.bc.pC->pCursor); + u.ba.res = sqlite3BtreeEof(u.ba.pC->pCursor); } } assert( pOp->p2>0 ); - if( u.bc.res ){ + if( u.ba.res ){ pc = pOp->p2 - 1; } - }else if( !u.bc.pC->pseudoTable ){ + }else{ /* This happens when attempting to open the sqlite3_master table ** for read access returns SQLITE_EMPTY. In this case always ** take the jump (since there are no records in the table). */ + assert( u.ba.pC->pseudoTable==0 ); pc = pOp->p2 - 1; } break; } @@ -54214,25 +54133,23 @@ ** This is actually a deferred seek. Nothing actually happens until ** the cursor is used to read a record. That way, if no reads ** occur, no unnecessary I/O happens. */ case OP_Seek: { /* in2 */ -#if 0 /* local variables moved into u.bd */ - int i; - VdbeCursor *pC; -#endif /* local variables moved into u.bd */ - - u.bd.i = pOp->p1; - assert( u.bd.i>=0 && u.bd.i<p->nCursor ); - u.bd.pC = p->apCsr[u.bd.i]; - assert( u.bd.pC!=0 ); - if( u.bd.pC->pCursor!=0 ){ - assert( u.bd.pC->isTable ); - u.bd.pC->nullRow = 0; - u.bd.pC->movetoTarget = sqlite3VdbeIntValue(pIn2); - u.bd.pC->rowidIsValid = 0; - u.bd.pC->deferredMoveto = 1; +#if 0 /* local variables moved into u.bb */ + VdbeCursor *pC; +#endif /* local variables moved into u.bb */ + + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + u.bb.pC = p->apCsr[pOp->p1]; + assert( u.bb.pC!=0 ); + if( ALWAYS(u.bb.pC->pCursor!=0) ){ + assert( u.bb.pC->isTable ); + u.bb.pC->nullRow = 0; + u.bb.pC->movetoTarget = sqlite3VdbeIntValue(pIn2); + u.bb.pC->rowidIsValid = 0; + u.bb.pC->deferredMoveto = 1; } break; } @@ -54266,48 +54183,47 @@ ** ** See also: Found, NotExists, IsUnique */ case OP_NotFound: /* jump, in3 */ case OP_Found: { /* jump, in3 */ -#if 0 /* local variables moved into u.be */ - int i; +#if 0 /* local variables moved into u.bc */ int alreadyExists; VdbeCursor *pC; int res; UnpackedRecord *pIdxKey; char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7]; -#endif /* local variables moved into u.be */ - - u.be.i = pOp->p1; - u.be.alreadyExists = 0; - assert( u.be.i>=0 && u.be.i<p->nCursor ); - assert( p->apCsr[u.be.i]!=0 ); - if( (u.be.pC = p->apCsr[u.be.i])->pCursor!=0 ){ - - assert( u.be.pC->isTable==0 ); +#endif /* local variables moved into u.bc */ + + u.bc.alreadyExists = 0; + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + u.bc.pC = p->apCsr[pOp->p1]; + assert( u.bc.pC!=0 ); + if( ALWAYS(u.bc.pC->pCursor!=0) ){ + + assert( u.bc.pC->isTable==0 ); assert( pIn3->flags & MEM_Blob ); - u.be.pIdxKey = sqlite3VdbeRecordUnpack(u.be.pC->pKeyInfo, pIn3->n, pIn3->z, - u.be.aTempRec, sizeof(u.be.aTempRec)); - if( u.be.pIdxKey==0 ){ + u.bc.pIdxKey = sqlite3VdbeRecordUnpack(u.bc.pC->pKeyInfo, pIn3->n, pIn3->z, + u.bc.aTempRec, sizeof(u.bc.aTempRec)); + if( u.bc.pIdxKey==0 ){ goto no_mem; } if( pOp->opcode==OP_Found ){ - u.be.pIdxKey->flags |= UNPACKED_PREFIX_MATCH; - } - rc = sqlite3BtreeMovetoUnpacked(u.be.pC->pCursor, u.be.pIdxKey, 0, 0, &u.be.res); - sqlite3VdbeDeleteUnpackedRecord(u.be.pIdxKey); + u.bc.pIdxKey->flags |= UNPACKED_PREFIX_MATCH; + } + rc = sqlite3BtreeMovetoUnpacked(u.bc.pC->pCursor, u.bc.pIdxKey, 0, 0, &u.bc.res); + sqlite3VdbeDeleteUnpackedRecord(u.bc.pIdxKey); if( rc!=SQLITE_OK ){ break; } - u.be.alreadyExists = (u.be.res==0); - u.be.pC->deferredMoveto = 0; - u.be.pC->cacheStatus = CACHE_STALE; + u.bc.alreadyExists = (u.bc.res==0); + u.bc.pC->deferredMoveto = 0; + u.bc.pC->cacheStatus = CACHE_STALE; } if( pOp->opcode==OP_Found ){ - if( u.be.alreadyExists ) pc = pOp->p2 - 1; - }else{ - if( !u.be.alreadyExists ) pc = pOp->p2 - 1; + if( u.bc.alreadyExists ) pc = pOp->p2 - 1; + }else{ + if( !u.bc.alreadyExists ) pc = pOp->p2 - 1; } break; } /* Opcode: IsUnique P1 P2 P3 P4 * @@ -54334,63 +54250,63 @@ ** instruction. ** ** See also: NotFound, NotExists, Found */ case OP_IsUnique: { /* jump, in3 */ -#if 0 /* local variables moved into u.bf */ +#if 0 /* local variables moved into u.bd */ u16 ii; VdbeCursor *pCx; BtCursor *pCrsr; u16 nField; Mem *aMem; UnpackedRecord r; /* B-Tree index search key */ i64 R; /* Rowid stored in register P3 */ -#endif /* local variables moved into u.bf */ - - u.bf.aMem = &p->aMem[pOp->p4.i]; +#endif /* local variables moved into u.bd */ + + u.bd.aMem = &p->aMem[pOp->p4.i]; /* Assert that the values of parameters P1 and P4 are in range. */ assert( pOp->p4type==P4_INT32 ); assert( pOp->p4.i>0 && pOp->p4.i<=p->nMem ); assert( pOp->p1>=0 && pOp->p1<p->nCursor ); /* Find the index cursor. */ - u.bf.pCx = p->apCsr[pOp->p1]; - assert( u.bf.pCx->deferredMoveto==0 ); - u.bf.pCx->seekResult = 0; - u.bf.pCx->cacheStatus = CACHE_STALE; - u.bf.pCrsr = u.bf.pCx->pCursor; + u.bd.pCx = p->apCsr[pOp->p1]; + assert( u.bd.pCx->deferredMoveto==0 ); + u.bd.pCx->seekResult = 0; + u.bd.pCx->cacheStatus = CACHE_STALE; + u.bd.pCrsr = u.bd.pCx->pCursor; /* If any of the values are NULL, take the jump. */ - u.bf.nField = u.bf.pCx->pKeyInfo->nField; - for(u.bf.ii=0; u.bf.ii<u.bf.nField; u.bf.ii++){ - if( u.bf.aMem[u.bf.ii].flags & MEM_Null ){ + u.bd.nField = u.bd.pCx->pKeyInfo->nField; + for(u.bd.ii=0; u.bd.ii<u.bd.nField; u.bd.ii++){ + if( u.bd.aMem[u.bd.ii].flags & MEM_Null ){ pc = pOp->p2 - 1; - u.bf.pCrsr = 0; - break; - } - } - assert( (u.bf.aMem[u.bf.nField].flags & MEM_Null)==0 ); - - if( u.bf.pCrsr!=0 ){ + u.bd.pCrsr = 0; + break; + } + } + assert( (u.bd.aMem[u.bd.nField].flags & MEM_Null)==0 ); + + if( u.bd.pCrsr!=0 ){ /* Populate the index search key. */ - u.bf.r.pKeyInfo = u.bf.pCx->pKeyInfo; - u.bf.r.nField = u.bf.nField + 1; - u.bf.r.flags = UNPACKED_PREFIX_SEARCH; - u.bf.r.aMem = u.bf.aMem; - - /* Extract the value of u.bf.R from register P3. */ + u.bd.r.pKeyInfo = u.bd.pCx->pKeyInfo; + u.bd.r.nField = u.bd.nField + 1; + u.bd.r.flags = UNPACKED_PREFIX_SEARCH; + u.bd.r.aMem = u.bd.aMem; + + /* Extract the value of u.bd.R from register P3. */ sqlite3VdbeMemIntegerify(pIn3); - u.bf.R = pIn3->u.i; + u.bd.R = pIn3->u.i; /* Search the B-Tree index. If no conflicting record is found, jump ** to P2. Otherwise, copy the rowid of the conflicting record to ** register P3 and fall through to the next instruction. */ - rc = sqlite3BtreeMovetoUnpacked(u.bf.pCrsr, &u.bf.r, 0, 0, &u.bf.pCx->seekResult); - if( (u.bf.r.flags & UNPACKED_PREFIX_SEARCH) || u.bf.r.rowid==u.bf.R ){ + rc = sqlite3BtreeMovetoUnpacked(u.bd.pCrsr, &u.bd.r, 0, 0, &u.bd.pCx->seekResult); + if( (u.bd.r.flags & UNPACKED_PREFIX_SEARCH) || u.bd.r.rowid==u.bd.R ){ pc = pOp->p2 - 1; }else{ - pIn3->u.i = u.bf.r.rowid; + pIn3->u.i = u.bd.r.rowid; } } break; } @@ -54407,45 +54323,46 @@ ** P1 is an index. ** ** See also: Found, NotFound, IsUnique */ case OP_NotExists: { /* jump, in3 */ -#if 0 /* local variables moved into u.bg */ - int i; +#if 0 /* local variables moved into u.be */ VdbeCursor *pC; BtCursor *pCrsr; int res; u64 iKey; -#endif /* local variables moved into u.bg */ - - u.bg.i = pOp->p1; - assert( u.bg.i>=0 && u.bg.i<p->nCursor ); - assert( p->apCsr[u.bg.i]!=0 ); - if( (u.bg.pCrsr = (u.bg.pC = p->apCsr[u.bg.i])->pCursor)!=0 ){ - u.bg.res = 0; - assert( pIn3->flags & MEM_Int ); - assert( p->apCsr[u.bg.i]->isTable ); - u.bg.iKey = intToKey(pIn3->u.i); - rc = sqlite3BtreeMovetoUnpacked(u.bg.pCrsr, 0, u.bg.iKey, 0, &u.bg.res); - u.bg.pC->lastRowid = pIn3->u.i; - u.bg.pC->rowidIsValid = u.bg.res==0 ?1:0; - u.bg.pC->nullRow = 0; - u.bg.pC->cacheStatus = CACHE_STALE; - u.bg.pC->deferredMoveto = 0; - if( u.bg.res!=0 ){ +#endif /* local variables moved into u.be */ + + assert( pIn3->flags & MEM_Int ); + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + u.be.pC = p->apCsr[pOp->p1]; + assert( u.be.pC!=0 ); + assert( u.be.pC->isTable ); + u.be.pCrsr = u.be.pC->pCursor; + if( u.be.pCrsr!=0 ){ + u.be.res = 0; + u.be.iKey = pIn3->u.i; + rc = sqlite3BtreeMovetoUnpacked(u.be.pCrsr, 0, u.be.iKey, 0, &u.be.res); + u.be.pC->lastRowid = pIn3->u.i; + u.be.pC->rowidIsValid = u.be.res==0 ?1:0; + u.be.pC->nullRow = 0; + u.be.pC->cacheStatus = CACHE_STALE; + u.be.pC->deferredMoveto = 0; + if( u.be.res!=0 ){ pc = pOp->p2 - 1; - assert( u.bg.pC->rowidIsValid==0 ); - } - u.bg.pC->seekResult = u.bg.res; - }else if( !u.bg.pC->pseudoTable ){ + assert( u.be.pC->rowidIsValid==0 ); + } + u.be.pC->seekResult = u.be.res; + }else{ /* This happens when an attempt to open a read cursor on the ** sqlite_master table returns SQLITE_EMPTY. */ - assert( u.bg.pC->isTable ); + assert( !u.be.pC->pseudoTable ); + assert( u.be.pC->isTable ); pc = pOp->p2 - 1; - assert( u.bg.pC->rowidIsValid==0 ); - u.bg.pC->seekResult = 0; + assert( u.be.pC->rowidIsValid==0 ); + u.be.pC->seekResult = 0; } break; } /* Opcode: Sequence P1 P2 * * * @@ -54454,14 +54371,13 @@ ** Write the sequence number into register P2. ** The sequence number on the cursor is incremented after this ** instruction. */ case OP_Sequence: { /* out2-prerelease */ - int i = pOp->p1; - assert( i>=0 && i<p->nCursor ); - assert( p->apCsr[i]!=0 ); - pOut->u.i = p->apCsr[i]->seqCount++; + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + assert( p->apCsr[pOp->p1]!=0 ); + pOut->u.i = p->apCsr[pOp->p1]->seqCount++; MemSetTypeFlag(pOut, MEM_Int); break; } @@ -54478,28 +54394,24 @@ ** error is generated. The P3 register is updated with the generated ** record number. This P3 mechanism is used to help implement the ** AUTOINCREMENT feature. */ case OP_NewRowid: { /* out2-prerelease */ -#if 0 /* local variables moved into u.bh */ - int i; - i64 v; - VdbeCursor *pC; - int res; - int rx; - int cnt; - i64 x; - Mem *pMem; -#endif /* local variables moved into u.bh */ - - u.bh.i = pOp->p1; - u.bh.v = 0; - u.bh.res = 0; - u.bh.rx = SQLITE_OK; - assert( u.bh.i>=0 && u.bh.i<p->nCursor ); - assert( p->apCsr[u.bh.i]!=0 ); - if( (u.bh.pC = p->apCsr[u.bh.i])->pCursor==0 ){ +#if 0 /* local variables moved into u.bf */ + i64 v; /* The new rowid */ + VdbeCursor *pC; /* Cursor of table to get the new rowid */ + int res; /* Result of an sqlite3BtreeLast() */ + int cnt; /* Counter to limit the number of searches */ + Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ +#endif /* local variables moved into u.bf */ + + u.bf.v = 0; + u.bf.res = 0; + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + u.bf.pC = p->apCsr[pOp->p1]; + assert( u.bf.pC!=0 ); + if( NEVER(u.bf.pC->pCursor==0) ){ /* The zero initialization above is all that is needed */ }else{ /* The next rowid or record number (different terms for the same ** thing) is obtained in a two-step algorithm. ** @@ -54509,38 +54421,14 @@ ** probabilistic algorithm ** ** The second algorithm is to select a rowid at random and see if ** it already exists in the table. If it does not exist, we have ** succeeded. If the random rowid does exist, we select a new one - ** and try again, up to 1000 times. - ** - ** For a table with less than 2 billion entries, the probability - ** of not finding a unused rowid is about 1.0e-300. This is a - ** non-zero probability, but it is still vanishingly small and should - ** never cause a problem. You are much, much more likely to have a - ** hardware failure than for this algorithm to fail. - ** - ** The analysis in the previous paragraph assumes that you have a good - ** source of random numbers. Is a library function like lrand48() - ** good enough? Maybe. Maybe not. It's hard to know whether there - ** might be subtle bugs is some implementations of lrand48() that - ** could cause problems. To avoid uncertainty, SQLite uses its own - ** random number generator based on the RC4 algorithm. - ** - ** To promote locality of reference for repetitive inserts, the - ** first few attempts at choosing a random rowid pick values just a little - ** larger than the previous rowid. This has been shown experimentally - ** to double the speed of the COPY operation. - */ - u.bh.cnt = 0; - if( (sqlite3BtreeFlags(u.bh.pC->pCursor)&(BTREE_INTKEY|BTREE_ZERODATA)) != - BTREE_INTKEY ){ - rc = SQLITE_CORRUPT_BKPT; - goto abort_due_to_error; - } - assert( (sqlite3BtreeFlags(u.bh.pC->pCursor) & BTREE_INTKEY)!=0 ); - assert( (sqlite3BtreeFlags(u.bh.pC->pCursor) & BTREE_ZERODATA)==0 ); + ** and try again, up to 100 times. + */ + assert( u.bf.pC->isTable ); + u.bf.cnt = 0; #ifdef SQLITE_32BIT_ROWID # define MAX_ROWID 0x7fffffff #else /* Some compilers complain about constants of the form 0x7fffffffffffffff. @@ -54548,78 +54436,76 @@ ** to provide the constant while making all compilers happy. */ # define MAX_ROWID (i64)( (((u64)0x7fffffff)<<32) | (u64)0xffffffff ) #endif - if( !u.bh.pC->useRandomRowid ){ - u.bh.v = sqlite3BtreeGetCachedRowid(u.bh.pC->pCursor); - if( u.bh.v==0 ){ - rc = sqlite3BtreeLast(u.bh.pC->pCursor, &u.bh.res); + if( !u.bf.pC->useRandomRowid ){ + u.bf.v = sqlite3BtreeGetCachedRowid(u.bf.pC->pCursor); + if( u.bf.v==0 ){ + rc = sqlite3BtreeLast(u.bf.pC->pCursor, &u.bf.res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } - if( u.bh.res ){ - u.bh.v = 1; - }else{ - sqlite3BtreeKeySize(u.bh.pC->pCursor, &u.bh.v); - u.bh.v = keyToInt(u.bh.v); - if( u.bh.v==MAX_ROWID ){ - u.bh.pC->useRandomRowid = 1; + if( u.bf.res ){ + u.bf.v = 1; + }else{ + sqlite3BtreeKeySize(u.bf.pC->pCursor, &u.bf.v); + if( u.bf.v==MAX_ROWID ){ + u.bf.pC->useRandomRowid = 1; }else{ - u.bh.v++; + u.bf.v++; } } } #ifndef SQLITE_OMIT_AUTOINCREMENT if( pOp->p3 ){ assert( pOp->p3>0 && pOp->p3<=p->nMem ); /* P3 is a valid memory cell */ - u.bh.pMem = &p->aMem[pOp->p3]; - REGISTER_TRACE(pOp->p3, u.bh.pMem); - sqlite3VdbeMemIntegerify(u.bh.pMem); - assert( (u.bh.pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ - if( u.bh.pMem->u.i==MAX_ROWID || u.bh.pC->useRandomRowid ){ + u.bf.pMem = &p->aMem[pOp->p3]; + REGISTER_TRACE(pOp->p3, u.bf.pMem); + sqlite3VdbeMemIntegerify(u.bf.pMem); + assert( (u.bf.pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ + if( u.bf.pMem->u.i==MAX_ROWID || u.bf.pC->useRandomRowid ){ rc = SQLITE_FULL; goto abort_due_to_error; } - if( u.bh.v<u.bh.pMem->u.i+1 ){ - u.bh.v = u.bh.pMem->u.i + 1; - } - u.bh.pMem->u.i = u.bh.v; - } -#endif - - sqlite3BtreeSetCachedRowid(u.bh.pC->pCursor, u.bh.v<MAX_ROWID ? u.bh.v+1 : 0); - } - if( u.bh.pC->useRandomRowid ){ - assert( pOp->p3==0 ); /* SQLITE_FULL must have occurred prior to this */ - u.bh.v = db->priorNewRowid; - u.bh.cnt = 0; + if( u.bf.v<u.bf.pMem->u.i+1 ){ + u.bf.v = u.bf.pMem->u.i + 1; + } + u.bf.pMem->u.i = u.bf.v; + } +#endif + + sqlite3BtreeSetCachedRowid(u.bf.pC->pCursor, u.bf.v<MAX_ROWID ? u.bf.v+1 : 0); + } + if( u.bf.pC->useRandomRowid ){ + assert( pOp->p3==0 ); /* We cannot be in random rowid mode if this is + ** an AUTOINCREMENT table. */ + u.bf.v = db->priorNewRowid; + u.bf.cnt = 0; do{ - if( u.bh.cnt==0 && (u.bh.v&0xffffff)==u.bh.v ){ - u.bh.v++; - }else{ - sqlite3_randomness(sizeof(u.bh.v), &u.bh.v); - if( u.bh.cnt<5 ) u.bh.v &= 0xffffff; - } - if( u.bh.v==0 ) continue; - u.bh.x = intToKey(u.bh.v); - u.bh.rx = sqlite3BtreeMovetoUnpacked(u.bh.pC->pCursor, 0, (u64)u.bh.x, 0, &u.bh.res); - u.bh.cnt++; - }while( u.bh.cnt<100 && u.bh.rx==SQLITE_OK && u.bh.res==0 ); - db->priorNewRowid = u.bh.v; - if( u.bh.rx==SQLITE_OK && u.bh.res==0 ){ + if( u.bf.cnt==0 && (u.bf.v&0xffffff)==u.bf.v ){ + u.bf.v++; + }else{ + sqlite3_randomness(sizeof(u.bf.v), &u.bf.v); + if( u.bf.cnt<5 ) u.bf.v &= 0xffffff; + } + rc = sqlite3BtreeMovetoUnpacked(u.bf.pC->pCursor, 0, (u64)u.bf.v, 0, &u.bf.res); + u.bf.cnt++; + }while( u.bf.cnt<100 && rc==SQLITE_OK && u.bf.res==0 ); + db->priorNewRowid = u.bf.v; + if( rc==SQLITE_OK && u.bf.res==0 ){ rc = SQLITE_FULL; goto abort_due_to_error; } } - u.bh.pC->rowidIsValid = 0; - u.bh.pC->deferredMoveto = 0; - u.bh.pC->cacheStatus = CACHE_STALE; + u.bf.pC->rowidIsValid = 0; + u.bf.pC->deferredMoveto = 0; + u.bf.pC->cacheStatus = CACHE_STALE; } MemSetTypeFlag(pOut, MEM_Int); - pOut->u.i = u.bh.v; + pOut->u.i = u.bf.v; break; } /* Opcode: Insert P1 P2 P3 P4 P5 ** @@ -54646,91 +54532,89 @@ ** ** This instruction only works on tables. The equivalent instruction ** for indices is OP_IdxInsert. */ case OP_Insert: { -#if 0 /* local variables moved into u.bi */ +#if 0 /* local variables moved into u.bg */ Mem *pData; Mem *pKey; i64 iKey; /* The integer ROWID or key for the record to be inserted */ - int i; VdbeCursor *pC; int nZero; int seekResult; const char *zDb; const char *zTbl; int op; -#endif /* local variables moved into u.bi */ - - u.bi.pData = &p->aMem[pOp->p2]; - u.bi.pKey = &p->aMem[pOp->p3]; - u.bi.i = pOp->p1; - assert( u.bi.i>=0 && u.bi.i<p->nCursor ); - u.bi.pC = p->apCsr[u.bi.i]; - assert( u.bi.pC!=0 ); - assert( u.bi.pC->pCursor!=0 || u.bi.pC->pseudoTable ); - assert( u.bi.pKey->flags & MEM_Int ); - assert( u.bi.pC->isTable ); - REGISTER_TRACE(pOp->p2, u.bi.pData); - REGISTER_TRACE(pOp->p3, u.bi.pKey); - - u.bi.iKey = intToKey(u.bi.pKey->u.i); +#endif /* local variables moved into u.bg */ + + u.bg.pData = &p->aMem[pOp->p2]; + u.bg.pKey = &p->aMem[pOp->p3]; + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + u.bg.pC = p->apCsr[pOp->p1]; + assert( u.bg.pC!=0 ); + assert( u.bg.pC->pCursor!=0 || u.bg.pC->pseudoTable ); + assert( u.bg.pKey->flags & MEM_Int ); + assert( u.bg.pC->isTable ); + REGISTER_TRACE(pOp->p2, u.bg.pData); + REGISTER_TRACE(pOp->p3, u.bg.pKey); + + u.bg.iKey = u.bg.pKey->u.i; if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; - if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = u.bi.pKey->u.i; - if( u.bi.pData->flags & MEM_Null ){ - u.bi.pData->z = 0; - u.bi.pData->n = 0; - }else{ - assert( u.bi.pData->flags & (MEM_Blob|MEM_Str) ); - } - if( u.bi.pC->pseudoTable ){ - if( !u.bi.pC->ephemPseudoTable ){ - sqlite3DbFree(db, u.bi.pC->pData); - } - u.bi.pC->iKey = u.bi.iKey; - u.bi.pC->nData = u.bi.pData->n; - if( u.bi.pData->z==u.bi.pData->zMalloc || u.bi.pC->ephemPseudoTable ){ - u.bi.pC->pData = u.bi.pData->z; - if( !u.bi.pC->ephemPseudoTable ){ - u.bi.pData->flags &= ~MEM_Dyn; - u.bi.pData->flags |= MEM_Ephem; - u.bi.pData->zMalloc = 0; - } - }else{ - u.bi.pC->pData = sqlite3Malloc( u.bi.pC->nData+2 ); - if( !u.bi.pC->pData ) goto no_mem; - memcpy(u.bi.pC->pData, u.bi.pData->z, u.bi.pC->nData); - u.bi.pC->pData[u.bi.pC->nData] = 0; - u.bi.pC->pData[u.bi.pC->nData+1] = 0; - } - u.bi.pC->nullRow = 0; - }else{ - u.bi.seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bi.pC->seekResult : 0); - if( u.bi.pData->flags & MEM_Zero ){ - u.bi.nZero = u.bi.pData->u.nZero; - }else{ - u.bi.nZero = 0; - } - sqlite3BtreeSetCachedRowid(u.bi.pC->pCursor, 0); - rc = sqlite3BtreeInsert(u.bi.pC->pCursor, 0, u.bi.iKey, - u.bi.pData->z, u.bi.pData->n, u.bi.nZero, - pOp->p5 & OPFLAG_APPEND, u.bi.seekResult - ); - } - - u.bi.pC->rowidIsValid = 0; - u.bi.pC->deferredMoveto = 0; - u.bi.pC->cacheStatus = CACHE_STALE; + if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = u.bg.pKey->u.i; + if( u.bg.pData->flags & MEM_Null ){ + u.bg.pData->z = 0; + u.bg.pData->n = 0; + }else{ + assert( u.bg.pData->flags & (MEM_Blob|MEM_Str) ); + } + if( u.bg.pC->pseudoTable ){ + if( !u.bg.pC->ephemPseudoTable ){ + sqlite3DbFree(db, u.bg.pC->pData); + } + u.bg.pC->iKey = u.bg.iKey; + u.bg.pC->nData = u.bg.pData->n; + if( u.bg.pC->ephemPseudoTable || u.bg.pData->z==u.bg.pData->zMalloc ){ + u.bg.pC->pData = u.bg.pData->z; + if( !u.bg.pC->ephemPseudoTable ){ + u.bg.pData->flags &= ~MEM_Dyn; + u.bg.pData->flags |= MEM_Ephem; + u.bg.pData->zMalloc = 0; + } + }else{ + u.bg.pC->pData = sqlite3Malloc( u.bg.pC->nData+2 ); + if( !u.bg.pC->pData ) goto no_mem; + memcpy(u.bg.pC->pData, u.bg.pData->z, u.bg.pC->nData); + u.bg.pC->pData[u.bg.pC->nData] = 0; + u.bg.pC->pData[u.bg.pC->nData+1] = 0; + } + u.bg.pC->nullRow = 0; + }else{ + u.bg.seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bg.pC->seekResult : 0); + if( u.bg.pData->flags & MEM_Zero ){ + u.bg.nZero = u.bg.pData->u.nZero; + }else{ + u.bg.nZero = 0; + } + sqlite3BtreeSetCachedRowid(u.bg.pC->pCursor, 0); + rc = sqlite3BtreeInsert(u.bg.pC->pCursor, 0, u.bg.iKey, + u.bg.pData->z, u.bg.pData->n, u.bg.nZero, + pOp->p5 & OPFLAG_APPEND, u.bg.seekResult + ); + } + + u.bg.pC->rowidIsValid = 0; + u.bg.pC->deferredMoveto = 0; + u.bg.pC->cacheStatus = CACHE_STALE; /* Invoke the update-hook if required. */ if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ - u.bi.zDb = db->aDb[u.bi.pC->iDb].zName; - u.bi.zTbl = pOp->p4.z; - u.bi.op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); - assert( u.bi.pC->isTable ); - db->xUpdateCallback(db->pUpdateArg, u.bi.op, u.bi.zDb, u.bi.zTbl, u.bi.iKey); - assert( u.bi.pC->iDb>=0 ); + u.bg.zDb = db->aDb[u.bg.pC->iDb].zName; + u.bg.zTbl = pOp->p4.z; + u.bg.op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); + assert( u.bg.pC->isTable ); + db->xUpdateCallback(db->pUpdateArg, u.bg.op, u.bg.zDb, u.bg.zTbl, u.bg.iKey); + assert( u.bg.pC->iDb>=0 ); } break; } /* Opcode: Delete P1 P2 * P4 * @@ -54752,44 +54636,51 @@ ** pointing to. The update hook will be invoked, if it exists. ** If P4 is not NULL then the P1 cursor must have been positioned ** using OP_NotFound prior to invoking this opcode. */ case OP_Delete: { -#if 0 /* local variables moved into u.bj */ - int i; +#if 0 /* local variables moved into u.bh */ i64 iKey; VdbeCursor *pC; -#endif /* local variables moved into u.bj */ - - u.bj.i = pOp->p1; - u.bj.iKey = 0; - assert( u.bj.i>=0 && u.bj.i<p->nCursor ); - u.bj.pC = p->apCsr[u.bj.i]; - assert( u.bj.pC!=0 ); - assert( u.bj.pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ - - /* If the update-hook will be invoked, set u.bj.iKey to the rowid of the +#endif /* local variables moved into u.bh */ + + u.bh.iKey = 0; + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + u.bh.pC = p->apCsr[pOp->p1]; + assert( u.bh.pC!=0 ); + assert( u.bh.pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ + + /* If the update-hook will be invoked, set u.bh.iKey to the rowid of the ** row being deleted. */ if( db->xUpdateCallback && pOp->p4.z ){ - assert( u.bj.pC->isTable ); - assert( u.bj.pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */ - u.bj.iKey = u.bj.pC->lastRowid; - } - - rc = sqlite3VdbeCursorMoveto(u.bj.pC); - if( rc ) goto abort_due_to_error; - sqlite3BtreeSetCachedRowid(u.bj.pC->pCursor, 0); - rc = sqlite3BtreeDelete(u.bj.pC->pCursor); - u.bj.pC->cacheStatus = CACHE_STALE; + assert( u.bh.pC->isTable ); + assert( u.bh.pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */ + u.bh.iKey = u.bh.pC->lastRowid; + } + + /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or + ** OP_Column on the same table without any intervening operations that + ** might move or invalidate the cursor. Hence cursor u.bh.pC is always pointing + ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation + ** below is always a no-op and cannot fail. We will run it anyhow, though, + ** to guard against future changes to the code generator. + **/ + assert( u.bh.pC->deferredMoveto==0 ); + rc = sqlite3VdbeCursorMoveto(u.bh.pC); + if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; + + sqlite3BtreeSetCachedRowid(u.bh.pC->pCursor, 0); + rc = sqlite3BtreeDelete(u.bh.pC->pCursor); + u.bh.pC->cacheStatus = CACHE_STALE; /* Invoke the update-hook if required. */ if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ - const char *zDb = db->aDb[u.bj.pC->iDb].zName; + const char *zDb = db->aDb[u.bh.pC->iDb].zName; const char *zTbl = pOp->p4.z; - db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, u.bj.iKey); - assert( u.bj.pC->iDb>=0 ); + db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, u.bh.iKey); + assert( u.bh.pC->iDb>=0 ); } if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++; break; } @@ -54828,55 +54719,61 @@ ** If the P1 cursor must be pointing to a valid row (not a NULL row) ** of a real table, not a pseudo-table. */ case OP_RowKey: case OP_RowData: { -#if 0 /* local variables moved into u.bk */ - int i; +#if 0 /* local variables moved into u.bi */ VdbeCursor *pC; BtCursor *pCrsr; u32 n; i64 n64; -#endif /* local variables moved into u.bk */ - - u.bk.i = pOp->p1; +#endif /* local variables moved into u.bi */ + pOut = &p->aMem[pOp->p2]; /* Note that RowKey and RowData are really exactly the same instruction */ - assert( u.bk.i>=0 && u.bk.i<p->nCursor ); - u.bk.pC = p->apCsr[u.bk.i]; - assert( u.bk.pC->isTable || pOp->opcode==OP_RowKey ); - assert( u.bk.pC->isIndex || pOp->opcode==OP_RowData ); - assert( u.bk.pC!=0 ); - assert( u.bk.pC->nullRow==0 ); - assert( u.bk.pC->pseudoTable==0 ); - assert( u.bk.pC->pCursor!=0 ); - u.bk.pCrsr = u.bk.pC->pCursor; - rc = sqlite3VdbeCursorMoveto(u.bk.pC); - if( rc ) goto abort_due_to_error; - if( u.bk.pC->isIndex ){ - assert( !u.bk.pC->isTable ); - sqlite3BtreeKeySize(u.bk.pCrsr, &u.bk.n64); - if( u.bk.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + u.bi.pC = p->apCsr[pOp->p1]; + assert( u.bi.pC->isTable || pOp->opcode==OP_RowKey ); + assert( u.bi.pC->isIndex || pOp->opcode==OP_RowData ); + assert( u.bi.pC!=0 ); + assert( u.bi.pC->nullRow==0 ); + assert( u.bi.pC->pseudoTable==0 ); + assert( u.bi.pC->pCursor!=0 ); + u.bi.pCrsr = u.bi.pC->pCursor; + + /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or + ** OP_Rewind/Op_Next with no intervening instructions that might invalidate + ** the cursor. Hence the following sqlite3VdbeCursorMoveto() call is always + ** a no-op and can never fail. But we leave it in place as a safety. + */ + assert( u.bi.pC->deferredMoveto==0 ); + rc = sqlite3VdbeCursorMoveto(u.bi.pC); + if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; + + if( u.bi.pC->isIndex ){ + assert( !u.bi.pC->isTable ); + sqlite3BtreeKeySize(u.bi.pCrsr, &u.bi.n64); + if( u.bi.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } - u.bk.n = (u32)u.bk.n64; - }else{ - sqlite3BtreeDataSize(u.bk.pCrsr, &u.bk.n); - if( u.bk.n>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + u.bi.n = (u32)u.bi.n64; + }else{ + sqlite3BtreeDataSize(u.bi.pCrsr, &u.bi.n); + if( u.bi.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } } - if( sqlite3VdbeMemGrow(pOut, u.bk.n, 0) ){ + if( sqlite3VdbeMemGrow(pOut, u.bi.n, 0) ){ goto no_mem; } - pOut->n = u.bk.n; + pOut->n = u.bi.n; MemSetTypeFlag(pOut, MEM_Blob); - if( u.bk.pC->isIndex ){ - rc = sqlite3BtreeKey(u.bk.pCrsr, 0, u.bk.n, pOut->z); - }else{ - rc = sqlite3BtreeData(u.bk.pCrsr, 0, u.bk.n, pOut->z); + if( u.bi.pC->isIndex ){ + rc = sqlite3BtreeKey(u.bi.pCrsr, 0, u.bi.n, pOut->z); + }else{ + rc = sqlite3BtreeData(u.bi.pCrsr, 0, u.bi.n, pOut->z); } pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */ UPDATE_MAX_BLOBSIZE(pOut); break; } @@ -54889,53 +54786,50 @@ ** P1 can be either an ordinary table or a virtual table. There used to ** be a separate OP_VRowid opcode for use with virtual tables, but this ** one opcode now works for both table types. */ case OP_Rowid: { /* out2-prerelease */ -#if 0 /* local variables moved into u.bl */ - int i; +#if 0 /* local variables moved into u.bj */ VdbeCursor *pC; i64 v; sqlite3_vtab *pVtab; const sqlite3_module *pModule; -#endif /* local variables moved into u.bl */ - - u.bl.i = pOp->p1; - assert( u.bl.i>=0 && u.bl.i<p->nCursor ); - u.bl.pC = p->apCsr[u.bl.i]; - assert( u.bl.pC!=0 ); - if( u.bl.pC->nullRow ){ +#endif /* local variables moved into u.bj */ + + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + u.bj.pC = p->apCsr[pOp->p1]; + assert( u.bj.pC!=0 ); + if( u.bj.pC->nullRow ){ /* Do nothing so that reg[P2] remains NULL */ break; - }else if( u.bl.pC->deferredMoveto ){ - u.bl.v = u.bl.pC->movetoTarget; - }else if( u.bl.pC->pseudoTable ){ - u.bl.v = keyToInt(u.bl.pC->iKey); -#ifndef SQLITE_OMIT_VIRTUALTABLE - }else if( u.bl.pC->pVtabCursor ){ - u.bl.pVtab = u.bl.pC->pVtabCursor->pVtab; - u.bl.pModule = u.bl.pVtab->pModule; - assert( u.bl.pModule->xRowid ); + }else if( u.bj.pC->deferredMoveto ){ + u.bj.v = u.bj.pC->movetoTarget; + }else if( u.bj.pC->pseudoTable ){ + u.bj.v = u.bj.pC->iKey; +#ifndef SQLITE_OMIT_VIRTUALTABLE + }else if( u.bj.pC->pVtabCursor ){ + u.bj.pVtab = u.bj.pC->pVtabCursor->pVtab; + u.bj.pModule = u.bj.pVtab->pModule; + assert( u.bj.pModule->xRowid ); if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; - rc = u.bl.pModule->xRowid(u.bl.pC->pVtabCursor, &u.bl.v); + rc = u.bj.pModule->xRowid(u.bj.pC->pVtabCursor, &u.bj.v); sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = u.bl.pVtab->zErrMsg; - u.bl.pVtab->zErrMsg = 0; + p->zErrMsg = u.bj.pVtab->zErrMsg; + u.bj.pVtab->zErrMsg = 0; if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; #endif /* SQLITE_OMIT_VIRTUALTABLE */ }else{ - rc = sqlite3VdbeCursorMoveto(u.bl.pC); + rc = sqlite3VdbeCursorMoveto(u.bj.pC); if( rc ) goto abort_due_to_error; - if( u.bl.pC->rowidIsValid ){ - u.bl.v = u.bl.pC->lastRowid; - }else{ - assert( u.bl.pC->pCursor!=0 ); - sqlite3BtreeKeySize(u.bl.pC->pCursor, &u.bl.v); - u.bl.v = keyToInt(u.bl.v); - } - } - pOut->u.i = u.bl.v; + if( u.bj.pC->rowidIsValid ){ + u.bj.v = u.bj.pC->lastRowid; + }else{ + assert( u.bj.pC->pCursor!=0 ); + sqlite3BtreeKeySize(u.bj.pC->pCursor, &u.bj.v); + } + } + pOut->u.i = u.bj.v; MemSetTypeFlag(pOut, MEM_Int); break; } /* Opcode: NullRow P1 * * * * @@ -54943,23 +54837,21 @@ ** Move the cursor P1 to a null row. Any OP_Column operations ** that occur while the cursor is on the null row will always ** write a NULL. */ case OP_NullRow: { -#if 0 /* local variables moved into u.bm */ - int i; +#if 0 /* local variables moved into u.bk */ VdbeCursor *pC; -#endif /* local variables moved into u.bm */ - - u.bm.i = pOp->p1; - assert( u.bm.i>=0 && u.bm.i<p->nCursor ); - u.bm.pC = p->apCsr[u.bm.i]; - assert( u.bm.pC!=0 ); - u.bm.pC->nullRow = 1; - u.bm.pC->rowidIsValid = 0; - if( u.bm.pC->pCursor ){ - sqlite3BtreeClearCursor(u.bm.pC->pCursor); +#endif /* local variables moved into u.bk */ + + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + u.bk.pC = p->apCsr[pOp->p1]; + assert( u.bk.pC!=0 ); + u.bk.pC->nullRow = 1; + u.bk.pC->rowidIsValid = 0; + if( u.bk.pC->pCursor ){ + sqlite3BtreeClearCursor(u.bk.pC->pCursor); } break; } /* Opcode: Last P1 P2 * * * @@ -54969,29 +54861,30 @@ ** If the table or index is empty and P2>0, then jump immediately to P2. ** If P2 is 0 or if the table or index is not empty, fall through ** to the following instruction. */ case OP_Last: { /* jump */ -#if 0 /* local variables moved into u.bn */ - int i; +#if 0 /* local variables moved into u.bl */ VdbeCursor *pC; BtCursor *pCrsr; int res; -#endif /* local variables moved into u.bn */ - - u.bn.i = pOp->p1; - assert( u.bn.i>=0 && u.bn.i<p->nCursor ); - u.bn.pC = p->apCsr[u.bn.i]; - assert( u.bn.pC!=0 ); - u.bn.pCrsr = u.bn.pC->pCursor; - assert( u.bn.pCrsr!=0 ); - rc = sqlite3BtreeLast(u.bn.pCrsr, &u.bn.res); - u.bn.pC->nullRow = (u8)u.bn.res; - u.bn.pC->deferredMoveto = 0; - u.bn.pC->rowidIsValid = 0; - u.bn.pC->cacheStatus = CACHE_STALE; - if( u.bn.res && pOp->p2>0 ){ +#endif /* local variables moved into u.bl */ + + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + u.bl.pC = p->apCsr[pOp->p1]; + assert( u.bl.pC!=0 ); + u.bl.pCrsr = u.bl.pC->pCursor; + if( u.bl.pCrsr==0 ){ + u.bl.res = 1; + }else{ + rc = sqlite3BtreeLast(u.bl.pCrsr, &u.bl.res); + } + u.bl.pC->nullRow = (u8)u.bl.res; + u.bl.pC->deferredMoveto = 0; + u.bl.pC->rowidIsValid = 0; + u.bl.pC->cacheStatus = CACHE_STALE; + if( pOp->p2>0 && u.bl.res ){ pc = pOp->p2 - 1; } break; } @@ -55023,33 +54916,31 @@ ** If the table or index is empty and P2>0, then jump immediately to P2. ** If P2 is 0 or if the table or index is not empty, fall through ** to the following instruction. */ case OP_Rewind: { /* jump */ -#if 0 /* local variables moved into u.bo */ - int i; +#if 0 /* local variables moved into u.bm */ VdbeCursor *pC; BtCursor *pCrsr; int res; -#endif /* local variables moved into u.bo */ - - u.bo.i = pOp->p1; - assert( u.bo.i>=0 && u.bo.i<p->nCursor ); - u.bo.pC = p->apCsr[u.bo.i]; - assert( u.bo.pC!=0 ); - if( (u.bo.pCrsr = u.bo.pC->pCursor)!=0 ){ - rc = sqlite3BtreeFirst(u.bo.pCrsr, &u.bo.res); - u.bo.pC->atFirst = u.bo.res==0 ?1:0; - u.bo.pC->deferredMoveto = 0; - u.bo.pC->cacheStatus = CACHE_STALE; - u.bo.pC->rowidIsValid = 0; - }else{ - u.bo.res = 1; - } - u.bo.pC->nullRow = (u8)u.bo.res; +#endif /* local variables moved into u.bm */ + + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + u.bm.pC = p->apCsr[pOp->p1]; + assert( u.bm.pC!=0 ); + if( (u.bm.pCrsr = u.bm.pC->pCursor)!=0 ){ + rc = sqlite3BtreeFirst(u.bm.pCrsr, &u.bm.res); + u.bm.pC->atFirst = u.bm.res==0 ?1:0; + u.bm.pC->deferredMoveto = 0; + u.bm.pC->cacheStatus = CACHE_STALE; + u.bm.pC->rowidIsValid = 0; + }else{ + u.bm.res = 1; + } + u.bm.pC->nullRow = (u8)u.bm.res; assert( pOp->p2>0 && pOp->p2<p->nOp ); - if( u.bo.res ){ + if( u.bm.res ){ pc = pOp->p2 - 1; } break; } @@ -55073,38 +54964,41 @@ ** ** The P1 cursor must be for a real table, not a pseudo-table. */ case OP_Prev: /* jump */ case OP_Next: { /* jump */ -#if 0 /* local variables moved into u.bp */ +#if 0 /* local variables moved into u.bn */ VdbeCursor *pC; BtCursor *pCrsr; int res; -#endif /* local variables moved into u.bp */ +#endif /* local variables moved into u.bn */ CHECK_FOR_INTERRUPT; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); - u.bp.pC = p->apCsr[pOp->p1]; - if( u.bp.pC==0 ){ + u.bn.pC = p->apCsr[pOp->p1]; + if( u.bn.pC==0 ){ break; /* See ticket #2273 */ } - u.bp.pCrsr = u.bp.pC->pCursor; - assert( u.bp.pCrsr ); - u.bp.res = 1; - assert( u.bp.pC->deferredMoveto==0 ); - rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(u.bp.pCrsr, &u.bp.res) : - sqlite3BtreePrevious(u.bp.pCrsr, &u.bp.res); - u.bp.pC->nullRow = (u8)u.bp.res; - u.bp.pC->cacheStatus = CACHE_STALE; - if( u.bp.res==0 ){ + u.bn.pCrsr = u.bn.pC->pCursor; + if( u.bn.pCrsr==0 ){ + u.bn.pC->nullRow = 1; + break; + } + u.bn.res = 1; + assert( u.bn.pC->deferredMoveto==0 ); + rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(u.bn.pCrsr, &u.bn.res) : + sqlite3BtreePrevious(u.bn.pCrsr, &u.bn.res); + u.bn.pC->nullRow = (u8)u.bn.res; + u.bn.pC->cacheStatus = CACHE_STALE; + if( u.bn.res==0 ){ pc = pOp->p2 - 1; if( pOp->p5 ) p->aCounter[pOp->p5-1]++; #ifdef SQLITE_TEST sqlite3_search_count++; #endif } - u.bp.pC->rowidIsValid = 0; + u.bn.pC->rowidIsValid = 0; break; } /* Opcode: IdxInsert P1 P2 P3 * P5 ** @@ -55117,33 +55011,33 @@ ** ** This instruction only works for indices. The equivalent instruction ** for tables is OP_Insert. */ case OP_IdxInsert: { /* in2 */ -#if 0 /* local variables moved into u.bq */ - int i; +#if 0 /* local variables moved into u.bo */ VdbeCursor *pC; BtCursor *pCrsr; int nKey; const char *zKey; -#endif /* local variables moved into u.bq */ - - u.bq.i = pOp->p1; - assert( u.bq.i>=0 && u.bq.i<p->nCursor ); - assert( p->apCsr[u.bq.i]!=0 ); +#endif /* local variables moved into u.bo */ + + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + u.bo.pC = p->apCsr[pOp->p1]; + assert( u.bo.pC!=0 ); assert( pIn2->flags & MEM_Blob ); - if( (u.bq.pCrsr = (u.bq.pC = p->apCsr[u.bq.i])->pCursor)!=0 ){ - assert( u.bq.pC->isTable==0 ); + u.bo.pCrsr = u.bo.pC->pCursor; + if( ALWAYS(u.bo.pCrsr!=0) ){ + assert( u.bo.pC->isTable==0 ); rc = ExpandBlob(pIn2); if( rc==SQLITE_OK ){ - u.bq.nKey = pIn2->n; - u.bq.zKey = pIn2->z; - rc = sqlite3BtreeInsert(u.bq.pCrsr, u.bq.zKey, u.bq.nKey, "", 0, 0, pOp->p3, - ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bq.pC->seekResult : 0) - ); - assert( u.bq.pC->deferredMoveto==0 ); - u.bq.pC->cacheStatus = CACHE_STALE; + u.bo.nKey = pIn2->n; + u.bo.zKey = pIn2->z; + rc = sqlite3BtreeInsert(u.bo.pCrsr, u.bo.zKey, u.bo.nKey, "", 0, 0, pOp->p3, + ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bo.pC->seekResult : 0) + ); + assert( u.bo.pC->deferredMoveto==0 ); + u.bo.pC->cacheStatus = CACHE_STALE; } } break; } @@ -55152,34 +55046,34 @@ ** The content of P3 registers starting at register P2 form ** an unpacked index key. This opcode removes that entry from the ** index opened by cursor P1. */ case OP_IdxDelete: { -#if 0 /* local variables moved into u.br */ - int i; +#if 0 /* local variables moved into u.bp */ VdbeCursor *pC; BtCursor *pCrsr; -#endif /* local variables moved into u.br */ - - u.br.i = pOp->p1; + int res; + UnpackedRecord r; +#endif /* local variables moved into u.bp */ + assert( pOp->p3>0 ); assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem+1 ); - assert( u.br.i>=0 && u.br.i<p->nCursor ); - assert( p->apCsr[u.br.i]!=0 ); - if( (u.br.pCrsr = (u.br.pC = p->apCsr[u.br.i])->pCursor)!=0 ){ - int res; - UnpackedRecord r; - r.pKeyInfo = u.br.pC->pKeyInfo; - r.nField = (u16)pOp->p3; - r.flags = 0; - r.aMem = &p->aMem[pOp->p2]; - rc = sqlite3BtreeMovetoUnpacked(u.br.pCrsr, &r, 0, 0, &res); - if( rc==SQLITE_OK && res==0 ){ - rc = sqlite3BtreeDelete(u.br.pCrsr); - } - assert( u.br.pC->deferredMoveto==0 ); - u.br.pC->cacheStatus = CACHE_STALE; + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + u.bp.pC = p->apCsr[pOp->p1]; + assert( u.bp.pC!=0 ); + u.bp.pCrsr = u.bp.pC->pCursor; + if( ALWAYS(u.bp.pCrsr!=0) ){ + u.bp.r.pKeyInfo = u.bp.pC->pKeyInfo; + u.bp.r.nField = (u16)pOp->p3; + u.bp.r.flags = 0; + u.bp.r.aMem = &p->aMem[pOp->p2]; + rc = sqlite3BtreeMovetoUnpacked(u.bp.pCrsr, &u.bp.r, 0, 0, &u.bp.res); + if( rc==SQLITE_OK && u.bp.res==0 ){ + rc = sqlite3BtreeDelete(u.bp.pCrsr); + } + assert( u.bp.pC->deferredMoveto==0 ); + u.bp.pC->cacheStatus = CACHE_STALE; } break; } /* Opcode: IdxRowid P1 P2 * * * @@ -55189,32 +55083,32 @@ ** the rowid of the table entry to which this index entry points. ** ** See also: Rowid, MakeRecord. */ case OP_IdxRowid: { /* out2-prerelease */ -#if 0 /* local variables moved into u.bs */ - int i; +#if 0 /* local variables moved into u.bq */ BtCursor *pCrsr; VdbeCursor *pC; i64 rowid; -#endif /* local variables moved into u.bs */ - - u.bs.i = pOp->p1; - assert( u.bs.i>=0 && u.bs.i<p->nCursor ); - assert( p->apCsr[u.bs.i]!=0 ); - if( (u.bs.pCrsr = (u.bs.pC = p->apCsr[u.bs.i])->pCursor)!=0 ){ - rc = sqlite3VdbeCursorMoveto(u.bs.pC); - if( rc ) goto abort_due_to_error; - assert( u.bs.pC->deferredMoveto==0 ); - assert( u.bs.pC->isTable==0 ); - if( !u.bs.pC->nullRow ){ - rc = sqlite3VdbeIdxRowid(u.bs.pCrsr, &u.bs.rowid); +#endif /* local variables moved into u.bq */ + + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + u.bq.pC = p->apCsr[pOp->p1]; + assert( u.bq.pC!=0 ); + u.bq.pCrsr = u.bq.pC->pCursor; + if( ALWAYS(u.bq.pCrsr!=0) ){ + rc = sqlite3VdbeCursorMoveto(u.bq.pC); + if( NEVER(rc) ) goto abort_due_to_error; + assert( u.bq.pC->deferredMoveto==0 ); + assert( u.bq.pC->isTable==0 ); + if( !u.bq.pC->nullRow ){ + rc = sqlite3VdbeIdxRowid(db, u.bq.pCrsr, &u.bq.rowid); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } MemSetTypeFlag(pOut, MEM_Int); - pOut->u.i = u.bs.rowid; + pOut->u.i = u.bq.rowid; } } break; } @@ -55244,40 +55138,39 @@ ** If P5 is non-zero then the key value is increased by an epsilon prior ** to the comparison. This makes the opcode work like IdxLE. */ case OP_IdxLT: /* jump, in3 */ case OP_IdxGE: { /* jump, in3 */ -#if 0 /* local variables moved into u.bt */ - int i; +#if 0 /* local variables moved into u.br */ VdbeCursor *pC; int res; UnpackedRecord r; -#endif /* local variables moved into u.bt */ - - u.bt.i = pOp->p1; - assert( u.bt.i>=0 && u.bt.i<p->nCursor ); - assert( p->apCsr[u.bt.i]!=0 ); - if( (u.bt.pC = p->apCsr[u.bt.i])->pCursor!=0 ){ - assert( u.bt.pC->deferredMoveto==0 ); +#endif /* local variables moved into u.br */ + + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + u.br.pC = p->apCsr[pOp->p1]; + assert( u.br.pC!=0 ); + if( ALWAYS(u.br.pC->pCursor!=0) ){ + assert( u.br.pC->deferredMoveto==0 ); assert( pOp->p5==0 || pOp->p5==1 ); assert( pOp->p4type==P4_INT32 ); - u.bt.r.pKeyInfo = u.bt.pC->pKeyInfo; - u.bt.r.nField = (u16)pOp->p4.i; + u.br.r.pKeyInfo = u.br.pC->pKeyInfo; + u.br.r.nField = (u16)pOp->p4.i; if( pOp->p5 ){ - u.bt.r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID; - }else{ - u.bt.r.flags = UNPACKED_IGNORE_ROWID; - } - u.bt.r.aMem = &p->aMem[pOp->p3]; - rc = sqlite3VdbeIdxKeyCompare(u.bt.pC, &u.bt.r, &u.bt.res); + u.br.r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID; + }else{ + u.br.r.flags = UNPACKED_IGNORE_ROWID; + } + u.br.r.aMem = &p->aMem[pOp->p3]; + rc = sqlite3VdbeIdxKeyCompare(u.br.pC, &u.br.r, &u.br.res); if( pOp->opcode==OP_IdxLT ){ - u.bt.res = -u.bt.res; + u.br.res = -u.br.res; }else{ assert( pOp->opcode==OP_IdxGE ); - u.bt.res++; - } - if( u.bt.res>0 ){ + u.br.res++; + } + if( u.br.res>0 ){ pc = pOp->p2 - 1 ; } } break; } @@ -55301,39 +55194,39 @@ ** If AUTOVACUUM is disabled then a zero is stored in register P2. ** ** See also: Clear */ case OP_Destroy: { /* out2-prerelease */ -#if 0 /* local variables moved into u.bu */ +#if 0 /* local variables moved into u.bs */ int iMoved; int iCnt; Vdbe *pVdbe; int iDb; -#endif /* local variables moved into u.bu */ -#ifndef SQLITE_OMIT_VIRTUALTABLE - u.bu.iCnt = 0; - for(u.bu.pVdbe=db->pVdbe; u.bu.pVdbe; u.bu.pVdbe = u.bu.pVdbe->pNext){ - if( u.bu.pVdbe->magic==VDBE_MAGIC_RUN && u.bu.pVdbe->inVtabMethod<2 && u.bu.pVdbe->pc>=0 ){ - u.bu.iCnt++; - } - } -#else - u.bu.iCnt = db->activeVdbeCnt; -#endif - if( u.bu.iCnt>1 ){ +#endif /* local variables moved into u.bs */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + u.bs.iCnt = 0; + for(u.bs.pVdbe=db->pVdbe; u.bs.pVdbe; u.bs.pVdbe = u.bs.pVdbe->pNext){ + if( u.bs.pVdbe->magic==VDBE_MAGIC_RUN && u.bs.pVdbe->inVtabMethod<2 && u.bs.pVdbe->pc>=0 ){ + u.bs.iCnt++; + } + } +#else + u.bs.iCnt = db->activeVdbeCnt; +#endif + if( u.bs.iCnt>1 ){ rc = SQLITE_LOCKED; p->errorAction = OE_Abort; }else{ - u.bu.iDb = pOp->p3; - assert( u.bu.iCnt==1 ); - assert( (p->btreeMask & (1<<u.bu.iDb))!=0 ); - rc = sqlite3BtreeDropTable(db->aDb[u.bu.iDb].pBt, pOp->p1, &u.bu.iMoved); + u.bs.iDb = pOp->p3; + assert( u.bs.iCnt==1 ); + assert( (p->btreeMask & (1<<u.bs.iDb))!=0 ); + rc = sqlite3BtreeDropTable(db->aDb[u.bs.iDb].pBt, pOp->p1, &u.bs.iMoved); MemSetTypeFlag(pOut, MEM_Int); - pOut->u.i = u.bu.iMoved; + pOut->u.i = u.bs.iMoved; #ifndef SQLITE_OMIT_AUTOVACUUM - if( rc==SQLITE_OK && u.bu.iMoved!=0 ){ - sqlite3RootPageMoved(&db->aDb[u.bu.iDb], u.bu.iMoved, pOp->p1); + if( rc==SQLITE_OK && u.bs.iMoved!=0 ){ + sqlite3RootPageMoved(&db->aDb[u.bs.iDb], u.bs.iMoved, pOp->p1); } #endif } break; } @@ -55355,23 +55248,23 @@ ** also incremented by the number of rows in the table being cleared. ** ** See also: Destroy */ case OP_Clear: { -#if 0 /* local variables moved into u.bv */ +#if 0 /* local variables moved into u.bt */ int nChange; -#endif /* local variables moved into u.bv */ - - u.bv.nChange = 0; +#endif /* local variables moved into u.bt */ + + u.bt.nChange = 0; assert( (p->btreeMask & (1<<pOp->p2))!=0 ); rc = sqlite3BtreeClearTable( - db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bv.nChange : 0) + db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bt.nChange : 0) ); if( pOp->p3 ){ - p->nChange += u.bv.nChange; + p->nChange += u.bt.nChange; if( pOp->p3>0 ){ - p->aMem[pOp->p3].u.i += u.bv.nChange; + p->aMem[pOp->p3].u.i += u.bt.nChange; } } break; } @@ -55397,29 +55290,29 @@ ** ** See documentation on OP_CreateTable for additional information. */ case OP_CreateIndex: /* out2-prerelease */ case OP_CreateTable: { /* out2-prerelease */ -#if 0 /* local variables moved into u.bw */ +#if 0 /* local variables moved into u.bu */ int pgno; int flags; Db *pDb; -#endif /* local variables moved into u.bw */ - - u.bw.pgno = 0; +#endif /* local variables moved into u.bu */ + + u.bu.pgno = 0; assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( (p->btreeMask & (1<<pOp->p1))!=0 ); - u.bw.pDb = &db->aDb[pOp->p1]; - assert( u.bw.pDb->pBt!=0 ); + u.bu.pDb = &db->aDb[pOp->p1]; + assert( u.bu.pDb->pBt!=0 ); if( pOp->opcode==OP_CreateTable ){ - /* u.bw.flags = BTREE_INTKEY; */ - u.bw.flags = BTREE_LEAFDATA|BTREE_INTKEY; - }else{ - u.bw.flags = BTREE_ZERODATA; - } - rc = sqlite3BtreeCreateTable(u.bw.pDb->pBt, &u.bw.pgno, u.bw.flags); - pOut->u.i = u.bw.pgno; + /* u.bu.flags = BTREE_INTKEY; */ + u.bu.flags = BTREE_LEAFDATA|BTREE_INTKEY; + }else{ + u.bu.flags = BTREE_ZERODATA; + } + rc = sqlite3BtreeCreateTable(u.bu.pDb->pBt, &u.bu.pgno, u.bu.flags); + pOut->u.i = u.bu.pgno; MemSetTypeFlag(pOut, MEM_Int); break; } /* Opcode: ParseSchema P1 P2 * P4 * @@ -55433,62 +55326,62 @@ ** ** This opcode invokes the parser to create a new virtual machine, ** then runs the new virtual machine. It is thus a re-entrant opcode. */ case OP_ParseSchema: { -#if 0 /* local variables moved into u.bx */ +#if 0 /* local variables moved into u.bv */ int iDb; const char *zMaster; char *zSql; InitData initData; -#endif /* local variables moved into u.bx */ - - u.bx.iDb = pOp->p1; - assert( u.bx.iDb>=0 && u.bx.iDb<db->nDb ); +#endif /* local variables moved into u.bv */ + + u.bv.iDb = pOp->p1; + assert( u.bv.iDb>=0 && u.bv.iDb<db->nDb ); /* If pOp->p2 is 0, then this opcode is being executed to read a ** single row, for example the row corresponding to a new index ** created by this VDBE, from the sqlite_master table. It only ** does this if the corresponding in-memory schema is currently ** loaded. Otherwise, the new index definition can be loaded along ** with the rest of the schema when it is required. ** ** Although the mutex on the BtShared object that corresponds to - ** database u.bx.iDb (the database containing the sqlite_master table + ** database u.bv.iDb (the database containing the sqlite_master table ** read by this instruction) is currently held, it is necessary to ** obtain the mutexes on all attached databases before checking if - ** the schema of u.bx.iDb is loaded. This is because, at the start of + ** the schema of u.bv.iDb is loaded. This is because, at the start of ** the sqlite3_exec() call below, SQLite will invoke ** sqlite3BtreeEnterAll(). If all mutexes are not already held, the - ** u.bx.iDb mutex may be temporarily released to avoid deadlock. If + ** u.bv.iDb mutex may be temporarily released to avoid deadlock. If ** this happens, then some other thread may delete the in-memory - ** schema of database u.bx.iDb before the SQL statement runs. The schema + ** schema of database u.bv.iDb before the SQL statement runs. The schema ** will not be reloaded becuase the db->init.busy flag is set. This ** can result in a "no such table: sqlite_master" or "malformed ** database schema" error being returned to the user. */ - assert( sqlite3BtreeHoldsMutex(db->aDb[u.bx.iDb].pBt) ); + assert( sqlite3BtreeHoldsMutex(db->aDb[u.bv.iDb].pBt) ); sqlite3BtreeEnterAll(db); - if( pOp->p2 || DbHasProperty(db, u.bx.iDb, DB_SchemaLoaded) ){ - u.bx.zMaster = SCHEMA_TABLE(u.bx.iDb); - u.bx.initData.db = db; - u.bx.initData.iDb = pOp->p1; - u.bx.initData.pzErrMsg = &p->zErrMsg; - u.bx.zSql = sqlite3MPrintf(db, + if( pOp->p2 || ALWAYS(DbHasProperty(db, u.bv.iDb, DB_SchemaLoaded)) ){ + u.bv.zMaster = SCHEMA_TABLE(u.bv.iDb); + u.bv.initData.db = db; + u.bv.initData.iDb = pOp->p1; + u.bv.initData.pzErrMsg = &p->zErrMsg; + u.bv.zSql = sqlite3MPrintf(db, "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s", - db->aDb[u.bx.iDb].zName, u.bx.zMaster, pOp->p4.z); - if( u.bx.zSql==0 ){ + db->aDb[u.bv.iDb].zName, u.bv.zMaster, pOp->p4.z); + if( u.bv.zSql==0 ){ rc = SQLITE_NOMEM; }else{ (void)sqlite3SafetyOff(db); assert( db->init.busy==0 ); db->init.busy = 1; - u.bx.initData.rc = SQLITE_OK; + u.bv.initData.rc = SQLITE_OK; assert( !db->mallocFailed ); - rc = sqlite3_exec(db, u.bx.zSql, sqlite3InitCallback, &u.bx.initData, 0); - if( rc==SQLITE_OK ) rc = u.bx.initData.rc; - sqlite3DbFree(db, u.bx.zSql); + rc = sqlite3_exec(db, u.bv.zSql, sqlite3InitCallback, &u.bv.initData, 0); + if( rc==SQLITE_OK ) rc = u.bv.initData.rc; + sqlite3DbFree(db, u.bv.zSql); db->init.busy = 0; (void)sqlite3SafetyOn(db); } } sqlite3BtreeLeaveAll(db); @@ -55496,11 +55389,11 @@ goto no_mem; } break; } -#if !defined(SQLITE_OMIT_ANALYZE) && !defined(SQLITE_OMIT_PARSER) +#if !defined(SQLITE_OMIT_ANALYZE) /* Opcode: LoadAnalysis P1 * * * * ** ** Read the sqlite_stat1 table for database P1 and load the content ** of that table into the internal index hash table. This will cause ** the analysis to be used when preparing all subsequent queries. @@ -55508,11 +55401,11 @@ case OP_LoadAnalysis: { assert( pOp->p1>=0 && pOp->p1<db->nDb ); rc = sqlite3AnalysisLoad(db, pOp->p1); break; } -#endif /* !defined(SQLITE_OMIT_ANALYZE) && !defined(SQLITE_OMIT_PARSER) */ +#endif /* !defined(SQLITE_OMIT_ANALYZE) */ /* Opcode: DropTable P1 * * P4 * ** ** Remove the internal (in-memory) data structures that describe ** the table named P4 in database P1. This is called after a table @@ -55569,45 +55462,45 @@ ** file, not the main database file. ** ** This opcode is used to implement the integrity_check pragma. */ case OP_IntegrityCk: { -#if 0 /* local variables moved into u.by */ +#if 0 /* local variables moved into u.bw */ int nRoot; /* Number of tables to check. (Number of root pages.) */ int *aRoot; /* Array of rootpage numbers for tables to be checked */ int j; /* Loop counter */ int nErr; /* Number of errors reported */ char *z; /* Text of the error report */ Mem *pnErr; /* Register keeping track of errors remaining */ -#endif /* local variables moved into u.by */ - - u.by.nRoot = pOp->p2; - assert( u.by.nRoot>0 ); - u.by.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.by.nRoot+1) ); - if( u.by.aRoot==0 ) goto no_mem; +#endif /* local variables moved into u.bw */ + + u.bw.nRoot = pOp->p2; + assert( u.bw.nRoot>0 ); + u.bw.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.bw.nRoot+1) ); + if( u.bw.aRoot==0 ) goto no_mem; assert( pOp->p3>0 && pOp->p3<=p->nMem ); - u.by.pnErr = &p->aMem[pOp->p3]; - assert( (u.by.pnErr->flags & MEM_Int)!=0 ); - assert( (u.by.pnErr->flags & (MEM_Str|MEM_Blob))==0 ); + u.bw.pnErr = &p->aMem[pOp->p3]; + assert( (u.bw.pnErr->flags & MEM_Int)!=0 ); + assert( (u.bw.pnErr->flags & (MEM_Str|MEM_Blob))==0 ); pIn1 = &p->aMem[pOp->p1]; - for(u.by.j=0; u.by.j<u.by.nRoot; u.by.j++){ - u.by.aRoot[u.by.j] = (int)sqlite3VdbeIntValue(&pIn1[u.by.j]); - } - u.by.aRoot[u.by.j] = 0; + for(u.bw.j=0; u.bw.j<u.bw.nRoot; u.bw.j++){ + u.bw.aRoot[u.bw.j] = (int)sqlite3VdbeIntValue(&pIn1[u.bw.j]); + } + u.bw.aRoot[u.bw.j] = 0; assert( pOp->p5<db->nDb ); assert( (p->btreeMask & (1<<pOp->p5))!=0 ); - u.by.z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, u.by.aRoot, u.by.nRoot, - (int)u.by.pnErr->u.i, &u.by.nErr); - sqlite3DbFree(db, u.by.aRoot); - u.by.pnErr->u.i -= u.by.nErr; + u.bw.z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, u.bw.aRoot, u.bw.nRoot, + (int)u.bw.pnErr->u.i, &u.bw.nErr); + sqlite3DbFree(db, u.bw.aRoot); + u.bw.pnErr->u.i -= u.bw.nErr; sqlite3VdbeMemSetNull(pIn1); - if( u.by.nErr==0 ){ - assert( u.by.z==0 ); - }else if( u.by.z==0 ){ + if( u.bw.nErr==0 ){ + assert( u.bw.z==0 ); + }else if( u.bw.z==0 ){ goto no_mem; }else{ - sqlite3VdbeMemSetStr(pIn1, u.by.z, -1, SQLITE_UTF8, sqlite3_free); + sqlite3VdbeMemSetStr(pIn1, u.bw.z, -1, SQLITE_UTF8, sqlite3_free); } UPDATE_MAX_BLOBSIZE(pIn1); sqlite3VdbeChangeEncoding(pIn1, encoding); break; } @@ -55619,24 +55512,24 @@ ** held in register P1. ** ** An assertion fails if P2 is not an integer. */ case OP_RowSetAdd: { /* in2 */ -#if 0 /* local variables moved into u.bz */ +#if 0 /* local variables moved into u.bx */ Mem *pIdx; Mem *pVal; -#endif /* local variables moved into u.bz */ +#endif /* local variables moved into u.bx */ assert( pOp->p1>0 && pOp->p1<=p->nMem ); - u.bz.pIdx = &p->aMem[pOp->p1]; + u.bx.pIdx = &p->aMem[pOp->p1]; assert( pOp->p2>0 && pOp->p2<=p->nMem ); - u.bz.pVal = &p->aMem[pOp->p2]; - assert( (u.bz.pVal->flags & MEM_Int)!=0 ); - if( (u.bz.pIdx->flags & MEM_RowSet)==0 ){ - sqlite3VdbeMemSetRowSet(u.bz.pIdx); - if( (u.bz.pIdx->flags & MEM_RowSet)==0 ) goto no_mem; - } - sqlite3RowSetInsert(u.bz.pIdx->u.pRowSet, u.bz.pVal->u.i); + u.bx.pVal = &p->aMem[pOp->p2]; + assert( (u.bx.pVal->flags & MEM_Int)!=0 ); + if( (u.bx.pIdx->flags & MEM_RowSet)==0 ){ + sqlite3VdbeMemSetRowSet(u.bx.pIdx); + if( (u.bx.pIdx->flags & MEM_RowSet)==0 ) goto no_mem; + } + sqlite3RowSetInsert(u.bx.pIdx->u.pRowSet, u.bx.pVal->u.i); break; } /* Opcode: RowSetRead P1 P2 P3 * * ** @@ -55643,28 +55536,28 @@ ** Extract the smallest value from boolean index P1 and put that value into ** register P3. Or, if boolean index P1 is initially empty, leave P3 ** unchanged and jump to instruction P2. */ case OP_RowSetRead: { /* jump, out3 */ -#if 0 /* local variables moved into u.ca */ +#if 0 /* local variables moved into u.by */ Mem *pIdx; i64 val; -#endif /* local variables moved into u.ca */ +#endif /* local variables moved into u.by */ assert( pOp->p1>0 && pOp->p1<=p->nMem ); CHECK_FOR_INTERRUPT; - u.ca.pIdx = &p->aMem[pOp->p1]; + u.by.pIdx = &p->aMem[pOp->p1]; pOut = &p->aMem[pOp->p3]; - if( (u.ca.pIdx->flags & MEM_RowSet)==0 - || sqlite3RowSetNext(u.ca.pIdx->u.pRowSet, &u.ca.val)==0 + if( (u.by.pIdx->flags & MEM_RowSet)==0 + || sqlite3RowSetNext(u.by.pIdx->u.pRowSet, &u.by.val)==0 ){ /* The boolean index is empty */ - sqlite3VdbeMemSetNull(u.ca.pIdx); + sqlite3VdbeMemSetNull(u.by.pIdx); pc = pOp->p2 - 1; }else{ /* A value was pulled from the index */ assert( pOp->p3>0 && pOp->p3<=p->nMem ); - sqlite3VdbeMemSetInt64(pOut, u.ca.val); + sqlite3VdbeMemSetInt64(pOut, u.by.val); } break; } /* Opcode: RowSetTest P1 P2 P3 P4 @@ -55689,16 +55582,16 @@ ** inserted, there is no need to search to see if the same value was ** previously inserted as part of set X (only if it was previously ** inserted as part of some other set). */ case OP_RowSetTest: { /* jump, in1, in3 */ -#if 0 /* local variables moved into u.cb */ +#if 0 /* local variables moved into u.bz */ int iSet; int exists; -#endif /* local variables moved into u.cb */ - - u.cb.iSet = pOp->p4.i; +#endif /* local variables moved into u.bz */ + + u.bz.iSet = pOp->p4.i; assert( pIn3->flags&MEM_Int ); /* If there is anything other than a rowset object in memory cell P1, ** delete it now and initialize P1 with an empty rowset */ @@ -55706,21 +55599,21 @@ sqlite3VdbeMemSetRowSet(pIn1); if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem; } assert( pOp->p4type==P4_INT32 ); - assert( u.cb.iSet==-1 || u.cb.iSet>=0 ); - if( u.cb.iSet ){ - u.cb.exists = sqlite3RowSetTest(pIn1->u.pRowSet, - (u8)(u.cb.iSet>=0 ? u.cb.iSet & 0xf : 0xff), + assert( u.bz.iSet==-1 || u.bz.iSet>=0 ); + if( u.bz.iSet ){ + u.bz.exists = sqlite3RowSetTest(pIn1->u.pRowSet, + (u8)(u.bz.iSet>=0 ? u.bz.iSet & 0xf : 0xff), pIn3->u.i); - if( u.cb.exists ){ + if( u.bz.exists ){ pc = pOp->p2 - 1; break; } } - if( u.cb.iSet>=0 ){ + if( u.bz.iSet>=0 ){ sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i); } break; } @@ -55731,27 +55624,27 @@ ** Save the current Vdbe context such that it can be restored by a ContextPop ** opcode. The context stores the last insert row id, the last statement change ** count, and the current statement change count. */ case OP_ContextPush: { -#if 0 /* local variables moved into u.cc */ +#if 0 /* local variables moved into u.ca */ int i; Context *pContext; -#endif /* local variables moved into u.cc */ - - u.cc.i = p->contextStackTop++; - assert( u.cc.i>=0 ); +#endif /* local variables moved into u.ca */ + + u.ca.i = p->contextStackTop++; + assert( u.ca.i>=0 ); /* FIX ME: This should be allocated as part of the vdbe at compile-time */ - if( u.cc.i>=p->contextStackDepth ){ - p->contextStackDepth = u.cc.i+1; + if( u.ca.i>=p->contextStackDepth ){ + p->contextStackDepth = u.ca.i+1; p->contextStack = sqlite3DbReallocOrFree(db, p->contextStack, - sizeof(Context)*(u.cc.i+1)); + sizeof(Context)*(u.ca.i+1)); if( p->contextStack==0 ) goto no_mem; } - u.cc.pContext = &p->contextStack[u.cc.i]; - u.cc.pContext->lastRowid = db->lastRowid; - u.cc.pContext->nChange = p->nChange; + u.ca.pContext = &p->contextStack[u.ca.i]; + u.ca.pContext->lastRowid = db->lastRowid; + u.ca.pContext->nChange = p->nChange; break; } /* Opcode: ContextPop * * * ** @@ -55758,17 +55651,17 @@ ** Restore the Vdbe context to the state it was in when contextPush was last ** executed. The context stores the last insert row id, the last statement ** change count, and the current statement change count. */ case OP_ContextPop: { -#if 0 /* local variables moved into u.cd */ +#if 0 /* local variables moved into u.cb */ Context *pContext; -#endif /* local variables moved into u.cd */ - u.cd.pContext = &p->contextStack[--p->contextStackTop]; +#endif /* local variables moved into u.cb */ + u.cb.pContext = &p->contextStack[--p->contextStackTop]; assert( p->contextStackTop>=0 ); - db->lastRowid = u.cd.pContext->lastRowid; - p->nChange = u.cd.pContext->nChange; + db->lastRowid = u.cb.pContext->lastRowid; + p->nChange = u.cb.pContext->nChange; break; } #endif /* #ifndef SQLITE_OMIT_TRIGGER */ #ifndef SQLITE_OMIT_AUTOINCREMENT @@ -55844,51 +55737,51 @@ ** ** The P5 arguments are taken from register P2 and its ** successors. */ case OP_AggStep: { -#if 0 /* local variables moved into u.ce */ +#if 0 /* local variables moved into u.cc */ int n; int i; Mem *pMem; Mem *pRec; sqlite3_context ctx; sqlite3_value **apVal; -#endif /* local variables moved into u.ce */ - - u.ce.n = pOp->p5; - assert( u.ce.n>=0 ); - u.ce.pRec = &p->aMem[pOp->p2]; - u.ce.apVal = p->apArg; - assert( u.ce.apVal || u.ce.n==0 ); - for(u.ce.i=0; u.ce.i<u.ce.n; u.ce.i++, u.ce.pRec++){ - u.ce.apVal[u.ce.i] = u.ce.pRec; - storeTypeInfo(u.ce.pRec, encoding); - } - u.ce.ctx.pFunc = pOp->p4.pFunc; +#endif /* local variables moved into u.cc */ + + u.cc.n = pOp->p5; + assert( u.cc.n>=0 ); + u.cc.pRec = &p->aMem[pOp->p2]; + u.cc.apVal = p->apArg; + assert( u.cc.apVal || u.cc.n==0 ); + for(u.cc.i=0; u.cc.i<u.cc.n; u.cc.i++, u.cc.pRec++){ + u.cc.apVal[u.cc.i] = u.cc.pRec; + storeTypeInfo(u.cc.pRec, encoding); + } + u.cc.ctx.pFunc = pOp->p4.pFunc; assert( pOp->p3>0 && pOp->p3<=p->nMem ); - u.ce.ctx.pMem = u.ce.pMem = &p->aMem[pOp->p3]; - u.ce.pMem->n++; - u.ce.ctx.s.flags = MEM_Null; - u.ce.ctx.s.z = 0; - u.ce.ctx.s.zMalloc = 0; - u.ce.ctx.s.xDel = 0; - u.ce.ctx.s.db = db; - u.ce.ctx.isError = 0; - u.ce.ctx.pColl = 0; - if( u.ce.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ + u.cc.ctx.pMem = u.cc.pMem = &p->aMem[pOp->p3]; + u.cc.pMem->n++; + u.cc.ctx.s.flags = MEM_Null; + u.cc.ctx.s.z = 0; + u.cc.ctx.s.zMalloc = 0; + u.cc.ctx.s.xDel = 0; + u.cc.ctx.s.db = db; + u.cc.ctx.isError = 0; + u.cc.ctx.pColl = 0; + if( u.cc.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ assert( pOp>p->aOp ); assert( pOp[-1].p4type==P4_COLLSEQ ); assert( pOp[-1].opcode==OP_CollSeq ); - u.ce.ctx.pColl = pOp[-1].p4.pColl; - } - (u.ce.ctx.pFunc->xStep)(&u.ce.ctx, u.ce.n, u.ce.apVal); - if( u.ce.ctx.isError ){ - sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ce.ctx.s)); - rc = u.ce.ctx.isError; - } - sqlite3VdbeMemRelease(&u.ce.ctx.s); + u.cc.ctx.pColl = pOp[-1].p4.pColl; + } + (u.cc.ctx.pFunc->xStep)(&u.cc.ctx, u.cc.n, u.cc.apVal); + if( u.cc.ctx.isError ){ + sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.cc.ctx.s)); + rc = u.cc.ctx.isError; + } + sqlite3VdbeMemRelease(&u.cc.ctx.s); break; } /* Opcode: AggFinal P1 P2 * P4 * ** @@ -55901,23 +55794,23 @@ ** functions that can take varying numbers of arguments. The ** P4 argument is only needed for the degenerate case where ** the step function was not previously called. */ case OP_AggFinal: { -#if 0 /* local variables moved into u.cf */ +#if 0 /* local variables moved into u.cd */ Mem *pMem; -#endif /* local variables moved into u.cf */ +#endif /* local variables moved into u.cd */ assert( pOp->p1>0 && pOp->p1<=p->nMem ); - u.cf.pMem = &p->aMem[pOp->p1]; - assert( (u.cf.pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); - rc = sqlite3VdbeMemFinalize(u.cf.pMem, pOp->p4.pFunc); + u.cd.pMem = &p->aMem[pOp->p1]; + assert( (u.cd.pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); + rc = sqlite3VdbeMemFinalize(u.cd.pMem, pOp->p4.pFunc); if( rc==SQLITE_ERROR ){ - sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.cf.pMem)); - } - sqlite3VdbeChangeEncoding(u.cf.pMem, encoding); - UPDATE_MAX_BLOBSIZE(u.cf.pMem); - if( sqlite3VdbeMemTooBig(u.cf.pMem) ){ + sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.cd.pMem)); + } + sqlite3VdbeChangeEncoding(u.cd.pMem, encoding); + UPDATE_MAX_BLOBSIZE(u.cd.pMem); + if( sqlite3VdbeMemTooBig(u.cd.pMem) ){ goto too_big; } break; } @@ -55943,18 +55836,18 @@ ** Perform a single step of the incremental vacuum procedure on ** the P1 database. If the vacuum has finished, jump to instruction ** P2. Otherwise, fall through to the next instruction. */ case OP_IncrVacuum: { /* jump */ -#if 0 /* local variables moved into u.cg */ +#if 0 /* local variables moved into u.ce */ Btree *pBt; -#endif /* local variables moved into u.cg */ +#endif /* local variables moved into u.ce */ assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( (p->btreeMask & (1<<pOp->p1))!=0 ); - u.cg.pBt = db->aDb[pOp->p1].pBt; - rc = sqlite3BtreeIncrVacuum(u.cg.pBt); + u.ce.pBt = db->aDb[pOp->p1].pBt; + rc = sqlite3BtreeIncrVacuum(u.ce.pBt); if( rc==SQLITE_DONE ){ pc = pOp->p2 - 1; rc = SQLITE_OK; } break; @@ -55993,21 +55886,21 @@ ** ** P4 contains a pointer to the name of the table being locked. This is only ** used to generate an error message if the lock cannot be obtained. */ case OP_TableLock: { -#if 0 /* local variables moved into u.ch */ +#if 0 /* local variables moved into u.cf */ int p1; u8 isWriteLock; -#endif /* local variables moved into u.ch */ - - u.ch.p1 = pOp->p1; - u.ch.isWriteLock = (u8)pOp->p3; - assert( u.ch.p1>=0 && u.ch.p1<db->nDb ); - assert( (p->btreeMask & (1<<u.ch.p1))!=0 ); - assert( u.ch.isWriteLock==0 || u.ch.isWriteLock==1 ); - rc = sqlite3BtreeLockTable(db->aDb[u.ch.p1].pBt, pOp->p2, u.ch.isWriteLock); +#endif /* local variables moved into u.cf */ + + u.cf.p1 = pOp->p1; + u.cf.isWriteLock = (u8)pOp->p3; + assert( u.cf.p1>=0 && u.cf.p1<db->nDb ); + assert( (p->btreeMask & (1<<u.cf.p1))!=0 ); + assert( u.cf.isWriteLock==0 || u.cf.isWriteLock==1 ); + rc = sqlite3BtreeLockTable(db->aDb[u.cf.p1].pBt, pOp->p2, u.cf.isWriteLock); if( (rc&0xFF)==SQLITE_LOCKED ){ const char *z = pOp->p4.z; sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z); } break; @@ -56023,19 +55916,19 @@ ** Also, whether or not P4 is set, check that this is not being called from ** within a callback to a virtual table xSync() method. If it is, the error ** code will be set to SQLITE_LOCKED. */ case OP_VBegin: { -#if 0 /* local variables moved into u.ci */ +#if 0 /* local variables moved into u.cg */ sqlite3_vtab *pVtab; -#endif /* local variables moved into u.ci */ - u.ci.pVtab = pOp->p4.pVtab; - rc = sqlite3VtabBegin(db, u.ci.pVtab); - if( u.ci.pVtab ){ +#endif /* local variables moved into u.cg */ + u.cg.pVtab = pOp->p4.pVtab; + rc = sqlite3VtabBegin(db, u.cg.pVtab); + if( u.cg.pVtab ){ sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = u.ci.pVtab->zErrMsg; - u.ci.pVtab->zErrMsg = 0; + p->zErrMsg = u.cg.pVtab->zErrMsg; + u.cg.pVtab->zErrMsg = 0; } break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -56071,40 +55964,40 @@ ** 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: { -#if 0 /* local variables moved into u.cj */ +#if 0 /* local variables moved into u.ch */ VdbeCursor *pCur; sqlite3_vtab_cursor *pVtabCursor; sqlite3_vtab *pVtab; sqlite3_module *pModule; -#endif /* local variables moved into u.cj */ - - u.cj.pCur = 0; - u.cj.pVtabCursor = 0; - u.cj.pVtab = pOp->p4.pVtab; - u.cj.pModule = (sqlite3_module *)u.cj.pVtab->pModule; - assert(u.cj.pVtab && u.cj.pModule); +#endif /* local variables moved into u.ch */ + + u.ch.pCur = 0; + u.ch.pVtabCursor = 0; + u.ch.pVtab = pOp->p4.pVtab; + u.ch.pModule = (sqlite3_module *)u.ch.pVtab->pModule; + assert(u.ch.pVtab && u.ch.pModule); if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; - rc = u.cj.pModule->xOpen(u.cj.pVtab, &u.cj.pVtabCursor); + rc = u.ch.pModule->xOpen(u.ch.pVtab, &u.ch.pVtabCursor); sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = u.cj.pVtab->zErrMsg; - u.cj.pVtab->zErrMsg = 0; + p->zErrMsg = u.ch.pVtab->zErrMsg; + u.ch.pVtab->zErrMsg = 0; if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; if( SQLITE_OK==rc ){ /* Initialize sqlite3_vtab_cursor base class */ - u.cj.pVtabCursor->pVtab = u.cj.pVtab; + u.ch.pVtabCursor->pVtab = u.ch.pVtab; /* Initialise vdbe cursor object */ - u.cj.pCur = allocateCursor(p, pOp->p1, 0, -1, 0); - if( u.cj.pCur ){ - u.cj.pCur->pVtabCursor = u.cj.pVtabCursor; - u.cj.pCur->pModule = u.cj.pVtabCursor->pVtab->pModule; + u.ch.pCur = allocateCursor(p, pOp->p1, 0, -1, 0); + if( u.ch.pCur ){ + u.ch.pCur->pVtabCursor = u.ch.pVtabCursor; + u.ch.pCur->pModule = u.ch.pVtabCursor->pVtab->pModule; }else{ db->mallocFailed = 1; - u.cj.pModule->xClose(u.cj.pVtabCursor); + u.ch.pModule->xClose(u.ch.pVtabCursor); } } break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -56127,11 +56020,11 @@ ** xFilter as argv. Register P3+2 becomes argv[0] when passed to xFilter. ** ** A jump is made to P2 if the result set after filtering would be empty. */ case OP_VFilter: { /* jump */ -#if 0 /* local variables moved into u.ck */ +#if 0 /* local variables moved into u.ci */ int nArg; int iQuery; const sqlite3_module *pModule; Mem *pQuery; Mem *pArgc; @@ -56139,54 +56032,54 @@ sqlite3_vtab *pVtab; VdbeCursor *pCur; int res; int i; Mem **apArg; -#endif /* local variables moved into u.ck */ - - u.ck.pQuery = &p->aMem[pOp->p3]; - u.ck.pArgc = &u.ck.pQuery[1]; - u.ck.pCur = p->apCsr[pOp->p1]; - REGISTER_TRACE(pOp->p3, u.ck.pQuery); - assert( u.ck.pCur->pVtabCursor ); - u.ck.pVtabCursor = u.ck.pCur->pVtabCursor; - u.ck.pVtab = u.ck.pVtabCursor->pVtab; - u.ck.pModule = u.ck.pVtab->pModule; +#endif /* local variables moved into u.ci */ + + u.ci.pQuery = &p->aMem[pOp->p3]; + u.ci.pArgc = &u.ci.pQuery[1]; + u.ci.pCur = p->apCsr[pOp->p1]; + REGISTER_TRACE(pOp->p3, u.ci.pQuery); + assert( u.ci.pCur->pVtabCursor ); + u.ci.pVtabCursor = u.ci.pCur->pVtabCursor; + u.ci.pVtab = u.ci.pVtabCursor->pVtab; + u.ci.pModule = u.ci.pVtab->pModule; /* Grab the index number and argc parameters */ - assert( (u.ck.pQuery->flags&MEM_Int)!=0 && u.ck.pArgc->flags==MEM_Int ); - u.ck.nArg = (int)u.ck.pArgc->u.i; - u.ck.iQuery = (int)u.ck.pQuery->u.i; + assert( (u.ci.pQuery->flags&MEM_Int)!=0 && u.ci.pArgc->flags==MEM_Int ); + u.ci.nArg = (int)u.ci.pArgc->u.i; + u.ci.iQuery = (int)u.ci.pQuery->u.i; /* Invoke the xFilter method */ { - u.ck.res = 0; - u.ck.apArg = p->apArg; - for(u.ck.i = 0; u.ck.i<u.ck.nArg; u.ck.i++){ - u.ck.apArg[u.ck.i] = &u.ck.pArgc[u.ck.i+1]; - storeTypeInfo(u.ck.apArg[u.ck.i], 0); + u.ci.res = 0; + u.ci.apArg = p->apArg; + for(u.ci.i = 0; u.ci.i<u.ci.nArg; u.ci.i++){ + u.ci.apArg[u.ci.i] = &u.ci.pArgc[u.ci.i+1]; + storeTypeInfo(u.ci.apArg[u.ci.i], 0); } if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; - sqlite3VtabLock(u.ck.pVtab); + sqlite3VtabLock(u.ci.pVtab); p->inVtabMethod = 1; - rc = u.ck.pModule->xFilter(u.ck.pVtabCursor, u.ck.iQuery, pOp->p4.z, u.ck.nArg, u.ck.apArg); + rc = u.ci.pModule->xFilter(u.ci.pVtabCursor, u.ci.iQuery, pOp->p4.z, u.ci.nArg, u.ci.apArg); p->inVtabMethod = 0; sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = u.ck.pVtab->zErrMsg; - u.ck.pVtab->zErrMsg = 0; - sqlite3VtabUnlock(db, u.ck.pVtab); - if( rc==SQLITE_OK ){ - u.ck.res = u.ck.pModule->xEof(u.ck.pVtabCursor); + p->zErrMsg = u.ci.pVtab->zErrMsg; + u.ci.pVtab->zErrMsg = 0; + sqlite3VtabUnlock(db, u.ci.pVtab); + if( rc==SQLITE_OK ){ + u.ci.res = u.ci.pModule->xEof(u.ci.pVtabCursor); } if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; - if( u.ck.res ){ + if( u.ci.res ){ pc = pOp->p2 - 1; } } - u.ck.pCur->nullRow = 0; + u.ci.pCur->nullRow = 0; break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -56196,57 +56089,57 @@ ** Store the value of the P2-th column of ** the row of the virtual-table that the ** P1 cursor is pointing to into register P3. */ case OP_VColumn: { -#if 0 /* local variables moved into u.cl */ +#if 0 /* local variables moved into u.cj */ sqlite3_vtab *pVtab; const sqlite3_module *pModule; Mem *pDest; sqlite3_context sContext; -#endif /* local variables moved into u.cl */ +#endif /* local variables moved into u.cj */ VdbeCursor *pCur = p->apCsr[pOp->p1]; assert( pCur->pVtabCursor ); assert( pOp->p3>0 && pOp->p3<=p->nMem ); - u.cl.pDest = &p->aMem[pOp->p3]; + u.cj.pDest = &p->aMem[pOp->p3]; if( pCur->nullRow ){ - sqlite3VdbeMemSetNull(u.cl.pDest); + sqlite3VdbeMemSetNull(u.cj.pDest); break; } - u.cl.pVtab = pCur->pVtabCursor->pVtab; - u.cl.pModule = u.cl.pVtab->pModule; - assert( u.cl.pModule->xColumn ); - memset(&u.cl.sContext, 0, sizeof(u.cl.sContext)); + u.cj.pVtab = pCur->pVtabCursor->pVtab; + u.cj.pModule = u.cj.pVtab->pModule; + assert( u.cj.pModule->xColumn ); + memset(&u.cj.sContext, 0, sizeof(u.cj.sContext)); /* The output cell may already have a buffer allocated. Move - ** the current contents to u.cl.sContext.s so in case the user-function + ** the current contents to u.cj.sContext.s so in case the user-function ** can use the already allocated buffer instead of allocating a ** new one. */ - sqlite3VdbeMemMove(&u.cl.sContext.s, u.cl.pDest); - MemSetTypeFlag(&u.cl.sContext.s, MEM_Null); + sqlite3VdbeMemMove(&u.cj.sContext.s, u.cj.pDest); + MemSetTypeFlag(&u.cj.sContext.s, MEM_Null); if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; - rc = u.cl.pModule->xColumn(pCur->pVtabCursor, &u.cl.sContext, pOp->p2); + rc = u.cj.pModule->xColumn(pCur->pVtabCursor, &u.cj.sContext, pOp->p2); sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = u.cl.pVtab->zErrMsg; - u.cl.pVtab->zErrMsg = 0; + p->zErrMsg = u.cj.pVtab->zErrMsg; + u.cj.pVtab->zErrMsg = 0; /* Copy the result of the function to the P3 register. We ** do this regardless of whether or not an error occurred to ensure any - ** dynamic allocation in u.cl.sContext.s (a Mem struct) is released. - */ - sqlite3VdbeChangeEncoding(&u.cl.sContext.s, encoding); - REGISTER_TRACE(pOp->p3, u.cl.pDest); - sqlite3VdbeMemMove(u.cl.pDest, &u.cl.sContext.s); - UPDATE_MAX_BLOBSIZE(u.cl.pDest); + ** dynamic allocation in u.cj.sContext.s (a Mem struct) is released. + */ + sqlite3VdbeChangeEncoding(&u.cj.sContext.s, encoding); + REGISTER_TRACE(pOp->p3, u.cj.pDest); + sqlite3VdbeMemMove(u.cj.pDest, &u.cj.sContext.s); + UPDATE_MAX_BLOBSIZE(u.cj.pDest); if( sqlite3SafetyOn(db) ){ goto abort_due_to_misuse; } - if( sqlite3VdbeMemTooBig(u.cl.pDest) ){ + if( sqlite3VdbeMemTooBig(u.cj.pDest) ){ goto too_big; } break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -56257,48 +56150,48 @@ ** Advance virtual table P1 to the next row in its result set and ** jump to instruction P2. Or, if the virtual table has reached ** the end of its result set, then fall through to the next instruction. */ case OP_VNext: { /* jump */ -#if 0 /* local variables moved into u.cm */ +#if 0 /* local variables moved into u.ck */ sqlite3_vtab *pVtab; const sqlite3_module *pModule; int res; VdbeCursor *pCur; -#endif /* local variables moved into u.cm */ - - u.cm.res = 0; - u.cm.pCur = p->apCsr[pOp->p1]; - assert( u.cm.pCur->pVtabCursor ); - if( u.cm.pCur->nullRow ){ +#endif /* local variables moved into u.ck */ + + u.ck.res = 0; + u.ck.pCur = p->apCsr[pOp->p1]; + assert( u.ck.pCur->pVtabCursor ); + if( u.ck.pCur->nullRow ){ break; } - u.cm.pVtab = u.cm.pCur->pVtabCursor->pVtab; - u.cm.pModule = u.cm.pVtab->pModule; - assert( u.cm.pModule->xNext ); + u.ck.pVtab = u.ck.pCur->pVtabCursor->pVtab; + u.ck.pModule = u.ck.pVtab->pModule; + assert( u.ck.pModule->xNext ); /* Invoke the xNext() method of the module. There is no way for the ** underlying implementation to return an error if one occurs during ** xNext(). Instead, if an error occurs, true is returned (indicating that ** data is available) and the error code returned when xColumn or ** some other method is next invoked on the save virtual table cursor. */ if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; - sqlite3VtabLock(u.cm.pVtab); + sqlite3VtabLock(u.ck.pVtab); p->inVtabMethod = 1; - rc = u.cm.pModule->xNext(u.cm.pCur->pVtabCursor); + rc = u.ck.pModule->xNext(u.ck.pCur->pVtabCursor); p->inVtabMethod = 0; sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = u.cm.pVtab->zErrMsg; - u.cm.pVtab->zErrMsg = 0; - sqlite3VtabUnlock(db, u.cm.pVtab); - if( rc==SQLITE_OK ){ - u.cm.res = u.cm.pModule->xEof(u.cm.pCur->pVtabCursor); + p->zErrMsg = u.ck.pVtab->zErrMsg; + u.ck.pVtab->zErrMsg = 0; + sqlite3VtabUnlock(db, u.ck.pVtab); + if( rc==SQLITE_OK ){ + u.ck.res = u.ck.pModule->xEof(u.ck.pCur->pVtabCursor); } if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; - if( !u.cm.res ){ + if( !u.ck.res ){ /* If there is data, jump to P2 */ pc = pOp->p2 - 1; } break; } @@ -56310,29 +56203,27 @@ ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. ** This opcode invokes the corresponding xRename method. The value ** in register P1 is passed as the zName argument to the xRename method. */ case OP_VRename: { -#if 0 /* local variables moved into u.cn */ +#if 0 /* local variables moved into u.cl */ sqlite3_vtab *pVtab; Mem *pName; -#endif /* local variables moved into u.cn */ - - u.cn.pVtab = pOp->p4.pVtab; - u.cn.pName = &p->aMem[pOp->p1]; - assert( u.cn.pVtab->pModule->xRename ); - REGISTER_TRACE(pOp->p1, u.cn.pName); - - Stringify(u.cn.pName, encoding); - +#endif /* local variables moved into u.cl */ + + u.cl.pVtab = pOp->p4.pVtab; + u.cl.pName = &p->aMem[pOp->p1]; + assert( u.cl.pVtab->pModule->xRename ); + REGISTER_TRACE(pOp->p1, u.cl.pName); + assert( u.cl.pName->flags & MEM_Str ); if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; - sqlite3VtabLock(u.cn.pVtab); - rc = u.cn.pVtab->pModule->xRename(u.cn.pVtab, u.cn.pName->z); + sqlite3VtabLock(u.cl.pVtab); + rc = u.cl.pVtab->pModule->xRename(u.cl.pVtab, u.cl.pName->z); sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = u.cn.pVtab->zErrMsg; - u.cn.pVtab->zErrMsg = 0; - sqlite3VtabUnlock(db, u.cn.pVtab); + p->zErrMsg = u.cl.pVtab->zErrMsg; + u.cl.pVtab->zErrMsg = 0; + sqlite3VtabUnlock(db, u.cl.pVtab); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; break; } #endif @@ -56360,46 +56251,43 @@ ** P1 is a boolean flag. If it is set to true and the xUpdate call ** is successful, then the value returned by sqlite3_last_insert_rowid() ** is set to the value of the rowid for the row just inserted. */ case OP_VUpdate: { -#if 0 /* local variables moved into u.co */ +#if 0 /* local variables moved into u.cm */ sqlite3_vtab *pVtab; sqlite3_module *pModule; int nArg; int i; sqlite_int64 rowid; Mem **apArg; Mem *pX; -#endif /* local variables moved into u.co */ - - u.co.pVtab = pOp->p4.pVtab; - u.co.pModule = (sqlite3_module *)u.co.pVtab->pModule; - u.co.nArg = pOp->p2; +#endif /* local variables moved into u.cm */ + + u.cm.pVtab = pOp->p4.pVtab; + u.cm.pModule = (sqlite3_module *)u.cm.pVtab->pModule; + u.cm.nArg = pOp->p2; assert( pOp->p4type==P4_VTAB ); - if( u.co.pModule->xUpdate==0 ){ - sqlite3SetString(&p->zErrMsg, db, "read-only table"); - rc = SQLITE_ERROR; - }else{ - u.co.apArg = p->apArg; - u.co.pX = &p->aMem[pOp->p3]; - for(u.co.i=0; u.co.i<u.co.nArg; u.co.i++){ - storeTypeInfo(u.co.pX, 0); - u.co.apArg[u.co.i] = u.co.pX; - u.co.pX++; + if( ALWAYS(u.cm.pModule->xUpdate) ){ + u.cm.apArg = p->apArg; + u.cm.pX = &p->aMem[pOp->p3]; + for(u.cm.i=0; u.cm.i<u.cm.nArg; u.cm.i++){ + storeTypeInfo(u.cm.pX, 0); + u.cm.apArg[u.cm.i] = u.cm.pX; + u.cm.pX++; } if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; - sqlite3VtabLock(u.co.pVtab); - rc = u.co.pModule->xUpdate(u.co.pVtab, u.co.nArg, u.co.apArg, &u.co.rowid); + sqlite3VtabLock(u.cm.pVtab); + rc = u.cm.pModule->xUpdate(u.cm.pVtab, u.cm.nArg, u.cm.apArg, &u.cm.rowid); sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = u.co.pVtab->zErrMsg; - u.co.pVtab->zErrMsg = 0; - sqlite3VtabUnlock(db, u.co.pVtab); + p->zErrMsg = u.cm.pVtab->zErrMsg; + u.cm.pVtab->zErrMsg = 0; + sqlite3VtabUnlock(db, u.cm.pVtab); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; - if( pOp->p1 && rc==SQLITE_OK ){ - assert( u.co.nArg>1 && u.co.apArg[0] && (u.co.apArg[0]->flags&MEM_Null) ); - db->lastRowid = u.co.rowid; + if( rc==SQLITE_OK && pOp->p1 ){ + assert( u.cm.nArg>1 && u.cm.apArg[0] && (u.cm.apArg[0]->flags&MEM_Null) ); + db->lastRowid = u.cm.rowid; } p->nChange++; } break; } @@ -56409,22 +56297,25 @@ /* Opcode: Pagecount P1 P2 * * * ** ** Write the current number of pages in database P1 to memory cell P2. */ case OP_Pagecount: { /* out2-prerelease */ -#if 0 /* local variables moved into u.cp */ +#if 0 /* local variables moved into u.cn */ int p1; int nPage; Pager *pPager; -#endif /* local variables moved into u.cp */ - - u.cp.p1 = pOp->p1; - u.cp.pPager = sqlite3BtreePager(db->aDb[u.cp.p1].pBt); - rc = sqlite3PagerPagecount(u.cp.pPager, &u.cp.nPage); - if( rc==SQLITE_OK ){ +#endif /* local variables moved into u.cn */ + + u.cn.p1 = pOp->p1; + u.cn.pPager = sqlite3BtreePager(db->aDb[u.cn.p1].pBt); + rc = sqlite3PagerPagecount(u.cn.pPager, &u.cn.nPage); + /* OP_Pagecount is always called from within a read transaction. The + ** page count has already been successfully read and cached. So the + ** sqlite3PagerPagecount() call above cannot fail. */ + if( ALWAYS(rc==SQLITE_OK) ){ pOut->flags = MEM_Int; - pOut->u.i = u.cp.nPage; + pOut->u.i = u.cn.nPage; } break; } #endif @@ -56433,22 +56324,22 @@ ** ** If tracing is enabled (by the sqlite3_trace()) interface, then ** the UTF-8 string contained in P4 is emitted on the trace callback. */ case OP_Trace: { -#if 0 /* local variables moved into u.cq */ +#if 0 /* local variables moved into u.co */ char *zTrace; -#endif /* local variables moved into u.cq */ - - u.cq.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); - if( u.cq.zTrace ){ +#endif /* local variables moved into u.co */ + + u.co.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); + if( u.co.zTrace ){ if( db->xTrace ){ - db->xTrace(db->pTraceArg, u.cq.zTrace); + db->xTrace(db->pTraceArg, u.co.zTrace); } #ifdef SQLITE_DEBUG if( (db->flags & SQLITE_SqlTrace)!=0 ){ - sqlite3DebugPrintf("SQL-trace: %s\n", u.cq.zTrace); + sqlite3DebugPrintf("SQL-trace: %s\n", u.co.zTrace); } #endif /* SQLITE_DEBUG */ } break; } @@ -57461,11 +57352,11 @@ ** ************************************************************************* ** This file contains routines used for walking the parser tree for ** an SQL statement. ** -** $Id: walker.c,v 1.6 2009/05/28 01:00:55 drh Exp $ +** $Id: walker.c,v 1.7 2009/06/15 23:15:59 drh Exp $ */ /* ** Walk an expression tree. Invoke the callback once for each node @@ -57508,18 +57399,18 @@ /* ** Call sqlite3WalkExpr() for every expression in list p or until ** an abort request is seen. */ SQLITE_PRIVATE int sqlite3WalkExprList(Walker *pWalker, ExprList *p){ - int i, rc = WRC_Continue; + int i; struct ExprList_item *pItem; if( p ){ for(i=p->nExpr, pItem=p->a; i>0; i--, pItem++){ if( sqlite3WalkExpr(pWalker, pItem->pExpr) ) return WRC_Abort; } } - return rc & WRC_Continue; + return WRC_Continue; } /* ** Walk all expressions associated with SELECT statement p. Do ** not invoke the SELECT callback on p, but do (of course) invoke @@ -57548,11 +57439,11 @@ SrcList *pSrc; int i; struct SrcList_item *pItem; pSrc = p->pSrc; - if( pSrc ){ + if( ALWAYS(pSrc) ){ for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ if( sqlite3WalkSelect(pWalker, pItem->pSelect) ){ return WRC_Abort; } } @@ -57601,11 +57492,11 @@ ** ** This file contains routines used for walking the parser tree and ** resolve all identifiers by associating them with a particular ** table and column. ** -** $Id: resolve.c,v 1.28 2009/06/01 16:53:10 shane Exp $ +** $Id: resolve.c,v 1.30 2009/06/15 23:15:59 drh Exp $ */ /* ** Turn the pExpr expression into an alias for the iCol-th column of the ** result set in pEList. @@ -57660,19 +57551,18 @@ }else if( ExprHasProperty(pOrig, EP_IntValue) || pOrig->u.zToken==0 ){ pDup = sqlite3ExprDup(db, pOrig, 0); if( pDup==0 ) return; }else{ char *zToken = pOrig->u.zToken; + assert( zToken!=0 ); pOrig->u.zToken = 0; pDup = sqlite3ExprDup(db, pOrig, 0); pOrig->u.zToken = zToken; if( pDup==0 ) return; - if( zToken ){ - assert( (pDup->flags & (EP_Reduced|EP_TokenOnly))==0 ); - pDup->flags2 |= EP2_MallocedToken; - pDup->u.zToken = sqlite3DbStrDup(db, zToken); - } + assert( (pDup->flags & (EP_Reduced|EP_TokenOnly))==0 ); + pDup->flags2 |= EP2_MallocedToken; + pDup->u.zToken = sqlite3DbStrDup(db, zToken); } if( pExpr->flags & EP_ExpCollate ){ pDup->pColl = pExpr->pColl; pDup->flags |= EP_ExpCollate; } @@ -57704,11 +57594,11 @@ ** value can be NULL if zDb is also NULL. If zTable is NULL it ** means that the form of the name is Z and that columns from any table ** can be used. ** ** If the name cannot be resolved unambiguously, leave an error message -** in pParse and return non-zero. Return zero on success. +** in pParse and return WRC_Abort. Return WRC_Prune on success. */ static int lookupName( Parse *pParse, /* The parsing context */ const char *zDb, /* Name of the database containing table, or NULL */ const char *zTab, /* Name of table containing column, or NULL */ @@ -57753,11 +57643,13 @@ if( pItem->zAlias ){ char *zTabName = pItem->zAlias; if( sqlite3StrICmp(zTabName, zTab)!=0 ) continue; }else{ char *zTabName = pTab->zName; - if( zTabName==0 || sqlite3StrICmp(zTabName, zTab)!=0 ) continue; + if( NEVER(zTabName==0) || sqlite3StrICmp(zTabName, zTab)!=0 ){ + continue; + } if( zDb!=0 && sqlite3StrICmp(db->aDb[iDb].zName, zDb)!=0 ){ continue; } } } @@ -57832,18 +57724,16 @@ for(iCol=0; iCol < pTab->nCol; iCol++, pCol++) { if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ cnt++; pExpr->iColumn = iCol==pTab->iPKey ? -1 : (i16)iCol; pExpr->pTab = pTab; - if( iCol>=0 ){ - testcase( iCol==31 ); - testcase( iCol==32 ); - if( iCol>=32 ){ - *piColMask = 0xffffffff; - }else{ - *piColMask |= ((u32)1)<<iCol; - } + testcase( iCol==31 ); + testcase( iCol==32 ); + if( iCol>=32 ){ + *piColMask = 0xffffffff; + }else{ + *piColMask |= ((u32)1)<<iCol; } break; } } } @@ -57880,11 +57770,11 @@ assert( pExpr->x.pList==0 ); assert( pExpr->x.pSelect==0 ); pOrig = pEList->a[j].pExpr; if( !pNC->allowAgg && ExprHasProperty(pOrig, EP_Agg) ){ sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs); - return 2; + return WRC_Abort; } resolveAlias(pParse, pEList, j, pExpr, ""); cnt = 1; pMatch = 0; assert( zTab==0 && zDb==0 ); @@ -57912,11 +57802,11 @@ ** fields are not changed in any context. */ if( cnt==0 && zTab==0 && ExprHasProperty(pExpr,EP_DblQuoted) ){ pExpr->op = TK_STRING; pExpr->pTab = 0; - return 0; + return WRC_Prune; } /* ** cnt==0 means there was not match. cnt>1 means there were two or ** more matches. Either way, we have an error. @@ -57967,13 +57857,13 @@ assert( pTopNC!=0 ); pTopNC->nRef++; if( pTopNC==pNC ) break; pTopNC = pTopNC->pNext; } - return 0; + return WRC_Prune; } else { - return 1; + return WRC_Abort; } } /* ** This routine is callback for sqlite3WalkExpr(). @@ -58028,12 +57918,11 @@ #endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */ /* A lone identifier is the name of a column. */ case TK_ID: { - lookupName(pParse, 0, 0, pExpr->u.zToken, pNC, pExpr); - return WRC_Prune; + return lookupName(pParse, 0, 0, pExpr->u.zToken, pNC, pExpr); } /* A table name and column name: ID.ID ** Or a database, table and column: ID.ID.ID */ @@ -58053,12 +57942,11 @@ assert( pRight->op==TK_DOT ); zDb = pExpr->pLeft->u.zToken; zTable = pRight->pLeft->u.zToken; zColumn = pRight->pRight->u.zToken; } - lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr); - return WRC_Prune; + return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr); } /* Resolve function names */ case TK_CONST_FUNC: @@ -58072,10 +57960,11 @@ int nId; /* Number of characters in function name */ const char *zId; /* The function name. */ FuncDef *pDef; /* Information about the function */ u8 enc = ENC(pParse->db); /* The database encoding */ + testcase( pExpr->op==TK_CONST_FUNC ); assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); zId = pExpr->u.zToken; nId = sqlite3Strlen30(zId); pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0); if( pDef==0 ){ @@ -58126,13 +58015,14 @@ */ return WRC_Prune; } #ifndef SQLITE_OMIT_SUBQUERY case TK_SELECT: - case TK_EXISTS: + case TK_EXISTS: testcase( pExpr->op==TK_EXISTS ); #endif case TK_IN: { + testcase( pExpr->op==TK_IN ); if( ExprHasProperty(pExpr, EP_xIsSelect) ){ int nRef = pNC->nRef; #ifndef SQLITE_OMIT_CHECK if( pNC->isCheck ){ sqlite3ErrorMsg(pParse,"subqueries prohibited in CHECK constraints"); @@ -58177,11 +58067,11 @@ ){ int i; /* Loop counter */ UNUSED_PARAMETER(pParse); - if( pE->op==TK_ID || (pE->op==TK_STRING && pE->u.zToken[0]!='\'') ){ + if( pE->op==TK_ID ){ char *zCol = pE->u.zToken; for(i=0; i<pEList->nExpr; i++){ char *zAs = pEList->a[i].zName; if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){ return i+1; @@ -58313,11 +58203,11 @@ int iCol = -1; Expr *pE, *pDup; if( pItem->done ) continue; pE = pItem->pExpr; if( sqlite3ExprIsInteger(pE, &iCol) ){ - if( iCol<0 || iCol>pEList->nExpr ){ + if( iCol<=0 || iCol>pEList->nExpr ){ resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr); return 1; } }else{ iCol = resolveAsName(pParse, pEList, pE); @@ -58326,13 +58216,10 @@ if( !db->mallocFailed ){ assert(pDup); iCol = resolveOrderByTermToExprList(pParse, pSelect, pDup); } sqlite3ExprDelete(db, pDup); - } - if( iCol<0 ){ - return 1; } } if( iCol>0 ){ CollSeq *pColl = pE->pColl; int flags = pE->flags & EP_ExpCollate; @@ -58436,13 +58323,10 @@ nResult = pSelect->pEList->nExpr; pParse = pNC->pParse; for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){ Expr *pE = pItem->pExpr; iCol = resolveAsName(pParse, pSelect->pEList, pE); - if( iCol<0 ){ - return 1; /* OOM error */ - } if( iCol>0 ){ /* If an AS-name match is found, mark this ORDER BY column as being ** a copy of the iCol-th result-set column. The subsequent call to ** sqlite3ResolveOrderGroupBy() will convert the expression to a ** copy of the iCol-th result-set expression. */ @@ -58768,11 +58652,11 @@ ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.445 2009/06/01 16:53:10 shane Exp $ +** $Id: expr.c,v 1.446 2009/06/19 18:32:55 drh Exp $ */ /* ** Return the 'affinity' of the expression pExpr if any. ** @@ -59245,15 +59129,15 @@ exprSetHeight(pRoot); } } /* -** Allocate a Expr node which joins up to two subtrees. -** -** The -** Works like sqlite3Expr() except that it takes an extra Parse* -** argument and notifies the associated connection object if malloc fails. +** Allocate a Expr node which joins as many as two subtrees. +** +** One or both of the subtrees can be NULL. Return a pointer to the new +** Expr node. Or, if an OOM error occurs, set pParse->db->mallocFailed, +** free the subtrees and return NULL. */ SQLITE_PRIVATE Expr *sqlite3PExpr( Parse *pParse, /* Parsing context */ int op, /* Expression opcode */ Expr *pLeft, /* Left operand */ @@ -64140,11 +64024,11 @@ ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** -** $Id: build.c,v 1.549 2009/06/03 11:25:07 danielk1977 Exp $ +** $Id: build.c,v 1.552 2009/06/18 17:22:39 drh Exp $ */ /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Initialize the pParse structure as needed. @@ -65372,11 +65256,10 @@ pColl = sqlite3FindCollSeq(db, enc, zName, initbusy); if( !initbusy && (!pColl || !pColl->xCmp) ){ pColl = sqlite3GetCollSeq(db, pColl, zName); if( !pColl ){ sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); - pColl = 0; } } return pColl; } @@ -67756,11 +67639,11 @@ ************************************************************************* ** ** This file contains functions used to access the internal hash tables ** of user defined functions and collation sequences. ** -** $Id: callback.c,v 1.41 2009/05/20 02:40:46 drh Exp $ +** $Id: callback.c,v 1.42 2009/06/17 00:35:31 drh Exp $ */ /* ** Invoke the 'collation needed' callback to request a collation sequence @@ -67866,13 +67749,11 @@ SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){ if( pColl ){ const char *zName = pColl->zName; CollSeq *p = sqlite3GetCollSeq(pParse->db, pColl, zName); if( !p ){ - if( pParse->nErr==0 ){ - sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); - } + sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); pParse->nErr++; return SQLITE_ERROR; } assert( p==pColl ); } @@ -68083,11 +67964,10 @@ int bestScore = 0; /* Score of best match */ int h; /* Hash value */ assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); - if( nArg<-1 ) nArg = -1; h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db->aFunc.a); /* First search for a match amongst the application-defined functions. */ p = functionSearch(&db->aFunc, h, zName, nName); @@ -68833,11 +68713,11 @@ ** ** There is only one exported symbol in this file - the function ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: func.c,v 1.237 2009/06/03 01:24:54 drh Exp $ +** $Id: func.c,v 1.239 2009/06/19 16:44:41 drh Exp $ */ /* ** Return the collating function associated with a function. */ @@ -70078,19 +69958,14 @@ if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum)); if( pAccum ){ sqlite3 *db = sqlite3_context_db_handle(context); - int n; + int firstTerm = pAccum->useMalloc==0; pAccum->useMalloc = 1; pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH]; -#ifdef SQLITE_OMIT_DEPRECATED - n = context->pMem->n; -#else - n = sqlite3_aggregate_count(context); -#endif - if( n>1 ){ + if( !firstTerm ){ if( argc==2 ){ zSep = (char*)sqlite3_value_text(argv[1]); nSep = sqlite3_value_bytes(argv[1]); }else{ zSep = ","; @@ -70132,13 +70007,10 @@ assert( rc==SQLITE_NOMEM || rc==SQLITE_OK ); if( rc==SQLITE_NOMEM ){ db->mallocFailed = 1; } } -#ifdef SQLITE_SSE - (void)sqlite3SseFunctions(db); -#endif } /* ** Set the LIKEOPT flag on the 2-argument function with the given name. */ @@ -73213,16 +73085,16 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** -** $Id: pragma.c,v 1.212 2009/06/03 11:25:07 danielk1977 Exp $ +** $Id: pragma.c,v 1.213 2009/06/19 14:06:03 drh Exp $ */ /* Ignore this whole file if pragmas are disabled */ -#if !defined(SQLITE_OMIT_PRAGMA) && !defined(SQLITE_OMIT_PARSER) +#if !defined(SQLITE_OMIT_PRAGMA) /* ** Interpret the given string as a safety level. Return 0 for OFF, ** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or ** unrecognized string argument. @@ -74549,21 +74421,10 @@ } }else #endif -#ifdef SQLITE_SSE - /* - ** Check to see if the sqlite_statements table exists. Create it - ** if it does not. - */ - if( sqlite3StrICmp(zLeft, "create_sqlite_statement_table")==0 ){ - extern int sqlite3CreateStatementsTable(Parse*); - sqlite3CreateStatementsTable(pParse); - }else -#endif - #if SQLITE_HAS_CODEC if( sqlite3StrICmp(zLeft, "key")==0 && zRight ){ sqlite3_key(db, zRight, sqlite3Strlen30(zRight)); }else if( sqlite3StrICmp(zLeft, "rekey")==0 && zRight ){ @@ -74624,11 +74485,11 @@ pragma_out: sqlite3DbFree(db, zLeft); sqlite3DbFree(db, zRight); } -#endif /* SQLITE_OMIT_PRAGMA || SQLITE_OMIT_PARSER */ +#endif /* SQLITE_OMIT_PRAGMA */ /************** End of pragma.c **********************************************/ /************** Begin file prepare.c *****************************************/ /* ** 2005 May 25 @@ -74643,11 +74504,11 @@ ************************************************************************* ** This file contains the implementation of the sqlite3_prepare() ** interface, and routines that contribute to loading the database schema ** from disk. ** -** $Id: prepare.c,v 1.121 2009/06/04 00:11:56 drh Exp $ +** $Id: prepare.c,v 1.124 2009/06/22 12:05:10 drh Exp $ */ /* ** Fill the InitData structure with an error message that indicates ** that the database is corrupt. @@ -74660,16 +74521,16 @@ sqlite3 *db = pData->db; if( !db->mallocFailed && (db->flags & SQLITE_RecoveryMode)==0 ){ if( zObj==0 ) zObj = "?"; sqlite3SetString(pData->pzErrMsg, pData->db, "malformed database schema (%s)", zObj); - if( zExtra && zExtra[0] ){ + if( zExtra ){ *pData->pzErrMsg = sqlite3MAppendf(pData->db, *pData->pzErrMsg, "%s - %s", *pData->pzErrMsg, zExtra); } } - pData->rc = SQLITE_CORRUPT; + pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT; } /* ** This is the callback routine for the code that initializes the ** database. See sqlite3Init() below for additional information. @@ -74691,11 +74552,11 @@ UNUSED_PARAMETER2(NotUsed, argc); assert( sqlite3_mutex_held(db->mutex) ); DbClearProperty(db, iDb, DB_Empty); if( db->mallocFailed ){ corruptSchema(pData, argv[0], 0); - return SQLITE_NOMEM; + return 1; } assert( iDb>=0 && iDb<db->nDb ); if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ if( argv[1]==0 ){ @@ -74716,11 +74577,11 @@ assert( rc!=SQLITE_OK || zErr==0 ); if( SQLITE_OK!=rc ){ pData->rc = rc; if( rc==SQLITE_NOMEM ){ db->mallocFailed = 1; - }else if( rc!=SQLITE_INTERRUPT && (rc&0xff)!=SQLITE_LOCKED ){ + }else if( rc!=SQLITE_INTERRUPT ){ corruptSchema(pData, argv[0], zErr); } sqlite3DbFree(db, zErr); } }else if( argv[0]==0 ){ @@ -74732,19 +74593,19 @@ ** been created when we processed the CREATE TABLE. All we have ** to do here is record the root page number for that index. */ Index *pIndex; pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zName); - if( pIndex==0 || pIndex->tnum!=0 ){ + if( pIndex==0 ){ /* This can occur if there exists an index on a TEMP table which ** has the same name as another index on a permanent index. Since ** the permanent table is hidden by the TEMP table, we can also ** safely ignore the index on the permanent table. */ /* Do Nothing */; - }else{ - pIndex->tnum = atoi(argv[1]); + }else if( sqlite3GetInt32(argv[1], &pIndex->tnum)==0 ){ + corruptSchema(pData, argv[0], "invalid rootpage"); } } return 0; } @@ -74826,19 +74687,19 @@ if( initData.rc ){ rc = initData.rc; goto error_out; } pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName); - if( pTab ){ + if( ALWAYS(pTab) ){ pTab->tabFlags |= TF_Readonly; } /* Create a cursor to hold the database open */ pDb = &db->aDb[iDb]; if( pDb->pBt==0 ){ - if( !OMIT_TEMPDB && iDb==1 ){ + if( !OMIT_TEMPDB && ALWAYS(iDb==1) ){ DbSetProperty(db, 1, DB_SchemaLoaded); } return SQLITE_OK; } curMain = sqlite3MallocZero(sqlite3BtreeCursorSize()); @@ -74854,12 +74715,17 @@ ** ** Meta values are as follows: ** meta[0] Schema cookie. Changes with each schema change. ** meta[1] File format of schema layer. ** meta[2] Size of the page cache. - ** meta[3] Use freelist if 0. Autovacuum if greater than zero. + ** meta[3] Largest rootpage (auto/incr_vacuum mode) ** meta[4] Db text encoding. 1:UTF-8 2:UTF-16LE 3:UTF-16BE + ** meta[5] User version + ** meta[6] Incremental vacuum mode + ** meta[7] unused + ** meta[8] unused + ** meta[9] unused ** ** Note: The #defined SQLITE_UTF* symbols in sqliteInt.h correspond to ** the possible values of meta[4]. */ for(i=0; rc==SQLITE_OK && i<ArraySize(meta); i++){ @@ -74932,14 +74798,11 @@ } /* Read the schema information out of the schema tables */ assert( db->init.busy ); - if( rc==SQLITE_EMPTY ){ - /* For an empty database, there is nothing to read */ - rc = SQLITE_OK; - }else{ + { char *zSql; zSql = sqlite3MPrintf(db, "SELECT name, rootpage, sql FROM '%q'.%s", db->aDb[iDb].zName, zMasterName); (void)sqlite3SafetyOff(db); @@ -75009,11 +74872,10 @@ SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){ int i, rc; int commit_internal = !(db->flags&SQLITE_InternChanges); assert( sqlite3_mutex_held(db->mutex) ); - if( db->init.busy ) return SQLITE_OK; rc = SQLITE_OK; db->init.busy = 1; for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue; rc = sqlite3InitOne(db, i, pzErrMsg); @@ -75025,11 +74887,12 @@ /* Once all the other databases have been initialised, load the schema ** for the TEMP database. This is loaded last, as the TEMP database ** schema may contain references to objects in other databases. */ #ifndef SQLITE_OMIT_TEMPDB - if( rc==SQLITE_OK && db->nDb>1 && !DbHasProperty(db, 1, DB_SchemaLoaded) ){ + if( rc==SQLITE_OK && ALWAYS(db->nDb>1) + && !DbHasProperty(db, 1, DB_SchemaLoaded) ){ rc = sqlite3InitOne(db, 1, pzErrMsg); if( rc ){ sqlite3ResetInternalSchema(db, 1); } } @@ -75082,16 +74945,17 @@ if( pBt==0 ) continue; memset(curTemp, 0, sqlite3BtreeCursorSize()); rc = sqlite3BtreeCursor(pBt, MASTER_ROOT, 0, 0, curTemp); if( rc==SQLITE_OK ){ rc = sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie); - if( rc==SQLITE_OK && cookie!=db->aDb[iDb].pSchema->schema_cookie ){ + if( ALWAYS(rc==SQLITE_OK) + && cookie!=db->aDb[iDb].pSchema->schema_cookie ){ allOk = 0; } sqlite3BtreeCloseCursor(curTemp); } - if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ + if( NEVER(rc==SQLITE_NOMEM) || rc==SQLITE_IOERR_NOMEM ){ db->mallocFailed = 1; } } sqlite3_free(curTemp); }else{ @@ -75206,10 +75070,12 @@ pParse->db = db; if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){ char *zSqlCopy; int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; + testcase( nBytes==mxLen ); + testcase( nBytes==mxLen+1 ); if( nBytes>mxLen ){ sqlite3Error(db, SQLITE_TOOBIG, "statement too long"); (void)sqlite3SafetyOff(db); rc = sqlite3ApiExit(db, SQLITE_TOOBIG); goto end_prepare; @@ -75312,10 +75178,14 @@ return SQLITE_MISUSE; } sqlite3_mutex_enter(db->mutex); sqlite3BtreeEnterAll(db); rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, ppStmt, pzTail); + if( rc==SQLITE_SCHEMA ){ + sqlite3_finalize(*ppStmt); + rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, ppStmt, pzTail); + } sqlite3BtreeLeaveAll(db); sqlite3_mutex_leave(db->mutex); return rc; } @@ -75485,11 +75355,11 @@ ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** -** $Id: select.c,v 1.523 2009/06/01 16:53:10 shane Exp $ +** $Id: select.c,v 1.524 2009/06/12 03:27:27 drh Exp $ */ /* ** Delete all the content of a Select structure but do not deallocate @@ -78269,10 +78139,11 @@ /* Transfer the FROM clause terms from the subquery into the ** outer query. */ for(i=0; i<nSubSrc; i++){ + sqlite3IdListDelete(db, pSrc->a[i+iFrom].pUsing); pSrc->a[i+iFrom] = pSubSrc->a[i]; memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i])); } pSrc->a[iFrom].jointype = jointype; @@ -81764,11 +81635,11 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to help implement virtual tables. ** -** $Id: vtab.c,v 1.90 2009/06/02 21:31:39 drh Exp $ +** $Id: vtab.c,v 1.91 2009/06/15 16:27:08 shane Exp $ */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* ** The actual function that does the work of creating a new module. @@ -81854,10 +81725,13 @@ /* ** Unlock a virtual table. When the last lock is removed, ** disconnect the virtual table. */ SQLITE_PRIVATE void sqlite3VtabUnlock(sqlite3 *db, sqlite3_vtab *pVtab){ +#ifndef SQLITE_DEBUG + UNUSED_PARAMETER(db); +#endif assert( pVtab->nRef>0 ); pVtab->nRef--; assert(db); assert( sqlite3SafetyCheckOk(db) ); if( pVtab->nRef==0 ){ @@ -82633,11 +82507,11 @@ ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** -** $Id: where.c,v 1.401 2009/06/06 15:17:28 drh Exp $ +** $Id: where.c,v 1.408 2009/06/16 14:15:22 shane Exp $ */ /* ** Trace output macros */ @@ -83275,23 +83149,24 @@ if( pColl==0 ) return 0; if( (pColl->type!=SQLITE_COLL_BINARY || *pnoCase) && (pColl->type!=SQLITE_COLL_NOCASE || !*pnoCase) ){ return 0; } - z = pRight->u.zToken; - cnt = 0; + if( sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT ) return 0; + z = pRight->u.zToken; if( ALWAYS(z) ){ + cnt = 0; while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){ cnt++; } - } - if( cnt==0 || c==0 || 255==(u8)z[cnt-1] ){ - return 0; - } - *pisComplete = z[cnt]==wc[0] && z[cnt+1]==0; - *pnPattern = cnt; - return 1; + if( cnt!=0 && c!=0 && 255!=(u8)z[cnt-1] ){ + *pisComplete = z[cnt]==wc[0] && z[cnt+1]==0; + *pnPattern = cnt; + return 1; + } + } + return 0; } #endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */ #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -83507,10 +83382,26 @@ /* ** chngToIN holds a set of tables that *might* satisfy case 1. But ** we have to do some additional checking to see if case 1 really ** is satisfied. + ** + ** chngToIN will hold either 0, 1, or 2 bits. The 0-bit case means + ** that there is no possibility of transforming the OR clause into an + ** IN operator because one or more terms in the OR clause contain + ** something other than == on a column in the single table. The 1-bit + ** case means that every term of the OR clause is of the form + ** "table.column=expr" for some single table. The one bit that is set + ** will correspond to the common table. We still need to check to make + ** sure the same column is used on all terms. The 2-bit case is when + ** the all terms are of the form "table1.column=table2.column". It + ** might be possible to form an IN operator with either table1.column + ** or table2.column as the LHS if either is common to every term of + ** the OR clause. + ** + ** Note that terms of the form "table.column1=table.column2" (the + ** same table on both sizes of the ==) cannot be optimized. */ if( chngToIN ){ int okToChngToIN = 0; /* True if the conversion to IN is valid */ int iColumn = -1; /* Column index on lhs of IN operator */ int iCursor = -1; /* Table cursor common to all terms */ @@ -83525,22 +83416,42 @@ for(j=0; j<2 && !okToChngToIN; j++){ pOrTerm = pOrWc->a; for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){ assert( pOrTerm->eOperator==WO_EQ ); pOrTerm->wtFlags &= ~TERM_OR_OK; - if( pOrTerm->leftCursor==iColumn ) continue; - if( (chngToIN & getMask(pMaskSet, pOrTerm->leftCursor))==0 ) continue; + if( pOrTerm->leftCursor==iCursor ){ + /* This is the 2-bit case and we are on the second iteration and + ** current term is from the first iteration. So skip this term. */ + assert( j==1 ); + continue; + } + if( (chngToIN & getMask(pMaskSet, pOrTerm->leftCursor))==0 ){ + /* This term must be of the form t1.a==t2.b where t2 is in the + ** chngToIN set but t1 is not. This term will be either preceeded + ** or follwed by an inverted copy (t2.b==t1.a). Skip this term + ** and use its inversion. */ + testcase( pOrTerm->wtFlags & TERM_COPIED ); + testcase( pOrTerm->wtFlags & TERM_VIRTUAL ); + assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) ); + continue; + } iColumn = pOrTerm->u.leftColumn; iCursor = pOrTerm->leftCursor; break; } if( i<0 ){ + /* No candidate table+column was found. This can only occur + ** on the second iteration */ assert( j==1 ); assert( (chngToIN&(chngToIN-1))==0 ); - assert( chngToIN==getMask(pMaskSet, iColumn) ); - break; - } + assert( chngToIN==getMask(pMaskSet, iCursor) ); + break; + } + testcase( j==1 ); + + /* We have found a candidate table and column. Check to see if that + ** table and column is common to every term in the OR clause */ okToChngToIN = 1; for(; i>=0 && okToChngToIN; i--, pOrTerm++){ assert( pOrTerm->eOperator==WO_EQ ); if( pOrTerm->leftCursor!=iCursor ){ pOrTerm->wtFlags &= ~TERM_OR_OK; @@ -83782,15 +83693,22 @@ pRight = pExpr->x.pList->a[0].pExpr; pStr1 = sqlite3Expr(db, TK_STRING, pRight->u.zToken); if( pStr1 ) pStr1->u.zToken[nPattern] = 0; pStr2 = sqlite3ExprDup(db, pStr1, 0); if( !db->mallocFailed ){ - u8 c, *pC; + u8 c, *pC; /* Last character before the first wildcard */ pC = (u8*)&pStr2->u.zToken[nPattern-1]; c = *pC; if( noCase ){ - if( c=='@' ) isComplete = 0; + /* The point is to increment the last character before the first + ** wildcard. But if we increment '@', that will push it into the + ** alphabetic range where case conversions will mess up the + ** inequality. To avoid this, make sure to also run the full + ** LIKE on all candidate expressions by clearing the isComplete flag + */ + if( c=='A'-1 ) isComplete = 0; + c = sqlite3UpperToLower[c]; } *pC = c + 1; } pNewExpr1 = sqlite3PExpr(pParse, TK_GE, sqlite3ExprDup(db,pLeft,0),pStr1,0); @@ -84456,11 +84374,11 @@ pCost->rCost = (SQLITE_BIG_DBL/((double)2)); }else{ pCost->rCost = pIdxInfo->estimatedCost; } pCost->plan.u.pVtabIdx = pIdxInfo; - if( pIdxInfo && pIdxInfo->orderByConsumed ){ + if( pIdxInfo->orderByConsumed ){ pCost->plan.wsFlags |= WHERE_ORDERBY; } pCost->plan.nEq = 0; pIdxInfo->nOrderBy = nOrderBy; @@ -84742,11 +84660,11 @@ } }else{ cost += cost*estLog(cost); WHERETRACE(("...... orderby increases cost to %.9g\n", cost)); } - }else if( pParse->db->flags & SQLITE_ReverseOrder ){ + }else if( wsFlags!=0 && (pParse->db->flags & SQLITE_ReverseOrder)!=0 ){ /* For application testing, randomly reverse the output order for ** SELECT statements that omit the ORDER BY clause. This will help ** to find cases where */ wsFlags |= WHERE_REVERSE; @@ -84805,18 +84723,21 @@ struct SrcList_item *pSrc, /* The FROM clause term to search */ Bitmask notReady, /* Mask of cursors that are not available */ ExprList *pOrderBy, /* The ORDER BY clause */ WhereCost *pCost /* Lowest cost query plan */ ){ +#ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pSrc->pTab) ){ sqlite3_index_info *p = 0; bestVirtualIndex(pParse, pWC, pSrc, notReady, pOrderBy, pCost, &p); if( p->needToFreeIdxStr ){ sqlite3_free(p->idxStr); } sqlite3DbFree(pParse->db, p); - }else{ + }else +#endif + { bestBtreeIndex(pParse, pWC, pSrc, notReady, pOrderBy, pCost); } } /* @@ -85448,12 +85369,12 @@ WhereClause *pOrWc; /* The OR-clause broken out into subterms */ WhereTerm *pFinal; /* Final subterm within the OR-clause. */ SrcList oneTab; /* Shortened table list */ int regReturn = ++pParse->nMem; /* Register used with OP_Gosub */ - int regRowset; /* Register for RowSet object */ - int regRowid; /* Register holding rowid */ + int regRowset = 0; /* Register for RowSet object */ + int regRowid = 0; /* Register holding rowid */ int iLoopBody = sqlite3VdbeMakeLabel(v); /* Start of loop body */ int iRetInit; /* Address of regReturn init */ int ii; pTerm = pLevel->plan.u.pTerm; @@ -85488,11 +85409,10 @@ for(ii=0; ii<pOrWc->nTerm; ii++){ WhereTerm *pOrTerm = &pOrWc->a[ii]; if( pOrTerm->leftCursor==iCur || pOrTerm->eOperator==WO_AND ){ WhereInfo *pSubWInfo; /* Info for single OR-term scan */ - /* Loop through table entries that match term pOrTerm. */ pSubWInfo = sqlite3WhereBegin(pParse, &oneTab, pOrTerm->pExpr, 0, WHERE_OMIT_OPEN | WHERE_OMIT_CLOSE | WHERE_FORCE_TABLE); if( pSubWInfo ){ if( (wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ @@ -85789,13 +85709,15 @@ ** with virtual tables. */ assert( pWC->vmask==0 && pMaskSet->n==0 ); for(i=0; i<pTabList->nSrc; i++){ createMask(pMaskSet, pTabList->a[i].iCursor); - if( pTabList->a[i].pTab && IsVirtual(pTabList->a[i].pTab) ){ +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( ALWAYS(pTabList->a[i].pTab) && IsVirtual(pTabList->a[i].pTab) ){ pWC->vmask |= ((Bitmask)1 << i); } +#endif } #ifndef NDEBUG { Bitmask toTheLeft = 0; for(i=0; i<pTabList->nSrc; i++){ @@ -86210,10 +86132,21 @@ /* First off, code is included that follows the "include" declaration ** in the input grammar file. */ /* +** Disable all error recovery processing in the parser push-down +** automaton. +*/ +#define YYNOERRORRECOVERY 1 + +/* +** Make yytestcase() the same as testcase() +*/ +#define yytestcase(X) testcase(X) + +/* ** An instance of this structure holds information about the ** LIMIT clause of a SELECT statement. */ struct LimitVal { Expr *pLimit; /* The LIMIT expression. NULL if there is no limit */ @@ -86354,11 +86287,11 @@ ** YYNSTATE the combined number of states. ** YYNRULE the number of rules in the grammar ** YYERRORSYMBOL is the code number of the error symbol. If not ** defined, then do no error processing. */ -#define YYCODETYPE unsigned short int +#define YYCODETYPE unsigned char #define YYNOCODE 252 #define YYACTIONTYPE unsigned short int #define YYWILDCARD 65 #define sqlite3ParserTOKENTYPE Token typedef union { @@ -86392,10 +86325,22 @@ #define YY_ERROR_ACTION (YYNSTATE+YYNRULE) /* The yyzerominor constant is used to initialize instances of ** YYMINORTYPE objects to zero. */ static const YYMINORTYPE yyzerominor = { 0 }; + +/* Define the yytestcase() macro to be a no-op if is not already defined +** otherwise. +** +** Applications can choose to define yytestcase() in the %include section +** to a macro that can assist in verifying code coverage. For production +** code the yytestcase() macro should be turned off. But it is useful +** for testing. +*/ +#ifndef yytestcase +# define yytestcase(X) +#endif /* Next are the tables used to determine what action to take based on the ** current state and lookahead token. These tables are used to implement ** functions that take a state number and lookahead value and return an @@ -86970,86 +86915,10 @@ 26, /* VIEW => ID */ 26, /* VIRTUAL => ID */ 26, /* REINDEX => ID */ 26, /* RENAME => ID */ 26, /* CTIME_KW => ID */ - 0, /* ANY => nothing */ - 0, /* OR => nothing */ - 0, /* AND => nothing */ - 0, /* IS => nothing */ - 0, /* BETWEEN => nothing */ - 0, /* IN => nothing */ - 0, /* ISNULL => nothing */ - 0, /* NOTNULL => nothing */ - 0, /* NE => nothing */ - 0, /* EQ => nothing */ - 0, /* GT => nothing */ - 0, /* LE => nothing */ - 0, /* LT => nothing */ - 0, /* GE => nothing */ - 0, /* ESCAPE => nothing */ - 0, /* BITAND => nothing */ - 0, /* BITOR => nothing */ - 0, /* LSHIFT => nothing */ - 0, /* RSHIFT => nothing */ - 0, /* PLUS => nothing */ - 0, /* MINUS => nothing */ - 0, /* STAR => nothing */ - 0, /* SLASH => nothing */ - 0, /* REM => nothing */ - 0, /* CONCAT => nothing */ - 0, /* COLLATE => nothing */ - 0, /* UMINUS => nothing */ - 0, /* UPLUS => nothing */ - 0, /* BITNOT => nothing */ - 0, /* STRING => nothing */ - 0, /* JOIN_KW => nothing */ - 0, /* CONSTRAINT => nothing */ - 0, /* DEFAULT => nothing */ - 0, /* NULL => nothing */ - 0, /* PRIMARY => nothing */ - 0, /* UNIQUE => nothing */ - 0, /* CHECK => nothing */ - 0, /* REFERENCES => nothing */ - 0, /* AUTOINCR => nothing */ - 0, /* ON => nothing */ - 0, /* DELETE => nothing */ - 0, /* UPDATE => nothing */ - 0, /* INSERT => nothing */ - 0, /* SET => nothing */ - 0, /* DEFERRABLE => nothing */ - 0, /* FOREIGN => nothing */ - 0, /* DROP => nothing */ - 0, /* UNION => nothing */ - 0, /* ALL => nothing */ - 0, /* EXCEPT => nothing */ - 0, /* INTERSECT => nothing */ - 0, /* SELECT => nothing */ - 0, /* DISTINCT => nothing */ - 0, /* DOT => nothing */ - 0, /* FROM => nothing */ - 0, /* JOIN => nothing */ - 0, /* USING => nothing */ - 0, /* ORDER => nothing */ - 0, /* GROUP => nothing */ - 0, /* HAVING => nothing */ - 0, /* LIMIT => nothing */ - 0, /* WHERE => nothing */ - 0, /* INTO => nothing */ - 0, /* VALUES => nothing */ - 0, /* INTEGER => nothing */ - 0, /* FLOAT => nothing */ - 0, /* BLOB => nothing */ - 0, /* REGISTER => nothing */ - 0, /* VARIABLE => nothing */ - 0, /* CASE => nothing */ - 0, /* WHEN => nothing */ - 0, /* THEN => nothing */ - 0, /* ELSE => nothing */ - 0, /* INDEX => nothing */ - 0, /* ALTER => nothing */ - 0, /* ADD => nothing */ }; #endif /* YYFALLBACK */ /* The following structure represents a single element of the ** parser's stack. Information stored includes: @@ -88270,52 +88139,10 @@ ** #line <lineno> <grammarfile> ** { ... } // User supplied code ** #line <lineno> <thisfile> ** break; */ - case 0: /* input ::= cmdlist */ - case 1: /* cmdlist ::= cmdlist ecmd */ - case 2: /* cmdlist ::= ecmd */ - case 3: /* ecmd ::= SEMI */ - case 4: /* ecmd ::= explain cmdx SEMI */ - case 10: /* trans_opt ::= */ - case 11: /* trans_opt ::= TRANSACTION */ - case 12: /* trans_opt ::= TRANSACTION nm */ - case 20: /* savepoint_opt ::= SAVEPOINT */ - case 21: /* savepoint_opt ::= */ - case 25: /* cmd ::= create_table create_table_args */ - case 34: /* columnlist ::= columnlist COMMA column */ - case 35: /* columnlist ::= column */ - case 44: /* type ::= */ - case 51: /* signed ::= plus_num */ - case 52: /* signed ::= minus_num */ - case 53: /* carglist ::= carglist carg */ - case 54: /* carglist ::= */ - case 55: /* carg ::= CONSTRAINT nm ccons */ - case 56: /* carg ::= ccons */ - case 62: /* ccons ::= NULL onconf */ - case 89: /* conslist ::= conslist COMMA tcons */ - case 90: /* conslist ::= conslist tcons */ - case 91: /* conslist ::= tcons */ - case 92: /* tcons ::= CONSTRAINT nm */ - case 268: /* plus_opt ::= PLUS */ - case 269: /* plus_opt ::= */ - case 279: /* foreach_clause ::= */ - case 280: /* foreach_clause ::= FOR EACH ROW */ - case 300: /* database_kw_opt ::= DATABASE */ - case 301: /* database_kw_opt ::= */ - case 309: /* kwcolumn_opt ::= */ - case 310: /* kwcolumn_opt ::= COLUMNKW */ - case 314: /* vtabarglist ::= vtabarg */ - case 315: /* vtabarglist ::= vtabarglist COMMA vtabarg */ - case 317: /* vtabarg ::= vtabarg vtabargtoken */ - case 321: /* anylist ::= */ - case 322: /* anylist ::= anylist LP anylist RP */ - case 323: /* anylist ::= anylist ANY */ -{ -} - break; case 5: /* explain ::= */ { sqlite3BeginParse(pParse, 0); } break; case 6: /* explain ::= EXPLAIN */ { sqlite3BeginParse(pParse, 1); } @@ -88331,18 +88158,18 @@ break; case 13: /* transtype ::= */ {yygotominor.yy194 = TK_DEFERRED;} break; case 14: /* transtype ::= DEFERRED */ - case 15: /* transtype ::= IMMEDIATE */ - case 16: /* transtype ::= EXCLUSIVE */ - case 114: /* multiselect_op ::= UNION */ - case 116: /* multiselect_op ::= EXCEPT|INTERSECT */ + case 15: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==15); + case 16: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==16); + case 114: /* multiselect_op ::= UNION */ yytestcase(yyruleno==114); + case 116: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==116); {yygotominor.yy194 = yymsp[0].major;} break; case 17: /* cmd ::= COMMIT trans_opt */ - case 18: /* cmd ::= END trans_opt */ + case 18: /* cmd ::= END trans_opt */ yytestcase(yyruleno==18); {sqlite3CommitTransaction(pParse);} break; case 19: /* cmd ::= ROLLBACK trans_opt */ {sqlite3RollbackTransaction(pParse);} break; @@ -88371,30 +88198,30 @@ pParse->db->lookaside.bEnabled = 0; yygotominor.yy0 = yymsp[0].minor.yy0; } break; case 28: /* ifnotexists ::= */ - case 31: /* temp ::= */ - case 70: /* autoinc ::= */ - case 84: /* init_deferred_pred_opt ::= */ - case 86: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ - case 97: /* defer_subclause_opt ::= */ - case 108: /* ifexists ::= */ - case 119: /* distinct ::= ALL */ - case 120: /* distinct ::= */ - case 222: /* between_op ::= BETWEEN */ - case 225: /* in_op ::= IN */ + case 31: /* temp ::= */ yytestcase(yyruleno==31); + case 70: /* autoinc ::= */ yytestcase(yyruleno==70); + case 84: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==84); + case 86: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==86); + case 97: /* defer_subclause_opt ::= */ yytestcase(yyruleno==97); + case 108: /* ifexists ::= */ yytestcase(yyruleno==108); + case 119: /* distinct ::= ALL */ yytestcase(yyruleno==119); + case 120: /* distinct ::= */ yytestcase(yyruleno==120); + case 222: /* between_op ::= BETWEEN */ yytestcase(yyruleno==222); + case 225: /* in_op ::= IN */ yytestcase(yyruleno==225); {yygotominor.yy194 = 0;} break; case 29: /* ifnotexists ::= IF NOT EXISTS */ - case 30: /* temp ::= TEMP */ - case 71: /* autoinc ::= AUTOINCR */ - case 85: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ - case 107: /* ifexists ::= IF EXISTS */ - case 118: /* distinct ::= DISTINCT */ - case 223: /* between_op ::= NOT BETWEEN */ - case 226: /* in_op ::= NOT IN */ + case 30: /* temp ::= TEMP */ yytestcase(yyruleno==30); + case 71: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==71); + case 85: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==85); + case 107: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==107); + case 118: /* distinct ::= DISTINCT */ yytestcase(yyruleno==118); + case 223: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==223); + case 226: /* in_op ::= NOT IN */ yytestcase(yyruleno==226); {yygotominor.yy194 = 1;} break; case 32: /* create_table_args ::= LP columnlist conslist_opt RP */ { sqlite3EndTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0); @@ -88417,30 +88244,30 @@ sqlite3AddColumn(pParse,&yymsp[0].minor.yy0); yygotominor.yy0 = yymsp[0].minor.yy0; } break; case 38: /* id ::= ID */ - case 39: /* id ::= INDEXED */ - case 40: /* ids ::= ID|STRING */ - case 41: /* nm ::= id */ - case 42: /* nm ::= STRING */ - case 43: /* nm ::= JOIN_KW */ - case 46: /* typetoken ::= typename */ - case 49: /* typename ::= ids */ - case 126: /* as ::= AS nm */ - case 127: /* as ::= ids */ - case 137: /* dbnm ::= DOT nm */ - case 146: /* indexed_opt ::= INDEXED BY nm */ - case 251: /* collate ::= COLLATE ids */ - case 260: /* nmnum ::= plus_num */ - case 261: /* nmnum ::= nm */ - case 262: /* nmnum ::= ON */ - case 263: /* nmnum ::= DELETE */ - case 264: /* nmnum ::= DEFAULT */ - case 265: /* plus_num ::= plus_opt number */ - case 266: /* minus_num ::= MINUS number */ - case 267: /* number ::= INTEGER|FLOAT */ + case 39: /* id ::= INDEXED */ yytestcase(yyruleno==39); + case 40: /* ids ::= ID|STRING */ yytestcase(yyruleno==40); + case 41: /* nm ::= id */ yytestcase(yyruleno==41); + case 42: /* nm ::= STRING */ yytestcase(yyruleno==42); + case 43: /* nm ::= JOIN_KW */ yytestcase(yyruleno==43); + case 46: /* typetoken ::= typename */ yytestcase(yyruleno==46); + case 49: /* typename ::= ids */ yytestcase(yyruleno==49); + case 126: /* as ::= AS nm */ yytestcase(yyruleno==126); + case 127: /* as ::= ids */ yytestcase(yyruleno==127); + case 137: /* dbnm ::= DOT nm */ yytestcase(yyruleno==137); + case 146: /* indexed_opt ::= INDEXED BY nm */ yytestcase(yyruleno==146); + case 251: /* collate ::= COLLATE ids */ yytestcase(yyruleno==251); + case 260: /* nmnum ::= plus_num */ yytestcase(yyruleno==260); + case 261: /* nmnum ::= nm */ yytestcase(yyruleno==261); + case 262: /* nmnum ::= ON */ yytestcase(yyruleno==262); + case 263: /* nmnum ::= DELETE */ yytestcase(yyruleno==263); + case 264: /* nmnum ::= DEFAULT */ yytestcase(yyruleno==264); + case 265: /* plus_num ::= plus_opt number */ yytestcase(yyruleno==265); + case 266: /* minus_num ::= MINUS number */ yytestcase(yyruleno==266); + case 267: /* number ::= INTEGER|FLOAT */ yytestcase(yyruleno==267); {yygotominor.yy0 = yymsp[0].minor.yy0;} break; case 45: /* type ::= typetoken */ {sqlite3AddColumnType(pParse,&yymsp[0].minor.yy0);} break; @@ -88458,11 +88285,11 @@ break; case 50: /* typename ::= typename ids */ {yygotominor.yy0.z=yymsp[-1].minor.yy0.z; yygotominor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);} break; case 57: /* ccons ::= DEFAULT term */ - case 59: /* ccons ::= DEFAULT PLUS term */ + case 59: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==59); {sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy190);} break; case 58: /* ccons ::= DEFAULT LP expr RP */ {sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy190);} break; @@ -88532,16 +88359,16 @@ break; case 81: /* refact ::= RESTRICT */ { yygotominor.yy194 = OE_Restrict; } break; case 82: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ - case 83: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ - case 98: /* defer_subclause_opt ::= defer_subclause */ - case 100: /* onconf ::= ON CONFLICT resolvetype */ - case 102: /* orconf ::= OR resolvetype */ - case 103: /* resolvetype ::= raisetype */ - case 175: /* insert_cmd ::= INSERT orconf */ + case 83: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==83); + case 98: /* defer_subclause_opt ::= defer_subclause */ yytestcase(yyruleno==98); + case 100: /* onconf ::= ON CONFLICT resolvetype */ yytestcase(yyruleno==100); + case 102: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==102); + case 103: /* resolvetype ::= raisetype */ yytestcase(yyruleno==103); + case 175: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==175); {yygotominor.yy194 = yymsp[0].minor.yy194;} break; case 87: /* conslist_opt ::= */ {yygotominor.yy0.n = 0; yygotominor.yy0.z = 0;} break; @@ -88562,18 +88389,18 @@ sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy148, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy148, yymsp[-1].minor.yy194); sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy194); } break; case 99: /* onconf ::= */ - case 101: /* orconf ::= */ + case 101: /* orconf ::= */ yytestcase(yyruleno==101); {yygotominor.yy194 = OE_Default;} break; case 104: /* resolvetype ::= IGNORE */ {yygotominor.yy194 = OE_Ignore;} break; case 105: /* resolvetype ::= REPLACE */ - case 176: /* insert_cmd ::= REPLACE */ + case 176: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==176); {yygotominor.yy194 = OE_Replace;} break; case 106: /* cmd ::= DROP TABLE ifexists fullname */ { sqlite3DropTable(pParse, yymsp[0].minor.yy185, 0, yymsp[-1].minor.yy194); @@ -88617,18 +88444,18 @@ { yygotominor.yy243 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy148,yymsp[-5].minor.yy185,yymsp[-4].minor.yy72,yymsp[-3].minor.yy148,yymsp[-2].minor.yy72,yymsp[-1].minor.yy148,yymsp[-7].minor.yy194,yymsp[0].minor.yy354.pLimit,yymsp[0].minor.yy354.pOffset); } break; case 121: /* sclp ::= selcollist COMMA */ - case 247: /* idxlist_opt ::= LP idxlist RP */ + case 247: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==247); {yygotominor.yy148 = yymsp[-1].minor.yy148;} break; case 122: /* sclp ::= */ - case 150: /* orderby_opt ::= */ - case 158: /* groupby_opt ::= */ - case 240: /* exprlist ::= */ - case 246: /* idxlist_opt ::= */ + case 150: /* orderby_opt ::= */ yytestcase(yyruleno==150); + case 158: /* groupby_opt ::= */ yytestcase(yyruleno==158); + case 240: /* exprlist ::= */ yytestcase(yyruleno==240); + case 246: /* idxlist_opt ::= */ yytestcase(yyruleno==246); {yygotominor.yy148 = 0;} break; case 123: /* selcollist ::= sclp expr as */ { yygotominor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy148, yymsp[-1].minor.yy190.pExpr); @@ -88663,11 +88490,11 @@ } break; case 131: /* stl_prefix ::= seltablist joinop */ { yygotominor.yy185 = yymsp[-1].minor.yy185; - if( yygotominor.yy185 && yygotominor.yy185->nSrc>0 ) yygotominor.yy185->a[yygotominor.yy185->nSrc-1].jointype = (u8)yymsp[0].minor.yy194; + if( ALWAYS(yygotominor.yy185 && yygotominor.yy185->nSrc>0) ) yygotominor.yy185->a[yygotominor.yy185->nSrc-1].jointype = (u8)yymsp[0].minor.yy194; } break; case 132: /* stl_prefix ::= */ {yygotominor.yy185 = 0;} break; @@ -88682,11 +88509,13 @@ yygotominor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy243,yymsp[-1].minor.yy72,yymsp[0].minor.yy254); } break; case 135: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ { - if( yymsp[-6].minor.yy185==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy72==0 && yymsp[0].minor.yy254==0 ){ + if( yymsp[-6].minor.yy185==0 ){ + sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy72); + sqlite3IdListDelete(pParse->db, yymsp[0].minor.yy254); yygotominor.yy185 = yymsp[-4].minor.yy185; }else{ Select *pSubquery; sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy185); pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy185,0,0,0,0,0,0,0); @@ -88693,11 +88522,11 @@ yygotominor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy72,yymsp[0].minor.yy254); } } break; case 136: /* dbnm ::= */ - case 145: /* indexed_opt ::= */ + case 145: /* indexed_opt ::= */ yytestcase(yyruleno==145); {yygotominor.yy0.z=0; yygotominor.yy0.n=0;} break; case 138: /* fullname ::= nm dbnm */ {yygotominor.yy185 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);} break; @@ -88712,38 +88541,38 @@ break; case 142: /* joinop ::= JOIN_KW nm nm JOIN */ { yygotominor.yy194 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); } break; case 143: /* on_opt ::= ON expr */ - case 154: /* sortitem ::= expr */ - case 161: /* having_opt ::= HAVING expr */ - case 168: /* where_opt ::= WHERE expr */ - case 235: /* case_else ::= ELSE expr */ - case 237: /* case_operand ::= expr */ + case 154: /* sortitem ::= expr */ yytestcase(yyruleno==154); + case 161: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==161); + case 168: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==168); + case 235: /* case_else ::= ELSE expr */ yytestcase(yyruleno==235); + case 237: /* case_operand ::= expr */ yytestcase(yyruleno==237); {yygotominor.yy72 = yymsp[0].minor.yy190.pExpr;} break; case 144: /* on_opt ::= */ - case 160: /* having_opt ::= */ - case 167: /* where_opt ::= */ - case 236: /* case_else ::= */ - case 238: /* case_operand ::= */ + case 160: /* having_opt ::= */ yytestcase(yyruleno==160); + case 167: /* where_opt ::= */ yytestcase(yyruleno==167); + case 236: /* case_else ::= */ yytestcase(yyruleno==236); + case 238: /* case_operand ::= */ yytestcase(yyruleno==238); {yygotominor.yy72 = 0;} break; case 147: /* indexed_opt ::= NOT INDEXED */ {yygotominor.yy0.z=0; yygotominor.yy0.n=1;} break; case 148: /* using_opt ::= USING LP inscollist RP */ - case 180: /* inscollist_opt ::= LP inscollist RP */ + case 180: /* inscollist_opt ::= LP inscollist RP */ yytestcase(yyruleno==180); {yygotominor.yy254 = yymsp[-1].minor.yy254;} break; case 149: /* using_opt ::= */ - case 179: /* inscollist_opt ::= */ + case 179: /* inscollist_opt ::= */ yytestcase(yyruleno==179); {yygotominor.yy254 = 0;} break; case 151: /* orderby_opt ::= ORDER BY sortlist */ - case 159: /* groupby_opt ::= GROUP BY nexprlist */ - case 239: /* exprlist ::= nexprlist */ + case 159: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==159); + case 239: /* exprlist ::= nexprlist */ yytestcase(yyruleno==239); {yygotominor.yy148 = yymsp[0].minor.yy148;} break; case 152: /* sortlist ::= sortlist COMMA sortitem sortorder */ { yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148,yymsp[-1].minor.yy72); @@ -88751,15 +88580,15 @@ } break; case 153: /* sortlist ::= sortitem sortorder */ { yygotominor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy72); - if( yygotominor.yy148 && yygotominor.yy148->a ) yygotominor.yy148->a[0].sortOrder = (u8)yymsp[0].minor.yy194; + if( yygotominor.yy148 && ALWAYS(yygotominor.yy148->a) ) yygotominor.yy148->a[0].sortOrder = (u8)yymsp[0].minor.yy194; } break; case 155: /* sortorder ::= ASC */ - case 157: /* sortorder ::= */ + case 157: /* sortorder ::= */ yytestcase(yyruleno==157); {yygotominor.yy194 = SQLITE_SO_ASC;} break; case 156: /* sortorder ::= DESC */ {yygotominor.yy194 = SQLITE_SO_DESC;} break; @@ -88808,37 +88637,37 @@ break; case 174: /* cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES */ {sqlite3Insert(pParse, yymsp[-3].minor.yy185, 0, 0, yymsp[-2].minor.yy254, yymsp[-5].minor.yy194);} break; case 177: /* itemlist ::= itemlist COMMA expr */ - case 241: /* nexprlist ::= nexprlist COMMA expr */ + case 241: /* nexprlist ::= nexprlist COMMA expr */ yytestcase(yyruleno==241); {yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[0].minor.yy190.pExpr);} break; case 178: /* itemlist ::= expr */ - case 242: /* nexprlist ::= expr */ + case 242: /* nexprlist ::= expr */ yytestcase(yyruleno==242); {yygotominor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy190.pExpr);} break; case 181: /* inscollist ::= inscollist COMMA nm */ {yygotominor.yy254 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);} break; case 182: /* inscollist ::= nm */ {yygotominor.yy254 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);} break; case 183: /* expr ::= term */ - case 211: /* escape ::= ESCAPE expr */ + case 211: /* escape ::= ESCAPE expr */ yytestcase(yyruleno==211); {yygotominor.yy190 = yymsp[0].minor.yy190;} break; case 184: /* expr ::= LP expr RP */ {yygotominor.yy190.pExpr = yymsp[-1].minor.yy190.pExpr; spanSet(&yygotominor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);} break; case 185: /* term ::= NULL */ - case 190: /* term ::= INTEGER|FLOAT|BLOB */ - case 191: /* term ::= STRING */ + case 190: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==190); + case 191: /* term ::= STRING */ yytestcase(yyruleno==191); {spanExpr(&yygotominor.yy190, pParse, yymsp[0].major, &yymsp[0].minor.yy0);} break; case 186: /* expr ::= id */ - case 187: /* expr ::= JOIN_KW */ + case 187: /* expr ::= JOIN_KW */ yytestcase(yyruleno==187); {spanExpr(&yygotominor.yy190, pParse, TK_ID, &yymsp[0].minor.yy0);} break; case 188: /* expr ::= nm DOT nm */ { Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0); @@ -88892,11 +88721,11 @@ spanSet(&yygotominor.yy190,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); } break; case 196: /* expr ::= ID LP distinct exprlist RP */ { - if( yymsp[-1].minor.yy148 && yymsp[-1].minor.yy148->nExpr>SQLITE_MAX_FUNCTION_ARG ){ + if( yymsp[-1].minor.yy148 && yymsp[-1].minor.yy148->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){ sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0); } yygotominor.yy190.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy148, &yymsp[-4].minor.yy0); spanSet(&yygotominor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); if( yymsp[-2].minor.yy194 && yygotominor.yy190.pExpr ){ @@ -88920,25 +88749,25 @@ } spanSet(&yygotominor.yy190, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); } break; case 199: /* expr ::= expr AND expr */ - case 200: /* expr ::= expr OR expr */ - case 201: /* expr ::= expr LT|GT|GE|LE expr */ - case 202: /* expr ::= expr EQ|NE expr */ - case 203: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ - case 204: /* expr ::= expr PLUS|MINUS expr */ - case 205: /* expr ::= expr STAR|SLASH|REM expr */ - case 206: /* expr ::= expr CONCAT expr */ + case 200: /* expr ::= expr OR expr */ yytestcase(yyruleno==200); + case 201: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==201); + case 202: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==202); + case 203: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==203); + case 204: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==204); + case 205: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==205); + case 206: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==206); {spanBinaryExpr(&yygotominor.yy190,pParse,yymsp[-1].major,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy190);} break; case 207: /* likeop ::= LIKE_KW */ - case 209: /* likeop ::= MATCH */ + case 209: /* likeop ::= MATCH */ yytestcase(yyruleno==209); {yygotominor.yy392.eOperator = yymsp[0].minor.yy0; yygotominor.yy392.not = 0;} break; case 208: /* likeop ::= NOT LIKE_KW */ - case 210: /* likeop ::= NOT MATCH */ + case 210: /* likeop ::= NOT MATCH */ yytestcase(yyruleno==210); {yygotominor.yy392.eOperator = yymsp[0].minor.yy0; yygotominor.yy392.not = 1;} break; case 212: /* escape ::= */ {memset(&yygotominor.yy190,0,sizeof(yygotominor.yy190));} break; @@ -88968,11 +88797,11 @@ break; case 217: /* expr ::= expr IS NOT NULL */ {spanUnaryPostfix(&yygotominor.yy190,pParse,TK_NOTNULL,&yymsp[-3].minor.yy190,&yymsp[0].minor.yy0);} break; case 218: /* expr ::= NOT expr */ - case 219: /* expr ::= BITNOT expr */ + case 219: /* expr ::= BITNOT expr */ yytestcase(yyruleno==219); {spanUnaryPrefix(&yygotominor.yy190,pParse,yymsp[-1].major,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);} break; case 220: /* expr ::= MINUS expr */ {spanUnaryPrefix(&yygotominor.yy190,pParse,TK_UMINUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);} break; @@ -89098,11 +88927,11 @@ sqlite3SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy0,0), yymsp[-1].minor.yy148, yymsp[-9].minor.yy194, &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy194); } break; case 244: /* uniqueflag ::= UNIQUE */ - case 293: /* raisetype ::= ABORT */ + case 293: /* raisetype ::= ABORT */ yytestcase(yyruleno==293); {yygotominor.yy194 = OE_Abort;} break; case 245: /* uniqueflag ::= */ {yygotominor.yy194 = OE_None;} break; @@ -89137,11 +88966,11 @@ break; case 252: /* cmd ::= DROP INDEX ifexists fullname */ {sqlite3DropIndex(pParse, yymsp[0].minor.yy185, yymsp[-1].minor.yy194);} break; case 253: /* cmd ::= VACUUM */ - case 254: /* cmd ::= VACUUM nm */ + case 254: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==254); {sqlite3Vacuum(pParse);} break; case 255: /* cmd ::= PRAGMA nm dbnm */ {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} break; @@ -89170,32 +88999,32 @@ sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy194, yymsp[-4].minor.yy332.a, yymsp[-4].minor.yy332.b, yymsp[-2].minor.yy185, yymsp[0].minor.yy72, yymsp[-10].minor.yy194, yymsp[-8].minor.yy194); yygotominor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); } break; case 272: /* trigger_time ::= BEFORE */ - case 275: /* trigger_time ::= */ + case 275: /* trigger_time ::= */ yytestcase(yyruleno==275); { yygotominor.yy194 = TK_BEFORE; } break; case 273: /* trigger_time ::= AFTER */ { yygotominor.yy194 = TK_AFTER; } break; case 274: /* trigger_time ::= INSTEAD OF */ { yygotominor.yy194 = TK_INSTEAD;} break; case 276: /* trigger_event ::= DELETE|INSERT */ - case 277: /* trigger_event ::= UPDATE */ + case 277: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==277); {yygotominor.yy332.a = yymsp[0].major; yygotominor.yy332.b = 0;} break; case 278: /* trigger_event ::= UPDATE OF inscollist */ {yygotominor.yy332.a = TK_UPDATE; yygotominor.yy332.b = yymsp[0].minor.yy254;} break; case 281: /* when_clause ::= */ - case 298: /* key_opt ::= */ + case 298: /* key_opt ::= */ yytestcase(yyruleno==298); { yygotominor.yy72 = 0; } break; case 282: /* when_clause ::= WHEN expr */ - case 299: /* key_opt ::= KEY expr */ + case 299: /* key_opt ::= KEY expr */ yytestcase(yyruleno==299); { yygotominor.yy72 = yymsp[0].minor.yy190.pExpr; } break; case 283: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ { assert( yymsp[-2].minor.yy145!=0 ); @@ -89308,13 +89137,54 @@ break; case 316: /* vtabarg ::= */ {sqlite3VtabArgInit(pParse);} break; case 318: /* vtabargtoken ::= ANY */ - case 319: /* vtabargtoken ::= lp anylist RP */ - case 320: /* lp ::= LP */ + case 319: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==319); + case 320: /* lp ::= LP */ yytestcase(yyruleno==320); {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} + break; + default: + /* (0) input ::= cmdlist */ yytestcase(yyruleno==0); + /* (1) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==1); + /* (2) cmdlist ::= ecmd */ yytestcase(yyruleno==2); + /* (3) ecmd ::= SEMI */ yytestcase(yyruleno==3); + /* (4) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==4); + /* (10) trans_opt ::= */ yytestcase(yyruleno==10); + /* (11) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==11); + /* (12) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==12); + /* (20) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==20); + /* (21) savepoint_opt ::= */ yytestcase(yyruleno==21); + /* (25) cmd ::= create_table create_table_args */ yytestcase(yyruleno==25); + /* (34) columnlist ::= columnlist COMMA column */ yytestcase(yyruleno==34); + /* (35) columnlist ::= column */ yytestcase(yyruleno==35); + /* (44) type ::= */ yytestcase(yyruleno==44); + /* (51) signed ::= plus_num */ yytestcase(yyruleno==51); + /* (52) signed ::= minus_num */ yytestcase(yyruleno==52); + /* (53) carglist ::= carglist carg */ yytestcase(yyruleno==53); + /* (54) carglist ::= */ yytestcase(yyruleno==54); + /* (55) carg ::= CONSTRAINT nm ccons */ yytestcase(yyruleno==55); + /* (56) carg ::= ccons */ yytestcase(yyruleno==56); + /* (62) ccons ::= NULL onconf */ yytestcase(yyruleno==62); + /* (89) conslist ::= conslist COMMA tcons */ yytestcase(yyruleno==89); + /* (90) conslist ::= conslist tcons */ yytestcase(yyruleno==90); + /* (91) conslist ::= tcons */ yytestcase(yyruleno==91); + /* (92) tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==92); + /* (268) plus_opt ::= PLUS */ yytestcase(yyruleno==268); + /* (269) plus_opt ::= */ yytestcase(yyruleno==269); + /* (279) foreach_clause ::= */ yytestcase(yyruleno==279); + /* (280) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==280); + /* (300) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==300); + /* (301) database_kw_opt ::= */ yytestcase(yyruleno==301); + /* (309) kwcolumn_opt ::= */ yytestcase(yyruleno==309); + /* (310) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==310); + /* (314) vtabarglist ::= vtabarg */ yytestcase(yyruleno==314); + /* (315) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==315); + /* (317) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==317); + /* (321) anylist ::= */ yytestcase(yyruleno==321); + /* (322) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==322); + /* (323) anylist ::= anylist ANY */ yytestcase(yyruleno==323); break; }; yygoto = yyRuleInfo[yyruleno].lhs; yysize = yyRuleInfo[yyruleno].nrhs; yypParser->yyidx -= yysize; @@ -89343,10 +89213,11 @@ } /* ** The following code executes when the parse fails */ +#ifndef YYNOERRORRECOVERY static void yy_parse_failed( yyParser *yypParser /* The parser */ ){ sqlite3ParserARG_FETCH; #ifndef NDEBUG @@ -89357,10 +89228,11 @@ while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); /* Here code is inserted which will be executed whenever the ** parser fails */ sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */ } +#endif /* YYNOERRORRECOVERY */ /* ** The following code executes when a syntax error first occurs. */ static void yy_syntax_error( @@ -89527,10 +89399,22 @@ yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2); } } yypParser->yyerrcnt = 3; yyerrorhit = 1; +#elif defined(YYNOERRORRECOVERY) + /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to + ** do any kind of error recovery. Instead, simply invoke the syntax + ** error routine and continue going as if nothing had happened. + ** + ** Applications can set this macro (for example inside %include) if + ** they intend to abandon the parse upon the first syntax error seen. + */ + yy_syntax_error(yypParser,yymajor,yyminorunion); + yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); + yymajor = YYNOCODE; + #else /* YYERRORSYMBOL is not defined */ /* This is what we do if the grammar does not define ERROR: ** ** * Report an error message, and throw away the input token. ** @@ -89571,11 +89455,11 @@ ** ** This file contains C code that splits an SQL input string up into ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** -** $Id: tokenize.c,v 1.158 2009/05/28 01:00:55 drh Exp $ +** $Id: tokenize.c,v 1.161 2009/06/17 01:17:13 drh Exp $ */ /* ** The charMap() macro maps alphabetic characters into their ** lower-case ASCII equivalent. On ASCII machines, this is just @@ -89624,11 +89508,11 @@ /************** Begin file keywordhash.h *************************************/ /***** This file contains automatically generated code ****** ** ** The code in this file has been automatically generated by ** -** $Header: /sqlite/sqlite/tool/mkkeywordhash.c,v 1.37 2009/02/01 00:00:46 drh Exp $ +** $Header: /sqlite/sqlite/tool/mkkeywordhash.c,v 1.38 2009/06/09 14:27:41 drh Exp $ ** ** The code in this file implements a function that determines whether ** or not a given identifier is really an SQL keyword. The same thing ** might be implemented more directly using a hand-written hash table. ** But by using this automatically generated code, the size of the code @@ -89759,129 +89643,129 @@ h = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n) % 127; for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){ if( aLen[i]==n && sqlite3StrNICmp(&zText[aOffset[i]],z,n)==0 ){ - testcase( i==0 ); /* TK_REINDEX */ - testcase( i==1 ); /* TK_INDEXED */ - testcase( i==2 ); /* TK_INDEX */ - testcase( i==3 ); /* TK_DESC */ - testcase( i==4 ); /* TK_ESCAPE */ - testcase( i==5 ); /* TK_EACH */ - testcase( i==6 ); /* TK_CHECK */ - testcase( i==7 ); /* TK_KEY */ - testcase( i==8 ); /* TK_BEFORE */ - testcase( i==9 ); /* TK_FOREIGN */ - testcase( i==10 ); /* TK_FOR */ - testcase( i==11 ); /* TK_IGNORE */ - testcase( i==12 ); /* TK_LIKE_KW */ - testcase( i==13 ); /* TK_EXPLAIN */ - testcase( i==14 ); /* TK_INSTEAD */ - testcase( i==15 ); /* TK_ADD */ - testcase( i==16 ); /* TK_DATABASE */ - testcase( i==17 ); /* TK_AS */ - testcase( i==18 ); /* TK_SELECT */ - testcase( i==19 ); /* TK_TABLE */ - testcase( i==20 ); /* TK_JOIN_KW */ - testcase( i==21 ); /* TK_THEN */ - testcase( i==22 ); /* TK_END */ - testcase( i==23 ); /* TK_DEFERRABLE */ - testcase( i==24 ); /* TK_ELSE */ - testcase( i==25 ); /* TK_EXCEPT */ - testcase( i==26 ); /* TK_TRANSACTION */ - testcase( i==27 ); /* TK_ON */ - testcase( i==28 ); /* TK_JOIN_KW */ - testcase( i==29 ); /* TK_ALTER */ - testcase( i==30 ); /* TK_RAISE */ - testcase( i==31 ); /* TK_EXCLUSIVE */ - testcase( i==32 ); /* TK_EXISTS */ - testcase( i==33 ); /* TK_SAVEPOINT */ - testcase( i==34 ); /* TK_INTERSECT */ - testcase( i==35 ); /* TK_TRIGGER */ - testcase( i==36 ); /* TK_REFERENCES */ - testcase( i==37 ); /* TK_CONSTRAINT */ - testcase( i==38 ); /* TK_INTO */ - testcase( i==39 ); /* TK_OFFSET */ - testcase( i==40 ); /* TK_OF */ - testcase( i==41 ); /* TK_SET */ - testcase( i==42 ); /* TK_TEMP */ - testcase( i==43 ); /* TK_TEMP */ - testcase( i==44 ); /* TK_OR */ - testcase( i==45 ); /* TK_UNIQUE */ - testcase( i==46 ); /* TK_QUERY */ - testcase( i==47 ); /* TK_ATTACH */ - testcase( i==48 ); /* TK_HAVING */ - testcase( i==49 ); /* TK_GROUP */ - testcase( i==50 ); /* TK_UPDATE */ - testcase( i==51 ); /* TK_BEGIN */ - testcase( i==52 ); /* TK_JOIN_KW */ - testcase( i==53 ); /* TK_RELEASE */ - testcase( i==54 ); /* TK_BETWEEN */ - testcase( i==55 ); /* TK_NOTNULL */ - testcase( i==56 ); /* TK_NOT */ - testcase( i==57 ); /* TK_NULL */ - testcase( i==58 ); /* TK_LIKE_KW */ - testcase( i==59 ); /* TK_CASCADE */ - testcase( i==60 ); /* TK_ASC */ - testcase( i==61 ); /* TK_DELETE */ - testcase( i==62 ); /* TK_CASE */ - testcase( i==63 ); /* TK_COLLATE */ - testcase( i==64 ); /* TK_CREATE */ - testcase( i==65 ); /* TK_CTIME_KW */ - testcase( i==66 ); /* TK_DETACH */ - testcase( i==67 ); /* TK_IMMEDIATE */ - testcase( i==68 ); /* TK_JOIN */ - testcase( i==69 ); /* TK_INSERT */ - testcase( i==70 ); /* TK_MATCH */ - testcase( i==71 ); /* TK_PLAN */ - testcase( i==72 ); /* TK_ANALYZE */ - testcase( i==73 ); /* TK_PRAGMA */ - testcase( i==74 ); /* TK_ABORT */ - testcase( i==75 ); /* TK_VALUES */ - testcase( i==76 ); /* TK_VIRTUAL */ - testcase( i==77 ); /* TK_LIMIT */ - testcase( i==78 ); /* TK_WHEN */ - testcase( i==79 ); /* TK_WHERE */ - testcase( i==80 ); /* TK_RENAME */ - testcase( i==81 ); /* TK_AFTER */ - testcase( i==82 ); /* TK_REPLACE */ - testcase( i==83 ); /* TK_AND */ - testcase( i==84 ); /* TK_DEFAULT */ - testcase( i==85 ); /* TK_AUTOINCR */ - testcase( i==86 ); /* TK_TO */ - testcase( i==87 ); /* TK_IN */ - testcase( i==88 ); /* TK_CAST */ - testcase( i==89 ); /* TK_COLUMNKW */ - testcase( i==90 ); /* TK_COMMIT */ - testcase( i==91 ); /* TK_CONFLICT */ - testcase( i==92 ); /* TK_JOIN_KW */ - testcase( i==93 ); /* TK_CTIME_KW */ - testcase( i==94 ); /* TK_CTIME_KW */ - testcase( i==95 ); /* TK_PRIMARY */ - testcase( i==96 ); /* TK_DEFERRED */ - testcase( i==97 ); /* TK_DISTINCT */ - testcase( i==98 ); /* TK_IS */ - testcase( i==99 ); /* TK_DROP */ - testcase( i==100 ); /* TK_FAIL */ - testcase( i==101 ); /* TK_FROM */ - testcase( i==102 ); /* TK_JOIN_KW */ - testcase( i==103 ); /* TK_LIKE_KW */ - testcase( i==104 ); /* TK_BY */ - testcase( i==105 ); /* TK_IF */ - testcase( i==106 ); /* TK_ISNULL */ - testcase( i==107 ); /* TK_ORDER */ - testcase( i==108 ); /* TK_RESTRICT */ - testcase( i==109 ); /* TK_JOIN_KW */ - testcase( i==110 ); /* TK_JOIN_KW */ - testcase( i==111 ); /* TK_ROLLBACK */ - testcase( i==112 ); /* TK_ROW */ - testcase( i==113 ); /* TK_UNION */ - testcase( i==114 ); /* TK_USING */ - testcase( i==115 ); /* TK_VACUUM */ - testcase( i==116 ); /* TK_VIEW */ - testcase( i==117 ); /* TK_INITIALLY */ - testcase( i==118 ); /* TK_ALL */ + testcase( i==0 ); /* REINDEX */ + testcase( i==1 ); /* INDEXED */ + testcase( i==2 ); /* INDEX */ + testcase( i==3 ); /* DESC */ + testcase( i==4 ); /* ESCAPE */ + testcase( i==5 ); /* EACH */ + testcase( i==6 ); /* CHECK */ + testcase( i==7 ); /* KEY */ + testcase( i==8 ); /* BEFORE */ + testcase( i==9 ); /* FOREIGN */ + testcase( i==10 ); /* FOR */ + testcase( i==11 ); /* IGNORE */ + testcase( i==12 ); /* REGEXP */ + testcase( i==13 ); /* EXPLAIN */ + testcase( i==14 ); /* INSTEAD */ + testcase( i==15 ); /* ADD */ + testcase( i==16 ); /* DATABASE */ + testcase( i==17 ); /* AS */ + testcase( i==18 ); /* SELECT */ + testcase( i==19 ); /* TABLE */ + testcase( i==20 ); /* LEFT */ + testcase( i==21 ); /* THEN */ + testcase( i==22 ); /* END */ + testcase( i==23 ); /* DEFERRABLE */ + testcase( i==24 ); /* ELSE */ + testcase( i==25 ); /* EXCEPT */ + testcase( i==26 ); /* TRANSACTION */ + testcase( i==27 ); /* ON */ + testcase( i==28 ); /* NATURAL */ + testcase( i==29 ); /* ALTER */ + testcase( i==30 ); /* RAISE */ + testcase( i==31 ); /* EXCLUSIVE */ + testcase( i==32 ); /* EXISTS */ + testcase( i==33 ); /* SAVEPOINT */ + testcase( i==34 ); /* INTERSECT */ + testcase( i==35 ); /* TRIGGER */ + testcase( i==36 ); /* REFERENCES */ + testcase( i==37 ); /* CONSTRAINT */ + testcase( i==38 ); /* INTO */ + testcase( i==39 ); /* OFFSET */ + testcase( i==40 ); /* OF */ + testcase( i==41 ); /* SET */ + testcase( i==42 ); /* TEMP */ + testcase( i==43 ); /* TEMPORARY */ + testcase( i==44 ); /* OR */ + testcase( i==45 ); /* UNIQUE */ + testcase( i==46 ); /* QUERY */ + testcase( i==47 ); /* ATTACH */ + testcase( i==48 ); /* HAVING */ + testcase( i==49 ); /* GROUP */ + testcase( i==50 ); /* UPDATE */ + testcase( i==51 ); /* BEGIN */ + testcase( i==52 ); /* INNER */ + testcase( i==53 ); /* RELEASE */ + testcase( i==54 ); /* BETWEEN */ + testcase( i==55 ); /* NOTNULL */ + testcase( i==56 ); /* NOT */ + testcase( i==57 ); /* NULL */ + testcase( i==58 ); /* LIKE */ + testcase( i==59 ); /* CASCADE */ + testcase( i==60 ); /* ASC */ + testcase( i==61 ); /* DELETE */ + testcase( i==62 ); /* CASE */ + testcase( i==63 ); /* COLLATE */ + testcase( i==64 ); /* CREATE */ + testcase( i==65 ); /* CURRENT_DATE */ + testcase( i==66 ); /* DETACH */ + testcase( i==67 ); /* IMMEDIATE */ + testcase( i==68 ); /* JOIN */ + testcase( i==69 ); /* INSERT */ + testcase( i==70 ); /* MATCH */ + testcase( i==71 ); /* PLAN */ + testcase( i==72 ); /* ANALYZE */ + testcase( i==73 ); /* PRAGMA */ + testcase( i==74 ); /* ABORT */ + testcase( i==75 ); /* VALUES */ + testcase( i==76 ); /* VIRTUAL */ + testcase( i==77 ); /* LIMIT */ + testcase( i==78 ); /* WHEN */ + testcase( i==79 ); /* WHERE */ + testcase( i==80 ); /* RENAME */ + testcase( i==81 ); /* AFTER */ + testcase( i==82 ); /* REPLACE */ + testcase( i==83 ); /* AND */ + testcase( i==84 ); /* DEFAULT */ + testcase( i==85 ); /* AUTOINCREMENT */ + testcase( i==86 ); /* TO */ + testcase( i==87 ); /* IN */ + testcase( i==88 ); /* CAST */ + testcase( i==89 ); /* COLUMN */ + testcase( i==90 ); /* COMMIT */ + testcase( i==91 ); /* CONFLICT */ + testcase( i==92 ); /* CROSS */ + testcase( i==93 ); /* CURRENT_TIMESTAMP */ + testcase( i==94 ); /* CURRENT_TIME */ + testcase( i==95 ); /* PRIMARY */ + testcase( i==96 ); /* DEFERRED */ + testcase( i==97 ); /* DISTINCT */ + testcase( i==98 ); /* IS */ + testcase( i==99 ); /* DROP */ + testcase( i==100 ); /* FAIL */ + testcase( i==101 ); /* FROM */ + testcase( i==102 ); /* FULL */ + testcase( i==103 ); /* GLOB */ + testcase( i==104 ); /* BY */ + testcase( i==105 ); /* IF */ + testcase( i==106 ); /* ISNULL */ + testcase( i==107 ); /* ORDER */ + testcase( i==108 ); /* RESTRICT */ + testcase( i==109 ); /* OUTER */ + testcase( i==110 ); /* RIGHT */ + testcase( i==111 ); /* ROLLBACK */ + testcase( i==112 ); /* ROW */ + testcase( i==113 ); /* UNION */ + testcase( i==114 ); /* USING */ + testcase( i==115 ); /* VACUUM */ + testcase( i==116 ); /* VIEW */ + testcase( i==117 ); /* INITIALLY */ + testcase( i==118 ); /* ALL */ return aCode[i]; } } return TK_ID; } @@ -89947,10 +89831,15 @@ */ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ int i, c; switch( *z ){ case ' ': case '\t': case '\n': case '\f': case '\r': { + testcase( z[0]==' ' ); + testcase( z[0]=='\t' ); + testcase( z[0]=='\n' ); + testcase( z[0]=='\f' ); + testcase( z[0]=='\r' ); for(i=1; sqlite3Isspace(z[i]); i++){} *tokenType = TK_SPACE; return i; } case '-': { @@ -90059,10 +89948,13 @@ } case '`': case '\'': case '"': { int delim = z[0]; + testcase( delim=='`' ); + testcase( delim=='\'' ); + testcase( delim=='"' ); for(i=1; (c=z[i])!=0; i++){ if( c==delim ){ if( z[i+1]==delim ){ i++; }else{ @@ -90092,10 +89984,14 @@ /* If the next character is a digit, this is a floating point ** number that begins with ".". Fall thru into the next case */ } case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { + testcase( z[0]=='0' ); testcase( z[0]=='1' ); testcase( z[0]=='2' ); + testcase( z[0]=='3' ); testcase( z[0]=='4' ); testcase( z[0]=='5' ); + testcase( z[0]=='6' ); testcase( z[0]=='7' ); testcase( z[0]=='8' ); + testcase( z[0]=='9' ); *tokenType = TK_INTEGER; for(i=0; sqlite3Isdigit(z[i]); i++){} #ifndef SQLITE_OMIT_FLOATING_POINT if( z[i]=='.' ){ i++; @@ -90143,10 +90039,11 @@ case '$': #endif case '@': /* For compatibility with MS SQL Server */ case ':': { int n = 0; + testcase( z[0]=='$' ); testcase( z[0]=='@' ); testcase( z[0]==':' ); *tokenType = TK_VARIABLE; for(i=1; (c=z[i])!=0; i++){ if( IdChar(c) ){ n++; #ifndef SQLITE_OMIT_TCL_VARIABLE @@ -90170,10 +90067,11 @@ if( n==0 ) *tokenType = TK_ILLEGAL; return i; } #ifndef SQLITE_OMIT_BLOB_LITERAL case 'x': case 'X': { + testcase( z[0]=='x' ); testcase( z[0]=='X' ); if( z[1]=='\'' ){ *tokenType = TK_BLOB; for(i=2; (c=z[i])!=0 && c!='\''; i++){ if( !sqlite3Isxdigit(c) ){ *tokenType = TK_ILLEGAL; @@ -90248,12 +90146,12 @@ break; } switch( tokenType ){ case TK_SPACE: { if( db->u1.isInterrupted ){ - pParse->rc = SQLITE_INTERRUPT; - sqlite3SetString(pzErrMsg, db, "interrupt"); + sqlite3ErrorMsg(pParse, "interrupt"); + pParse->rc = SQLITE_INTERRUPT; goto abort_parse; } break; } case TK_ILLEGAL: { @@ -90296,16 +90194,13 @@ pParse->rc = SQLITE_NOMEM; } if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){ sqlite3SetString(&pParse->zErrMsg, db, "%s", sqlite3ErrStr(pParse->rc)); } + assert( pzErrMsg!=0 ); if( pParse->zErrMsg ){ - if( *pzErrMsg==0 ){ - *pzErrMsg = pParse->zErrMsg; - }else{ - sqlite3DbFree(db, pParse->zErrMsg); - } + *pzErrMsg = pParse->zErrMsg; pParse->zErrMsg = 0; nErr++; } if( pParse->pVdbe && pParse->nErr>0 && pParse->nested==0 ){ sqlite3VdbeDelete(pParse->pVdbe); @@ -90336,11 +90231,11 @@ while( pParse->pZombieTab ){ Table *p = pParse->pZombieTab; pParse->pZombieTab = p->pNextZombie; sqlite3DeleteTable(p); } - if( nErr>0 && (pParse->rc==SQLITE_OK || pParse->rc==SQLITE_DONE) ){ + if( nErr>0 && pParse->rc==SQLITE_OK ){ pParse->rc = SQLITE_ERROR; } return nErr; } @@ -90639,11 +90534,11 @@ ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: main.c,v 1.555 2009/06/01 16:53:10 shane Exp $ +** $Id: main.c,v 1.558 2009/06/19 14:06:03 drh Exp $ */ #ifdef SQLITE_ENABLE_FTS3 /************** Include fts3.h in the middle of main.c ***********************/ /************** Begin file fts3.h ********************************************/ @@ -91061,11 +90956,10 @@ memset(&sqlite3GlobalConfig.m, 0, sizeof(sqlite3GlobalConfig.m)); }else{ /* The heap pointer is not NULL, then install one of the ** mem5.c/mem3.c methods. If neither ENABLE_MEMSYS3 nor ** ENABLE_MEMSYS5 is defined, return an error. - ** the default case and return an error. */ #ifdef SQLITE_ENABLE_MEMSYS3 sqlite3GlobalConfig.m = *sqlite3MemGetMemsys3(); #endif #ifdef SQLITE_ENABLE_MEMSYS5 @@ -91295,17 +91189,10 @@ } if( !sqlite3SafetyCheckSickOrOk(db) ){ return SQLITE_MISUSE; } sqlite3_mutex_enter(db->mutex); - -#ifdef SQLITE_SSE - { - extern void sqlite3SseCleanup(sqlite3*); - sqlite3SseCleanup(db); - } -#endif sqlite3ResetInternalSchema(db, 0); /* If a transaction is open, the ResetInternalSchema() call above ** will not have called the xDisconnect() method on any virtual
Modified src/sqlite3.h from [3026073613] to [eb5eaf8a49].
@@ -28,11 +28,11 @@ ** The name of this file under configuration management is "sqlite.h.in". ** The makefile makes some minor changes to this file (such as inserting ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. ** -** @(#) $Id: sqlite.h.in,v 1.455 2009/05/24 21:59:28 drh Exp $ +** @(#) $Id: sqlite.h.in,v 1.458 2009/06/19 22:50:31 drh Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ #include <stdarg.h> /* Needed for the definition of va_list */ @@ -97,12 +97,12 @@ ** ** See also: [sqlite3_libversion()] and [sqlite3_libversion_number()]. ** ** Requirements: [H10011] [H10014] */ -#define SQLITE_VERSION "3.6.14" -#define SQLITE_VERSION_NUMBER 3006014 +#define SQLITE_VERSION "3.6.15" +#define SQLITE_VERSION_NUMBER 3006015 /* ** CAPI3REF: Run-Time Library Version Numbers {H10020} <S60100> ** KEYWORDS: sqlite3_version ** @@ -492,10 +492,16 @@ ** [sqlite3_file] object (or, more commonly, a subclass of the ** [sqlite3_file] object) with a pointer to an instance of this object. ** This object defines the methods used to perform various operations ** against the open file represented by the [sqlite3_file] object. ** +** If the xOpen method sets the sqlite3_file.pMethods element +** to a non-NULL pointer, then the sqlite3_io_methods.xClose method +** may be invoked even if the xOpen reported that it failed. The +** only way to prevent a call to xClose following a failed xOpen +** is for the xOpen to set the sqlite3_file.pMethods element to NULL. +** ** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or ** [SQLITE_SYNC_FULL]. The first choice is the normal fsync(). ** The second choice is a Mac OS X style fullsync. The [SQLITE_SYNC_DATAONLY] ** flag may be ORed in to indicate that only the data of the file ** and not its inode needs to be synced. @@ -652,15 +658,15 @@ ** ** SQLite will guarantee that the zFilename parameter to xOpen ** is either a NULL pointer or string obtained ** from xFullPathname(). SQLite further guarantees that ** the string will be valid and unchanged until xClose() is -** called. Because of the previous sentense, +** called. Because of the previous sentence, ** the [sqlite3_file] can safely store a pointer to the ** filename if it needs to remember the filename for some reason. ** If the zFilename parameter is xOpen is a NULL pointer then xOpen -** must invite its own temporary name for the file. Whenever the +** must invent its own temporary name for the file. Whenever the ** xFilename parameter is NULL it will also be the case that the ** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE]. ** ** The flags argument to xOpen() includes all bits set in ** the flags argument to [sqlite3_open_v2()]. Or if [sqlite3_open()] @@ -712,11 +718,16 @@ ** for exclusive access. ** ** At least szOsFile bytes of memory are allocated by SQLite ** to hold the [sqlite3_file] structure passed as the third ** argument to xOpen. The xOpen method does not have to -** allocate the structure; it should just fill it in. +** allocate the structure; it should just fill it in. Note that +** the xOpen method must set the sqlite3_file.pMethods to either +** a valid [sqlite3_io_methods] object or to NULL. xOpen must do +** this even if the open fails. SQLite expects that the sqlite3_file.pMethods +** element will be valid after xOpen returns regardless of the success +** or failure of the xOpen call. ** ** The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] ** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to ** test whether a file is readable and writable, or [SQLITE_ACCESS_READ] ** to test whether a file is at least readable. The file can be a @@ -1034,16 +1045,18 @@ ** </ul> ** </dd> ** ** <dt>SQLITE_CONFIG_SCRATCH</dt> ** <dd>This option specifies a static memory buffer that SQLite can use for -** scratch memory. There are three arguments: A pointer to the memory, the -** size of each scratch buffer (sz), and the number of buffers (N). The sz +** scratch memory. There are three arguments: A pointer an 8-byte +** aligned memory buffer from which the scrach allocations will be +** drawn, the size of each scratch allocation (sz), +** and the maximum number of scratch allocations (N). The sz ** argument must be a multiple of 16. The sz parameter should be a few bytes -** larger than the actual scratch space required due internal overhead. -** The first -** argument should point to an allocation of at least sz*N bytes of memory. +** larger than the actual scratch space required due to internal overhead. +** The first argument should pointer to an 8-byte aligned buffer +** of at least sz*N bytes of memory. ** SQLite will use no more than one scratch buffer at once per thread, so ** N should be set to the expected maximum number of threads. The sz ** parameter should be 6 times the size of the largest database page size. ** Scratch buffers are used as part of the btree balance operation. If ** The btree balancer needs additional memory beyond what is provided by @@ -1053,33 +1066,41 @@ ** <dt>SQLITE_CONFIG_PAGECACHE</dt> ** <dd>This option specifies a static memory buffer that SQLite can use for ** the database page cache with the default page cache implemenation. ** This configuration should not be used if an application-define page ** cache implementation is loaded using the SQLITE_CONFIG_PCACHE option. -** There are three arguments to this option: A pointer to the +** There are three arguments to this option: A pointer to 8-byte aligned ** memory, the size of each page buffer (sz), and the number of pages (N). -** The sz argument must be a power of two between 512 and 32768. The first +** The sz argument should be the size of the largest database page +** (a power of two between 512 and 32768) plus a little extra for each +** page header. The page header size is 20 to 40 bytes depending on +** the host architecture. It is harmless, apart from the wasted memory, +** to make sz a little too large. The first ** argument should point to an allocation of at least sz*N bytes of memory. ** SQLite will use the memory provided by the first argument to satisfy its ** memory needs for the first N pages that it adds to cache. If additional ** page cache memory is needed beyond what is provided by this option, then ** SQLite goes to [sqlite3_malloc()] for the additional storage space. ** The implementation might use one or more of the N buffers to hold -** memory accounting information. </dd> +** memory accounting information. The pointer in the first argument must +** be aligned to an 8-byte boundary or subsequent behavior of SQLite +** will be undefined.</dd> ** ** <dt>SQLITE_CONFIG_HEAP</dt> ** <dd>This option specifies a static memory buffer that SQLite will use ** for all of its dynamic memory allocation needs beyond those provided ** for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE]. -** There are three arguments: A pointer to the memory, the number of -** bytes in the memory buffer, and the minimum allocation size. If -** the first pointer (the memory pointer) is NULL, then SQLite reverts +** There are three arguments: An 8-byte aligned pointer to the memory, +** the number of bytes in the memory buffer, and the minimum allocation size. +** If the first pointer (the memory pointer) is NULL, then SQLite reverts ** to using its default memory allocator (the system malloc() implementation), ** undoing any prior invocation of [SQLITE_CONFIG_MALLOC]. If the ** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or ** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory -** allocator is engaged to handle all of SQLites memory allocation needs.</dd> +** allocator is engaged to handle all of SQLites memory allocation needs. +** The first pointer (the memory pointer) must be aligned to an 8-byte +** boundary or subsequent behavior of SQLite will be undefined.</dd> ** ** <dt>SQLITE_CONFIG_MUTEX</dt> ** <dd>This option takes a single argument which is a pointer to an ** instance of the [sqlite3_mutex_methods] structure. The argument specifies ** alternative low-level mutex routines to be used in place @@ -1146,13 +1167,13 @@ ** <dl> ** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt> ** <dd>This option takes three additional arguments that determine the ** [lookaside memory allocator] configuration for the [database connection]. ** The first argument (the third parameter to [sqlite3_db_config()] is a -** pointer to a memory buffer to use for lookaside memory. The first -** argument may be NULL in which case SQLite will allocate the lookaside -** buffer itself using [sqlite3_malloc()]. The second argument is the +** pointer to an 8-byte aligned memory buffer to use for lookaside memory. +** The first argument may be NULL in which case SQLite will allocate the +** lookaside buffer itself using [sqlite3_malloc()]. The second argument is the ** size of each lookaside buffer slot and the third argument is the number of ** slots. The size of the buffer in the first argument must be greater than ** or equal to the product of the second and third arguments.</dd> ** ** </dl>