@@ -1,7 +1,7 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-** version 3.6.14.2. By combining all the individual C code files into this
+** version 3.6.14. 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
@@ -10,15 +10,15 @@
** 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
-** 5533 lines past this header comment.) Additional code files may be
+** 5605 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-05-25 12:34:31 UTC.
+** This amalgamation was generated on 2009-06-07 12:34:52 UTC.
*/
#define SQLITE_CORE 1
#define SQLITE_AMALGAMATION 1
#ifndef SQLITE_PRIVATE
@@ -40,9 +40,9 @@
**
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.868 2009/05/04 11:42:30 danielk1977 Exp $
+** @(#) $Id: sqliteInt.h,v 1.882 2009/06/05 14:17:23 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@@ -274,23 +274,38 @@
#include <inttypes.h>
#endif
/*
- * This macro is used to "hide" some ugliness in casting an int
- * value to a ptr value under the MSVC 64-bit compiler. Casting
- * non 64-bit values to ptr types results in a "hard" error with
- * the MSVC 64-bit compiler which this attempts to avoid.
- *
- * A simple compiler pragma or casting sequence could not be found
- * to correct this in all situations, so this macro was introduced.
- *
- * It could be argued that the intptr_t type could be used in this
- * case, but that type is not available on all compilers, or
- * requires the #include of specific headers which differs between
- * platforms.
- */
-#define SQLITE_INT_TO_PTR(X) ((void*)&((char*)0)[X])
-#define SQLITE_PTR_TO_INT(X) ((int)(((char*)X)-(char*)0))
+** This macro is used to "hide" some ugliness in casting an int
+** value to a ptr value under the MSVC 64-bit compiler. Casting
+** non 64-bit values to ptr types results in a "hard" error with
+** the MSVC 64-bit compiler which this attempts to avoid.
+**
+** A simple compiler pragma or casting sequence could not be found
+** to correct this in all situations, so this macro was introduced.
+**
+** It could be argued that the intptr_t type could be used in this
+** case, but that type is not available on all compilers, or
+** requires the #include of specific headers which differs between
+** platforms.
+**
+** Ticket #3860: The llvm-gcc-4.2 compiler from Apple chokes on
+** the ((void*)&((char*)0)[X]) construct. But MSVC chokes on ((void*)(X)).
+** So we have to define the macros in different ways depending on the
+** compiler.
+*/
+#if defined(__GNUC__)
+# if defined(HAVE_STDINT_H)
+# define SQLITE_INT_TO_PTR(X) ((void*)(intptr_t)(X))
+# define SQLITE_PTR_TO_INT(X) ((int)(intptr_t)(X))
+# else
+# define SQLITE_INT_TO_PTR(X) ((void*)(X))
+# define SQLITE_PTR_TO_INT(X) ((int)(X))
+# endif
+#else
+# define SQLITE_INT_TO_PTR(X) ((void*)&((char*)0)[X])
+# define SQLITE_PTR_TO_INT(X) ((int)(((char*)X)-(char*)0))
+#endif
/*
** These #defines should enable >2GB file support on POSIX if the
** underlying operating system supports it. If the OS lacks
@@ -531,9 +546,9 @@
** 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.447 2009/04/30 15:59:56 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.455 2009/05/24 21:59:28 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h> /* Needed for the definition of va_list */
@@ -600,9 +615,9 @@
** See also: [sqlite3_libversion()] and [sqlite3_libversion_number()].
**
** Requirements: [H10011] [H10014]
*/
-#define SQLITE_VERSION "3.6.14.2"
+#define SQLITE_VERSION "3.6.14"
#define SQLITE_VERSION_NUMBER 3006014
/*
** CAPI3REF: Run-Time Library Version Numbers {H10020} <S60100>
@@ -893,22 +908,22 @@
** 3rd parameter to the [sqlite3_open_v2()] interface and
** in the 4th parameter to the xOpen method of the
** [sqlite3_vfs] object.
*/
-#define SQLITE_OPEN_READONLY 0x00000001
-#define SQLITE_OPEN_READWRITE 0x00000002
-#define SQLITE_OPEN_CREATE 0x00000004
-#define SQLITE_OPEN_DELETEONCLOSE 0x00000008
-#define SQLITE_OPEN_EXCLUSIVE 0x00000010
-#define SQLITE_OPEN_MAIN_DB 0x00000100
-#define SQLITE_OPEN_TEMP_DB 0x00000200
-#define SQLITE_OPEN_TRANSIENT_DB 0x00000400
-#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800
-#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000
-#define SQLITE_OPEN_SUBJOURNAL 0x00002000
-#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000
-#define SQLITE_OPEN_NOMUTEX 0x00008000
-#define SQLITE_OPEN_FULLMUTEX 0x00010000
+#define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */
+#define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */
+#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */
+#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */
+#define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */
+#define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */
+#define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */
+#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */
+#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */
+#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */
+#define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */
+#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */
+#define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */
+#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */
/*
** CAPI3REF: Device Characteristics {H10240} <H11120>
**
@@ -1203,11 +1218,16 @@
** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be
** deleted when it is closed. The [SQLITE_OPEN_DELETEONCLOSE]
** will be set for TEMP databases, journals and for subjournals.
**
-** The [SQLITE_OPEN_EXCLUSIVE] flag means the file should be opened
-** for exclusive access. This flag is set for all files except
-** for the main database file.
+** The [SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction
+** with the [SQLITE_OPEN_CREATE] flag, which are both directly
+** analogous to the O_EXCL and O_CREAT flags of the POSIX open()
+** API. The SQLITE_OPEN_EXCLUSIVE flag, when paired with the
+** SQLITE_OPEN_CREATE, is used to indicate that file should always
+** be created, and that it is an error if it already exists.
+** It is <i>not</i> used to indicate the file should be opened
+** 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
@@ -1778,11 +1798,11 @@
** The count includes all changes from all
** [CREATE TRIGGER | trigger] contexts. However,
** the count does not include changes used to implement [REPLACE] constraints,
** do rollbacks or ABORT processing, or [DROP TABLE] processing. The
-** count does not rows of views that fire an [INSTEAD OF trigger], though if
-** the INSTEAD OF trigger makes changes of its own, those changes are
-** counted.
+** count does not include rows of views that fire an [INSTEAD OF trigger],
+** though if the INSTEAD OF trigger makes changes of its own, those changes
+** are counted.
** The changes are counted as soon as the statement that makes them is
** completed (when the statement handle is passed to [sqlite3_reset()] or
** [sqlite3_finalize()]).
**
@@ -3570,10 +3590,13 @@
** will result in [SQLITE_ERROR] being returned.
**
** The third parameter (nArg)
** is the number of arguments that the SQL function or
-** aggregate takes. If this parameter is negative, then the SQL function or
-** aggregate may take any number of arguments.
+** aggregate takes. If this parameter is -1, then the SQL function or
+** aggregate may take any number of arguments between 0 and the limit
+** set by [sqlite3_limit]([SQLITE_LIMIT_FUNCTION_ARG]). If the third
+** parameter is less than -1 or greater than 127 then the behavior is
+** undefined.
**
** The fourth parameter, eTextRep, specifies what
** [SQLITE_UTF8 | text encoding] this SQL function prefers for
** its parameters. Any SQL function implementation should be able to work
@@ -3622,9 +3645,9 @@
** close the database connection nor finalize or reset the prepared
** statement in which the function is running.
**
** Requirements:
-** [H16103] [H16106] [H16109] [H16112] [H16118] [H16121] [H16124] [H16127]
+** [H16103] [H16106] [H16109] [H16112] [H16118] [H16121] [H16127]
** [H16130] [H16133] [H16136] [H16139] [H16142]
*/
SQLITE_API int sqlite3_create_function(
sqlite3 *db,
@@ -4237,13 +4260,13 @@
/*
** CAPI3REF: Commit And Rollback Notification Callbacks {H12950} <S60400>
**
** The sqlite3_commit_hook() interface registers a callback
-** function to be invoked whenever a transaction is committed.
+** function to be invoked whenever a transaction is [COMMIT | committed].
** Any callback set by a previous call to sqlite3_commit_hook()
** for the same database connection is overridden.
** The sqlite3_rollback_hook() interface registers a callback
-** function to be invoked whenever a transaction is committed.
+** function to be invoked whenever a transaction is [ROLLBACK | rolled back].
** Any callback set by a previous call to sqlite3_commit_hook()
** for the same database connection is overridden.
** The pArg argument is passed through to the callback.
** If the callback on a commit hook function returns non-zero,
@@ -4261,8 +4284,14 @@
** database connections for the meaning of "modify" in this paragraph.
**
** Registering a NULL function disables the callback.
**
+** When the commit hook callback routine returns zero, the [COMMIT]
+** operation is allowed to continue normally. If the commit hook
+** returns non-zero, then the [COMMIT] is converted into a [ROLLBACK].
+** The rollback hook is invoked on a rollback that results from a commit
+** hook returning non-zero, just as it would be with any other rollback.
+**
** For the purposes of this API, a transaction is said to have been
** rolled back if an explicit "ROLLBACK" statement is executed, or
** an error or constraint causes an implicit rollback to occur.
** The rollback callback is not invoked if a transaction is
@@ -4269,8 +4298,10 @@
** automatically rolled back because the database connection is closed.
** The rollback callback is not invoked if a transaction is
** rolled back because a commit callback returned non-zero.
** <todo> Check on this </todo>
+**
+** See also the [sqlite3_update_hook()] interface.
**
** Requirements:
** [H12951] [H12952] [H12953] [H12954] [H12955]
** [H12961] [H12962] [H12963] [H12964]
@@ -4301,8 +4332,15 @@
**
** The update hook is not invoked when internal system tables are
** modified (i.e. sqlite_master and sqlite_sequence).
**
+** In the current implementation, the update hook
+** is not invoked when duplication rows are deleted because of an
+** [ON CONFLICT | ON CONFLICT REPLACE] clause. Nor is the update hook
+** invoked when rows are deleted using the [truncate optimization].
+** The exceptions defined in this paragraph might change in a future
+** release of SQLite.
+**
** The update hook implementation must not do anything that will modify
** the database connection that invoked the update hook. Any actions
** to modify the database connection must be deferred until after the
** completion of the [sqlite3_step()] call that triggered the update hook.
@@ -4310,8 +4348,11 @@
** database connections for the meaning of "modify" in this paragraph.
**
** If another function was previously registered, its pArg value
** is returned. Otherwise NULL is returned.
+**
+** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()]
+** interfaces.
**
** Requirements:
** [H12971] [H12973] [H12975] [H12977] [H12979] [H12981] [H12983] [H12986]
*/
@@ -4880,9 +4921,9 @@
** <pre>
** SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
** </pre> {END}
**
-** If the flags parameter is non-zero, the the BLOB is opened for read
+** If the flags parameter is non-zero, then the BLOB is opened for read
** and write access. If it is zero, the BLOB is opened for read access.
**
** Note that the database name is not the filename that contains
** the database but rather the symbolic name of the database that
@@ -4890,12 +4931,15 @@
** For the main database file, the database name is "main".
** For TEMP tables, the database name is "temp".
**
** On success, [SQLITE_OK] is returned and the new [BLOB handle] is written
-** to *ppBlob. Otherwise an [error code] is returned and any value written
-** to *ppBlob should not be used by the caller.
+** to *ppBlob. Otherwise an [error code] is returned and *ppBlob is set
+** to be a null pointer.
** This function sets the [database connection] error code and message
-** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()].
+** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()] and related
+** functions. Note that the *ppBlob variable is always initialized in a
+** way that makes it safe to invoke [sqlite3_blob_close()] on *ppBlob
+** regardless of the success or failure of this routine.
**
** If the row that a BLOB handle points to is modified by an
** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
** then the BLOB handle is marked as "expired".
@@ -4905,8 +4949,21 @@
** a expired BLOB handle fail with an return code of [SQLITE_ABORT].
** Changes written into a BLOB prior to the BLOB expiring are not
** rollback by the expiration of the BLOB. Such changes will eventually
** commit if the transaction continues to completion.
+**
+** Use the [sqlite3_blob_bytes()] interface to determine the size of
+** the opened blob. The size of a blob may not be changed by this
+** underface. Use the [UPDATE] SQL command to change the size of a
+** blob.
+**
+** The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
+** and the built-in [zeroblob] SQL function can be used, if desired,
+** to create an empty, zero-filled blob in which to read or write using
+** this interface.
+**
+** To avoid a resource leak, every open [BLOB handle] should eventually
+** be released by a call to [sqlite3_blob_close()].
**
** Requirements:
** [H17813] [H17814] [H17816] [H17819] [H17821] [H17824]
*/
@@ -4928,17 +4985,20 @@
** Closing a BLOB shall cause the current transaction to commit
** if there are no other BLOBs, no pending prepared statements, and the
** database connection is in [autocommit mode].
** If any writes were made to the BLOB, they might be held in cache
-** until the close operation if they will fit. {END}
+** until the close operation if they will fit.
**
** Closing the BLOB often forces the changes
** out to disk and so if any I/O errors occur, they will likely occur
-** at the time when the BLOB is closed. {H17833} Any errors that occur during
+** at the time when the BLOB is closed. Any errors that occur during
** closing are reported as a non-zero return value.
**
** The BLOB is closed unconditionally. Even if this routine returns
** an error code, the BLOB is still closed.
+**
+** Calling this routine with a null pointer (which as would be returned
+** by failed call to [sqlite3_blob_open()]) is a harmless no-op.
**
** Requirements:
** [H17833] [H17836] [H17839]
*/
@@ -4946,10 +5006,17 @@
/*
** CAPI3REF: Return The Size Of An Open BLOB {H17840} <S30230>
**
-** Returns the size in bytes of the BLOB accessible via the open
-** []BLOB handle] in its only argument.
+** Returns the size in bytes of the BLOB accessible via the
+** successfully opened [BLOB handle] in its only argument. The
+** incremental blob I/O routines can only read or overwriting existing
+** blob content; they cannot change the size of a blob.
+**
+** This routine only works on a [BLOB handle] which has been created
+** by a prior successful call to [sqlite3_blob_open()] and which has not
+** been closed by [sqlite3_blob_close()]. Passing any other pointer in
+** to this routine results in undefined and probably undesirable behavior.
**
** Requirements:
** [H17843]
*/
@@ -4964,14 +5031,23 @@
**
** If offset iOffset is less than N bytes from the end of the BLOB,
** [SQLITE_ERROR] is returned and no data is read. If N or iOffset is
** less than zero, [SQLITE_ERROR] is returned and no data is read.
+** The size of the blob (and hence the maximum value of N+iOffset)
+** can be determined using the [sqlite3_blob_bytes()] interface.
**
** An attempt to read from an expired [BLOB handle] fails with an
** error code of [SQLITE_ABORT].
**
** On success, SQLITE_OK is returned.
** Otherwise, an [error code] or an [extended error code] is returned.
+**
+** This routine only works on a [BLOB handle] which has been created
+** by a prior successful call to [sqlite3_blob_open()] and which has not
+** been closed by [sqlite3_blob_close()]. Passing any other pointer in
+** to this routine results in undefined and probably undesirable behavior.
+**
+** See also: [sqlite3_blob_write()].
**
** Requirements:
** [H17853] [H17856] [H17859] [H17862] [H17863] [H17865] [H17868]
*/
@@ -4992,8 +5068,10 @@
** not possible to increase the size of a BLOB using this API.
** If offset iOffset is less than N bytes from the end of the BLOB,
** [SQLITE_ERROR] is returned and no data is written. If N is
** less than zero [SQLITE_ERROR] is returned and no data is written.
+** The size of the BLOB (and hence the maximum value of N+iOffset)
+** can be determined using the [sqlite3_blob_bytes()] interface.
**
** An attempt to write to an expired [BLOB handle] fails with an
** error code of [SQLITE_ABORT]. Writes to the BLOB that occurred
** before the [BLOB handle] expired are not rolled back by the
@@ -5002,8 +5080,15 @@
** or by other independent statements.
**
** On success, SQLITE_OK is returned.
** Otherwise, an [error code] or an [extended error code] is returned.
+**
+** This routine only works on a [BLOB handle] which has been created
+** by a prior successful call to [sqlite3_blob_open()] and which has not
+** been closed by [sqlite3_blob_close()]. Passing any other pointer in
+** to this routine results in undefined and probably undesirable behavior.
+**
+** See also: [sqlite3_blob_read()].
**
** Requirements:
** [H17873] [H17874] [H17875] [H17876] [H17877] [H17879] [H17882] [H17885]
** [H17888]
@@ -5353,8 +5438,10 @@
#define SQLITE_TESTCTRL_BITVEC_TEST 8
#define SQLITE_TESTCTRL_FAULT_INSTALL 9
#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10
#define SQLITE_TESTCTRL_PENDING_BYTE 11
+#define SQLITE_TESTCTRL_ASSERT 12
+#define SQLITE_TESTCTRL_ALWAYS 13
/*
** CAPI3REF: SQLite Runtime Status {H17200} <S60200>
** EXPERIMENTAL
@@ -6437,8 +6524,16 @@
typedef UINT8_TYPE u8; /* 1-byte unsigned integer */
typedef INT8_TYPE i8; /* 1-byte signed integer */
/*
+** SQLITE_MAX_U32 is a u64 constant that is the maximum u64 value
+** that can be stored in a u32 without loss of data. The value
+** is 0x00000000ffffffff. But because of quirks of some compilers, we
+** have to specify the value in the less intuitive manner shown:
+*/
+#define SQLITE_MAX_U32 ((((u64)1)<<32)-1)
+
+/*
** Macros to determine whether the machine is big or little endian,
** evaluated at runtime.
*/
#ifdef SQLITE_AMALGAMATION
@@ -6479,8 +6574,9 @@
/*
** Assert that the pointer X is aligned to an 8-byte boundary.
*/
#define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&7)==0)
+
/*
** An instance of the following structure is used to store the busy-handler
** callback for a given sqlite handle.
@@ -6584,8 +6680,9 @@
typedef struct Db Db;
typedef struct Schema Schema;
typedef struct Expr Expr;
typedef struct ExprList ExprList;
+typedef struct ExprSpan ExprSpan;
typedef struct FKey FKey;
typedef struct FuncDef FuncDef;
typedef struct FuncDefHash FuncDefHash;
typedef struct IdList IdList;
@@ -6634,9 +6731,9 @@
** This header file defines the interface that the sqlite B-Tree file
** subsystem. See comments in the source code for a detailed description
** of what each interface routine does.
**
-** @(#) $Id: btree.h,v 1.114 2009/05/04 11:42:30 danielk1977 Exp $
+** @(#) $Id: btree.h,v 1.116 2009/06/03 11:25:07 danielk1977 Exp $
*/
#ifndef _BTREE_H_
#define _BTREE_H_
@@ -6679,9 +6776,9 @@
SQLITE_PRIVATE int sqlite3BtreeOpen(
const char *zFilename, /* Name of database file to open */
sqlite3 *db, /* Associated database connection */
- Btree **, /* Return open Btree* here */
+ Btree **ppBtree, /* Return open Btree* here */
int flags, /* Flags */
int vfsFlags /* Flags passed through to VFS open */
);
@@ -6701,9 +6798,9 @@
SQLITE_PRIVATE int sqlite3BtreeClose(Btree*);
SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int);
SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(Btree*,int,int);
SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree*);
-SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree*,int,int,int);
+SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*);
SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree*,int);
SQLITE_PRIVATE int sqlite3BtreeGetReserve(Btree*);
SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int);
@@ -6737,11 +6834,33 @@
#define BTREE_LEAFDATA 4 /* Data stored in leaves only. Implies INTKEY */
SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree*, int, int*);
SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree*, int, int*);
+SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree*, int);
+
SQLITE_PRIVATE int sqlite3BtreeGetMeta(Btree*, int idx, u32 *pValue);
SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
-SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree*, int);
+
+/*
+** The second parameter to sqlite3BtreeGetMeta or sqlite3BtreeUpdateMeta
+** should be one of the following values. The integer values are assigned
+** to constants so that the offset of the corresponding field in an
+** SQLite database header may be found using the following formula:
+**
+** offset = 36 + (idx * 4)
+**
+** For example, the free-page-count field is located at byte offset 36 of
+** the database file header. The incr-vacuum-flag field is located at
+** byte offset 64 (== 36+4*7).
+*/
+#define BTREE_FREE_PAGE_COUNT 0
+#define BTREE_SCHEMA_VERSION 1
+#define BTREE_FILE_FORMAT 2
+#define BTREE_DEFAULT_CACHE_SIZE 3
+#define BTREE_LARGEST_ROOT_PAGE 4
+#define BTREE_TEXT_ENCODING 5
+#define BTREE_USER_VERSION 6
+#define BTREE_INCR_VACUUM 7
SQLITE_PRIVATE int sqlite3BtreeCursor(
Btree*, /* BTree containing table to open */
int iTable, /* Index of root page */
@@ -6778,9 +6897,8 @@
SQLITE_PRIVATE int sqlite3BtreeFlags(BtCursor*);
SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int *pRes);
SQLITE_PRIVATE int sqlite3BtreeKeySize(BtCursor*, i64 *pSize);
SQLITE_PRIVATE int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*);
-SQLITE_PRIVATE sqlite3 *sqlite3BtreeCursorDb(const BtCursor*);
SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor*, int *pAmt);
SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor*, int *pAmt);
SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor*, u32 *pSize);
SQLITE_PRIVATE int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*);
@@ -7938,10 +8056,8 @@
char *zName; /* Name of this database */
Btree *pBt; /* The B*Tree structure for this database file */
u8 inTrans; /* 0: not writable. 1: Transaction. 2: Checkpoint */
u8 safety_level; /* How aggressive at syncing data to disk */
- void *pAux; /* Auxiliary data. Usually NULL */
- void (*xFreeAux)(void*); /* Routine to free pAux */
Schema *pSchema; /* Pointer to database schema (possibly shared) */
};
/*
@@ -8258,9 +8374,9 @@
** Used to create a scalar function definition of a function zName
** implemented by C function xFunc that accepts nArg arguments. The
** value passed as iArg is cast to a (void*) and made available
** as the user-data (sqlite3_user_data()) for the function. If
-** argument bNC is true, then the FuncDef.needCollate flag is set.
+** argument bNC is true, then the SQLITE_FUNC_NEEDCOLL flag is set.
**
** AGGREGATE(zName, nArg, iArg, bNC, xStep, xFinal)
** Used to create an aggregate function definition implemented by
** the C functions xStep and xFinal. The first four parameters
@@ -8275,15 +8391,18 @@
** FuncDef.flags variable is set to the value passed as the flags
** parameter.
*/
#define FUNCTION(zName, nArg, iArg, bNC, xFunc) \
- {nArg, SQLITE_UTF8, bNC*8, SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0}
+ {nArg, SQLITE_UTF8, bNC*SQLITE_FUNC_NEEDCOLL, \
+ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0}
#define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \
- {nArg, SQLITE_UTF8, bNC*8, pArg, 0, xFunc, 0, 0, #zName, 0}
+ {nArg, SQLITE_UTF8, bNC*SQLITE_FUNC_NEEDCOLL, \
+ pArg, 0, xFunc, 0, 0, #zName, 0}
#define LIKEFUNC(zName, nArg, arg, flags) \
{nArg, SQLITE_UTF8, flags, (void *)arg, 0, likeFunc, 0, 0, #zName, 0}
#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \
- {nArg, SQLITE_UTF8, nc*8, SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0}
+ {nArg, SQLITE_UTF8, nc*SQLITE_FUNC_NEEDCOLL, \
+ SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0}
/*
** All current savepoints are stored in a linked list starting at
** sqlite3.pSavepoint. The first element in the list is the most recently
@@ -8322,8 +8441,9 @@
*/
struct Column {
char *zName; /* Name of this column */
Expr *pDflt; /* Default value of this column */
+ char *zDflt; /* Original text of the default value */
char *zType; /* Data type for this column */
char *zColl; /* Collating sequence. If NULL, use the default */
u8 notNull; /* True if there is a NOT NULL constraint */
u8 isPrimKey; /* True if this column is part of the PRIMARY KEY */
@@ -8667,12 +8787,10 @@
** may contain random values. Do not make any assumptions about Token.dyn
** and Token.n when Token.z==0.
*/
struct Token {
- const unsigned char *z; /* Text of the token. Not NULL-terminated! */
- unsigned dyn : 1; /* True for malloced memory, false for static */
- unsigned quoted : 1; /* True if token still has its quotes */
- unsigned n : 30; /* Number of characters in this token */
+ const char *z; /* Text of the token. Not NULL-terminated! */
+ unsigned int n; /* Number of characters in this token */
};
/*
** An instance of this structure contains information needed to generate
@@ -8771,11 +8889,11 @@
** Expr objects can use a lot of memory space in database schema. To
** help reduce memory requirements, sometimes an Expr object will be
** truncated. And to reduce the number of memory allocations, sometimes
** two or more Expr objects will be stored in a single memory allocation,
-** together with Expr.token and/or Expr.span strings.
-**
-** If the EP_Reduced, EP_SpanToken, and EP_TokenOnly flags are set when
+** together with Expr.zToken strings.
+**
+** If the EP_Reduced and EP_TokenOnly flags are set when
** an Expr object is truncated. When EP_Reduced is set, then all
** the child Expr objects in the Expr.pLeft and Expr.pRight subtrees
** are contained within the same memory allocation. Note, however, that
** the subtrees in Expr.x.pList or Expr.x.pSelect are always separately
@@ -8783,20 +8901,15 @@
*/
struct Expr {
u8 op; /* Operation performed by this node */
char affinity; /* The affinity of the column or 0 if not a column */
- VVA_ONLY(u8 vvaFlags;) /* Flags used for VV&A only. EVVA_* below. */
u16 flags; /* Various flags. EP_* See below */
- Token token; /* An operand token */
-
- /* If the EP_TokenOnly flag is set in the Expr.flags mask, then no
- ** space is allocated for the fields below this point. An attempt to
- ** access them will result in a segfault or malfunction.
- *********************************************************************/
-
- Token span; /* Complete text of the expression */
-
- /* If the EP_SpanToken flag is set in the Expr.flags mask, then no
+ union {
+ char *zToken; /* Token value. Zero terminated and dequoted */
+ int iValue; /* Integer value if EP_IntValue */
+ } u;
+
+ /* If the EP_TokenOnly flag is set in the Expr.flags mask, then no
** space is allocated for the fields below this point. An attempt to
** access them will result in a segfault or malfunction.
*********************************************************************/
@@ -8812,13 +8925,15 @@
** space is allocated for the fields below this point. An attempt to
** access them will result in a segfault or malfunction.
*********************************************************************/
- int iTable, iColumn; /* When op==TK_COLUMN, then this expr node means the
- ** iColumn-th field of the iTable-th table. */
- AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
- int iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
- int iRightJoinTable; /* If EP_FromJoin, the right table of the join */
+ int iTable; /* TK_COLUMN: cursor number of table holding column
+ ** TK_REGISTER: register number */
+ i16 iColumn; /* TK_COLUMN: column index. -1 for rowid */
+ i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
+ i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */
+ u16 flags2; /* Second set of flags. EP2_... */
+ AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
Table *pTab; /* Table for TK_COLUMN expressions. */
#if SQLITE_MAX_EXPR_DEPTH>0
int nHeight; /* Height of the tree headed by this node */
#endif
@@ -8837,22 +8952,31 @@
#define EP_InfixFunc 0x0080 /* True for an infix function: LIKE, GLOB, etc */
#define EP_ExpCollate 0x0100 /* Collating sequence specified explicitly */
#define EP_AnyAff 0x0200 /* Can take a cached column of any affinity */
#define EP_FixedDest 0x0400 /* Result needed in a specific register */
-#define EP_IntValue 0x0800 /* Integer value contained in iTable */
+#define EP_IntValue 0x0800 /* Integer value contained in u.iValue */
#define EP_xIsSelect 0x1000 /* x.pSelect is valid (otherwise x.pList is) */
#define EP_Reduced 0x2000 /* Expr struct is EXPR_REDUCEDSIZE bytes only */
#define EP_TokenOnly 0x4000 /* Expr struct is EXPR_TOKENONLYSIZE bytes only */
-#define EP_SpanToken 0x8000 /* Expr size is EXPR_SPANTOKENSIZE bytes */
-
-/*
-** The following are the meanings of bits in the Expr.vvaFlags field.
-** This information is only used when SQLite is compiled with
-** SQLITE_DEBUG defined.
-*/
-#ifndef NDEBUG
-#define EVVA_ReadOnlyToken 0x01 /* Expr.token.z is read-only */
+#define EP_Static 0x8000 /* Held in memory not obtained from malloc() */
+
+/*
+** The following are the meanings of bits in the Expr.flags2 field.
+*/
+#define EP2_MallocedToken 0x0001 /* Need to sqlite3DbFree() Expr.zToken */
+#define EP2_Irreducible 0x0002 /* Cannot EXPRDUP_REDUCE this Expr */
+
+/*
+** The pseudo-routine sqlite3ExprSetIrreducible sets the EP2_Irreducible
+** flag on an expression structure. This flag is used for VV&A only. The
+** routine is implemented as a macro that only works when in debugging mode,
+** so as not to burden production code.
+*/
+#ifdef SQLITE_DEBUG
+# define ExprSetIrreducible(X) (X)->flags2 |= EP2_Irreducible
+#else
+# define ExprSetIrreducible(X)
#endif
/*
** These macros can be used to test, set, or clear bits in the
@@ -8869,17 +8993,15 @@
** and an Expr struct with the EP_TokenOnly flag set.
*/
#define EXPR_FULLSIZE sizeof(Expr) /* Full size */
#define EXPR_REDUCEDSIZE offsetof(Expr,iTable) /* Common features */
-#define EXPR_SPANTOKENSIZE offsetof(Expr,pLeft) /* Fewer features */
-#define EXPR_TOKENONLYSIZE offsetof(Expr,span) /* Smallest possible */
+#define EXPR_TOKENONLYSIZE offsetof(Expr,pLeft) /* Fewer features */
/*
** Flags passed to the sqlite3ExprDup() function. See the header comment
** above sqlite3ExprDup() for details.
*/
#define EXPRDUP_REDUCE 0x0001 /* Used reduced-size Expr nodes */
-#define EXPRDUP_SPAN 0x0002 /* Make a copy of Expr.span */
/*
** A list of expressions. Each expression may optionally have a
** name. An expr/name combination can be used in several ways, such
@@ -8894,13 +9016,25 @@
int iECursor; /* VDBE Cursor associated with this ExprList */
struct ExprList_item {
Expr *pExpr; /* The list of expressions */
char *zName; /* Token associated with this expression */
+ char *zSpan; /* Original text of the expression */
u8 sortOrder; /* 1 for DESC or 0 for ASC */
u8 done; /* A flag to indicate when processing is finished */
u16 iCol; /* For ORDER BY, column number in result set */
u16 iAlias; /* Index into Parse.aAlias[] for zName */
} *a; /* One entry for each expression */
+};
+
+/*
+** An instance of this structure is used by the parser to record both
+** the parse tree for an expression and the span of input text for an
+** expression.
+*/
+struct ExprSpan {
+ Expr *pExpr; /* The expression parse tree */
+ const char *zStart; /* First character of input text */
+ const char *zEnd; /* One character past the end of input text */
};
/*
** An instance of this structure can hold a simple list of identifiers,
@@ -9351,9 +9485,8 @@
u8 tr_tm; /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
Expr *pWhen; /* The WHEN clause of the expression (may be NULL) */
IdList *pColumns; /* If this is an UPDATE OF <column-list> trigger,
the <column-list> is stored here */
- Token nameToken; /* Token containing zName. Use during parsing only */
Schema *pSchema; /* Schema containing the trigger */
Schema *pTabSchema; /* Schema containing the table */
TriggerStep *step_list; /* Link list of trigger program steps */
Trigger *pNext; /* Next trigger associated with the table */
@@ -9385,22 +9518,22 @@
* (op == TK_INSERT)
* orconf -> stores the ON CONFLICT algorithm
* pSelect -> If this is an INSERT INTO ... SELECT ... statement, then
* this stores a pointer to the SELECT statement. Otherwise NULL.
- * target -> A token holding the name of the table to insert into.
+ * target -> A token holding the quoted name of the table to insert into.
* pExprList -> If this is an INSERT INTO ... VALUES ... statement, then
* this stores values to be inserted. Otherwise NULL.
* pIdList -> If this is an INSERT INTO ... (<column-names>) VALUES ...
* statement, then this stores the column-names to be
* inserted into.
*
* (op == TK_DELETE)
- * target -> A token holding the name of the table to delete from.
+ * target -> A token holding the quoted name of the table to delete from.
* pWhere -> The WHERE clause of the DELETE statement if one is specified.
* Otherwise NULL.
*
* (op == TK_UPDATE)
- * target -> A token holding the name of the table to update rows of.
+ * target -> A token holding the quoted name of the table to update rows of.
* pWhere -> The WHERE clause of the UPDATE statement if one is specified.
* Otherwise NULL.
* pExprList -> A list of the columns to update and the expressions to update
* them to. See sqlite3Update() documentation of "pChanges"
@@ -9413,9 +9546,9 @@
Trigger *pTrig; /* The trigger that this step is a part of */
Select *pSelect; /* Valid for SELECT and sometimes
INSERT steps (when pExprList == 0) */
- Token target; /* Valid for DELETE, UPDATE, INSERT steps */
+ Token target; /* Target table for DELETE, UPDATE, INSERT. Quoted */
Expr *pWhere; /* Valid for DELETE, UPDATE steps */
ExprList *pExprList; /* Valid for UPDATE statements and sometimes
INSERT steps (when pSelect == 0) */
IdList *pIdList; /* Valid for INSERT statements only */
@@ -9588,8 +9721,17 @@
# define SQLITE_CORRUPT_BKPT SQLITE_CORRUPT
#endif
/*
+** The ctype.h header is needed for non-ASCII systems. It is also
+** needed by FTS3 when FTS3 is included in the amalgamation.
+*/
+#if !defined(SQLITE_ASCII) || \
+ (defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_AMALGAMATION))
+# include <ctype.h>
+#endif
+
+/*
** The following macros mimic the standard library functions toupper(),
** isspace(), isalnum(), isdigit() and isxdigit(), respectively. The
** sqlite versions only work for ASCII characters, regardless of locale.
*/
@@ -9601,9 +9743,8 @@
# define sqlite3Isdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x04)
# define sqlite3Isxdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x08)
# define sqlite3Tolower(x) (sqlite3UpperToLower[(unsigned char)(x)])
#else
-# include <ctype.h>
# define sqlite3Toupper(x) toupper((unsigned char)(x))
# define sqlite3Isspace(x) isspace((unsigned char)(x))
# define sqlite3Isalnum(x) isalnum((unsigned char)(x))
# define sqlite3Isalpha(x) isalpha((unsigned char)(x))
@@ -9640,8 +9781,26 @@
SQLITE_PRIVATE void sqlite3PageFree(void*);
SQLITE_PRIVATE void sqlite3MemSetDefault(void);
SQLITE_PRIVATE void sqlite3BenignMallocHooks(void (*)(void), void (*)(void));
SQLITE_PRIVATE int sqlite3MemoryAlarm(void (*)(void*, sqlite3_int64, int), void*, sqlite3_int64);
+
+/*
+** On systems with ample stack space and that support alloca(), make
+** use of alloca() to obtain space for large automatic objects. By default,
+** obtain space from malloc().
+**
+** The alloca() routine never returns NULL. This will cause code paths
+** that deal with sqlite3StackAlloc() failures to be unreachable.
+*/
+#ifdef SQLITE_USE_ALLOCA
+# define sqlite3StackAllocRaw(D,N) alloca(N)
+# define sqlite3StackAllocZero(D,N) memset(alloca(N), 0, N)
+# define sqlite3StackFree(D,P)
+#else
+# define sqlite3StackAllocRaw(D,N) sqlite3DbMallocRaw(D,N)
+# define sqlite3StackAllocZero(D,N) sqlite3DbMallocZero(D,N)
+# define sqlite3StackFree(D,P) sqlite3DbFree(D,P)
+#endif
#ifdef SQLITE_ENABLE_MEMSYS3
SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void);
#endif
@@ -9683,18 +9842,20 @@
SQLITE_PRIVATE int sqlite3GetTempReg(Parse*);
SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse*,int);
SQLITE_PRIVATE int sqlite3GetTempRange(Parse*,int);
SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse*,int,int);
-SQLITE_PRIVATE Expr *sqlite3Expr(sqlite3*, int, Expr*, Expr*, const Token*);
+SQLITE_PRIVATE Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int);
+SQLITE_PRIVATE Expr *sqlite3Expr(sqlite3*,int,const char*);
+SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*);
-SQLITE_PRIVATE Expr *sqlite3RegisterExpr(Parse*,Token*);
-SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
-SQLITE_PRIVATE void sqlite3ExprSpan(Expr*,Token*,Token*);
+SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*);
SQLITE_PRIVATE void sqlite3ExprClear(sqlite3*, Expr*);
SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
-SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*,Token*);
+SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
+SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
+SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*);
SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*);
SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**);
SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**);
SQLITE_PRIVATE void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
@@ -9708,16 +9869,16 @@
SQLITE_PRIVATE void sqlite3AddNotNull(Parse*, int);
SQLITE_PRIVATE void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
SQLITE_PRIVATE void sqlite3AddCheckConstraint(Parse*, Expr*);
SQLITE_PRIVATE void sqlite3AddColumnType(Parse*,Token*);
-SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,Expr*);
+SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,ExprSpan*);
SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*);
SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,Select*);
SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32);
SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec*, u32);
SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec*, u32);
-SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec*, u32);
+SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec*, u32, void*);
SQLITE_PRIVATE void sqlite3BitvecDestroy(Bitvec*);
SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec*);
SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int,int*);
@@ -9822,9 +9983,8 @@
SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int,int,int);
SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int);
SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
-SQLITE_PRIVATE void sqlite3TokenCopy(sqlite3*,Token*,const Token*);
SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*);
SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int);
@@ -9953,10 +10113,10 @@
SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
SQLITE_PRIVATE const char *sqlite3ErrStr(int);
SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse);
-SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char *,int,int);
-SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName);
+SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
+SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
SQLITE_PRIVATE Expr *sqlite3ExprSetColl(Parse *pParse, Expr *, Token *);
SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *);
SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *);
@@ -9992,10 +10152,10 @@
SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int);
SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
-SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(sqlite3*, CollSeq *, const char *, int);
-SQLITE_PRIVATE char sqlite3AffinityType(const Token*);
+SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(sqlite3*, CollSeq *, const char*);
+SQLITE_PRIVATE char sqlite3AffinityType(const char*);
SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*);
SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*);
SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*);
SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *, const char *);
@@ -10032,9 +10192,9 @@
#ifdef YYTRACKMAXSTACKDEPTH
SQLITE_PRIVATE int sqlite3ParserStackPeak(void*);
#endif
-SQLITE_PRIVATE int sqlite3AutoLoadExtensions(sqlite3*);
+SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3*);
#ifndef SQLITE_OMIT_LOAD_EXTENSION
SQLITE_PRIVATE void sqlite3CloseExtensions(sqlite3*);
#else
# define sqlite3CloseExtensions(X)
@@ -14761,9 +14921,9 @@
**
*************************************************************************
** This file contains the C functions that implement mutexes for win32
**
-** $Id: mutex_w32.c,v 1.15 2009/01/30 16:09:23 shane Exp $
+** $Id: mutex_w32.c,v 1.17 2009/06/01 17:10:22 shane Exp $
*/
/*
** The code in this file is only used if we are compiling multithreaded
@@ -14831,10 +14991,47 @@
/*
** Initialize and deinitialize the mutex subsystem.
*/
-static int winMutexInit(void){ return SQLITE_OK; }
-static int winMutexEnd(void){ return SQLITE_OK; }
+static sqlite3_mutex winMutex_staticMutexes[6];
+static int winMutex_isInit = 0;
+/* As winMutexInit() and winMutexEnd() are called as part
+** of the sqlite3_initialize and sqlite3_shutdown()
+** processing, the "interlocked" magic is probably not
+** strictly necessary.
+*/
+static long winMutex_lock = 0;
+
+static int winMutexInit(void){
+ /* The first to increment to 1 does actual initialization */
+ if( InterlockedIncrement(&winMutex_lock)==1 ){
+ int i;
+ for(i=0; i<sizeof(winMutex_staticMutexes)/sizeof(winMutex_staticMutexes[0]); i++){
+ InitializeCriticalSection(&winMutex_staticMutexes[i].mutex);
+ }
+ winMutex_isInit = 1;
+ }else{
+ while( !winMutex_isInit ){
+ Sleep(1);
+ }
+ }
+ return SQLITE_OK;
+}
+
+static int winMutexEnd(void){
+ /* The first to decrement to 0 does actual shutdown
+ ** (which should be the last to shutdown.) */
+ if( InterlockedDecrement(&winMutex_lock)==0 ){
+ if( winMutex_isInit==1 ){
+ int i;
+ for(i=0; i<sizeof(winMutex_staticMutexes)/sizeof(winMutex_staticMutexes[0]); i++){
+ DeleteCriticalSection(&winMutex_staticMutexes[i].mutex);
+ }
+ winMutex_isInit = 0;
+ }
+ }
+ return SQLITE_OK;
+}
/*
** The sqlite3_mutex_alloc() routine allocates a new
** mutex and returns a pointer to it. If it returns NULL
@@ -14887,25 +15084,12 @@
}
break;
}
default: {
- static sqlite3_mutex staticMutexes[6];
- static int isInit = 0;
- while( !isInit ){
- static long lock = 0;
- if( InterlockedIncrement(&lock)==1 ){
- int i;
- for(i=0; i<sizeof(staticMutexes)/sizeof(staticMutexes[0]); i++){
- InitializeCriticalSection(&staticMutexes[i].mutex);
- }
- isInit = 1;
- }else{
- Sleep(1);
- }
- }
+ assert( winMutex_isInit==1 );
assert( iType-2 >= 0 );
- assert( iType-2 < sizeof(staticMutexes)/sizeof(staticMutexes[0]) );
- p = &staticMutexes[iType-2];
+ assert( iType-2 < sizeof(winMutex_staticMutexes)/sizeof(winMutex_staticMutexes[0]) );
+ p = &winMutex_staticMutexes[iType-2];
p->id = iType;
break;
}
}
@@ -15732,9 +15916,9 @@
** completeness. They are very out-of-date but might be useful as
** an historical reference. Most of the "enhancements" have been backed
** out so that the functionality is now the same as standard printf().
**
-** $Id: printf.c,v 1.103 2009/05/04 20:20:16 drh Exp $
+** $Id: printf.c,v 1.104 2009/06/03 01:24:54 drh Exp $
**
**************************************************************************
**
** The following modules is an enhanced replacement for the "printf" subroutines
@@ -15915,13 +16099,16 @@
}
/*
** On machines with a small stack size, you can redefine the
-** SQLITE_PRINT_BUF_SIZE to be less than 350. But beware - for
-** smaller values some %f conversions may go into an infinite loop.
+** SQLITE_PRINT_BUF_SIZE to be less than 350.
*/
#ifndef SQLITE_PRINT_BUF_SIZE
-# define SQLITE_PRINT_BUF_SIZE 350
+# if defined(SQLITE_SMALL_STACK)
+# define SQLITE_PRINT_BUF_SIZE 50
+# else
+# define SQLITE_PRINT_BUF_SIZE 350
+# endif
#endif
#define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */
/*
@@ -16887,9 +17074,9 @@
** 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.170 2009/05/04 11:42:30 danielk1977 Exp $
+** $Id: vdbeInt.h,v 1.171 2009/06/05 14:17:25 drh Exp $
*/
#ifndef _VDBEINT_H_
#define _VDBEINT_H_
@@ -17210,12 +17397,12 @@
SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*);
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*);
#endif
-SQLITE_PRIVATE int sqlite3VdbeSerialTypeLen(u32);
+SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int);
-SQLITE_PRIVATE int sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int);
-SQLITE_PRIVATE int sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
+SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int);
+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*);
@@ -17799,9 +17986,9 @@
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
-** $Id: util.c,v 1.254 2009/05/06 19:03:14 drh Exp $
+** $Id: util.c,v 1.258 2009/06/05 14:17:23 drh Exp $
*/
#ifdef SQLITE_HAVE_ISNAN
# include <math.h>
#endif
@@ -17891,8 +18078,9 @@
** 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;
while( *z2 ){ z2++; }
return 0x3fffffff & (int)(z2 - z);
}
@@ -17953,16 +18141,13 @@
SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
va_list ap;
sqlite3 *db = pParse->db;
pParse->nErr++;
- testcase( pParse->zErrMsg!=0 );
sqlite3DbFree(db, pParse->zErrMsg);
va_start(ap, zFormat);
pParse->zErrMsg = sqlite3VMPrintf(db, zFormat, ap);
va_end(ap);
- if( pParse->rc==SQLITE_OK ){
- pParse->rc = SQLITE_ERROR;
- }
+ pParse->rc = SQLITE_ERROR;
}
/*
** Clear the error message in pParse, if any
@@ -18232,11 +18417,14 @@
}
}
/*
-** The string zNum represents an unsigned integer. There might be some other
-** information following the integer too, but that part is ignored.
-** If the integer that the prefix of zNum represents will fit in a
+** The string zNum represents an unsigned integer. The zNum string
+** consists of one or more digit characters and is terminated by
+** a zero character. Any stray characters in zNum result in undefined
+** behavior.
+**
+** If the unsigned integer that zNum represents will fit in a
** 64-bit signed integer, return TRUE. Otherwise return FALSE.
**
** If the negFlag parameter is true, that means that zNum really represents
** a negative number. (The leading "-" is omitted from zNum.) This
@@ -18246,9 +18434,9 @@
**
** Leading zeros are ignored.
*/
SQLITE_PRIVATE int sqlite3FitsIn64Bits(const char *zNum, int negFlag){
- int i, c;
+ int i;
int neg = 0;
assert( zNum[0]>='0' && zNum[0]<='9' ); /* zNum is an unsigned number */
@@ -18255,9 +18443,9 @@
if( negFlag ) neg = 1-neg;
while( *zNum=='0' ){
zNum++; /* Skip leading zeros. Ticket #2454 */
}
- for(i=0; (c=zNum[i])>='0' && c<='9'; i++){}
+ for(i=0; zNum[i]; i++){ assert( zNum[i]>='0' && zNum[i]<='9' ); }
if( i<19 ){
/* Guaranteed to fit if less than 19 digits */
return 1;
}else if( i>19 ){
@@ -18548,8 +18736,12 @@
/*
** Read a 32-bit variable-length integer from memory starting at p[0].
** Return the number of bytes read. The value is stored in *v.
+**
+** If the varint stored in p[0] is larger than can fit in a 32-bit unsigned
+** integer, then set *v to 0xffffffff.
+**
** A MACRO version, getVarint32, is provided which inlines the
** single-byte case. All code should use the MACRO version as
** this function assumes the single-byte case has already been handled.
*/
@@ -18613,9 +18805,13 @@
p -= 2;
n = sqlite3GetVarint(p, &v64);
assert( n>3 && n<=9 );
- *v = (u32)v64;
+ if( (v64 & SQLITE_MAX_U32)!=v64 ){
+ *v = 0xffffffff;
+ }else{
+ *v = (u32)v64;
+ }
return n;
}
#else
@@ -18849,9 +19045,9 @@
*************************************************************************
** This is the implementation of generic hash-tables
** used in SQLite.
**
-** $Id: hash.c,v 1.37 2009/05/02 13:29:38 drh Exp $
+** $Id: hash.c,v 1.38 2009/05/09 23:29:12 drh Exp $
*/
/* Turn bulk memory into a hash table object by initializing the
** fields of the Hash structure.
@@ -19100,9 +19296,10 @@
new_elem->nKey = nKey;
new_elem->data = data;
pH->count++;
if( pH->count>=10 && pH->count > 2*pH->htsize ){
- if( rehash(pH, pH->count*2) && pH->htsize ){
+ if( rehash(pH, pH->count*2) ){
+ assert( pH->htsize>0 );
h = strHash(pKey, nKey) % pH->htsize;
}
}
if( pH->ht ){
@@ -20668,9 +20865,9 @@
** * 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.250 2009/04/07 05:35:04 chw Exp $
+** $Id: os_unix.c,v 1.251 2009/05/08 11:34:37 danielk1977 Exp $
*/
#if SQLITE_OS_UNIX /* This file is used on unix only */
/*
@@ -25272,10 +25469,10 @@
confstr(_CS_DARWIN_USER_TEMP_DIR, lPath, maxLen);
len = strlcat(lPath, "sqliteplocks", maxLen);
if( mkdir(lPath, SQLITE_DEFAULT_PROXYDIR_PERMISSIONS) ){
/* if mkdir fails, handle as lock file creation failure */
- int err = errno;
# ifdef SQLITE_DEBUG
+ int err = errno;
if( err!=EEXIST ){
fprintf(stderr, "proxyGetLockPath: mkdir(%s,0%o) error %d %s\n", lPath,
SQLITE_DEFAULT_PROXYDIR_PERMISSIONS, err, strerror(err));
}
@@ -28128,9 +28325,9 @@
** Bitvec object is the number of pages in the database file at the
** start of a transaction, and is thus usually less than a few thousand,
** but can be as large as 2 billion for a really big database.
**
-** @(#) $Id: bitvec.c,v 1.14 2009/04/01 23:49:04 drh Exp $
+** @(#) $Id: bitvec.c,v 1.15 2009/06/02 21:31:39 drh Exp $
*/
/* Size of the Bitvec structure in bytes. */
#define BITVEC_SZ 512
@@ -28302,17 +28499,22 @@
bitvec_set_rehash:
if( p->nSet>=BITVEC_MXHASH ){
unsigned int j;
int rc;
- u32 aiValues[BITVEC_NINT];
- memcpy(aiValues, p->u.aHash, sizeof(aiValues));
- memset(p->u.apSub, 0, sizeof(aiValues));
- p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR;
- rc = sqlite3BitvecSet(p, i);
- for(j=0; j<BITVEC_NINT; j++){
- if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]);
- }
- return rc;
+ u32 *aiValues = sqlite3StackAllocRaw(0, sizeof(p->u.aHash));
+ if( aiValues==0 ){
+ return SQLITE_NOMEM;
+ }else{
+ memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
+ memset(p->u.apSub, 0, sizeof(p->u.apSub));
+ p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR;
+ rc = sqlite3BitvecSet(p, i);
+ for(j=0; j<BITVEC_NINT; j++){
+ if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]);
+ }
+ sqlite3StackFree(0, aiValues);
+ return rc;
+ }
}
bitvec_set_end:
p->nSet++;
p->u.aHash[h] = i;
@@ -28320,10 +28522,13 @@
}
/*
** Clear the i-th bit.
-*/
-SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec *p, u32 i){
+**
+** pBuf must be a pointer to at least BITVEC_SZ bytes of temporary storage
+** that BitvecClear can use to rebuilt its hash table.
+*/
+SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec *p, u32 i, void *pBuf){
assert( p!=0 );
assert( i>0 );
i--;
while( p->iDivisor ){
@@ -28337,11 +28542,11 @@
if( p->iSize<=BITVEC_NBIT ){
p->u.aBitmap[i/BITVEC_SZELEM] &= ~(1 << (i&(BITVEC_SZELEM-1)));
}else{
unsigned int j;
- u32 aiValues[BITVEC_NINT];
- memcpy(aiValues, p->u.aHash, sizeof(aiValues));
- memset(p->u.aHash, 0, sizeof(aiValues));
+ u32 *aiValues = pBuf;
+ memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
+ memset(p->u.aHash, 0, sizeof(p->u.aHash));
p->nSet = 0;
for(j=0; j<BITVEC_NINT; j++){
if( aiValues[j] && aiValues[j]!=(i+1) ){
u32 h = BITVEC_HASH(aiValues[j]-1);
@@ -28423,14 +28628,16 @@
Bitvec *pBitvec = 0;
unsigned char *pV = 0;
int rc = -1;
int i, nx, pc, op;
+ void *pTmpSpace;
/* Allocate the Bitvec to be tested and a linear array of
** bits to act as the reference */
pBitvec = sqlite3BitvecCreate( sz );
pV = sqlite3_malloc( (sz+7)/8 + 1 );
- if( pBitvec==0 || pV==0 ) goto bitvec_end;
+ pTmpSpace = sqlite3_malloc(BITVEC_SZ);
+ if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end;
memset(pV, 0, (sz+7)/8 + 1);
/* Run the program */
pc = 0;
@@ -28461,9 +28668,9 @@
if( sqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end;
}
}else{
CLEARBIT(pV, (i+1));
- sqlite3BitvecClear(pBitvec, i+1);
+ sqlite3BitvecClear(pBitvec, i+1, pTmpSpace);
}
}
/* Test to make sure the linear array exactly matches the
@@ -28482,8 +28689,9 @@
}
/* Free allocated structure */
bitvec_end:
+ sqlite3_free(pTmpSpace);
sqlite3_free(pV);
sqlite3BitvecDestroy(pBitvec);
return rc;
}
@@ -29092,9 +29300,9 @@
** 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.11.2.1 2009/05/18 16:14:25 drh Exp $
+** @(#) $Id: pcache1.c,v 1.16 2009/06/03 21:04:36 drh Exp $
*/
typedef struct PCache1 PCache1;
@@ -29129,9 +29337,9 @@
/*
** Each cache entry is represented by an instance of the following
** structure. A buffer of PgHdr1.pCache->szPage bytes is allocated
-** directly after the structure in memory (see the PGHDR1_TO_PAGE()
+** directly before this structure in memory (see the PGHDR1_TO_PAGE()
** macro below).
*/
struct PgHdr1 {
unsigned int iKey; /* Key value (page number) */
@@ -29163,8 +29371,9 @@
/* Variables related to SQLITE_CONFIG_PAGECACHE settings. */
int szSlot; /* Size of each free slot */
void *pStart, *pEnd; /* Bounds of pagecache malloc range */
PgFreeslot *pFree; /* Free page blocks */
+ int isInit; /* True if initialized */
} pcache1_g;
/*
** All code in this file should access the global structure above via the
@@ -29174,20 +29383,20 @@
#define pcache1 (GLOBAL(struct PCacheGlobal, pcache1_g))
/*
** When a PgHdr1 structure is allocated, the associated PCache1.szPage
-** bytes of data are located directly after it in memory (i.e. the total
+** bytes of data are located directly before it in memory (i.e. the total
** size of the allocation is sizeof(PgHdr1)+PCache1.szPage byte). The
** PGHDR1_TO_PAGE() macro takes a pointer to a PgHdr1 structure as
** an argument and returns a pointer to the associated block of szPage
** bytes. The PAGE_TO_PGHDR1() macro does the opposite: its argument is
** a pointer to a block of szPage bytes of data and the return value is
** a pointer to the associated PgHdr1 structure.
**
-** assert( PGHDR1_TO_PAGE(PAGE_TO_PGHDR1(X))==X );
-*/
-#define PGHDR1_TO_PAGE(p) (void *)(&((unsigned char *)p)[sizeof(PgHdr1)])
-#define PAGE_TO_PGHDR1(p) (PgHdr1 *)(&((unsigned char *)p)[-1*(int)sizeof(PgHdr1)])
+** assert( PGHDR1_TO_PAGE(PAGE_TO_PGHDR1(pCache, X))==X );
+*/
+#define PGHDR1_TO_PAGE(p) (void*)(((char*)p) - p->pCache->szPage)
+#define PAGE_TO_PGHDR1(c, p) (PgHdr1*)(((char*)p) + c->szPage)
/*
** Macros to enter and leave the global LRU mutex.
*/
@@ -29203,20 +29412,22 @@
** verb to sqlite3_config(). Parameter pBuf points to an allocation large
** enough to contain 'n' buffers of 'sz' bytes each.
*/
SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){
- PgFreeslot *p;
- sz = ROUNDDOWN8(sz);
- pcache1.szSlot = sz;
- pcache1.pStart = pBuf;
- pcache1.pFree = 0;
- while( n-- ){
- p = (PgFreeslot*)pBuf;
- p->pNext = pcache1.pFree;
- pcache1.pFree = p;
- pBuf = (void*)&((char*)pBuf)[sz];
- }
- pcache1.pEnd = pBuf;
+ if( pcache1.isInit ){
+ PgFreeslot *p;
+ sz = ROUNDDOWN8(sz);
+ pcache1.szSlot = sz;
+ pcache1.pStart = pBuf;
+ pcache1.pFree = 0;
+ while( n-- ){
+ p = (PgFreeslot*)pBuf;
+ p->pNext = pcache1.pFree;
+ pcache1.pFree = p;
+ pBuf = (void*)&((char*)pBuf)[sz];
+ }
+ pcache1.pEnd = pBuf;
+ }
}
/*
** Malloc function used within this file to allocate space from the buffer
@@ -29227,8 +29438,9 @@
static void *pcache1Alloc(int nByte){
void *p;
assert( sqlite3_mutex_held(pcache1.mutex) );
if( nByte<=pcache1.szSlot && pcache1.pFree ){
+ assert( pcache1.isInit );
p = (PgHdr1 *)pcache1.pFree;
pcache1.pFree = pcache1.pFree->pNext;
sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, 1);
@@ -29274,13 +29486,17 @@
** Allocate a new page object initially associated with cache pCache.
*/
static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
int nByte = sizeof(PgHdr1) + pCache->szPage;
- PgHdr1 *p = (PgHdr1 *)pcache1Alloc(nByte);
- if( p ){
+ void *pPg = pcache1Alloc(nByte);
+ PgHdr1 *p;
+ if( pPg ){
+ p = PAGE_TO_PGHDR1(pCache, pPg);
if( pCache->bPurgeable ){
pcache1.nCurrentPage++;
}
+ }else{
+ p = 0;
}
return p;
}
@@ -29291,9 +29507,9 @@
if( p ){
if( p->pCache->bPurgeable ){
pcache1.nCurrentPage--;
}
- pcache1Free(p);
+ pcache1Free(PGHDR1_TO_PAGE(p));
}
}
/*
@@ -29449,9 +29665,9 @@
pcache1PinPage(pPage);
pcache1FreePage(pPage);
}else{
pp = &pPage->pNext;
- TESTONLY( nPage++ );
+ TESTONLY( nPage++; )
}
}
}
assert( pCache->nPage==nPage );
@@ -29464,12 +29680,14 @@
** Implementation of the sqlite3_pcache.xInit method.
*/
static int pcache1Init(void *NotUsed){
UNUSED_PARAMETER(NotUsed);
+ assert( pcache1.isInit==0 );
memset(&pcache1, 0, sizeof(pcache1));
if( sqlite3GlobalConfig.bCoreMutex ){
pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU);
}
+ pcache1.isInit = 1;
return SQLITE_OK;
}
/*
@@ -29476,9 +29694,10 @@
** Implementation of the sqlite3_pcache.xShutdown method.
*/
static void pcache1Shutdown(void *NotUsed){
UNUSED_PARAMETER(NotUsed);
- /* no-op */
+ assert( pcache1.isInit!=0 );
+ memset(&pcache1, 0, sizeof(pcache1));
}
/*
** Implementation of the sqlite3_pcache.xCreate method.
@@ -29628,15 +29847,15 @@
}
if( pPage ){
unsigned int h = iKey % pCache->nHash;
- *(void **)(PGHDR1_TO_PAGE(pPage)) = 0;
pCache->nPage++;
pPage->iKey = iKey;
pPage->pNext = pCache->apHash[h];
pPage->pCache = pCache;
pPage->pLruPrev = 0;
pPage->pLruNext = 0;
+ *(void **)(PGHDR1_TO_PAGE(pPage)) = 0;
pCache->apHash[h] = pPage;
}
fetch_out:
@@ -29655,10 +29874,11 @@
** Mark a page as unpinned (eligible for asynchronous recycling).
*/
static void pcache1Unpin(sqlite3_pcache *p, void *pPg, int reuseUnlikely){
PCache1 *pCache = (PCache1 *)p;
- PgHdr1 *pPage = PAGE_TO_PGHDR1(pPg);
-
+ PgHdr1 *pPage = PAGE_TO_PGHDR1(pCache, pPg);
+
+ assert( pPage->pCache==pCache );
pcache1EnterMutex();
/* It is an error to call this function if the page is already
** part of the global LRU list.
@@ -29698,12 +29918,13 @@
unsigned int iOld,
unsigned int iNew
){
PCache1 *pCache = (PCache1 *)p;
- PgHdr1 *pPage = PAGE_TO_PGHDR1(pPg);
+ PgHdr1 *pPage = PAGE_TO_PGHDR1(pCache, pPg);
PgHdr1 **pp;
unsigned int h;
assert( pPage->iKey==iOld );
+ assert( pPage->pCache==pCache );
pcache1EnterMutex();
h = iOld%pCache->nHash;
@@ -29796,9 +30017,9 @@
if( pcache1.pStart==0 ){
PgHdr1 *p;
pcache1EnterMutex();
while( (nReq<0 || nFree<nReq) && (p=pcache1.pLruTail) ){
- nFree += sqlite3MallocSize(p);
+ nFree += sqlite3MallocSize(PGHDR1_TO_PAGE(p));
pcache1PinPage(p);
pcache1RemoveFromHash(p);
pcache1FreePage(p);
}
@@ -29894,9 +30115,9 @@
**
** There is an added cost of O(N) when switching between TEST and
** SMALLEST primitives.
**
-** $Id: rowset.c,v 1.6 2009/04/22 15:32:59 drh Exp $
+** $Id: rowset.c,v 1.7 2009/05/22 01:00:13 drh Exp $
*/
/*
@@ -29960,17 +30181,17 @@
** allocation of entries available to be filled.
*/
SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int N){
RowSet *p;
- assert( N >= sizeof(*p) );
+ assert( N >= ROUND8(sizeof(*p)) );
p = pSpace;
p->pChunk = 0;
p->db = db;
p->pEntry = 0;
p->pLast = 0;
p->pTree = 0;
- p->pFresh = (struct RowSetEntry*)&p[1];
- p->nFresh = (u16)((N - sizeof(*p))/sizeof(struct RowSetEntry));
+ p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p);
+ p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry));
p->isSorted = 1;
p->iBatch = 0;
return p;
}
@@ -30278,9 +30499,9 @@
** 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.586.2.1 2009/05/18 17:11:31 drh Exp $
+** @(#) $Id: pager.c,v 1.591 2009/06/02 21:31:39 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
/*
@@ -33643,20 +33864,40 @@
*pExists = 0;
rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &exists);
if( rc==SQLITE_OK && exists ){
int locked; /* True if some process holds a RESERVED lock */
+
+ /* Race condition here: Another process might have been holding the
+ ** the RESERVED lock and have a journal open at the sqlite3OsAccess()
+ ** call above, but then delete the journal and drop the lock before
+ ** we get to the following sqlite3OsCheckReservedLock() call. If that
+ ** is the case, this routine might think there is a hot journal when
+ ** in fact there is none. This results in a false-positive which will
+ ** be dealt with by the playback routine. Ticket #3883.
+ */
rc = sqlite3OsCheckReservedLock(pPager->fd, &locked);
if( rc==SQLITE_OK && !locked ){
int nPage;
/* Check the size of the database file. If it consists of 0 pages,
** then delete the journal file. See the header comment above for
- ** the reasoning here.
+ ** the reasoning here. Delete the obsolete journal file under
+ ** a RESERVED lock to avoid race conditions and to avoid violating
+ ** [H33020].
*/
rc = sqlite3PagerPagecount(pPager, &nPage);
if( rc==SQLITE_OK ){
if( nPage==0 ){
- rc = sqlite3OsDelete(pVfs, pPager->zJournal, 0);
+ sqlite3BeginBenignMalloc();
+ if( pPager->state>=PAGER_RESERVED
+ || sqlite3OsLock(pPager->fd, RESERVED_LOCK)==SQLITE_OK ){
+ sqlite3OsDelete(pVfs, pPager->zJournal, 0);
+ assert( pPager->state>=PAGER_SHARED );
+ if( pPager->state==PAGER_SHARED ){
+ sqlite3OsUnlock(pPager->fd, SHARED_LOCK);
+ }
+ }
+ sqlite3EndBenignMalloc();
}else{
/* The journal file exists and no other connection has a reserved
** or greater lock on the database file. Now check that there is
** at least one non-zero bytes at the start of the journal file.
@@ -33672,8 +33913,20 @@
rc = SQLITE_OK;
}
sqlite3OsClose(pPager->jfd);
*pExists = (first!=0);
+ }else if( rc==SQLITE_CANTOPEN ){
+ /* If we cannot open the rollback journal file in order to see if
+ ** its has a zero header, that might be due to an I/O error, or
+ ** it might be due to the race condition described above and in
+ ** ticket #3883. Either way, assume that the journal is hot.
+ ** This might be a false positive. But if it is, then the
+ ** automatic journal playback and recovery mechanism will deal
+ ** with it under an EXCLUSIVE lock where we do not need to
+ ** worry so much with race conditions.
+ */
+ *pExists = 1;
+ rc = SQLITE_OK;
}
}
}
}
@@ -35393,9 +35646,10 @@
assert( pPager->needSync );
rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr);
if( rc!=SQLITE_OK ){
if( pPager->pInJournal && needSyncPgno<=pPager->dbOrigSize ){
- sqlite3BitvecClear(pPager->pInJournal, needSyncPgno);
+ assert( pPager->pTmpSpace!=0 );
+ sqlite3BitvecClear(pPager->pInJournal, needSyncPgno, pPager->pTmpSpace);
}
return rc;
}
pPager->needSync = 1;
@@ -36542,9 +36796,9 @@
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
-** $Id: btree.c,v 1.608 2009/05/06 18:57:10 shane Exp $
+** $Id: btree.c,v 1.619 2009/06/05 18:44:15 drh 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.
@@ -37116,8 +37370,11 @@
if( rc!=SQLITE_OK ){
return rc;
}
offset = PTRMAP_PTROFFSET(iPtrmap, key);
+ if( offset<0 ){
+ return SQLITE_CORRUPT_BKPT;
+ }
pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage);
if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){
TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent));
@@ -37675,11 +37932,41 @@
/* To many cells for a single page. The page must be corrupt */
return SQLITE_CORRUPT_BKPT;
}
+ /* A malformed database page might cause use to read past the end
+ ** of page when parsing a cell.
+ **
+ ** 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
+ {
+ 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 */
+
+ iCellFirst = cellOffset + 2*pPage->nCell;
+ iCellLast = usableSize - 4;
+ if( !pPage->leaf ) iCellLast--;
+ for(i=0; i<pPage->nCell; i++){
+ pc = get2byte(&data[cellOffset+i*2]);
+ if( pc<iCellFirst || pc>iCellLast ){
+ return SQLITE_CORRUPT_BKPT;
+ }
+ sz = cellSizePtr(pPage, &data[pc]);
+ if( pc+sz>usableSize ){
+ return SQLITE_CORRUPT_BKPT;
+ }
+ }
+ }
+#endif
+
/* Compute the total free space on the page */
pc = get2byte(&data[hdr+1]);
- nFree = data[hdr+7] + top - (cellOffset + 2*pPage->nCell);
+ nFree = data[hdr+7] + top;
while( pc>0 ){
u16 next, size;
if( pc>usableSize-4 ){
/* Free block is off the page */
@@ -37693,13 +37980,20 @@
}
nFree += size;
pc = next;
}
- pPage->nFree = (u16)nFree;
- if( nFree>=usableSize ){
- /* Free space cannot exceed total page size */
+
+ /* At this point, nFree contains the sum of the offset to the start
+ ** of the cell-content area plus the number of free bytes within
+ ** the cell-content area. If this is greater than the usable-size
+ ** of the page, then the page must be corrupted. This check also
+ ** serves to verify that the offset to the start of the cell-content
+ ** area, according to the page header, lies within the page.
+ */
+ if( nFree>usableSize ){
return SQLITE_CORRUPT_BKPT;
}
+ pPage->nFree = nFree - (cellOffset + 2*pPage->nCell);
#if 0
/* Check that all the offsets in the cell offset array are within range.
**
@@ -39180,8 +39474,9 @@
}
while( PTRMAP_ISPAGE(pBt, nFin) || nFin==PENDING_BYTE_PAGE(pBt) ){
nFin--;
}
+ if( nFin>nOrig ) return SQLITE_CORRUPT_BKPT;
for(iFree=nOrig; iFree>nFin && rc==SQLITE_OK; iFree--){
rc = incrVacuumStep(pBt, nFin, iFree);
}
@@ -40224,15 +40519,17 @@
** These routines is used to get quick access to key and data
** in the common case where no overflow pages are used.
*/
SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int *pAmt){
+ assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
assert( cursorHoldsMutex(pCur) );
if( pCur->eState==CURSOR_VALID ){
return (const void*)fetchPayload(pCur, pAmt, 0);
}
return 0;
}
SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor *pCur, int *pAmt){
+ assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
assert( cursorHoldsMutex(pCur) );
if( pCur->eState==CURSOR_VALID ){
return (const void*)fetchPayload(pCur, pAmt, 1);
}
@@ -40357,8 +40654,9 @@
pCur->validNKey = 0;
if( pRoot->nCell==0 && !pRoot->leaf ){
Pgno subpage;
+ if( pRoot->pgno!=1 ) return SQLITE_CORRUPT_BKPT;
assert( pRoot->pgno==1 );
subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+8]);
assert( subpage>0 );
pCur->eState = CURSOR_VALID;
@@ -40726,16 +41024,8 @@
return (CURSOR_VALID!=pCur->eState);
}
/*
-** Return the database connection handle for a cursor.
-*/
-SQLITE_PRIVATE sqlite3 *sqlite3BtreeCursorDb(const BtCursor *pCur){
- assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
- return pCur->pBtree->db;
-}
-
-/*
** Advance the cursor to the next entry in the database. If
** successful then set *pRes=0. If the cursor
** was already pointing to the last entry in the database before
** this routine was called, then set *pRes=1.
@@ -40892,16 +41182,21 @@
u8 exact
){
MemPage *pPage1;
int rc;
- int n; /* Number of pages on the freelist */
+ u32 n; /* Number of pages on the freelist */
int 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) );
pPage1 = pBt->pPage1;
+ mxPage = pagerPagecount(pBt);
n = get4byte(&pPage1->aData[36]);
+ if( n>mxPage ){
+ return SQLITE_CORRUPT_BKPT;
+ }
if( n>0 ){
/* There are pages on the freelist. Reuse one of those pages. */
Pgno iTrunk;
u8 searchList = 0; /* If the free-list must be searched for 'nearby' */
@@ -40910,9 +41205,9 @@
** shows that the page 'nearby' is somewhere on the free-list, then
** the entire-list will be searched for that page.
*/
#ifndef SQLITE_OMIT_AUTOVACUUM
- if( exact && nearby<=pagerPagecount(pBt) ){
+ if( exact && nearby<=mxPage ){
u8 eType;
assert( nearby>0 );
assert( pBt->autoVacuum );
rc = ptrmapGet(pBt, nearby, &eType, 0);
@@ -40941,9 +41236,13 @@
iTrunk = get4byte(&pPrevTrunk->aData[0]);
}else{
iTrunk = get4byte(&pPage1->aData[32]);
}
- rc = sqlite3BtreeGetPage(pBt, iTrunk, &pTrunk, 0);
+ if( iTrunk>mxPage ){
+ rc = SQLITE_CORRUPT_BKPT;
+ }else{
+ rc = sqlite3BtreeGetPage(pBt, iTrunk, &pTrunk, 0);
+ }
if( rc ){
pTrunk = 0;
goto end_allocate_page;
}
@@ -40991,8 +41290,12 @@
** page in this case.
*/
MemPage *pNewTrunk;
Pgno iNewTrunk = get4byte(&pTrunk->aData[8]);
+ if( iNewTrunk>mxPage ){
+ rc = SQLITE_CORRUPT_BKPT;
+ goto end_allocate_page;
+ }
rc = sqlite3BtreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0);
if( rc!=SQLITE_OK ){
goto end_allocate_page;
}
@@ -41045,8 +41348,12 @@
closest = 0;
}
iPage = get4byte(&aData[8+closest*4]);
+ if( iPage>mxPage ){
+ rc = SQLITE_CORRUPT_BKPT;
+ goto end_allocate_page;
+ }
if( !searchList || iPage==nearby ){
int noContent;
Pgno nPage;
*pPgno = iPage;
@@ -41697,57 +42004,63 @@
** 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){
- int rc;
- MemPage *pNew = 0;
- Pgno pgnoNew;
- u8 *pCell;
- u16 szCell;
- CellInfo info;
- MemPage *pPage = pCur->apPage[pCur->iPage];
- MemPage *pParent = pCur->apPage[pCur->iPage-1];
- BtShared *pBt = pPage->pBt;
- int parentIdx = pParent->nCell; /* pParent new divider cell index */
- int parentSize; /* Size of new divider cell */
- u8 parentCell[64]; /* Space for the new divider cell */
+ MemPage *const pPage = pCur->apPage[pCur->iPage];
+ BtShared *const pBt = pCur->pBt;
+ MemPage *pNew = 0; /* Newly allocated page */
+ int rc; /* Return Code */
+ Pgno pgnoNew; /* Page number of pNew */
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
-
- /* Allocate a new page. Insert the overflow cell from pPage
- ** into it. Then remove the overflow cell from pPage.
- */
+ if( pPage->nCell<=0 ) return SQLITE_CORRUPT_BKPT;
+
+ /* Allocate a new page. This page will become the right-sibling of pPage */
rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);
- if( rc==SQLITE_OK ){
- pCell = pPage->aOvfl[0].pCell;
- szCell = cellSizePtr(pPage, pCell);
+
+ 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 *pCell = pPage->aOvfl[0].pCell;
+ u16 szCell = cellSizePtr(pPage, pCell);
+ u8 *pStop;
+
assert( sqlite3PagerIswriteable(pNew->pDbPage) );
zeroPage(pNew, pPage->aData[0]);
assemblePage(pNew, 1, &pCell, &szCell);
pPage->nOverflow = 0;
- /* pPage is currently the right-child of pParent. Change this
- ** so that the right-child is the new page allocated above and
- ** pPage is the next-to-right child.
- **
- ** Ignore the return value of the call to fillInCell(). fillInCell()
- ** may only return other than SQLITE_OK if it is required to allocate
- ** one or more overflow pages. Since an internal table B-Tree cell
- ** may never spill over onto an overflow page (it is a maximum of
- ** 13 bytes in size), it is not neccessary to check the return code.
- **
- ** Similarly, the insertCell() function cannot fail if the page
- ** being inserted into is already writable and the cell does not
- ** contain an overflow pointer. So ignore this return code too.
- */
- assert( pPage->nCell>0 );
+ /* 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).
+ **
+ ** To find the largest key value on pPage, first find the right-most
+ ** 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);
pCell = findCell(pPage, pPage->nCell-1);
- sqlite3BtreeParseCellPtr(pPage, pCell, &info);
- fillInCell(pParent, parentCell, 0, info.nKey, 0, 0, 0, &parentSize);
- assert( parentSize<64 );
- assert( sqlite3PagerIswriteable(pParent->pDbPage) );
- insertCell(pParent, parentIdx, parentCell, parentSize, 0, 4);
- put4byte(findOverflowCell(pParent,parentIdx), pPage->pgno);
+ 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);
+
+ /* 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
@@ -42141,9 +42454,9 @@
szNew[i] = szRight;
szNew[i-1] = szLeft;
}
- /* Either we found one or more cells (cntnew[0])>0) or we are the
+ /* Either we found one or more cells (cntnew[0])>0) or pPage is
** a virtual root page. A virtual root page is when the real root
** page is page 1 and we are the only child of that page.
*/
assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) );
@@ -43077,9 +43390,9 @@
/* Read the value of meta[3] from the database to determine where the
** root page of the new table should go. meta[3] is the largest root-page
** created so far, so the new root-page is (meta[3]+1).
*/
- rc = sqlite3BtreeGetMeta(p, 4, &pgnoRoot);
+ rc = sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &pgnoRoot);
if( rc!=SQLITE_OK ){
return rc;
}
pgnoRoot++;
@@ -43310,9 +43623,9 @@
releasePage(pPage);
#else
if( pBt->autoVacuum ){
Pgno maxRootPgno;
- rc = sqlite3BtreeGetMeta(p, 4, &maxRootPgno);
+ rc = sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &maxRootPgno);
if( rc!=SQLITE_OK ){
releasePage(pPage);
return rc;
}
@@ -43451,9 +43764,9 @@
/* If autovacuumed is disabled in this build but we are trying to
** access an autovacuumed database, then make the database readonly.
*/
#ifdef SQLITE_OMIT_AUTOVACUUM
- if( idx==4 && *pMeta>0 ) pBt->readOnly = 1;
+ if( idx==BTREE_LARGEST_ROOT_PAGE && *pMeta>0 ) pBt->readOnly = 1;
#endif
/* If there is currently an open transaction, grab a read-lock
** on page 1 of the database file. This is done to make sure that
@@ -43483,9 +43796,9 @@
rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
if( rc==SQLITE_OK ){
put4byte(&pP1[36 + idx*4], iMeta);
#ifndef SQLITE_OMIT_AUTOVACUUM
- if( idx==7 ){
+ if( idx==BTREE_INCR_VACUUM ){
assert( pBt->autoVacuum || iMeta==0 );
assert( iMeta==0 || iMeta==1 );
pBt->incrVacuum = (u8)iMeta;
}
@@ -44243,9 +44556,9 @@
*************************************************************************
** This file contains the implementation of the sqlite3_backup_XXX()
** API functions and the related features.
**
-** $Id: backup.c,v 1.13.2.1 2009/05/18 17:11:31 drh Exp $
+** $Id: backup.c,v 1.17 2009/06/03 11:25:07 danielk1977 Exp $
*/
/* Macro to find the minimum of two numeric values.
*/
@@ -44320,17 +44633,26 @@
static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
int i = sqlite3FindDbName(pDb, zDb);
if( i==1 ){
- Parse sParse;
- memset(&sParse, 0, sizeof(sParse));
- sParse.db = pDb;
- if( sqlite3OpenTempDatabase(&sParse) ){
- sqlite3ErrorClear(&sParse);
- sqlite3Error(pErrorDb, sParse.rc, "%s", sParse.zErrMsg);
- return 0;
- }
- assert( sParse.zErrMsg==0 );
+ Parse *pParse;
+ int rc = 0;
+ pParse = sqlite3StackAllocZero(pErrorDb, sizeof(*pParse));
+ if( pParse==0 ){
+ sqlite3Error(pErrorDb, SQLITE_NOMEM, "out of memory");
+ rc = SQLITE_NOMEM;
+ }else{
+ pParse->db = pDb;
+ if( sqlite3OpenTempDatabase(pParse) ){
+ sqlite3ErrorClear(pParse);
+ sqlite3Error(pErrorDb, pParse->rc, "%s", pParse->zErrMsg);
+ rc = SQLITE_ERROR;
+ }
+ sqlite3StackFree(pErrorDb, pParse);
+ }
+ if( rc ){
+ return 0;
+ }
}
if( i<0 ){
sqlite3Error(pErrorDb, SQLITE_ERROR, "unknown database %s", zDb);
@@ -44413,9 +44735,9 @@
** considered fatal if encountered during a backup operation. All errors
** are considered fatal except for SQLITE_BUSY and SQLITE_LOCKED.
*/
static int isFatalError(int rc){
- return (rc!=SQLITE_OK && rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED);
+ return (rc!=SQLITE_OK && rc!=SQLITE_BUSY && ALWAYS(rc!=SQLITE_LOCKED));
}
/*
** Parameter zSrcData points to a buffer containing the data for
@@ -44538,9 +44860,9 @@
if( SQLITE_OK==rc && p->bDestLocked==0
&& SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2))
){
p->bDestLocked = 1;
- rc = sqlite3BtreeGetMeta(p->pDest, 1, &p->iDestSchema);
+ rc = sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema);
}
/* If there is no open read-transaction on the source database, open
** one now. If a transaction is opened here, then it will be closed
@@ -44698,8 +45020,9 @@
sqlite3_mutex *mutex; /* Mutex to protect source database */
int rc; /* Value to return */
/* Enter the mutexes */
+ if( p==0 ) return SQLITE_OK;
sqlite3_mutex_enter(p->pSrcDb->mutex);
sqlite3BtreeEnter(p->pSrc);
mutex = p->pSrcDb->mutex;
if( p->pDestDb ){
@@ -44866,9 +45189,9 @@
** 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.144 2009/05/05 12:54:50 drh Exp $
+** $Id: vdbemem.c,v 1.147 2009/05/28 11:05:57 danielk1977 Exp $
*/
/*
** Call sqlite3VdbeMemExpandBlob() on the supplied value (type Mem*)
@@ -45697,15 +46020,14 @@
int amt, /* Number of bytes to return. */
int key, /* If true, retrieve from the btree key, not data. */
Mem *pMem /* OUT: Return data in this Mem structure. */
){
- char *zData; /* Data from the btree layer */
- int available = 0; /* Number of bytes available on the local btree page */
- sqlite3 *db; /* Database connection */
- int rc = SQLITE_OK;
-
- db = sqlite3BtreeCursorDb(pCur);
- assert( sqlite3_mutex_held(db->mutex) );
+ char *zData; /* Data from the btree layer */
+ int available = 0; /* Number of bytes available on the local btree page */
+ int rc = SQLITE_OK; /* Return code */
+
+ /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert()
+ ** that both the BtShared and database handle mutexes are held. */
assert( (pMem->flags & MEM_RowSet)==0 );
if( key ){
zData = (char *)sqlite3BtreeKeyFetch(pCur, &available);
}else{
@@ -45823,12 +46145,17 @@
}
op = pExpr->op;
if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){
- zVal = sqlite3DbStrNDup(db, (char*)pExpr->token.z, pExpr->token.n);
pVal = sqlite3ValueNew(db);
- if( !zVal || !pVal ) goto no_mem;
- sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);
+ if( pVal==0 ) goto no_mem;
+ if( ExprHasProperty(pExpr, EP_IntValue) ){
+ sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue);
+ }else{
+ zVal = sqlite3DbStrDup(db, pExpr->u.zToken);
+ if( zVal==0 ) goto no_mem;
+ sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);
+ }
if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){
sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8);
}else{
sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8);
@@ -45845,16 +46172,15 @@
}
#ifndef SQLITE_OMIT_BLOB_LITERAL
else if( op==TK_BLOB ){
int nVal;
- assert( pExpr->token.n>=3 );
- assert( pExpr->token.z[0]=='x' || pExpr->token.z[0]=='X' );
- assert( pExpr->token.z[1]=='\'' );
- assert( pExpr->token.z[pExpr->token.n-1]=='\'' );
+ assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' );
+ assert( pExpr->u.zToken[1]=='\'' );
pVal = sqlite3ValueNew(db);
if( !pVal ) goto no_mem;
- nVal = pExpr->token.n - 3;
- zVal = (char*)pExpr->token.z + 2;
+ zVal = &pExpr->u.zToken[2];
+ nVal = sqlite3Strlen30(zVal)-1;
+ assert( zVal[nVal]=='\'' );
sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2,
0, SQLITE_DYNAMIC);
}
#endif
@@ -45925,9 +46251,9 @@
** 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.457 2009/05/06 18:57:10 shane Exp $
+** $Id: vdbeaux.c,v 1.459 2009/06/05 14:17:25 drh Exp $
*/
@@ -46527,14 +46853,27 @@
}
#endif /* NDEBUG */
/*
-** Return the opcode for a given address.
+** Return the opcode for a given address. If the address is -1, then
+** return the most recently inserted opcode.
+**
+** If a memory allocation error has occurred prior to the calling of this
+** routine, then a pointer to a dummy VdbeOp will be returned. That opcode
+** is readable 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.
*/
SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
+ static VdbeOp dummy;
assert( p->magic==VDBE_MAGIC_INIT );
+ if( addr<0 ) addr = p->nOp - 1;
assert( (addr>=0 && addr<p->nOp) || p->db->mallocFailed );
- return ((addr>=0 && addr<p->nOp)?(&p->aOp[addr]):0);
+ if( p->db->mallocFailed ){
+ return &dummy;
+ }else{
+ return &p->aOp[addr];
+ }
}
#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
|| defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
@@ -48016,9 +48355,9 @@
/*
** Return the length of the data corresponding to the supplied serial-type.
*/
-SQLITE_PRIVATE int sqlite3VdbeSerialTypeLen(u32 serial_type){
+SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32 serial_type){
if( serial_type>=12 ){
return (serial_type-12)/2;
}else{
static const u8 aSize[] = { 0, 1, 2, 3, 4, 6, 8, 8, 0, 0, 0, 0 };
@@ -48096,16 +48435,16 @@
** Return the number of bytes actually written into buf[]. The number
** of bytes in the zero-filled tail is included in the return value only
** if those bytes were zeroed in buf[].
*/
-SQLITE_PRIVATE int sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_format){
+SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_format){
u32 serial_type = sqlite3VdbeSerialType(pMem, file_format);
- int len;
+ u32 len;
/* Integer and Real */
if( serial_type<=7 && serial_type>0 ){
u64 v;
- int i;
+ u32 i;
if( serial_type==7 ){
assert( sizeof(v)==sizeof(pMem->r) );
memcpy(&v, &pMem->r, sizeof(v));
swapMixedEndianFloat(v);
@@ -48129,10 +48468,11 @@
len = pMem->n;
memcpy(buf, pMem->z, len);
if( pMem->flags & MEM_Zero ){
len += pMem->u.nZero;
- if( len>nBuf ){
- len = nBuf;
+ assert( nBuf>=0 );
+ if( len > (u32)nBuf ){
+ len = (u32)nBuf;
}
memset(&buf[pMem->n], 0, len-pMem->n);
}
return len;
@@ -48145,9 +48485,9 @@
/*
** Deserialize the data blob pointed to by buf as serial type serial_type
** and store the result in pMem. Return the number of bytes read.
*/
-SQLITE_PRIVATE int sqlite3VdbeSerialGet(
+SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(
const unsigned char *buf, /* Buffer to deserialize from */
u32 serial_type, /* Serial type to deserialize */
Mem *pMem /* Memory cell to write value into */
){
@@ -48223,9 +48563,9 @@
pMem->flags = MEM_Int;
return 0;
}
default: {
- int len = (serial_type-12)/2;
+ u32 len = (serial_type-12)/2;
pMem->z = (char *)buf;
pMem->n = len;
pMem->xDel = 0;
if( serial_type&0x01 ){
@@ -48618,9 +48958,9 @@
**
** This file contains code use to implement APIs that are part of the
** VDBE.
**
-** $Id: vdbeapi.c,v 1.164 2009/04/27 18:46:06 drh Exp $
+** $Id: vdbeapi.c,v 1.165 2009/06/06 14:13:27 danielk1977 Exp $
*/
#if 0 && defined(SQLITE_ENABLE_MEMORY_MANAGEMENT)
/*
@@ -49369,10 +49709,25 @@
sqlite3_mutex_enter(pVm->db->mutex);
vals = sqlite3_data_count(pStmt);
pOut = &pVm->pResultSet[i];
}else{
- /* ((double)0) In case of SQLITE_OMIT_FLOATING_POINT... */
- static const Mem nullMem = {{0}, (double)0, 0, "", 0, MEM_Null, SQLITE_NULL, 0, 0, 0 };
+ /* If the value passed as the second argument is out of range, return
+ ** a pointer to the following static Mem object which contains the
+ ** value SQL NULL. Even though the Mem structure contains an element
+ ** of type i64, on certain architecture (x86) with certain compiler
+ ** switches (-Os), gcc may align this Mem object on a 4-byte boundary
+ ** instead of an 8-byte one. This all works fine, except that when
+ ** running with SQLITE_DEBUG defined the SQLite code sometimes assert()s
+ ** that a Mem structure is located on an 8-byte boundary. To prevent
+ ** this assert() from failing, when building with SQLITE_DEBUG defined
+ ** using gcc, force nullMem to be 8-byte aligned using the magical
+ ** __attribute__((aligned(8))) macro. */
+ static const Mem nullMem
+#if defined(SQLITE_DEBUG) && defined(__GNUC__)
+ __attribute__((aligned(8)))
+#endif
+ = {{0}, (double)0, 0, "", 0, MEM_Null, SQLITE_NULL, 0, 0, 0 };
+
if( pVm && ALWAYS(pVm->db) ){
sqlite3_mutex_enter(pVm->db->mutex);
sqlite3Error(pVm->db, SQLITE_RANGE, 0);
}
@@ -49997,9 +50352,9 @@
** 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.842.2.1 2009/05/18 16:14:25 drh Exp $
+** $Id: vdbe.c,v 1.848 2009/06/05 16:46:53 drh Exp $
*/
/*
** The following global variable is incremented every time a cursor
@@ -50607,11 +50962,436 @@
#endif
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
int nProgressOps = 0; /* Opcodes executed since progress callback. */
#endif
-
- /* Temporary space into which to unpack a record. */
- char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7];
+ /********************************************************************
+ ** Automatically generated code
+ **
+ ** The following union is automatically generated by the
+ ** vdbe-compress.tcl script. The purpose of this union is to
+ ** reduce the amount of stack space required by this function.
+ ** See comments in the vdbe-compress.tcl script for details.
+ */
+ union vdbeExecUnion {
+ struct OP_Yield_stack_vars {
+ int pcDest;
+ } aa;
+ struct OP_Variable_stack_vars {
+ int p1; /* Variable to copy from */
+ int p2; /* Register to copy to */
+ int n; /* Number of values left to copy */
+ Mem *pVar; /* Value being transferred */
+ } ab;
+ struct OP_Move_stack_vars {
+ char *zMalloc; /* Holding variable for allocated memory */
+ int n; /* Number of registers left to copy */
+ int p1; /* Register to copy from */
+ int p2; /* Register to copy to */
+ } ac;
+ struct OP_ResultRow_stack_vars {
+ Mem *pMem;
+ int i;
+ } ad;
+ struct OP_Concat_stack_vars {
+ i64 nByte;
+ } ae;
+ struct OP_Remainder_stack_vars {
+ int flags; /* Combined MEM_* flags from both inputs */
+ i64 iA; /* Integer value of left operand */
+ i64 iB; /* Integer value of right operand */
+ double rA; /* Real value of left operand */
+ double rB; /* Real value of right operand */
+ } af;
+ struct OP_Function_stack_vars {
+ int i;
+ Mem *pArg;
+ sqlite3_context ctx;
+ sqlite3_value **apVal;
+ int n;
+ } ag;
+ struct OP_ShiftRight_stack_vars {
+ i64 a;
+ i64 b;
+ } ah;
+ struct OP_Ge_stack_vars {
+ int flags;
+ int res;
+ char affinity;
+ } ai;
+ struct OP_Compare_stack_vars {
+ int n;
+ int i;
+ int p1;
+ int p2;
+ const KeyInfo *pKeyInfo;
+ int idx;
+ CollSeq *pColl; /* Collating sequence to use on this term */
+ int bRev; /* True for DESCENDING sort order */
+ } aj;
+ struct OP_Or_stack_vars {
+ int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
+ int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
+ } 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 */
+ VdbeCursor *pC; /* The VDBE cursor */
+ char *zRec; /* Pointer to complete record-data */
+ BtCursor *pCrsr; /* The BTree cursor */
+ u32 *aType; /* aType[i] holds the numeric type of the i-th column */
+ u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */
+ int nField; /* number of fields in the record */
+ int len; /* The length of the serialized data for the column */
+ int i; /* Loop counter */
+ char *zData; /* Part of the record being decoded */
+ Mem *pDest; /* Where to write the extracted value */
+ Mem sMem; /* For storing the record being decoded */
+ u8 *zIdx; /* Index into header */
+ 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;
+ 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;
+ 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 */
+ i64 nByte; /* Data space required for this record */
+ int nZero; /* Number of zero bytes at the end of the record */
+ int nVarint; /* Number of bytes in a varint */
+ u32 serial_type; /* Type field */
+ Mem *pData0; /* First field to be combined into the record */
+ Mem *pLast; /* Last field of the record */
+ int nField; /* Number of fields in the record */
+ char *zAffinity; /* The affinity string for the record */
+ int file_format; /* File format to use for encoding */
+ int i; /* Space used in zNewRecord[] */
+ int len; /* Length of a field */
+ } ap;
+ struct OP_Count_stack_vars {
+ i64 nEntry;
+ BtCursor *pCrsr;
+ } aq;
+ struct OP_Statement_stack_vars {
+ int i;
+ Btree *pBt;
+ } ar;
+ 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;
+ struct OP_AutoCommit_stack_vars {
+ int desiredAutoCommit;
+ int rollback;
+ int turnOnAC;
+ } at;
+ struct OP_Transaction_stack_vars {
+ int i;
+ Btree *pBt;
+ } au;
+ struct OP_ReadCookie_stack_vars {
+ int iMeta;
+ int iDb;
+ int iCookie;
+ } av;
+ struct OP_SetCookie_stack_vars {
+ Db *pDb;
+ } aw;
+ struct OP_VerifyCookie_stack_vars {
+ int iMeta;
+ Btree *pBt;
+ } ax;
+ 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;
+ struct OP_OpenEphemeral_stack_vars {
+ int i;
+ 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;
+ int res;
+ int oc;
+ VdbeCursor *pC;
+ UnpackedRecord r;
+ int nField;
+ i64 iKey; /* The rowid we are to seek to */
+ } bc;
+ struct OP_Seek_stack_vars {
+ int i;
+ VdbeCursor *pC;
+ } bd;
+ struct OP_Found_stack_vars {
+ int i;
+ int alreadyExists;
+ VdbeCursor *pC;
+ int res;
+ UnpackedRecord *pIdxKey;
+ char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7];
+ } be;
+ 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;
+ VdbeCursor *pC;
+ BtCursor *pCrsr;
+ int res;
+ u64 iKey;
+ } bg;
+ struct OP_NewRowid_stack_vars {
+ int i;
+ i64 v;
+ VdbeCursor *pC;
+ int res;
+ int rx;
+ int cnt;
+ i64 x;
+ Mem *pMem;
+ } bh;
+ 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;
+ i64 iKey;
+ VdbeCursor *pC;
+ } bj;
+ struct OP_RowData_stack_vars {
+ int i;
+ VdbeCursor *pC;
+ BtCursor *pCrsr;
+ u32 n;
+ i64 n64;
+ } bk;
+ struct OP_Rowid_stack_vars {
+ int i;
+ VdbeCursor *pC;
+ i64 v;
+ sqlite3_vtab *pVtab;
+ const sqlite3_module *pModule;
+ } bl;
+ struct OP_NullRow_stack_vars {
+ int i;
+ VdbeCursor *pC;
+ } bm;
+ struct OP_Last_stack_vars {
+ int i;
+ VdbeCursor *pC;
+ BtCursor *pCrsr;
+ int res;
+ } bn;
+ struct OP_Rewind_stack_vars {
+ int i;
+ VdbeCursor *pC;
+ BtCursor *pCrsr;
+ int res;
+ } bo;
+ struct OP_Next_stack_vars {
+ VdbeCursor *pC;
+ BtCursor *pCrsr;
+ int res;
+ } bp;
+ struct OP_IdxInsert_stack_vars {
+ int i;
+ VdbeCursor *pC;
+ BtCursor *pCrsr;
+ int nKey;
+ const char *zKey;
+ } bq;
+ struct OP_IdxDelete_stack_vars {
+ int i;
+ VdbeCursor *pC;
+ BtCursor *pCrsr;
+ } br;
+ struct OP_IdxRowid_stack_vars {
+ int i;
+ BtCursor *pCrsr;
+ VdbeCursor *pC;
+ i64 rowid;
+ } bs;
+ struct OP_IdxGE_stack_vars {
+ int i;
+ VdbeCursor *pC;
+ int res;
+ UnpackedRecord r;
+ } bt;
+ struct OP_Destroy_stack_vars {
+ int iMoved;
+ int iCnt;
+ Vdbe *pVdbe;
+ int iDb;
+ } bu;
+ struct OP_Clear_stack_vars {
+ int nChange;
+ } bv;
+ struct OP_CreateTable_stack_vars {
+ int pgno;
+ int flags;
+ Db *pDb;
+ } bw;
+ struct OP_ParseSchema_stack_vars {
+ int iDb;
+ const char *zMaster;
+ char *zSql;
+ InitData initData;
+ } bx;
+ 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;
+ struct OP_RowSetAdd_stack_vars {
+ Mem *pIdx;
+ Mem *pVal;
+ } bz;
+ struct OP_RowSetRead_stack_vars {
+ Mem *pIdx;
+ i64 val;
+ } ca;
+ struct OP_RowSetTest_stack_vars {
+ int iSet;
+ int exists;
+ } cb;
+ struct OP_ContextPush_stack_vars {
+ int i;
+ Context *pContext;
+ } cc;
+ struct OP_ContextPop_stack_vars {
+ Context *pContext;
+ } cd;
+ struct OP_AggStep_stack_vars {
+ int n;
+ int i;
+ Mem *pMem;
+ Mem *pRec;
+ sqlite3_context ctx;
+ sqlite3_value **apVal;
+ } ce;
+ struct OP_AggFinal_stack_vars {
+ Mem *pMem;
+ } cf;
+ struct OP_IncrVacuum_stack_vars {
+ Btree *pBt;
+ } cg;
+ struct OP_TableLock_stack_vars {
+ int p1;
+ u8 isWriteLock;
+ } ch;
+ struct OP_VBegin_stack_vars {
+ sqlite3_vtab *pVtab;
+ } ci;
+ struct OP_VOpen_stack_vars {
+ VdbeCursor *pCur;
+ sqlite3_vtab_cursor *pVtabCursor;
+ sqlite3_vtab *pVtab;
+ sqlite3_module *pModule;
+ } cj;
+ struct OP_VFilter_stack_vars {
+ int nArg;
+ int iQuery;
+ const sqlite3_module *pModule;
+ Mem *pQuery;
+ Mem *pArgc;
+ sqlite3_vtab_cursor *pVtabCursor;
+ sqlite3_vtab *pVtab;
+ VdbeCursor *pCur;
+ int res;
+ int i;
+ Mem **apArg;
+ } ck;
+ struct OP_VColumn_stack_vars {
+ sqlite3_vtab *pVtab;
+ const sqlite3_module *pModule;
+ Mem *pDest;
+ sqlite3_context sContext;
+ } cl;
+ struct OP_VNext_stack_vars {
+ sqlite3_vtab *pVtab;
+ const sqlite3_module *pModule;
+ int res;
+ VdbeCursor *pCur;
+ } cm;
+ struct OP_VRename_stack_vars {
+ sqlite3_vtab *pVtab;
+ Mem *pName;
+ } cn;
+ struct OP_VUpdate_stack_vars {
+ sqlite3_vtab *pVtab;
+ sqlite3_module *pModule;
+ int nArg;
+ int i;
+ sqlite_int64 rowid;
+ Mem **apArg;
+ Mem *pX;
+ } co;
+ struct OP_Pagecount_stack_vars {
+ int p1;
+ int nPage;
+ Pager *pPager;
+ } cp;
+ struct OP_Trace_stack_vars {
+ char *zTrace;
+ } cq;
+ } u;
+ /* End automatically generated code
+ ********************************************************************/
assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */
assert( db->magic==SQLITE_MAGIC_BUSY );
sqlite3VdbeMutexArrayEnter(p);
@@ -50848,15 +51628,17 @@
**
** Swap the program counter with the value in register P1.
*/
case OP_Yield: { /* in1 */
+#if 0 /* local variables moved into u.aa */
int pcDest;
+#endif /* local variables moved into u.aa */
assert( (pIn1->flags & MEM_Dyn)==0 );
pIn1->flags = MEM_Int;
- pcDest = (int)pIn1->u.i;
+ u.aa.pcDest = (int)pIn1->u.i;
pIn1->u.i = pc;
REGISTER_TRACE(pOp->p1, pIn1);
- pc = pcDest;
+ pc = u.aa.pcDest;
break;
}
/* Opcode: HaltIfNull P1 P2 P3 P4 *
@@ -51025,25 +51807,31 @@
** If the parameter is named, then its name appears in P4 and P3==1.
** The P4 value is used by sqlite3_bind_parameter_name().
*/
case OP_Variable: {
- int j = pOp->p1 - 1;
- int k = pOp->p2;
- Mem *pVar;
- int n = pOp->p3;
- assert( j>=0 && j+n<=p->nVar );
- assert( k>=1 && k+n-1<=p->nMem );
+#if 0 /* local variables moved into u.ab */
+ int p1; /* Variable to copy from */
+ int p2; /* Register to copy to */
+ int n; /* Number of values left to copy */
+ Mem *pVar; /* Value being transferred */
+#endif /* local variables moved into u.ab */
+
+ u.ab.p1 = pOp->p1 - 1;
+ u.ab.p2 = pOp->p2;
+ u.ab.n = pOp->p3;
+ assert( u.ab.p1>=0 && u.ab.p1+u.ab.n<=p->nVar );
+ assert( u.ab.p2>=1 && u.ab.p2+u.ab.n-1<=p->nMem );
assert( pOp->p4.z==0 || pOp->p3==1 );
- while( n-- > 0 ){
- pVar = &p->aVar[j++];
- if( sqlite3VdbeMemTooBig(pVar) ){
+ while( u.ab.n-- > 0 ){
+ u.ab.pVar = &p->aVar[u.ab.p1++];
+ if( sqlite3VdbeMemTooBig(u.ab.pVar) ){
goto too_big;
}
- pOut = &p->aMem[k++];
+ pOut = &p->aMem[u.ab.p2++];
sqlite3VdbeMemReleaseExternal(pOut);
pOut->flags = MEM_Null;
- sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static);
+ sqlite3VdbeMemShallowCopy(pOut, u.ab.pVar, MEM_Static);
UPDATE_MAX_BLOBSIZE(pOut);
}
break;
}
@@ -51055,25 +51843,31 @@
** left holding a NULL. It is an error for register ranges
** P1..P1+P3-1 and P2..P2+P3-1 to overlap.
*/
case OP_Move: {
- char *zMalloc;
- int n = pOp->p3;
- int p1 = pOp->p1;
- int p2 = pOp->p2;
- assert( n>0 && p1>0 && p2>0 );
- assert( p1+n<=p2 || p2+n<=p1 );
-
- pIn1 = &p->aMem[p1];
- pOut = &p->aMem[p2];
- while( n-- ){
+#if 0 /* local variables moved into u.ac */
+ char *zMalloc; /* Holding variable for allocated memory */
+ int n; /* Number of registers left to copy */
+ int p1; /* Register to copy from */
+ int p2; /* Register to copy to */
+#endif /* local variables moved into u.ac */
+
+ u.ac.n = pOp->p3;
+ u.ac.p1 = pOp->p1;
+ u.ac.p2 = pOp->p2;
+ assert( u.ac.n>0 && u.ac.p1>0 && u.ac.p2>0 );
+ assert( u.ac.p1+u.ac.n<=u.ac.p2 || u.ac.p2+u.ac.n<=u.ac.p1 );
+
+ pIn1 = &p->aMem[u.ac.p1];
+ pOut = &p->aMem[u.ac.p2];
+ while( u.ac.n-- ){
assert( pOut<=&p->aMem[p->nMem] );
assert( pIn1<=&p->aMem[p->nMem] );
- zMalloc = pOut->zMalloc;
+ u.ac.zMalloc = pOut->zMalloc;
pOut->zMalloc = 0;
sqlite3VdbeMemMove(pOut, pIn1);
- pIn1->zMalloc = zMalloc;
- REGISTER_TRACE(p2++, pOut);
+ pIn1->zMalloc = u.ac.zMalloc;
+ REGISTER_TRACE(u.ac.p2++, pOut);
pIn1++;
pOut++;
}
break;
@@ -51128,10 +51922,12 @@
** structure to provide access to the top P1 values as the result
** row.
*/
case OP_ResultRow: {
+#if 0 /* local variables moved into u.ad */
Mem *pMem;
int i;
+#endif /* local variables moved into u.ad */
assert( p->nResColumn==pOp->p2 );
assert( pOp->p1>0 );
assert( pOp->p1+pOp->p2<=p->nMem+1 );
@@ -51158,13 +51954,13 @@
/* Make sure the results of the current row are \000 terminated
** and have an assigned type. The results are de-ephemeralized as
** as side effect.
*/
- pMem = p->pResultSet = &p->aMem[pOp->p1];
- for(i=0; i<pOp->p2; i++){
- sqlite3VdbeMemNulTerminate(&pMem[i]);
- storeTypeInfo(&pMem[i], encoding);
- REGISTER_TRACE(pOp->p1+i, &pMem[i]);
+ u.ad.pMem = p->pResultSet = &p->aMem[pOp->p1];
+ for(u.ad.i=0; u.ad.i<pOp->p2; u.ad.i++){
+ sqlite3VdbeMemNulTerminate(&u.ad.pMem[u.ad.i]);
+ storeTypeInfo(&u.ad.pMem[u.ad.i], encoding);
+ REGISTER_TRACE(pOp->p1+u.ad.i, &u.ad.pMem[u.ad.i]);
}
if( db->mallocFailed ) goto no_mem;
/* Return SQLITE_ROW
@@ -51186,9 +51982,11 @@
** if P3 is the same register as P2, the implementation is able
** to avoid a memcpy().
*/
case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
+#if 0 /* local variables moved into u.ae */
i64 nByte;
+#endif /* local variables moved into u.ae */
assert( pIn1!=pOut );
if( (pIn1->flags | pIn2->flags) & MEM_Null ){
sqlite3VdbeMemSetNull(pOut);
@@ -51197,24 +51995,24 @@
ExpandBlob(pIn1);
Stringify(pIn1, encoding);
ExpandBlob(pIn2);
Stringify(pIn2, encoding);
- nByte = pIn1->n + pIn2->n;
- if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ u.ae.nByte = pIn1->n + pIn2->n;
+ if( u.ae.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
MemSetTypeFlag(pOut, MEM_Str);
- if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){
+ if( sqlite3VdbeMemGrow(pOut, (int)u.ae.nByte+2, pOut==pIn2) ){
goto no_mem;
}
if( pOut!=pIn2 ){
memcpy(pOut->z, pIn2->z, pIn2->n);
}
memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n);
- pOut->z[nByte] = 0;
- pOut->z[nByte+1] = 0;
+ pOut->z[u.ae.nByte] = 0;
+ pOut->z[u.ae.nByte+1] = 0;
pOut->flags |= MEM_Term;
- pOut->n = (int)nByte;
+ pOut->n = (int)u.ae.nByte;
pOut->enc = encoding;
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
@@ -51256,72 +52054,77 @@
case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */
case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */
case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */
case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
- int flags;
+#if 0 /* local variables moved into u.af */
+ int flags; /* Combined MEM_* flags from both inputs */
+ i64 iA; /* Integer value of left operand */
+ i64 iB; /* Integer value of right operand */
+ double rA; /* Real value of left operand */
+ double rB; /* Real value of right operand */
+#endif /* local variables moved into u.af */
+
applyNumericAffinity(pIn1);
applyNumericAffinity(pIn2);
- flags = pIn1->flags | pIn2->flags;
- if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
+ u.af.flags = pIn1->flags | pIn2->flags;
+ if( (u.af.flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
- i64 a, b;
- a = pIn1->u.i;
- b = pIn2->u.i;
+ u.af.iA = pIn1->u.i;
+ u.af.iB = pIn2->u.i;
switch( pOp->opcode ){
- case OP_Add: b += a; break;
- case OP_Subtract: b -= a; break;
- case OP_Multiply: b *= a; break;
+ case OP_Add: u.af.iB += u.af.iA; break;
+ case OP_Subtract: u.af.iB -= u.af.iA; break;
+ case OP_Multiply: u.af.iB *= u.af.iA; break;
case OP_Divide: {
- if( a==0 ) goto arithmetic_result_is_null;
+ if( u.af.iA==0 ) goto arithmetic_result_is_null;
/* Dividing the largest possible negative 64-bit integer (1<<63) by
** -1 returns an integer too large to store in a 64-bit data-type. On
** some architectures, the value overflows to (1<<63). On others,
** a SIGFPE is issued. The following statement normalizes this
** behavior so that all architectures behave as if integer
** overflow occurred.
*/
- if( a==-1 && b==SMALLEST_INT64 ) a = 1;
- b /= a;
+ if( u.af.iA==-1 && u.af.iB==SMALLEST_INT64 ) u.af.iA = 1;
+ u.af.iB /= u.af.iA;
break;
}
default: {
- if( a==0 ) goto arithmetic_result_is_null;
- if( a==-1 ) a = 1;
- b %= a;
- break;
- }
- }
- pOut->u.i = b;
+ if( u.af.iA==0 ) goto arithmetic_result_is_null;
+ if( u.af.iA==-1 ) u.af.iA = 1;
+ u.af.iB %= u.af.iA;
+ break;
+ }
+ }
+ pOut->u.i = u.af.iB;
MemSetTypeFlag(pOut, MEM_Int);
}else{
- double a, b;
- a = sqlite3VdbeRealValue(pIn1);
- b = sqlite3VdbeRealValue(pIn2);
+ u.af.rA = sqlite3VdbeRealValue(pIn1);
+ u.af.rB = sqlite3VdbeRealValue(pIn2);
switch( pOp->opcode ){
- case OP_Add: b += a; break;
- case OP_Subtract: b -= a; break;
- case OP_Multiply: b *= a; break;
+ case OP_Add: u.af.rB += u.af.rA; break;
+ case OP_Subtract: u.af.rB -= u.af.rA; break;
+ case OP_Multiply: u.af.rB *= u.af.rA; break;
case OP_Divide: {
/* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
- if( a==(double)0 ) goto arithmetic_result_is_null;
- b /= a;
+ if( u.af.rA==(double)0 ) goto arithmetic_result_is_null;
+ u.af.rB /= u.af.rA;
break;
}
default: {
- i64 ia = (i64)a;
- i64 ib = (i64)b;
- if( ia==0 ) goto arithmetic_result_is_null;
- if( ia==-1 ) ia = 1;
- b = (double)(ib % ia);
- break;
- }
- }
- if( sqlite3IsNaN(b) ){
+ u.af.iA = u.af.rA;
+ u.af.iB = 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;
+ }
+ }
+ if( sqlite3IsNaN(u.af.rB) ){
goto arithmetic_result_is_null;
}
- pOut->r = b;
+ pOut->r = u.af.rB;
MemSetTypeFlag(pOut, MEM_Real);
- if( (flags & MEM_Real)==0 ){
+ if( (u.af.flags & MEM_Real)==0 ){
sqlite3VdbeIntegerAffinity(pOut);
}
}
break;
@@ -51363,60 +52166,63 @@
**
** See also: AggStep and AggFinal
*/
case OP_Function: {
+#if 0 /* local variables moved into u.ag */
int i;
Mem *pArg;
sqlite3_context ctx;
sqlite3_value **apVal;
- int n = pOp->p5;
-
- apVal = p->apArg;
- assert( apVal || n==0 );
-
- assert( n==0 || (pOp->p2>0 && pOp->p2+n<=p->nMem+1) );
- assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
- pArg = &p->aMem[pOp->p2];
- for(i=0; i<n; i++, pArg++){
- apVal[i] = pArg;
- storeTypeInfo(pArg, encoding);
- REGISTER_TRACE(pOp->p2, pArg);
+ int n;
+#endif /* local variables moved into u.ag */
+
+ u.ag.n = pOp->p5;
+ u.ag.apVal = p->apArg;
+ assert( u.ag.apVal || u.ag.n==0 );
+
+ assert( u.ag.n==0 || (pOp->p2>0 && pOp->p2+u.ag.n<=p->nMem+1) );
+ assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+u.ag.n );
+ u.ag.pArg = &p->aMem[pOp->p2];
+ for(u.ag.i=0; u.ag.i<u.ag.n; u.ag.i++, u.ag.pArg++){
+ u.ag.apVal[u.ag.i] = u.ag.pArg;
+ storeTypeInfo(u.ag.pArg, encoding);
+ REGISTER_TRACE(pOp->p2, u.ag.pArg);
}
assert( pOp->p4type==P4_FUNCDEF || pOp->p4type==P4_VDBEFUNC );
if( pOp->p4type==P4_FUNCDEF ){
- ctx.pFunc = pOp->p4.pFunc;
- ctx.pVdbeFunc = 0;
- }else{
- ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.pVdbeFunc;
- ctx.pFunc = ctx.pVdbeFunc->pFunc;
+ u.ag.ctx.pFunc = pOp->p4.pFunc;
+ u.ag.ctx.pVdbeFunc = 0;
+ }else{
+ u.ag.ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.pVdbeFunc;
+ u.ag.ctx.pFunc = u.ag.ctx.pVdbeFunc->pFunc;
}
assert( pOp->p3>0 && pOp->p3<=p->nMem );
pOut = &p->aMem[pOp->p3];
- ctx.s.flags = MEM_Null;
- ctx.s.db = db;
- ctx.s.xDel = 0;
- ctx.s.zMalloc = 0;
+ u.ag.ctx.s.flags = MEM_Null;
+ u.ag.ctx.s.db = db;
+ u.ag.ctx.s.xDel = 0;
+ u.ag.ctx.s.zMalloc = 0;
/* The output cell may already have a buffer allocated. Move
- ** the pointer to ctx.s so in case the user-function can use
+ ** the pointer to u.ag.ctx.s so in case the user-function can use
** the already allocated buffer instead of allocating a new one.
*/
- sqlite3VdbeMemMove(&ctx.s, pOut);
- MemSetTypeFlag(&ctx.s, MEM_Null);
-
- ctx.isError = 0;
- if( ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
+ sqlite3VdbeMemMove(&u.ag.ctx.s, pOut);
+ MemSetTypeFlag(&u.ag.ctx.s, MEM_Null);
+
+ u.ag.ctx.isError = 0;
+ if( u.ag.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
assert( pOp>p->aOp );
assert( pOp[-1].p4type==P4_COLLSEQ );
assert( pOp[-1].opcode==OP_CollSeq );
- ctx.pColl = pOp[-1].p4.pColl;
+ u.ag.ctx.pColl = pOp[-1].p4.pColl;
}
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- (*ctx.pFunc->xFunc)(&ctx, n, apVal);
+ (*u.ag.ctx.pFunc->xFunc)(&u.ag.ctx, u.ag.n, u.ag.apVal);
if( sqlite3SafetyOn(db) ){
- sqlite3VdbeMemRelease(&ctx.s);
+ sqlite3VdbeMemRelease(&u.ag.ctx.s);
goto abort_due_to_misuse;
}
if( db->mallocFailed ){
/* Even though a malloc() has failed, the implementation of the
@@ -51427,30 +52233,30 @@
** Note: Maybe MemRelease() should be called if sqlite3SafetyOn()
** fails also (the if(...) statement above). But if people are
** misusing sqlite, they have bigger problems than a leaked value.
*/
- sqlite3VdbeMemRelease(&ctx.s);
+ sqlite3VdbeMemRelease(&u.ag.ctx.s);
goto no_mem;
}
/* If any auxiliary data functions have been called by this user function,
** immediately call the destructor for any non-static values.
*/
- if( ctx.pVdbeFunc ){
- sqlite3VdbeDeleteAuxData(ctx.pVdbeFunc, pOp->p1);
- pOp->p4.pVdbeFunc = ctx.pVdbeFunc;
+ if( u.ag.ctx.pVdbeFunc ){
+ sqlite3VdbeDeleteAuxData(u.ag.ctx.pVdbeFunc, pOp->p1);
+ pOp->p4.pVdbeFunc = u.ag.ctx.pVdbeFunc;
pOp->p4type = P4_VDBEFUNC;
}
/* If the function returned an error, throw an exception */
- if( ctx.isError ){
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s));
- rc = ctx.isError;
+ if( u.ag.ctx.isError ){
+ sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ag.ctx.s));
+ rc = u.ag.ctx.isError;
}
/* Copy the result of the function into register P3 */
- sqlite3VdbeChangeEncoding(&ctx.s, encoding);
- sqlite3VdbeMemMove(pOut, &ctx.s);
+ sqlite3VdbeChangeEncoding(&u.ag.ctx.s, encoding);
+ sqlite3VdbeMemMove(pOut, &u.ag.ctx.s);
if( sqlite3VdbeMemTooBig(pOut) ){
goto too_big;
}
REGISTER_TRACE(pOp->p3, pOut);
@@ -51487,24 +52293,27 @@
case OP_BitAnd: /* same as TK_BITAND, in1, in2, out3 */
case OP_BitOr: /* same as TK_BITOR, in1, in2, out3 */
case OP_ShiftLeft: /* same as TK_LSHIFT, in1, in2, out3 */
case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */
- i64 a, b;
+#if 0 /* local variables moved into u.ah */
+ i64 a;
+ i64 b;
+#endif /* local variables moved into u.ah */
if( (pIn1->flags | pIn2->flags) & MEM_Null ){
sqlite3VdbeMemSetNull(pOut);
break;
}
- a = sqlite3VdbeIntValue(pIn2);
- b = sqlite3VdbeIntValue(pIn1);
- switch( pOp->opcode ){
- case OP_BitAnd: a &= b; break;
- case OP_BitOr: a |= b; break;
- case OP_ShiftLeft: a <<= b; break;
+ u.ah.a = sqlite3VdbeIntValue(pIn2);
+ u.ah.b = sqlite3VdbeIntValue(pIn1);
+ switch( pOp->opcode ){
+ case OP_BitAnd: u.ah.a &= u.ah.b; break;
+ case OP_BitOr: u.ah.a |= u.ah.b; break;
+ case OP_ShiftLeft: u.ah.a <<= u.ah.b; break;
default: assert( pOp->opcode==OP_ShiftRight );
- a >>= b; break;
- }
- pOut->u.i = a;
+ u.ah.a >>= u.ah.b; break;
+ }
+ pOut->u.i = u.ah.a;
MemSetTypeFlag(pOut, MEM_Int);
break;
}
@@ -51720,15 +52529,17 @@
case OP_Lt: /* same as TK_LT, jump, in1, in3 */
case OP_Le: /* same as TK_LE, jump, in1, in3 */
case OP_Gt: /* same as TK_GT, jump, in1, in3 */
case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
+#if 0 /* local variables moved into u.ai */
int flags;
int res;
char affinity;
-
- flags = pIn1->flags|pIn3->flags;
-
- if( flags&MEM_Null ){
+#endif /* local variables moved into u.ai */
+
+ u.ai.flags = pIn1->flags|pIn3->flags;
+
+ if( u.ai.flags&MEM_Null ){
/* If either operand is NULL then the result is always NULL.
** The jump is taken if the SQLITE_JUMPIFNULL bit is set.
*/
if( pOp->p5 & SQLITE_STOREP2 ){
@@ -51740,34 +52551,34 @@
}
break;
}
- affinity = pOp->p5 & SQLITE_AFF_MASK;
- if( affinity ){
- applyAffinity(pIn1, affinity, encoding);
- applyAffinity(pIn3, affinity, encoding);
+ u.ai.affinity = pOp->p5 & SQLITE_AFF_MASK;
+ if( u.ai.affinity ){
+ applyAffinity(pIn1, u.ai.affinity, encoding);
+ applyAffinity(pIn3, u.ai.affinity, encoding);
if( db->mallocFailed ) goto no_mem;
}
assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
ExpandBlob(pIn1);
ExpandBlob(pIn3);
- res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
- switch( pOp->opcode ){
- case OP_Eq: res = res==0; break;
- case OP_Ne: res = res!=0; break;
- case OP_Lt: res = res<0; break;
- case OP_Le: res = res<=0; break;
- case OP_Gt: res = res>0; break;
- default: res = res>=0; break;
+ u.ai.res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
+ switch( pOp->opcode ){
+ case OP_Eq: u.ai.res = u.ai.res==0; break;
+ case OP_Ne: u.ai.res = u.ai.res!=0; break;
+ case OP_Lt: u.ai.res = u.ai.res<0; break;
+ case OP_Le: u.ai.res = u.ai.res<=0; break;
+ case OP_Gt: u.ai.res = u.ai.res>0; break;
+ default: u.ai.res = u.ai.res>=0; break;
}
if( pOp->p5 & SQLITE_STOREP2 ){
pOut = &p->aMem[pOp->p2];
MemSetTypeFlag(pOut, MEM_Int);
- pOut->u.i = res;
+ pOut->u.i = u.ai.res;
REGISTER_TRACE(pOp->p2, pOut);
- }else if( res ){
+ }else if( u.ai.res ){
pc = pOp->p2-1;
}
break;
}
@@ -51802,29 +52613,37 @@
** NULLs are less than numbers, numbers are less than strings,
** and strings are less than blobs.
*/
case OP_Compare: {
- int n = pOp->p3;
- int i, p1, p2;
- const KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
- assert( n>0 );
- assert( pKeyInfo!=0 );
- p1 = pOp->p1;
- assert( p1>0 && p1+n<=p->nMem+1 );
- p2 = pOp->p2;
- assert( p2>0 && p2+n<=p->nMem+1 );
- for(i=0; i<n; i++){
- int idx = aPermute ? aPermute[i] : i;
- CollSeq *pColl; /* Collating sequence to use on this term */
- int bRev; /* True for DESCENDING sort order */
- REGISTER_TRACE(p1+idx, &p->aMem[p1+idx]);
- REGISTER_TRACE(p2+idx, &p->aMem[p2+idx]);
- assert( i<pKeyInfo->nField );
- pColl = pKeyInfo->aColl[i];
- bRev = pKeyInfo->aSortOrder[i];
- iCompare = sqlite3MemCompare(&p->aMem[p1+idx], &p->aMem[p2+idx], pColl);
+#if 0 /* local variables moved into u.aj */
+ int n;
+ int i;
+ int p1;
+ int p2;
+ const KeyInfo *pKeyInfo;
+ int idx;
+ CollSeq *pColl; /* Collating sequence to use on this term */
+ int bRev; /* True for DESCENDING sort order */
+#endif /* local variables moved into u.aj */
+
+ u.aj.n = pOp->p3;
+ u.aj.pKeyInfo = pOp->p4.pKeyInfo;
+ assert( u.aj.n>0 );
+ assert( u.aj.pKeyInfo!=0 );
+ u.aj.p1 = pOp->p1;
+ assert( u.aj.p1>0 && u.aj.p1+u.aj.n<=p->nMem+1 );
+ u.aj.p2 = pOp->p2;
+ assert( u.aj.p2>0 && u.aj.p2+u.aj.n<=p->nMem+1 );
+ for(u.aj.i=0; u.aj.i<u.aj.n; u.aj.i++){
+ u.aj.idx = aPermute ? aPermute[u.aj.i] : u.aj.i;
+ REGISTER_TRACE(u.aj.p1+u.aj.idx, &p->aMem[u.aj.p1+u.aj.idx]);
+ REGISTER_TRACE(u.aj.p2+u.aj.idx, &p->aMem[u.aj.p2+u.aj.idx]);
+ assert( u.aj.i<u.aj.pKeyInfo->nField );
+ u.aj.pColl = u.aj.pKeyInfo->aColl[u.aj.i];
+ u.aj.bRev = u.aj.pKeyInfo->aSortOrder[u.aj.i];
+ iCompare = sqlite3MemCompare(&p->aMem[u.aj.p1+u.aj.idx], &p->aMem[u.aj.p2+u.aj.idx], u.aj.pColl);
if( iCompare ){
- if( bRev ) iCompare = -iCompare;
+ if( u.aj.bRev ) iCompare = -iCompare;
break;
}
}
aPermute = 0;
@@ -51867,31 +52686,34 @@
** give a NULL output.
*/
case OP_And: /* same as TK_AND, in1, in2, out3 */
case OP_Or: { /* same as TK_OR, in1, in2, out3 */
- int v1, v2; /* 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
+#if 0 /* local variables moved into u.ak */
+ int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
+ int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
+#endif /* local variables moved into u.ak */
if( pIn1->flags & MEM_Null ){
- v1 = 2;
- }else{
- v1 = sqlite3VdbeIntValue(pIn1)!=0;
+ u.ak.v1 = 2;
+ }else{
+ u.ak.v1 = sqlite3VdbeIntValue(pIn1)!=0;
}
if( pIn2->flags & MEM_Null ){
- v2 = 2;
- }else{
- v2 = sqlite3VdbeIntValue(pIn2)!=0;
+ u.ak.v2 = 2;
+ }else{
+ u.ak.v2 = sqlite3VdbeIntValue(pIn2)!=0;
}
if( pOp->opcode==OP_And ){
static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 };
- v1 = and_logic[v1*3+v2];
+ u.ak.v1 = and_logic[u.ak.v1*3+u.ak.v2];
}else{
static const unsigned char or_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 };
- v1 = or_logic[v1*3+v2];
- }
- if( v1==2 ){
+ u.ak.v1 = or_logic[u.ak.v1*3+u.ak.v2];
+ }
+ if( u.ak.v1==2 ){
MemSetTypeFlag(pOut, MEM_Null);
}else{
- pOut->u.i = v1;
+ pOut->u.i = u.ak.v1;
MemSetTypeFlag(pOut, MEM_Int);
}
break;
}
@@ -51941,20 +52763,22 @@
** in P1 is NULL then take the jump if P3 is true.
*/
case OP_If: /* jump, in1 */
case OP_IfNot: { /* jump, in1 */
+#if 0 /* local variables moved into u.al */
int c;
+#endif /* local variables moved into u.al */
if( pIn1->flags & MEM_Null ){
- c = pOp->p3;
+ u.al.c = pOp->p3;
}else{
#ifdef SQLITE_OMIT_FLOATING_POINT
- c = sqlite3VdbeIntValue(pIn1)!=0;
-#else
- c = sqlite3VdbeRealValue(pIn1)!=0.0;
-#endif
- if( pOp->opcode==OP_IfNot ) c = !c;
- }
- if( c ){
+ u.al.c = sqlite3VdbeIntValue(pIn1)!=0;
+#else
+ u.al.c = sqlite3VdbeRealValue(pIn1)!=0.0;
+#endif
+ if( pOp->opcode==OP_IfNot ) u.al.c = !u.al.c;
+ }
+ if( u.al.c ){
pc = pOp->p2-1;
}
break;
}
@@ -51965,17 +52789,21 @@
** than zero, then check all values reg(P1), reg(P1+1),
** reg(P1+2), ..., reg(P1+P3-1).
*/
case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */
- int n = pOp->p3;
+#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( --n > 0 );
+ }while( --u.am.n > 0 );
break;
}
/* Opcode: NotNull P1 P2 * * *
@@ -52025,12 +52853,14 @@
** if the P4 argument is a P4_MEM use the value of the P4 argument as
** the result.
*/
case OP_Column: {
- int payloadSize; /* Number of bytes in the record */
- int p1 = pOp->p1; /* P1 value of the opcode */
- int p2 = pOp->p2; /* column number to retrieve */
- VdbeCursor *pC = 0;/* The VDBE cursor */
+#if 0 /* local variables moved into u.an */
+ 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 */
char *zRec; /* Pointer to complete record-data */
BtCursor *pCrsr; /* The BTree cursor */
u32 *aType; /* aType[i] holds the numeric type of the i-th column */
u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */
@@ -52039,221 +52869,263 @@
int i; /* Loop counter */
char *zData; /* Part of the record being decoded */
Mem *pDest; /* Where to write the extracted value */
Mem sMem; /* For storing the record being decoded */
-
- memset(&sMem, 0, sizeof(sMem));
- assert( p1<p->nCursor );
+ u8 *zIdx; /* Index into header */
+ 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 );
assert( pOp->p3>0 && pOp->p3<=p->nMem );
- pDest = &p->aMem[pOp->p3];
- MemSetTypeFlag(pDest, MEM_Null);
-
- /* This block sets the variable payloadSize to be the total number of
+ 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
** bytes in the record.
**
- ** zRec is set to be the complete text of the record if it is available.
+ ** u.an.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 pC->aRow cache. Or it might not be.
- ** If the data is unavailable, zRec is set to NULL.
+ ** 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.
**
** We also compute the number of columns in the record. For cursors,
** the number of columns is stored in the VdbeCursor.nField element.
*/
- pC = p->apCsr[p1];
- assert( pC!=0 );
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- assert( pC->pVtabCursor==0 );
-#endif
- if( pC->pCursor!=0 ){
+ 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 ){
/* The record is stored in a B-Tree */
- rc = sqlite3VdbeCursorMoveto(pC);
+ rc = sqlite3VdbeCursorMoveto(u.an.pC);
if( rc ) goto abort_due_to_error;
- zRec = 0;
- pCrsr = pC->pCursor;
- if( pC->nullRow ){
- payloadSize = 0;
- }else if( pC->cacheStatus==p->cacheCtr ){
- payloadSize = pC->payloadSize;
- zRec = (char*)pC->aRow;
- }else if( pC->isIndex ){
- i64 payloadSize64;
- sqlite3BtreeKeySize(pCrsr, &payloadSize64);
- payloadSize = (int)payloadSize64;
- }else{
- sqlite3BtreeDataSize(pCrsr, (u32 *)&payloadSize);
- }
- nField = pC->nField;
- }else{
- assert( pC->pseudoTable );
+ 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 );
/* The record is the sole entry of a pseudo-table */
- payloadSize = pC->nData;
- zRec = pC->pData;
- pC->cacheStatus = CACHE_STALE;
- assert( payloadSize==0 || zRec!=0 );
- nField = pC->nField;
- pCrsr = 0;
- }
-
- /* If payloadSize is 0, then just store a NULL */
- if( payloadSize==0 ){
- assert( pDest->flags&MEM_Null );
+ 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 );
goto op_column_out;
}
- if( payloadSize>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ assert( db->aLimit[SQLITE_LIMIT_LENGTH]>=0 );
+ if( u.an.payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
- assert( p2<nField );
+ assert( u.an.p2<u.an.nField );
/* Read and parse the table header. Store the results of the parse
** into the record header cache fields of the cursor.
*/
- aType = pC->aType;
- if( pC->cacheStatus==p->cacheCtr ){
- aOffset = pC->aOffset;
- }else{
- u8 *zIdx; /* Index into header */
- u8 *zEndHdr; /* Pointer to first byte after the header */
- int offset; /* Offset into the data */
- int szHdrSz; /* Size of the header size field at start of record */
- int avail = 0; /* Number of bytes of available data */
-
- assert(aType);
- pC->aOffset = aOffset = &aType[nField];
- pC->payloadSize = payloadSize;
- pC->cacheStatus = p->cacheCtr;
+ 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;
/* Figure out how many bytes are in the header */
- if( zRec ){
- zData = zRec;
- }else{
- if( pC->isIndex ){
- zData = (char*)sqlite3BtreeKeyFetch(pCrsr, &avail);
- }else{
- zData = (char*)sqlite3BtreeDataFetch(pCrsr, &avail);
+ 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 KeyFetch()/DataFetch() managed to get the entire payload,
- ** save the payload in the pC->aRow cache. That will save us from
+ ** save the payload in the u.an.pC->aRow cache. That will save us from
** having to make additional calls to fetch the content portion of
** the record.
*/
- if( avail>=payloadSize ){
- zRec = zData;
- pC->aRow = (u8*)zData;
- }else{
- pC->aRow = 0;
+ 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;
}
}
/* The following assert is true in all cases accept when
** the database file has been corrupted externally.
- ** assert( zRec!=0 || avail>=payloadSize || avail>=9 ); */
- szHdrSz = getVarint32((u8*)zData, offset);
+ ** 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);
+
+ /* Make sure a corrupt database has not given us an oversize header.
+ ** Do this now to avoid an oversize memory allocation.
+ **
+ ** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte
+ ** types use so much data space that there can only be 4096 and 32 of
+ ** them, respectively. So the maximum header length results from a
+ ** 3-byte type for each of the maximum of 32768 columns plus three
+ ** extra bytes for the header length itself. 32768*3 + 3 = 98307.
+ */
+ if( u.an.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
+ ** 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
+ ** 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;
/* 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( !zRec && avail<offset ){
- sMem.flags = 0;
- sMem.db = 0;
- rc = sqlite3VdbeMemFromBtree(pCrsr, 0, offset, pC->isIndex, &sMem);
+ 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( rc!=SQLITE_OK ){
goto op_column_out;
}
- zData = sMem.z;
- }
- zEndHdr = (u8 *)&zData[offset];
- zIdx = (u8 *)&zData[szHdrSz];
-
- /* Scan the header and use it to fill in the aType[] and aOffset[]
- ** arrays. aType[i] will contain the type integer for the i-th
- ** column and aOffset[i] will contain the offset from the beginning
- ** of the record to the start of the data for the i-th column
- */
- for(i=0; i<nField; i++){
- if( zIdx<zEndHdr ){
- aOffset[i] = offset;
- zIdx += getVarint32(zIdx, aType[i]);
- offset += sqlite3VdbeSerialTypeLen(aType[i]);
- }else{
- /* If i is less that nField, then there are less fields in this
+ 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
** record than SetNumColumns indicated there are columns in the
- ** table. Set the offset for any extra columns not present in
+ ** table. Set the u.an.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.
*/
- aOffset[i] = 0;
- }
- }
- sqlite3VdbeMemRelease(&sMem);
- sMem.flags = MEM_Null;
+ u.an.aOffset[u.an.i] = 0;
+ }
+ }
+ sqlite3VdbeMemRelease(&u.an.sMem);
+ u.an.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( zIdx>zEndHdr || offset>payloadSize
- || (zIdx==zEndHdr && offset!=payloadSize) ){
+ 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) ){
rc = SQLITE_CORRUPT_BKPT;
goto op_column_out;
}
}
- /* Get the column information. If aOffset[p2] is non-zero, then
- ** deserialize the value from the record. If aOffset[p2] is zero,
+ /* 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,
** 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( aOffset[p2] ){
+ if( u.an.aOffset[u.an.p2] ){
assert( rc==SQLITE_OK );
- if( zRec ){
- sqlite3VdbeMemReleaseExternal(pDest);
- sqlite3VdbeSerialGet((u8 *)&zRec[aOffset[p2]], aType[p2], pDest);
- }else{
- len = sqlite3VdbeSerialTypeLen(aType[p2]);
- sqlite3VdbeMemMove(&sMem, pDest);
- rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->isIndex, &sMem);
+ if( 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( rc!=SQLITE_OK ){
goto op_column_out;
}
- zData = sMem.z;
- sqlite3VdbeSerialGet((u8*)zData, aType[p2], pDest);
- }
- pDest->enc = encoding;
+ 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;
}else{
if( pOp->p4type==P4_MEM ){
- sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static);
- }else{
- assert( pDest->flags&MEM_Null );
+ sqlite3VdbeMemShallowCopy(u.an.pDest, pOp->p4.pMem, MEM_Static);
+ }else{
+ assert( u.an.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 pDest structure.
+ ** dynamically allocated space over to the u.an.pDest structure.
** This prevents a memory copy.
*/
- if( sMem.zMalloc ){
- assert( sMem.z==sMem.zMalloc );
- assert( !(pDest->flags & MEM_Dyn) );
- assert( !(pDest->flags & (MEM_Blob|MEM_Str)) || pDest->z==sMem.z );
- pDest->flags &= ~(MEM_Ephem|MEM_Static);
- pDest->flags |= MEM_Term;
- pDest->z = sMem.z;
- pDest->zMalloc = sMem.zMalloc;
- }
-
- rc = sqlite3VdbeMemMakeWriteable(pDest);
+ 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);
op_column_out:
- UPDATE_MAX_BLOBSIZE(pDest);
- REGISTER_TRACE(pOp->p3, pDest);
+ UPDATE_MAX_BLOBSIZE(u.an.pDest);
+ REGISTER_TRACE(pOp->p3, u.an.pDest);
break;
}
/* Opcode: Affinity P1 P2 * P4 *
@@ -52264,16 +53136,21 @@
** string indicates the column affinity that should be used for the nth
** memory cell in the range.
*/
case OP_Affinity: {
- char *zAffinity = pOp->p4.z;
- Mem *pData0 = &p->aMem[pOp->p1];
- Mem *pLast = &pData0[pOp->p2-1];
- Mem *pRec;
-
- for(pRec=pData0; pRec<=pLast; pRec++){
- ExpandBlob(pRec);
- applyAffinity(pRec, zAffinity[pRec-pData0], encoding);
+#if 0 /* local variables moved into u.ao */
+ 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);
}
break;
}
@@ -52295,8 +53172,26 @@
**
** If P4 is NULL then all index fields have the affinity NONE.
*/
case OP_MakeRecord: {
+#if 0 /* local variables moved into u.ap */
+ 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 */
+ int nZero; /* Number of zero bytes at the end of the record */
+ int nVarint; /* Number of bytes in a varint */
+ u32 serial_type; /* Type field */
+ Mem *pData0; /* First field to be combined into the record */
+ Mem *pLast; /* Last field of the record */
+ int nField; /* Number of fields in the record */
+ char *zAffinity; /* The affinity string for the record */
+ int file_format; /* File format to use for encoding */
+ int i; /* Space used in zNewRecord[] */
+ int len; /* Length of a field */
+#endif /* local variables moved into u.ap */
+
/* Assuming the record contains N fields, the record format looks
** like this:
**
** ------------------------------------------------------------------------
@@ -52310,62 +53205,50 @@
** 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.
*/
- u8 *zNewRecord; /* A buffer to hold the data for the new record */
- Mem *pRec; /* The new record */
- u64 nData = 0; /* Number of bytes of data space */
- int nHdr = 0; /* Number of bytes of header space */
- i64 nByte = 0; /* Data space required for this record */
- int nZero = 0; /* Number of zero bytes at the end of the record */
- int nVarint; /* Number of bytes in a varint */
- u32 serial_type; /* Type field */
- Mem *pData0; /* First field to be combined into the record */
- Mem *pLast; /* Last field of the record */
- int nField; /* Number of fields in the record */
- char *zAffinity; /* The affinity string for the record */
- int file_format; /* File format to use for encoding */
- int i; /* Space used in zNewRecord[] */
-
- nField = pOp->p1;
- zAffinity = pOp->p4.z;
- assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=p->nMem+1 );
- pData0 = &p->aMem[nField];
- nField = pOp->p2;
- pLast = &pData0[nField-1];
- file_format = p->minWriteFileFormat;
+ 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;
/* Loop through the elements that will make up the record to figure
** out how much space is required for the new record.
*/
- for(pRec=pData0; pRec<=pLast; pRec++){
- int len;
- if( zAffinity ){
- applyAffinity(pRec, zAffinity[pRec-pData0], encoding);
- }
- if( pRec->flags&MEM_Zero && pRec->n>0 ){
- sqlite3VdbeMemExpandBlob(pRec);
- }
- serial_type = sqlite3VdbeSerialType(pRec, file_format);
- len = sqlite3VdbeSerialTypeLen(serial_type);
- nData += len;
- nHdr += sqlite3VarintLen(serial_type);
- if( pRec->flags & MEM_Zero ){
+ 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 ){
/* Only pure zero-filled BLOBs can be input to this Opcode.
** We do not allow blobs with a prefix and a zero-filled tail. */
- nZero += pRec->u.nZero;
- }else if( len ){
- nZero = 0;
+ u.ap.nZero += u.ap.pRec->u.nZero;
+ }else if( u.ap.len ){
+ u.ap.nZero = 0;
}
}
/* Add the initial header varint and total the size */
- nHdr += nVarint = sqlite3VarintLen(nHdr);
- if( nVarint<sqlite3VarintLen(nHdr) ){
- nHdr++;
- }
- nByte = nHdr+nData-nZero;
- if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ 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] ){
goto too_big;
}
/* Make sure the output register has a buffer large enough to store
@@ -52374,30 +53257,30 @@
** 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)nByte, 0) ){
+ if( sqlite3VdbeMemGrow(pOut, (int)u.ap.nByte, 0) ){
goto no_mem;
}
- zNewRecord = (u8 *)pOut->z;
+ u.ap.zNewRecord = (u8 *)pOut->z;
/* Write the record */
- i = putVarint32(zNewRecord, nHdr);
- for(pRec=pData0; pRec<=pLast; pRec++){
- serial_type = sqlite3VdbeSerialType(pRec, file_format);
- i += putVarint32(&zNewRecord[i], serial_type); /* serial type */
- }
- for(pRec=pData0; pRec<=pLast; pRec++){ /* serial data */
- i += sqlite3VdbeSerialPut(&zNewRecord[i], (int)(nByte-i), pRec,file_format);
- }
- assert( i==nByte );
+ 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 );
assert( pOp->p3>0 && pOp->p3<=p->nMem );
- pOut->n = (int)nByte;
+ pOut->n = (int)u.ap.nByte;
pOut->flags = MEM_Blob | MEM_Dyn;
pOut->xDel = 0;
- if( nZero ){
- pOut->u.nZero = nZero;
+ if( u.ap.nZero ){
+ pOut->u.nZero = u.ap.nZero;
pOut->flags |= MEM_Zero;
}
pOut->enc = SQLITE_UTF8; /* In case the blob is ever converted to text */
REGISTER_TRACE(pOp->p3, pOut);
@@ -52411,17 +53294,21 @@
** opened by cursor P1 in register P2
*/
#ifndef SQLITE_OMIT_BTREECOUNT
case OP_Count: { /* out2-prerelease */
+#if 0 /* local variables moved into u.aq */
i64 nEntry;
- BtCursor *pCrsr = p->apCsr[pOp->p1]->pCursor;
- if( pCrsr ){
- rc = sqlite3BtreeCount(pCrsr, &nEntry);
- }else{
- nEntry = 0;
+ 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;
}
pOut->flags = MEM_Int;
- pOut->u.i = nEntry;
+ pOut->u.i = u.aq.nEntry;
break;
}
#endif
@@ -52447,22 +53334,25 @@
** 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;
+ Btree *pBt;
+#endif /* local variables moved into u.ar */
if( db->autoCommit==0 || db->activeVdbeCnt>1 ){
- int i = pOp->p1;
- Btree *pBt;
- assert( i>=0 && i<db->nDb );
- assert( db->aDb[i].pBt!=0 );
- pBt = db->aDb[i].pBt;
- assert( sqlite3BtreeIsInTrans(pBt) );
- assert( (p->btreeMask & (1<<i))!=0 );
+ 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 );
if( p->iStatement==0 ){
assert( db->nStatement>=0 && db->nSavepoint>=0 );
db->nStatement++;
p->iStatement = db->nSavepoint + db->nStatement;
}
- rc = sqlite3BtreeBeginStmt(pBt, p->iStatement);
+ rc = sqlite3BtreeBeginStmt(u.ar.pBt, p->iStatement);
}
break;
}
@@ -52472,20 +53362,31 @@
** 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: {
- int p1 = pOp->p1;
- char *zName = pOp->p4.z; /* Name of savepoint */
-
- /* Assert that the p1 parameter is valid. Also that if there is no open
+#if 0 /* local variables moved into u.as */
+ 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
** transaction, then there cannot be any savepoints.
*/
assert( db->pSavepoint==0 || db->autoCommit==0 );
- assert( p1==SAVEPOINT_BEGIN||p1==SAVEPOINT_RELEASE||p1==SAVEPOINT_ROLLBACK );
+ assert( u.as.p1==SAVEPOINT_BEGIN||u.as.p1==SAVEPOINT_RELEASE||u.as.p1==SAVEPOINT_ROLLBACK );
assert( db->pSavepoint || db->isTransactionSavepoint==0 );
assert( checkSavepointCount(db) );
- if( p1==SAVEPOINT_BEGIN ){
+ if( u.as.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).
*/
@@ -52492,16 +53393,15 @@
sqlite3SetString(&p->zErrMsg, db, "cannot open savepoint - "
"SQL statements in progress");
rc = SQLITE_BUSY;
}else{
- int nName = sqlite3Strlen30(zName);
- Savepoint *pNew;
+ u.as.nName = sqlite3Strlen30(u.as.zName);
/* Create a new savepoint structure. */
- pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+nName+1);
- if( pNew ){
- pNew->zName = (char *)&pNew[1];
- memcpy(pNew->zName, zName, nName+1);
+ 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);
/* If there is no open transaction, then mark this as a special
** "transaction savepoint". */
if( db->autoCommit ){
@@ -52511,38 +53411,37 @@
db->nSavepoint++;
}
/* Link the new savepoint into the database handle's list. */
- pNew->pNext = db->pSavepoint;
- db->pSavepoint = pNew;
- }
- }
- }else{
- Savepoint *pSavepoint;
- int iSavepoint = 0;
+ u.as.pNew->pNext = db->pSavepoint;
+ db->pSavepoint = u.as.pNew;
+ }
+ }
+ }else{
+ u.as.iSavepoint = 0;
/* Find the named savepoint. If there is no such savepoint, then an
** an error is returned to the user. */
for(
- pSavepoint=db->pSavepoint;
- pSavepoint && sqlite3StrICmp(pSavepoint->zName, zName);
- pSavepoint=pSavepoint->pNext
- ){
- iSavepoint++;
- }
- if( !pSavepoint ){
- sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", zName);
+ 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);
rc = SQLITE_ERROR;
}else if(
- db->writeVdbeCnt>0 || (p1==SAVEPOINT_ROLLBACK && db->activeVdbeCnt>1)
+ db->writeVdbeCnt>0 || (u.as.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",
- (p1==SAVEPOINT_ROLLBACK ? "rollback": "release")
+ (u.as.p1==SAVEPOINT_ROLLBACK ? "rollback": "release")
);
rc = SQLITE_BUSY;
}else{
@@ -52549,10 +53448,10 @@
/* 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 = pSavepoint->pNext==0 && db->isTransactionSavepoint;
- if( isTransaction && p1==SAVEPOINT_RELEASE ){
+ int isTransaction = u.as.pSavepoint->pNext==0 && db->isTransactionSavepoint;
+ if( isTransaction && u.as.p1==SAVEPOINT_RELEASE ){
db->autoCommit = 1;
if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
p->pc = pc;
db->autoCommit = 0;
@@ -52561,36 +53460,35 @@
}
db->isTransactionSavepoint = 0;
rc = p->rc;
}else{
- int ii;
- iSavepoint = db->nSavepoint - iSavepoint - 1;
- for(ii=0; ii<db->nDb; ii++){
- rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint);
+ 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);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
}
- if( p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
+ if( u.as.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!=pSavepoint ){
- Savepoint *pTmp = db->pSavepoint;
- db->pSavepoint = pTmp->pNext;
- sqlite3DbFree(db, pTmp);
+ while( db->pSavepoint!=u.as.pSavepoint ){
+ u.as.pTmp = db->pSavepoint;
+ db->pSavepoint = u.as.pTmp->pNext;
+ sqlite3DbFree(db, u.as.pTmp);
db->nSavepoint--;
}
/* If it is a RELEASE, then destroy the savepoint being operated on too */
- if( p1==SAVEPOINT_RELEASE ){
- assert( pSavepoint==db->pSavepoint );
- db->pSavepoint = pSavepoint->pNext;
- sqlite3DbFree(db, pSavepoint);
+ if( u.as.p1==SAVEPOINT_RELEASE ){
+ assert( u.as.pSavepoint==db->pSavepoint );
+ db->pSavepoint = u.as.pSavepoint->pNext;
+ sqlite3DbFree(db, u.as.pSavepoint);
if( !isTransaction ){
db->nSavepoint--;
}
}
@@ -52609,42 +53507,46 @@
**
** This instruction causes the VM to halt.
*/
case OP_AutoCommit: {
- int desiredAutoCommit = pOp->p1;
- int rollback = pOp->p2;
- int turnOnAC = desiredAutoCommit && !db->autoCommit;
-
- assert( desiredAutoCommit==1 || desiredAutoCommit==0 );
- assert( desiredAutoCommit==1 || rollback==0 );
-
+#if 0 /* local variables moved into u.at */
+ int desiredAutoCommit;
+ int rollback;
+ 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 );
assert( db->activeVdbeCnt>0 ); /* At least this one VM is active */
- if( turnOnAC && rollback && db->activeVdbeCnt>1 ){
+ if( u.at.turnOnAC && u.at.rollback && 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 rollback transaction - "
+ sqlite3SetString(&p->zErrMsg, db, "cannot u.at.rollback transaction - "
"SQL statements in progress");
rc = SQLITE_BUSY;
- }else if( turnOnAC && !rollback && db->writeVdbeCnt>1 ){
+ }else if( u.at.turnOnAC && !u.at.rollback && db->writeVdbeCnt>1 ){
/* 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( desiredAutoCommit!=db->autoCommit ){
- if( rollback ){
- assert( desiredAutoCommit==1 );
+ }else if( u.at.desiredAutoCommit!=db->autoCommit ){
+ if( u.at.rollback ){
+ assert( u.at.desiredAutoCommit==1 );
sqlite3RollbackAll(db);
db->autoCommit = 1;
}else{
- db->autoCommit = (u8)desiredAutoCommit;
+ db->autoCommit = (u8)u.at.desiredAutoCommit;
if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
p->pc = pc;
- db->autoCommit = (u8)(1-desiredAutoCommit);
+ db->autoCommit = (u8)(1-u.at.desiredAutoCommit);
p->rc = rc = SQLITE_BUSY;
goto vdbe_return;
}
}
@@ -52657,10 +53559,10 @@
}
goto vdbe_return;
}else{
sqlite3SetString(&p->zErrMsg, db,
- (!desiredAutoCommit)?"cannot start a transaction within a transaction":(
- (rollback)?"cannot rollback - no transaction is active":
+ (!u.at.desiredAutoCommit)?"cannot start a transaction within a transaction":(
+ (u.at.rollback)?"cannot u.at.rollback - no transaction is active":
"cannot commit - no transaction is active"));
rc = SQLITE_ERROR;
}
@@ -52688,17 +53590,20 @@
**
** If P2 is zero, then a read-lock is obtained on the database file.
*/
case OP_Transaction: {
- int i = pOp->p1;
+#if 0 /* local variables moved into u.au */
+ int i;
Btree *pBt;
-
- assert( i>=0 && i<db->nDb );
- assert( (p->btreeMask & (1<<i))!=0 );
- pBt = db->aDb[i].pBt;
-
- if( pBt ){
- rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
+#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);
if( rc==SQLITE_BUSY ){
p->pc = pc;
p->rc = rc = SQLITE_BUSY;
goto vdbe_return;
@@ -52712,76 +53617,66 @@
/* Opcode: ReadCookie P1 P2 P3 * *
**
** Read cookie number P3 from database P1 and write it into register P2.
-** P3==0 is the schema version. P3==1 is the database format.
-** P3==2 is the recommended pager cache size, and so forth. P1==0 is
+** P3==1 is the schema version. P3==2 is the database format.
+** P3==3 is the recommended pager cache size, and so forth. P1==0 is
** the main database file and P1==1 is the database file used to store
** temporary tables.
-**
-** If P1 is negative, then this is a request to read the size of a
-** databases free-list. P3 must be set to 1 in this case. The actual
-** database accessed is ((P1+1)*-1). For example, a P1 parameter of -1
-** corresponds to database 0 ("main"), a P1 of -2 is database 1 ("temp").
**
** 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 */
int iMeta;
- int iDb = pOp->p1;
- int iCookie = pOp->p3;
-
+ int iDb;
+ int iCookie;
+#endif /* local variables moved into u.av */
+
+ u.av.iDb = pOp->p1;
+ u.av.iCookie = pOp->p3;
assert( pOp->p3<SQLITE_N_BTREE_META );
- if( iDb<0 ){
- iDb = (-1*(iDb+1));
- iCookie *= -1;
- }
- assert( iDb>=0 && iDb<db->nDb );
- assert( db->aDb[iDb].pBt!=0 );
- assert( (p->btreeMask & (1<<iDb))!=0 );
- /* The indexing of meta values at the schema layer is off by one from
- ** the indexing in the btree layer. The btree considers meta[0] to
- ** be the number of free pages in the database (a read-only value)
- ** and meta[1] to be the schema cookie. The schema layer considers
- ** meta[1] to be the schema cookie. So we have to shift the index
- ** by one in the following statement.
- */
- rc = sqlite3BtreeGetMeta(db->aDb[iDb].pBt, 1 + iCookie, (u32 *)&iMeta);
- pOut->u.i = iMeta;
+ 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;
MemSetTypeFlag(pOut, MEM_Int);
break;
}
/* Opcode: SetCookie P1 P2 P3 * *
**
** Write the content of register P3 (interpreted as an integer)
-** into cookie number P2 of database P1.
-** P2==0 is the schema version. P2==1 is the database format.
-** P2==2 is the recommended pager cache size, and so forth. P1==0 is
-** the main database file and P1==1 is the database file used to store
-** temporary tables.
+** into cookie number P2 of database P1. P2==1 is the schema version.
+** P2==2 is the database format. P2==3 is the recommended pager cache
+** size, and so forth. P1==0 is the main database file and P1==1 is the
+** database file used to store temporary tables.
**
** A transaction must be started before executing this opcode.
*/
case OP_SetCookie: { /* in3 */
+#if 0 /* local variables moved into u.aw */
Db *pDb;
+#endif /* local variables moved into u.aw */
assert( pOp->p2<SQLITE_N_BTREE_META );
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (1<<pOp->p1))!=0 );
- pDb = &db->aDb[pOp->p1];
- assert( pDb->pBt!=0 );
+ u.aw.pDb = &db->aDb[pOp->p1];
+ assert( u.aw.pDb->pBt!=0 );
sqlite3VdbeMemIntegerify(pIn3);
/* See note about index shifting on OP_ReadCookie */
- rc = sqlite3BtreeUpdateMeta(pDb->pBt, 1+pOp->p2, (int)pIn3->u.i);
- if( pOp->p2==0 ){
+ rc = sqlite3BtreeUpdateMeta(u.aw.pDb->pBt, pOp->p2, (int)pIn3->u.i);
+ if( pOp->p2==BTREE_SCHEMA_VERSION ){
/* When the schema cookie changes, record the new cookie internally */
- pDb->pSchema->schema_cookie = (int)pIn3->u.i;
+ u.aw.pDb->pSchema->schema_cookie = (int)pIn3->u.i;
db->flags |= SQLITE_InternChanges;
- }else if( pOp->p2==1 ){
+ }else if( pOp->p2==BTREE_FILE_FORMAT ){
/* Record changes in the file format */
- pDb->pSchema->file_format = (u8)pIn3->u.i;
+ u.aw.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 */
@@ -52806,20 +53701,22 @@
** to be executed (to establish a read lock) before this opcode is
** invoked.
*/
case OP_VerifyCookie: {
+#if 0 /* local variables moved into u.ax */
int iMeta;
Btree *pBt;
+#endif /* local variables moved into u.ax */
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (1<<pOp->p1))!=0 );
- pBt = db->aDb[pOp->p1].pBt;
- if( pBt ){
- rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&iMeta);
+ u.ax.pBt = db->aDb[pOp->p1].pBt;
+ if( u.ax.pBt ){
+ rc = sqlite3BtreeGetMeta(u.ax.pBt, BTREE_SCHEMA_VERSION, (u32 *)&u.ax.iMeta);
}else{
rc = SQLITE_OK;
- iMeta = 0;
- }
- if( rc==SQLITE_OK && iMeta!=pOp->p2 ){
+ u.ax.iMeta = 0;
+ }
+ if( rc==SQLITE_OK && u.ax.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
@@ -52833,9 +53730,9 @@
** 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!=iMeta ){
+ if( db->aDb[pOp->p1].pSchema->schema_cookie!=u.ax.iMeta ){
sqlite3ResetInternalSchema(db, pOp->p1);
}
sqlite3ExpirePreparedStatements(db);
@@ -52883,9 +53780,10 @@
** The P4 value may be either an integer (P4_INT32) or a pointer to
** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo
** structure, then said structure defines the content and collating
** sequence of the index being opened. Otherwise, if P4 is an integer
-** value, it is set to the number of columns in the table.
+** value, it is set to the number of columns in the table, or to the
+** largest index of any column of the table that is actually used.
**
** This instruction works just like OpenRead except that it opens the cursor
** in read/write mode. For a given table, there can be one or more read-only
** cursors or a single read/write cursor but not both.
@@ -52893,55 +53791,63 @@
** See also OpenRead.
*/
case OP_OpenRead:
case OP_OpenWrite: {
- int nField = 0;
- KeyInfo *pKeyInfo = 0;
- int i = pOp->p1;
- int p2 = pOp->p2;
- int iDb = pOp->p3;
+#if 0 /* local variables moved into u.ay */
+ int nField;
+ KeyInfo *pKeyInfo;
+ int i;
+ int p2;
+ int iDb;
int wrFlag;
Btree *pX;
VdbeCursor *pCur;
Db *pDb;
-
- assert( iDb>=0 && iDb<db->nDb );
- assert( (p->btreeMask & (1<<iDb))!=0 );
- pDb = &db->aDb[iDb];
- pX = pDb->pBt;
- assert( pX!=0 );
+ 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 );
if( pOp->opcode==OP_OpenWrite ){
- wrFlag = 1;
- if( pDb->pSchema->file_format < p->minWriteFileFormat ){
- p->minWriteFileFormat = pDb->pSchema->file_format;
- }
- }else{
- wrFlag = 0;
+ 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;
}
if( pOp->p5 ){
- assert( p2>0 );
- assert( p2<=p->nMem );
- pIn2 = &p->aMem[p2];
+ assert( u.ay.p2>0 );
+ assert( u.ay.p2<=p->nMem );
+ pIn2 = &p->aMem[u.ay.p2];
sqlite3VdbeMemIntegerify(pIn2);
- p2 = (int)pIn2->u.i;
- if( p2<2 ) {
+ u.ay.p2 = (int)pIn2->u.i;
+ if( u.ay.p2<2 ) {
rc = SQLITE_CORRUPT_BKPT;
goto abort_due_to_error;
}
}
- assert( i>=0 );
+ assert( u.ay.i>=0 );
if( pOp->p4type==P4_KEYINFO ){
- pKeyInfo = pOp->p4.pKeyInfo;
- pKeyInfo->enc = ENC(p->db);
- nField = pKeyInfo->nField+1;
+ u.ay.pKeyInfo = pOp->p4.pKeyInfo;
+ u.ay.pKeyInfo->enc = ENC(p->db);
+ u.ay.nField = u.ay.pKeyInfo->nField+1;
}else if( pOp->p4type==P4_INT32 ){
- nField = pOp->p4.i;
- }
- pCur = allocateCursor(p, i, nField, iDb, 1);
- if( pCur==0 ) goto no_mem;
- pCur->nullRow = 1;
- rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor);
- pCur->pKeyInfo = pKeyInfo;
+ 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;
switch( rc ){
case SQLITE_BUSY: {
p->pc = pc;
@@ -52948,36 +53854,36 @@
p->rc = rc = SQLITE_BUSY;
goto vdbe_return;
}
case SQLITE_OK: {
- int flags = sqlite3BtreeFlags(pCur->pCursor);
- /* Sanity checking. Only the lower four bits of the flags byte should
+ u.ay.flags = sqlite3BtreeFlags(u.ay.pCur->pCursor);
+ /* Sanity checking. Only the lower four bits of the u.ay.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( (flags & 0xf0)!=0 || ((flags & 0x07)!=5 && (flags & 0x07)!=2) ){
+ 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;
}
- pCur->isTable = (flags & BTREE_INTKEY)!=0 ?1:0;
- pCur->isIndex = (flags & BTREE_ZERODATA)!=0 ?1:0;
+ u.ay.pCur->isTable = (u.ay.flags & BTREE_INTKEY)!=0 ?1:0;
+ u.ay.pCur->isIndex = (u.ay.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( (pCur->isTable && pOp->p4type==P4_KEYINFO)
- || (pCur->isIndex && pOp->p4type!=P4_KEYINFO) ){
+ if( (u.ay.pCur->isTable && pOp->p4type==P4_KEYINFO)
+ || (u.ay.pCur->isIndex && pOp->p4type!=P4_KEYINFO) ){
rc = SQLITE_CORRUPT_BKPT;
goto abort_due_to_error;
}
break;
}
case SQLITE_EMPTY: {
- pCur->isTable = pOp->p4type!=P4_KEYINFO;
- pCur->isIndex = !pCur->isTable;
- pCur->pCursor = 0;
+ u.ay.pCur->isTable = pOp->p4type!=P4_KEYINFO;
+ u.ay.pCur->isIndex = !u.ay.pCur->isTable;
+ u.ay.pCur->pCursor = 0;
rc = SQLITE_OK;
break;
}
default: {
@@ -53005,25 +53911,28 @@
** this opcode. Then this opcode was call OpenVirtual. But
** that created confusion with the whole virtual-table idea.
*/
case OP_OpenEphemeral: {
- int i = pOp->p1;
+#if 0 /* local variables moved into u.az */
+ int i;
VdbeCursor *pCx;
+#endif /* local variables moved into u.az */
static const int openFlags =
SQLITE_OPEN_READWRITE |
SQLITE_OPEN_CREATE |
SQLITE_OPEN_EXCLUSIVE |
SQLITE_OPEN_DELETEONCLOSE |
SQLITE_OPEN_TRANSIENT_DB;
- assert( i>=0 );
- pCx = allocateCursor(p, i, pOp->p2, -1, 1);
- if( pCx==0 ) goto no_mem;
- pCx->nullRow = 1;
+ 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;
rc = sqlite3BtreeFactory(db, 0, 1, SQLITE_DEFAULT_TEMP_CACHE_SIZE, openFlags,
- &pCx->pBt);
- if( rc==SQLITE_OK ){
- rc = sqlite3BtreeBeginTrans(pCx->pBt, 1);
+ &u.az.pCx->pBt);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3BtreeBeginTrans(u.az.pCx->pBt, 1);
}
if( rc==SQLITE_OK ){
/* If a transient index is required, create it by calling
** sqlite3BtreeCreateTable() with the BTREE_ZERODATA flag before
@@ -53032,23 +53941,23 @@
*/
if( pOp->p4.pKeyInfo ){
int pgno;
assert( pOp->p4type==P4_KEYINFO );
- rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_ZERODATA);
+ rc = sqlite3BtreeCreateTable(u.az.pCx->pBt, &pgno, BTREE_ZERODATA);
if( rc==SQLITE_OK ){
assert( pgno==MASTER_ROOT+1 );
- rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1,
- (KeyInfo*)pOp->p4.z, pCx->pCursor);
- pCx->pKeyInfo = pOp->p4.pKeyInfo;
- pCx->pKeyInfo->enc = ENC(p->db);
- }
- pCx->isTable = 0;
- }else{
- rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, pCx->pCursor);
- pCx->isTable = 1;
- }
- }
- pCx->isIndex = !pCx->isTable;
+ 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;
break;
}
/* Opcode: OpenPseudo P1 P2 P3 * *
@@ -53074,18 +53983,22 @@
** P3 is the number of fields in the records that will be stored by
** the pseudo-table.
*/
case OP_OpenPseudo: {
- int i = pOp->p1;
+#if 0 /* local variables moved into u.ba */
+ int i;
VdbeCursor *pCx;
- assert( i>=0 );
- pCx = allocateCursor(p, i, pOp->p3, -1, 0);
- if( pCx==0 ) goto no_mem;
- pCx->nullRow = 1;
- pCx->pseudoTable = 1;
- pCx->ephemPseudoTable = (u8)pOp->p2;
- pCx->isTable = 1;
- pCx->isIndex = 0;
+#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;
break;
}
/* Opcode: Close P1 * * * *
@@ -53093,12 +54006,15 @@
** Close a cursor previously opened as P1. If P1 is not
** currently open, this instruction is a no-op.
*/
case OP_Close: {
- int i = pOp->p1;
- assert( i>=0 && i<p->nCursor );
- sqlite3VdbeFreeCursor(p, p->apCsr[i]);
- p->apCsr[i] = 0;
+#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;
break;
}
/* Opcode: SeekGe P1 P2 P3 P4 *
@@ -53156,28 +54072,33 @@
case OP_SeekLt: /* jump, in3 */
case OP_SeekLe: /* jump, in3 */
case OP_SeekGe: /* jump, in3 */
case OP_SeekGt: { /* jump, in3 */
- int i = pOp->p1;
- VdbeCursor *pC;
-
- assert( i>=0 && i<p->nCursor );
+#if 0 /* local variables moved into u.bc */
+ int i;
+ 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 );
assert( pOp->p2!=0 );
- pC = p->apCsr[i];
- assert( pC!=0 );
- if( pC->pCursor!=0 ){
- int res, oc;
- oc = pOp->opcode;
- pC->nullRow = 0;
- if( pC->isTable ){
- i64 iKey; /* The rowid we are to seek to */
-
+ 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 ){
/* 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);
- iKey = sqlite3VdbeIntValue(pIn3);
- pC->rowidIsValid = 0;
+ u.bc.iKey = sqlite3VdbeIntValue(pIn3);
+ u.bc.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 ){
@@ -53190,94 +54111,93 @@
/* If we reach this point, then the P3 value must be a floating
** point number. */
assert( (pIn3->flags & MEM_Real)!=0 );
- if( iKey==SMALLEST_INT64 && (pIn3->r<(double)iKey || pIn3->r>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
** integer. */
- res = 1;
+ u.bc.res = 1;
if( pIn3->r<0 ){
- if( oc==OP_SeekGt || oc==OP_SeekGe ){
- rc = sqlite3BtreeFirst(pC->pCursor, &res);
+ if( u.bc.oc==OP_SeekGt || u.bc.oc==OP_SeekGe ){
+ rc = sqlite3BtreeFirst(u.bc.pC->pCursor, &u.bc.res);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
}
}else{
- if( oc==OP_SeekLt || oc==OP_SeekLe ){
- rc = sqlite3BtreeLast(pC->pCursor, &res);
+ if( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekLe ){
+ rc = sqlite3BtreeLast(u.bc.pC->pCursor, &u.bc.res);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
}
}
- if( res ){
+ if( u.bc.res ){
pc = pOp->p2 - 1;
}
break;
- }else if( oc==OP_SeekLt || oc==OP_SeekGe ){
+ }else if( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekGe ){
/* Use the ceiling() function to convert real->int */
- if( pIn3->r > (double)iKey ) iKey++;
+ if( pIn3->r > (double)u.bc.iKey ) u.bc.iKey++;
}else{
/* Use the floor() function to convert real->int */
- assert( oc==OP_SeekLe || oc==OP_SeekGt );
- if( pIn3->r < (double)iKey ) iKey--;
- }
- }
- rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res);
+ 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);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
- if( res==0 ){
- pC->rowidIsValid = 1;
- pC->lastRowid = iKey;
- }
- }else{
- UnpackedRecord r;
- int nField = pOp->p4.i;
+ if( u.bc.res==0 ){
+ u.bc.pC->rowidIsValid = 1;
+ u.bc.pC->lastRowid = u.bc.iKey;
+ }
+ }else{
+ u.bc.nField = pOp->p4.i;
assert( pOp->p4type==P4_INT32 );
- assert( nField>0 );
- r.pKeyInfo = pC->pKeyInfo;
- r.nField = (u16)nField;
- if( oc==OP_SeekGt || oc==OP_SeekLe ){
- r.flags = UNPACKED_INCRKEY;
- }else{
- r.flags = 0;
- }
- r.aMem = &p->aMem[pOp->p3];
- rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, &r, 0, 0, &res);
+ 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);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
- pC->rowidIsValid = 0;
- }
- pC->deferredMoveto = 0;
- pC->cacheStatus = CACHE_STALE;
+ u.bc.pC->rowidIsValid = 0;
+ }
+ u.bc.pC->deferredMoveto = 0;
+ u.bc.pC->cacheStatus = CACHE_STALE;
#ifdef SQLITE_TEST
sqlite3_search_count++;
#endif
- if( oc==OP_SeekGe || oc==OP_SeekGt ){
- if( res<0 || (res==0 && oc==OP_SeekGt) ){
- rc = sqlite3BtreeNext(pC->pCursor, &res);
+ 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( rc!=SQLITE_OK ) goto abort_due_to_error;
- pC->rowidIsValid = 0;
- }else{
- res = 0;
- }
- }else{
- assert( oc==OP_SeekLt || oc==OP_SeekLe );
- if( res>0 || (res==0 && oc==OP_SeekLt) ){
- rc = sqlite3BtreePrevious(pC->pCursor, &res);
+ 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);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
- pC->rowidIsValid = 0;
- }else{
- /* res might be negative because the table is empty. Check to
+ u.bc.pC->rowidIsValid = 0;
+ }else{
+ /* u.bc.res might be negative because the table is empty. Check to
** see if this is the case.
*/
- res = sqlite3BtreeEof(pC->pCursor);
+ u.bc.res = sqlite3BtreeEof(u.bc.pC->pCursor);
}
}
assert( pOp->p2>0 );
- if( res ){
+ if( u.bc.res ){
pc = pOp->p2 - 1;
}
- }else if( !pC->pseudoTable ){
+ }else if( !u.bc.pC->pseudoTable ){
/* 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).
*/
@@ -53295,20 +54215,23 @@
** the cursor is used to read a record. That way, if no reads
** occur, no unnecessary I/O happens.
*/
case OP_Seek: { /* in2 */
- int i = pOp->p1;
- VdbeCursor *pC;
-
- assert( i>=0 && i<p->nCursor );
- pC = p->apCsr[i];
- assert( pC!=0 );
- if( pC->pCursor!=0 ){
- assert( pC->isTable );
- pC->nullRow = 0;
- pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
- pC->rowidIsValid = 0;
- pC->deferredMoveto = 1;
+#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;
}
break;
}
@@ -53344,40 +54267,46 @@
** See also: Found, NotExists, IsUnique
*/
case OP_NotFound: /* jump, in3 */
case OP_Found: { /* jump, in3 */
- int i = pOp->p1;
- int alreadyExists = 0;
- VdbeCursor *pC;
- assert( i>=0 && i<p->nCursor );
- assert( p->apCsr[i]!=0 );
- if( (pC = p->apCsr[i])->pCursor!=0 ){
- int res;
- UnpackedRecord *pIdxKey;
-
- assert( pC->isTable==0 );
+#if 0 /* local variables moved into u.be */
+ int i;
+ 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 );
assert( pIn3->flags & MEM_Blob );
- pIdxKey = sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z,
- aTempRec, sizeof(aTempRec));
- if( pIdxKey==0 ){
+ u.be.pIdxKey = sqlite3VdbeRecordUnpack(u.be.pC->pKeyInfo, pIn3->n, pIn3->z,
+ u.be.aTempRec, sizeof(u.be.aTempRec));
+ if( u.be.pIdxKey==0 ){
goto no_mem;
}
if( pOp->opcode==OP_Found ){
- pIdxKey->flags |= UNPACKED_PREFIX_MATCH;
- }
- rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, pIdxKey, 0, 0, &res);
- sqlite3VdbeDeleteUnpackedRecord(pIdxKey);
+ 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);
if( rc!=SQLITE_OK ){
break;
}
- alreadyExists = (res==0);
- pC->deferredMoveto = 0;
- pC->cacheStatus = CACHE_STALE;
+ u.be.alreadyExists = (u.be.res==0);
+ u.be.pC->deferredMoveto = 0;
+ u.be.pC->cacheStatus = CACHE_STALE;
}
if( pOp->opcode==OP_Found ){
- if( alreadyExists ) pc = pOp->p2 - 1;
- }else{
- if( !alreadyExists ) pc = pOp->p2 - 1;
+ if( u.be.alreadyExists ) pc = pOp->p2 - 1;
+ }else{
+ if( !u.be.alreadyExists ) pc = pOp->p2 - 1;
}
break;
}
@@ -53406,59 +54335,61 @@
**
** See also: NotFound, NotExists, Found
*/
case OP_IsUnique: { /* jump, in3 */
+#if 0 /* local variables moved into u.bf */
u16 ii;
VdbeCursor *pCx;
BtCursor *pCrsr;
u16 nField;
- Mem *aMem = &p->aMem[pOp->p4.i];
-
+ 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];
/* 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. */
- pCx = p->apCsr[pOp->p1];
- assert( pCx->deferredMoveto==0 );
- pCx->seekResult = 0;
- pCx->cacheStatus = CACHE_STALE;
- pCrsr = pCx->pCursor;
+ 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;
/* If any of the values are NULL, take the jump. */
- nField = pCx->pKeyInfo->nField;
- for(ii=0; ii<nField; ii++){
- if( aMem[ii].flags & MEM_Null ){
+ 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 ){
pc = pOp->p2 - 1;
- pCrsr = 0;
- break;
- }
- }
- assert( (aMem[nField].flags & MEM_Null)==0 );
-
- if( pCrsr!=0 ){
- UnpackedRecord r; /* B-Tree index search key */
- i64 R; /* Rowid stored in register P3 */
-
+ u.bf.pCrsr = 0;
+ break;
+ }
+ }
+ assert( (u.bf.aMem[u.bf.nField].flags & MEM_Null)==0 );
+
+ if( u.bf.pCrsr!=0 ){
/* Populate the index search key. */
- r.pKeyInfo = pCx->pKeyInfo;
- r.nField = nField + 1;
- r.flags = UNPACKED_PREFIX_SEARCH;
- r.aMem = aMem;
-
- /* Extract the value of R from register P3. */
+ 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. */
sqlite3VdbeMemIntegerify(pIn3);
- R = pIn3->u.i;
+ u.bf.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(pCrsr, &r, 0, 0, &pCx->seekResult);
- if( (r.flags & UNPACKED_PREFIX_SEARCH) || r.rowid==R ){
+ 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 ){
pc = pOp->p2 - 1;
}else{
- pIn3->u.i = r.rowid;
+ pIn3->u.i = u.bf.r.rowid;
}
}
break;
}
@@ -53477,38 +54408,43 @@
**
** See also: Found, NotFound, IsUnique
*/
case OP_NotExists: { /* jump, in3 */
- int i = pOp->p1;
+#if 0 /* local variables moved into u.bg */
+ int i;
VdbeCursor *pC;
BtCursor *pCrsr;
- assert( i>=0 && i<p->nCursor );
- assert( p->apCsr[i]!=0 );
- if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
- int res = 0;
- u64 iKey;
+ 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[i]->isTable );
- iKey = intToKey(pIn3->u.i);
- rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res);
- pC->lastRowid = pIn3->u.i;
- pC->rowidIsValid = res==0 ?1:0;
- pC->nullRow = 0;
- pC->cacheStatus = CACHE_STALE;
- pC->deferredMoveto = 0;
- if( res!=0 ){
+ 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 ){
pc = pOp->p2 - 1;
- assert( pC->rowidIsValid==0 );
- }
- pC->seekResult = res;
- }else if( !pC->pseudoTable ){
+ assert( u.bg.pC->rowidIsValid==0 );
+ }
+ u.bg.pC->seekResult = u.bg.res;
+ }else if( !u.bg.pC->pseudoTable ){
/* This happens when an attempt to open a read cursor on the
** sqlite_master table returns SQLITE_EMPTY.
*/
- assert( pC->isTable );
+ assert( u.bg.pC->isTable );
pc = pOp->p2 - 1;
- assert( pC->rowidIsValid==0 );
- pC->seekResult = 0;
+ assert( u.bg.pC->rowidIsValid==0 );
+ u.bg.pC->seekResult = 0;
}
break;
}
@@ -53543,14 +54479,26 @@
** record number. This P3 mechanism is used to help implement the
** AUTOINCREMENT feature.
*/
case OP_NewRowid: { /* out2-prerelease */
- int i = pOp->p1;
- i64 v = 0;
- VdbeCursor *pC;
- assert( i>=0 && i<p->nCursor );
- assert( p->apCsr[i]!=0 );
- if( (pC = p->apCsr[i])->pCursor==0 ){
+#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 ){
/* 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.
@@ -53582,18 +54530,16 @@
** 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.
*/
- int res=0, rx=SQLITE_OK, cnt;
- i64 x;
- cnt = 0;
- if( (sqlite3BtreeFlags(pC->pCursor)&(BTREE_INTKEY|BTREE_ZERODATA)) !=
+ 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(pC->pCursor) & BTREE_INTKEY)!=0 );
- assert( (sqlite3BtreeFlags(pC->pCursor) & BTREE_ZERODATA)==0 );
+ assert( (sqlite3BtreeFlags(u.bh.pC->pCursor) & BTREE_INTKEY)!=0 );
+ assert( (sqlite3BtreeFlags(u.bh.pC->pCursor) & BTREE_ZERODATA)==0 );
#ifdef SQLITE_32BIT_ROWID
# define MAX_ROWID 0x7fffffff
#else
@@ -53603,77 +54549,76 @@
*/
# define MAX_ROWID (i64)( (((u64)0x7fffffff)<<32) | (u64)0xffffffff )
#endif
- if( !pC->useRandomRowid ){
- v = sqlite3BtreeGetCachedRowid(pC->pCursor);
- if( v==0 ){
- rc = sqlite3BtreeLast(pC->pCursor, &res);
+ 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( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
- if( res ){
- v = 1;
- }else{
- sqlite3BtreeKeySize(pC->pCursor, &v);
- v = keyToInt(v);
- if( v==MAX_ROWID ){
- pC->useRandomRowid = 1;
+ 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;
}else{
- v++;
+ u.bh.v++;
}
}
}
#ifndef SQLITE_OMIT_AUTOINCREMENT
if( pOp->p3 ){
- Mem *pMem;
assert( pOp->p3>0 && pOp->p3<=p->nMem ); /* P3 is a valid memory cell */
- pMem = &p->aMem[pOp->p3];
- REGISTER_TRACE(pOp->p3, pMem);
- sqlite3VdbeMemIntegerify(pMem);
- assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */
- if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){
+ 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 ){
rc = SQLITE_FULL;
goto abort_due_to_error;
}
- if( v<pMem->u.i+1 ){
- v = pMem->u.i + 1;
- }
- pMem->u.i = v;
- }
-#endif
-
- sqlite3BtreeSetCachedRowid(pC->pCursor, v<MAX_ROWID ? v+1 : 0);
- }
- if( pC->useRandomRowid ){
+ 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 */
- v = db->priorNewRowid;
- cnt = 0;
+ u.bh.v = db->priorNewRowid;
+ u.bh.cnt = 0;
do{
- if( cnt==0 && (v&0xffffff)==v ){
- v++;
- }else{
- sqlite3_randomness(sizeof(v), &v);
- if( cnt<5 ) v &= 0xffffff;
- }
- if( v==0 ) continue;
- x = intToKey(v);
- rx = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)x, 0, &res);
- cnt++;
- }while( cnt<100 && rx==SQLITE_OK && res==0 );
- db->priorNewRowid = v;
- if( rx==SQLITE_OK && res==0 ){
+ 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 ){
rc = SQLITE_FULL;
goto abort_due_to_error;
}
}
- pC->rowidIsValid = 0;
- pC->deferredMoveto = 0;
- pC->cacheStatus = CACHE_STALE;
+ u.bh.pC->rowidIsValid = 0;
+ u.bh.pC->deferredMoveto = 0;
+ u.bh.pC->cacheStatus = CACHE_STALE;
}
MemSetTypeFlag(pOut, MEM_Int);
- pOut->u.i = v;
+ pOut->u.i = u.bh.v;
break;
}
/* Opcode: Insert P1 P2 P3 P4 P5
@@ -53702,80 +54647,89 @@
** This instruction only works on tables. The equivalent instruction
** for indices is OP_IdxInsert.
*/
case OP_Insert: {
- Mem *pData = &p->aMem[pOp->p2];
- Mem *pKey = &p->aMem[pOp->p3];
-
+#if 0 /* local variables moved into u.bi */
+ Mem *pData;
+ Mem *pKey;
i64 iKey; /* The integer ROWID or key for the record to be inserted */
- int i = pOp->p1;
+ int i;
VdbeCursor *pC;
- assert( i>=0 && i<p->nCursor );
- pC = p->apCsr[i];
- assert( pC!=0 );
- assert( pC->pCursor!=0 || pC->pseudoTable );
- assert( pKey->flags & MEM_Int );
- assert( pC->isTable );
- REGISTER_TRACE(pOp->p2, pData);
- REGISTER_TRACE(pOp->p3, pKey);
-
- iKey = intToKey(pKey->u.i);
+ 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);
if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
- if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = pKey->u.i;
- if( pData->flags & MEM_Null ){
- pData->z = 0;
- pData->n = 0;
- }else{
- assert( pData->flags & (MEM_Blob|MEM_Str) );
- }
- if( pC->pseudoTable ){
- if( !pC->ephemPseudoTable ){
- sqlite3DbFree(db, pC->pData);
- }
- pC->iKey = iKey;
- pC->nData = pData->n;
- if( pData->z==pData->zMalloc || pC->ephemPseudoTable ){
- pC->pData = pData->z;
- if( !pC->ephemPseudoTable ){
- pData->flags &= ~MEM_Dyn;
- pData->flags |= MEM_Ephem;
- pData->zMalloc = 0;
- }
- }else{
- pC->pData = sqlite3Malloc( pC->nData+2 );
- if( !pC->pData ) goto no_mem;
- memcpy(pC->pData, pData->z, pC->nData);
- pC->pData[pC->nData] = 0;
- pC->pData[pC->nData+1] = 0;
- }
- pC->nullRow = 0;
- }else{
- int nZero;
- int seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0);
- if( pData->flags & MEM_Zero ){
- nZero = pData->u.nZero;
- }else{
- nZero = 0;
- }
- sqlite3BtreeSetCachedRowid(pC->pCursor, 0);
- rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey,
- pData->z, pData->n, nZero,
- pOp->p5 & OPFLAG_APPEND, seekResult
- );
- }
-
- pC->rowidIsValid = 0;
- pC->deferredMoveto = 0;
- pC->cacheStatus = CACHE_STALE;
+ 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;
/* Invoke the update-hook if required. */
if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
- const char *zDb = db->aDb[pC->iDb].zName;
- const char *zTbl = pOp->p4.z;
- int op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
- assert( pC->isTable );
- db->xUpdateCallback(db->pUpdateArg, op, zDb, zTbl, iKey);
- assert( pC->iDb>=0 );
+ 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 );
}
break;
}
@@ -53799,38 +54753,42 @@
** If P4 is not NULL then the P1 cursor must have been positioned
** using OP_NotFound prior to invoking this opcode.
*/
case OP_Delete: {
- int i = pOp->p1;
- i64 iKey = 0;
+#if 0 /* local variables moved into u.bj */
+ int i;
+ i64 iKey;
VdbeCursor *pC;
-
- assert( i>=0 && i<p->nCursor );
- pC = p->apCsr[i];
- assert( pC!=0 );
- assert( pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */
-
- /* If the update-hook will be invoked, set iKey to the rowid of the
+#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
** row being deleted.
*/
if( db->xUpdateCallback && pOp->p4.z ){
- assert( pC->isTable );
- assert( pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */
- iKey = pC->lastRowid;
- }
-
- rc = sqlite3VdbeCursorMoveto(pC);
+ 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(pC->pCursor, 0);
- rc = sqlite3BtreeDelete(pC->pCursor);
- pC->cacheStatus = CACHE_STALE;
+ sqlite3BtreeSetCachedRowid(u.bj.pC->pCursor, 0);
+ rc = sqlite3BtreeDelete(u.bj.pC->pCursor);
+ u.bj.pC->cacheStatus = CACHE_STALE;
/* Invoke the update-hook if required. */
if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
- const char *zDb = db->aDb[pC->iDb].zName;
+ const char *zDb = db->aDb[u.bj.pC->iDb].zName;
const char *zTbl = pOp->p4.z;
- db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, iKey);
- assert( pC->iDb>=0 );
+ db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, u.bj.iKey);
+ assert( u.bj.pC->iDb>=0 );
}
if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
break;
}
@@ -53871,50 +54829,53 @@
** of a real table, not a pseudo-table.
*/
case OP_RowKey:
case OP_RowData: {
- int i = pOp->p1;
+#if 0 /* local variables moved into u.bk */
+ int i;
VdbeCursor *pC;
BtCursor *pCrsr;
u32 n;
-
+ i64 n64;
+#endif /* local variables moved into u.bk */
+
+ u.bk.i = pOp->p1;
pOut = &p->aMem[pOp->p2];
/* Note that RowKey and RowData are really exactly the same instruction */
- assert( i>=0 && i<p->nCursor );
- pC = p->apCsr[i];
- assert( pC->isTable || pOp->opcode==OP_RowKey );
- assert( pC->isIndex || pOp->opcode==OP_RowData );
- assert( pC!=0 );
- assert( pC->nullRow==0 );
- assert( pC->pseudoTable==0 );
- assert( pC->pCursor!=0 );
- pCrsr = pC->pCursor;
- rc = sqlite3VdbeCursorMoveto(pC);
+ 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( pC->isIndex ){
- i64 n64;
- assert( !pC->isTable );
- sqlite3BtreeKeySize(pCrsr, &n64);
- if( n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ 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] ){
goto too_big;
}
- n = (int)n64;
- }else{
- sqlite3BtreeDataSize(pCrsr, &n);
- if( (int)n>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ u.bk.n = (u32)u.bk.n64;
+ }else{
+ sqlite3BtreeDataSize(u.bk.pCrsr, &u.bk.n);
+ if( u.bk.n>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
}
- if( sqlite3VdbeMemGrow(pOut, n, 0) ){
+ if( sqlite3VdbeMemGrow(pOut, u.bk.n, 0) ){
goto no_mem;
}
- pOut->n = n;
+ pOut->n = u.bk.n;
MemSetTypeFlag(pOut, MEM_Blob);
- if( pC->isIndex ){
- rc = sqlite3BtreeKey(pCrsr, 0, n, pOut->z);
- }else{
- rc = sqlite3BtreeData(pCrsr, 0, n, pOut->z);
+ 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);
}
pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */
UPDATE_MAX_BLOBSIZE(pOut);
break;
@@ -53929,48 +54890,51 @@
** 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 */
- int i = pOp->p1;
+#if 0 /* local variables moved into u.bl */
+ int i;
VdbeCursor *pC;
i64 v;
-
- assert( i>=0 && i<p->nCursor );
- pC = p->apCsr[i];
- assert( pC!=0 );
- if( pC->nullRow ){
+ 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 ){
/* Do nothing so that reg[P2] remains NULL */
break;
- }else if( pC->deferredMoveto ){
- v = pC->movetoTarget;
- }else if( pC->pseudoTable ){
- v = keyToInt(pC->iKey);
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- }else if( pC->pVtabCursor ){
- sqlite3_vtab *pVtab;
- const sqlite3_module *pModule;
- pVtab = pC->pVtabCursor->pVtab;
- pModule = pVtab->pModule;
- assert( pModule->xRowid );
+ }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 );
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- rc = pModule->xRowid(pC->pVtabCursor, &v);
+ rc = u.bl.pModule->xRowid(u.bl.pC->pVtabCursor, &u.bl.v);
sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = pVtab->zErrMsg;
- pVtab->zErrMsg = 0;
+ p->zErrMsg = u.bl.pVtab->zErrMsg;
+ u.bl.pVtab->zErrMsg = 0;
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
#endif /* SQLITE_OMIT_VIRTUALTABLE */
}else{
- rc = sqlite3VdbeCursorMoveto(pC);
+ rc = sqlite3VdbeCursorMoveto(u.bl.pC);
if( rc ) goto abort_due_to_error;
- if( pC->rowidIsValid ){
- v = pC->lastRowid;
- }else{
- assert( pC->pCursor!=0 );
- sqlite3BtreeKeySize(pC->pCursor, &v);
- v = keyToInt(v);
- }
- }
- pOut->u.i = v;
+ 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;
MemSetTypeFlag(pOut, MEM_Int);
break;
}
@@ -53980,18 +54944,21 @@
** that occur while the cursor is on the null row will always
** write a NULL.
*/
case OP_NullRow: {
- int i = pOp->p1;
+#if 0 /* local variables moved into u.bm */
+ int i;
VdbeCursor *pC;
-
- assert( i>=0 && i<p->nCursor );
- pC = p->apCsr[i];
- assert( pC!=0 );
- pC->nullRow = 1;
- pC->rowidIsValid = 0;
- if( pC->pCursor ){
- sqlite3BtreeClearCursor(pC->pCursor);
+#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);
}
break;
}
@@ -54003,24 +54970,27 @@
** If P2 is 0 or if the table or index is not empty, fall through
** to the following instruction.
*/
case OP_Last: { /* jump */
- int i = pOp->p1;
+#if 0 /* local variables moved into u.bn */
+ int i;
VdbeCursor *pC;
BtCursor *pCrsr;
int res;
-
- assert( i>=0 && i<p->nCursor );
- pC = p->apCsr[i];
- assert( pC!=0 );
- pCrsr = pC->pCursor;
- assert( pCrsr!=0 );
- rc = sqlite3BtreeLast(pCrsr, &res);
- pC->nullRow = (u8)res;
- pC->deferredMoveto = 0;
- pC->rowidIsValid = 0;
- pC->cacheStatus = CACHE_STALE;
- if( res && pOp->p2>0 ){
+#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 ){
pc = pOp->p2 - 1;
}
break;
}
@@ -54054,28 +55024,31 @@
** If P2 is 0 or if the table or index is not empty, fall through
** to the following instruction.
*/
case OP_Rewind: { /* jump */
- int i = pOp->p1;
+#if 0 /* local variables moved into u.bo */
+ int i;
VdbeCursor *pC;
BtCursor *pCrsr;
int res;
-
- assert( i>=0 && i<p->nCursor );
- pC = p->apCsr[i];
- assert( pC!=0 );
- if( (pCrsr = pC->pCursor)!=0 ){
- rc = sqlite3BtreeFirst(pCrsr, &res);
- pC->atFirst = res==0 ?1:0;
- pC->deferredMoveto = 0;
- pC->cacheStatus = CACHE_STALE;
- pC->rowidIsValid = 0;
- }else{
- res = 1;
- }
- pC->nullRow = (u8)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;
assert( pOp->p2>0 && pOp->p2<p->nOp );
- if( res ){
+ if( u.bo.res ){
pc = pOp->p2 - 1;
}
break;
}
@@ -54101,34 +55074,36 @@
** 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 */
VdbeCursor *pC;
BtCursor *pCrsr;
int res;
+#endif /* local variables moved into u.bp */
CHECK_FOR_INTERRUPT;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- pC = p->apCsr[pOp->p1];
- if( pC==0 ){
+ u.bp.pC = p->apCsr[pOp->p1];
+ if( u.bp.pC==0 ){
break; /* See ticket #2273 */
}
- pCrsr = pC->pCursor;
- assert( pCrsr );
- res = 1;
- assert( pC->deferredMoveto==0 );
- rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(pCrsr, &res) :
- sqlite3BtreePrevious(pCrsr, &res);
- pC->nullRow = (u8)res;
- pC->cacheStatus = CACHE_STALE;
- if( res==0 ){
+ 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 ){
pc = pOp->p2 - 1;
if( pOp->p5 ) p->aCounter[pOp->p5-1]++;
#ifdef SQLITE_TEST
sqlite3_search_count++;
#endif
}
- pC->rowidIsValid = 0;
+ u.bp.pC->rowidIsValid = 0;
break;
}
/* Opcode: IdxInsert P1 P2 P3 * P5
@@ -54143,25 +55118,31 @@
** This instruction only works for indices. The equivalent instruction
** for tables is OP_Insert.
*/
case OP_IdxInsert: { /* in2 */
- int i = pOp->p1;
+#if 0 /* local variables moved into u.bq */
+ int i;
VdbeCursor *pC;
BtCursor *pCrsr;
- assert( i>=0 && i<p->nCursor );
- assert( p->apCsr[i]!=0 );
+ 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 );
assert( pIn2->flags & MEM_Blob );
- if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
- assert( pC->isTable==0 );
+ if( (u.bq.pCrsr = (u.bq.pC = p->apCsr[u.bq.i])->pCursor)!=0 ){
+ assert( u.bq.pC->isTable==0 );
rc = ExpandBlob(pIn2);
if( rc==SQLITE_OK ){
- int nKey = pIn2->n;
- const char *zKey = pIn2->z;
- rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0, 0, pOp->p3,
- ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
+ 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( pC->deferredMoveto==0 );
- pC->cacheStatus = CACHE_STALE;
+ assert( u.bq.pC->deferredMoveto==0 );
+ u.bq.pC->cacheStatus = CACHE_STALE;
}
}
break;
}
@@ -54172,28 +55153,32 @@
** an unpacked index key. This opcode removes that entry from the
** index opened by cursor P1.
*/
case OP_IdxDelete: {
- int i = pOp->p1;
+#if 0 /* local variables moved into u.br */
+ int i;
VdbeCursor *pC;
BtCursor *pCrsr;
+#endif /* local variables moved into u.br */
+
+ u.br.i = pOp->p1;
assert( pOp->p3>0 );
assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem+1 );
- assert( i>=0 && i<p->nCursor );
- assert( p->apCsr[i]!=0 );
- if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
+ 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 = pC->pKeyInfo;
+ r.pKeyInfo = u.br.pC->pKeyInfo;
r.nField = (u16)pOp->p3;
r.flags = 0;
r.aMem = &p->aMem[pOp->p2];
- rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res);
+ rc = sqlite3BtreeMovetoUnpacked(u.br.pCrsr, &r, 0, 0, &res);
if( rc==SQLITE_OK && res==0 ){
- rc = sqlite3BtreeDelete(pCrsr);
- }
- assert( pC->deferredMoveto==0 );
- pC->cacheStatus = CACHE_STALE;
+ rc = sqlite3BtreeDelete(u.br.pCrsr);
+ }
+ assert( u.br.pC->deferredMoveto==0 );
+ u.br.pC->cacheStatus = CACHE_STALE;
}
break;
}
@@ -54205,28 +55190,30 @@
**
** See also: Rowid, MakeRecord.
*/
case OP_IdxRowid: { /* out2-prerelease */
- int i = pOp->p1;
+#if 0 /* local variables moved into u.bs */
+ int i;
BtCursor *pCrsr;
VdbeCursor *pC;
-
-
- assert( i>=0 && i<p->nCursor );
- assert( p->apCsr[i]!=0 );
- if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
- i64 rowid;
- rc = sqlite3VdbeCursorMoveto(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( pC->deferredMoveto==0 );
- assert( pC->isTable==0 );
- if( !pC->nullRow ){
- rc = sqlite3VdbeIdxRowid(pCrsr, &rowid);
+ 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);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
MemSetTypeFlag(pOut, MEM_Int);
- pOut->u.i = rowid;
+ pOut->u.i = u.bs.rowid;
}
}
break;
}
@@ -54258,35 +55245,38 @@
** to the comparison. This makes the opcode work like IdxLE.
*/
case OP_IdxLT: /* jump, in3 */
case OP_IdxGE: { /* jump, in3 */
- int i= pOp->p1;
+#if 0 /* local variables moved into u.bt */
+ int i;
VdbeCursor *pC;
-
- assert( i>=0 && i<p->nCursor );
- assert( p->apCsr[i]!=0 );
- if( (pC = p->apCsr[i])->pCursor!=0 ){
- int res;
- UnpackedRecord r;
- assert( pC->deferredMoveto==0 );
+ 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 );
assert( pOp->p5==0 || pOp->p5==1 );
assert( pOp->p4type==P4_INT32 );
- r.pKeyInfo = pC->pKeyInfo;
- r.nField = (u16)pOp->p4.i;
+ u.bt.r.pKeyInfo = u.bt.pC->pKeyInfo;
+ u.bt.r.nField = (u16)pOp->p4.i;
if( pOp->p5 ){
- r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID;
- }else{
- r.flags = UNPACKED_IGNORE_ROWID;
- }
- r.aMem = &p->aMem[pOp->p3];
- rc = sqlite3VdbeIdxKeyCompare(pC, &r, &res);
+ 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);
if( pOp->opcode==OP_IdxLT ){
- res = -res;
+ u.bt.res = -u.bt.res;
}else{
assert( pOp->opcode==OP_IdxGE );
- res++;
- }
- if( res>0 ){
+ u.bt.res++;
+ }
+ if( u.bt.res>0 ){
pc = pOp->p2 - 1 ;
}
}
break;
@@ -54312,34 +55302,37 @@
**
** See also: Clear
*/
case OP_Destroy: { /* out2-prerelease */
+#if 0 /* local variables moved into u.bu */
int iMoved;
int iCnt;
-#ifndef SQLITE_OMIT_VIRTUALTABLE
Vdbe *pVdbe;
- iCnt = 0;
- for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){
- if( pVdbe->magic==VDBE_MAGIC_RUN && pVdbe->inVtabMethod<2 && pVdbe->pc>=0 ){
- iCnt++;
- }
- }
-#else
- iCnt = db->activeVdbeCnt;
-#endif
- if( iCnt>1 ){
+ 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 ){
rc = SQLITE_LOCKED;
p->errorAction = OE_Abort;
}else{
- int iDb = pOp->p3;
- assert( iCnt==1 );
- assert( (p->btreeMask & (1<<iDb))!=0 );
- rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved);
+ 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);
MemSetTypeFlag(pOut, MEM_Int);
- pOut->u.i = iMoved;
+ pOut->u.i = u.bu.iMoved;
#ifndef SQLITE_OMIT_AUTOVACUUM
- if( rc==SQLITE_OK && iMoved!=0 ){
- sqlite3RootPageMoved(&db->aDb[iDb], iMoved, pOp->p1);
+ if( rc==SQLITE_OK && u.bu.iMoved!=0 ){
+ sqlite3RootPageMoved(&db->aDb[u.bu.iDb], u.bu.iMoved, pOp->p1);
}
#endif
}
break;
@@ -54363,17 +55356,21 @@
**
** See also: Destroy
*/
case OP_Clear: {
- int nChange = 0;
+#if 0 /* local variables moved into u.bv */
+ int nChange;
+#endif /* local variables moved into u.bv */
+
+ u.bv.nChange = 0;
assert( (p->btreeMask & (1<<pOp->p2))!=0 );
rc = sqlite3BtreeClearTable(
- db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0)
+ db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bv.nChange : 0)
);
if( pOp->p3 ){
- p->nChange += nChange;
+ p->nChange += u.bv.nChange;
if( pOp->p3>0 ){
- p->aMem[pOp->p3].u.i += nChange;
+ p->aMem[pOp->p3].u.i += u.bv.nChange;
}
}
break;
}
@@ -54401,23 +55398,27 @@
** See documentation on OP_CreateTable for additional information.
*/
case OP_CreateIndex: /* out2-prerelease */
case OP_CreateTable: { /* out2-prerelease */
- int pgno = 0;
+#if 0 /* local variables moved into u.bw */
+ int pgno;
int flags;
Db *pDb;
+#endif /* local variables moved into u.bw */
+
+ u.bw.pgno = 0;
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (1<<pOp->p1))!=0 );
- pDb = &db->aDb[pOp->p1];
- assert( pDb->pBt!=0 );
+ u.bw.pDb = &db->aDb[pOp->p1];
+ assert( u.bw.pDb->pBt!=0 );
if( pOp->opcode==OP_CreateTable ){
- /* flags = BTREE_INTKEY; */
- flags = BTREE_LEAFDATA|BTREE_INTKEY;
- }else{
- flags = BTREE_ZERODATA;
- }
- rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags);
- pOut->u.i = pgno;
+ /* 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;
MemSetTypeFlag(pOut, MEM_Int);
break;
}
@@ -54433,10 +55434,17 @@
** 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: {
- int iDb = pOp->p1;
- assert( iDb>=0 && iDb<db->nDb );
+#if 0 /* local variables moved into u.bx */
+ 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 );
/* 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
@@ -54444,44 +55452,42 @@
** 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 iDb (the database containing the sqlite_master table
+ ** database u.bx.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 iDb is loaded. This is because, at the start of
+ ** the schema of u.bx.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
- ** iDb mutex may be temporarily released to avoid deadlock. If
+ ** u.bx.iDb mutex may be temporarily released to avoid deadlock. If
** this happens, then some other thread may delete the in-memory
- ** schema of database iDb before the SQL statement runs. The schema
+ ** schema of database u.bx.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[iDb].pBt) );
+ assert( sqlite3BtreeHoldsMutex(db->aDb[u.bx.iDb].pBt) );
sqlite3BtreeEnterAll(db);
- if( pOp->p2 || DbHasProperty(db, iDb, DB_SchemaLoaded) ){
- const char *zMaster = SCHEMA_TABLE(iDb);
- char *zSql;
- InitData initData;
- initData.db = db;
- initData.iDb = pOp->p1;
- initData.pzErrMsg = &p->zErrMsg;
- zSql = sqlite3MPrintf(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,
"SELECT name, rootpage, sql FROM '%q'.%s WHERE %s",
- db->aDb[iDb].zName, zMaster, pOp->p4.z);
- if( zSql==0 ){
+ db->aDb[u.bx.iDb].zName, u.bx.zMaster, pOp->p4.z);
+ if( u.bx.zSql==0 ){
rc = SQLITE_NOMEM;
}else{
(void)sqlite3SafetyOff(db);
assert( db->init.busy==0 );
db->init.busy = 1;
- initData.rc = SQLITE_OK;
+ u.bx.initData.rc = SQLITE_OK;
assert( !db->mallocFailed );
- rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
- if( rc==SQLITE_OK ) rc = initData.rc;
- sqlite3DbFree(db, zSql);
+ 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);
db->init.busy = 0;
(void)sqlite3SafetyOn(db);
}
}
@@ -54499,11 +55505,10 @@
** of that table into the internal index hash table. This will cause
** the analysis to be used when preparing all subsequent queries.
*/
case OP_LoadAnalysis: {
- int iDb = pOp->p1;
- assert( iDb>=0 && iDb<db->nDb );
- rc = sqlite3AnalysisLoad(db, iDb);
+ assert( pOp->p1>=0 && pOp->p1<db->nDb );
+ rc = sqlite3AnalysisLoad(db, pOp->p1);
break;
}
#endif /* !defined(SQLITE_OMIT_ANALYZE) && !defined(SQLITE_OMIT_PARSER) */
@@ -54565,41 +55570,43 @@
**
** This opcode is used to implement the integrity_check pragma.
*/
case OP_IntegrityCk: {
+#if 0 /* local variables moved into u.by */
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 */
-
- nRoot = pOp->p2;
- assert( nRoot>0 );
- aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(nRoot+1) );
- if( aRoot==0 ) goto no_mem;
+#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;
assert( pOp->p3>0 && pOp->p3<=p->nMem );
- pnErr = &p->aMem[pOp->p3];
- assert( (pnErr->flags & MEM_Int)!=0 );
- assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 );
+ 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 );
pIn1 = &p->aMem[pOp->p1];
- for(j=0; j<nRoot; j++){
- aRoot[j] = (int)sqlite3VdbeIntValue(&pIn1[j]);
- }
- aRoot[j] = 0;
+ 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;
assert( pOp->p5<db->nDb );
assert( (p->btreeMask & (1<<pOp->p5))!=0 );
- z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot,
- (int)pnErr->u.i, &nErr);
- sqlite3DbFree(db, aRoot);
- pnErr->u.i -= nErr;
+ 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;
sqlite3VdbeMemSetNull(pIn1);
- if( nErr==0 ){
- assert( z==0 );
- }else if( z==0 ){
+ if( u.by.nErr==0 ){
+ assert( u.by.z==0 );
+ }else if( u.by.z==0 ){
goto no_mem;
}else{
- sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free);
+ sqlite3VdbeMemSetStr(pIn1, u.by.z, -1, SQLITE_UTF8, sqlite3_free);
}
UPDATE_MAX_BLOBSIZE(pIn1);
sqlite3VdbeChangeEncoding(pIn1, encoding);
break;
@@ -54613,20 +55620,22 @@
**
** An assertion fails if P2 is not an integer.
*/
case OP_RowSetAdd: { /* in2 */
+#if 0 /* local variables moved into u.bz */
Mem *pIdx;
Mem *pVal;
+#endif /* local variables moved into u.bz */
assert( pOp->p1>0 && pOp->p1<=p->nMem );
- pIdx = &p->aMem[pOp->p1];
+ u.bz.pIdx = &p->aMem[pOp->p1];
assert( pOp->p2>0 && pOp->p2<=p->nMem );
- pVal = &p->aMem[pOp->p2];
- assert( (pVal->flags & MEM_Int)!=0 );
- if( (pIdx->flags & MEM_RowSet)==0 ){
- sqlite3VdbeMemSetRowSet(pIdx);
- if( (pIdx->flags & MEM_RowSet)==0 ) goto no_mem;
- }
- sqlite3RowSetInsert(pIdx->u.pRowSet, pVal->u.i);
+ 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);
break;
}
/* Opcode: RowSetRead P1 P2 P3 * *
@@ -54635,24 +55644,26 @@
** 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 */
Mem *pIdx;
i64 val;
+#endif /* local variables moved into u.ca */
assert( pOp->p1>0 && pOp->p1<=p->nMem );
CHECK_FOR_INTERRUPT;
- pIdx = &p->aMem[pOp->p1];
+ u.ca.pIdx = &p->aMem[pOp->p1];
pOut = &p->aMem[pOp->p3];
- if( (pIdx->flags & MEM_RowSet)==0
- || sqlite3RowSetNext(pIdx->u.pRowSet, &val)==0
+ if( (u.ca.pIdx->flags & MEM_RowSet)==0
+ || sqlite3RowSetNext(u.ca.pIdx->u.pRowSet, &u.ca.val)==0
){
/* The boolean index is empty */
- sqlite3VdbeMemSetNull(pIdx);
+ sqlite3VdbeMemSetNull(u.ca.pIdx);
pc = pOp->p2 - 1;
}else{
/* A value was pulled from the index */
assert( pOp->p3>0 && pOp->p3<=p->nMem );
- sqlite3VdbeMemSetInt64(pOut, val);
+ sqlite3VdbeMemSetInt64(pOut, u.ca.val);
}
break;
}
@@ -54679,9 +55690,14 @@
** 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 */
- int iSet = pOp->p4.i;
+#if 0 /* local variables moved into u.cb */
+ int iSet;
+ int exists;
+#endif /* local variables moved into u.cb */
+
+ u.cb.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
@@ -54691,20 +55707,19 @@
if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem;
}
assert( pOp->p4type==P4_INT32 );
- assert( iSet==-1 || iSet>=0 );
- if( iSet ){
- int exists;
- exists = sqlite3RowSetTest(pIn1->u.pRowSet,
- (u8)(iSet>=0 ? iSet & 0xf : 0xff),
+ 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),
pIn3->u.i);
- if( exists ){
+ if( u.cb.exists ){
pc = pOp->p2 - 1;
break;
}
}
- if( iSet>=0 ){
+ if( u.cb.iSet>=0 ){
sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i);
}
break;
}
@@ -54717,22 +55732,25 @@
** opcode. The context stores the last insert row id, the last statement change
** count, and the current statement change count.
*/
case OP_ContextPush: {
- int i = p->contextStackTop++;
+#if 0 /* local variables moved into u.cc */
+ int i;
Context *pContext;
-
- assert( i>=0 );
+#endif /* local variables moved into u.cc */
+
+ u.cc.i = p->contextStackTop++;
+ assert( u.cc.i>=0 );
/* FIX ME: This should be allocated as part of the vdbe at compile-time */
- if( i>=p->contextStackDepth ){
- p->contextStackDepth = i+1;
+ if( u.cc.i>=p->contextStackDepth ){
+ p->contextStackDepth = u.cc.i+1;
p->contextStack = sqlite3DbReallocOrFree(db, p->contextStack,
- sizeof(Context)*(i+1));
+ sizeof(Context)*(u.cc.i+1));
if( p->contextStack==0 ) goto no_mem;
}
- pContext = &p->contextStack[i];
- pContext->lastRowid = db->lastRowid;
- pContext->nChange = p->nChange;
+ u.cc.pContext = &p->contextStack[u.cc.i];
+ u.cc.pContext->lastRowid = db->lastRowid;
+ u.cc.pContext->nChange = p->nChange;
break;
}
/* Opcode: ContextPop * * *
@@ -54741,12 +55759,15 @@
** executed. The context stores the last insert row id, the last statement
** change count, and the current statement change count.
*/
case OP_ContextPop: {
- Context *pContext = &p->contextStack[--p->contextStackTop];
+#if 0 /* local variables moved into u.cd */
+ Context *pContext;
+#endif /* local variables moved into u.cd */
+ u.cd.pContext = &p->contextStack[--p->contextStackTop];
assert( p->contextStackTop>=0 );
- db->lastRowid = pContext->lastRowid;
- p->nChange = pContext->nChange;
+ db->lastRowid = u.cd.pContext->lastRowid;
+ p->nChange = u.cd.pContext->nChange;
break;
}
#endif /* #ifndef SQLITE_OMIT_TRIGGER */
@@ -54824,45 +55845,49 @@
** The P5 arguments are taken from register P2 and its
** successors.
*/
case OP_AggStep: {
- int n = pOp->p5;
- int i;
- Mem *pMem, *pRec;
+#if 0 /* local variables moved into u.ce */
+ int n;
+ int i;
+ Mem *pMem;
+ Mem *pRec;
sqlite3_context ctx;
sqlite3_value **apVal;
-
- assert( n>=0 );
- pRec = &p->aMem[pOp->p2];
- apVal = p->apArg;
- assert( apVal || n==0 );
- for(i=0; i<n; i++, pRec++){
- apVal[i] = pRec;
- storeTypeInfo(pRec, encoding);
- }
- ctx.pFunc = pOp->p4.pFunc;
+#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;
assert( pOp->p3>0 && pOp->p3<=p->nMem );
- ctx.pMem = pMem = &p->aMem[pOp->p3];
- pMem->n++;
- ctx.s.flags = MEM_Null;
- ctx.s.z = 0;
- ctx.s.zMalloc = 0;
- ctx.s.xDel = 0;
- ctx.s.db = db;
- ctx.isError = 0;
- ctx.pColl = 0;
- if( ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
+ 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 ){
assert( pOp>p->aOp );
assert( pOp[-1].p4type==P4_COLLSEQ );
assert( pOp[-1].opcode==OP_CollSeq );
- ctx.pColl = pOp[-1].p4.pColl;
- }
- (ctx.pFunc->xStep)(&ctx, n, apVal);
- if( ctx.isError ){
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s));
- rc = ctx.isError;
- }
- sqlite3VdbeMemRelease(&ctx.s);
+ 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);
break;
}
/* Opcode: AggFinal P1 P2 * P4 *
@@ -54877,19 +55902,21 @@
** 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 */
Mem *pMem;
+#endif /* local variables moved into u.cf */
assert( pOp->p1>0 && pOp->p1<=p->nMem );
- pMem = &p->aMem[pOp->p1];
- assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
- rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
+ 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);
if( rc==SQLITE_ERROR ){
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(pMem));
- }
- sqlite3VdbeChangeEncoding(pMem, encoding);
- UPDATE_MAX_BLOBSIZE(pMem);
- if( sqlite3VdbeMemTooBig(pMem) ){
+ 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) ){
goto too_big;
}
break;
}
@@ -54917,14 +55944,16 @@
** 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 */
Btree *pBt;
+#endif /* local variables moved into u.cg */
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (1<<pOp->p1))!=0 );
- pBt = db->aDb[pOp->p1].pBt;
- rc = sqlite3BtreeIncrVacuum(pBt);
+ u.cg.pBt = db->aDb[pOp->p1].pBt;
+ rc = sqlite3BtreeIncrVacuum(u.cg.pBt);
if( rc==SQLITE_DONE ){
pc = pOp->p2 - 1;
rc = SQLITE_OK;
}
@@ -54965,14 +55994,19 @@
** 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: {
- int p1 = pOp->p1;
- u8 isWriteLock = (u8)pOp->p3;
- assert( p1>=0 && p1<db->nDb );
- assert( (p->btreeMask & (1<<p1))!=0 );
- assert( isWriteLock==0 || isWriteLock==1 );
- rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
+#if 0 /* local variables moved into u.ch */
+ 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);
if( (rc&0xFF)==SQLITE_LOCKED ){
const char *z = pOp->p4.z;
sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z);
}
@@ -54990,14 +56024,17 @@
** within a callback to a virtual table xSync() method. If it is, the error
** code will be set to SQLITE_LOCKED.
*/
case OP_VBegin: {
- sqlite3_vtab *pVtab = pOp->p4.pVtab;
- rc = sqlite3VtabBegin(db, pVtab);
- if( pVtab ){
+#if 0 /* local variables moved into u.ci */
+ 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 ){
sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = pVtab->zErrMsg;
- pVtab->zErrMsg = 0;
+ p->zErrMsg = u.ci.pVtab->zErrMsg;
+ u.ci.pVtab->zErrMsg = 0;
}
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -55035,33 +56072,38 @@
** P1 is a cursor number. This opcode opens a cursor to the virtual
** table and stores that cursor in P1.
*/
case OP_VOpen: {
- VdbeCursor *pCur = 0;
- sqlite3_vtab_cursor *pVtabCursor = 0;
-
- sqlite3_vtab *pVtab = pOp->p4.pVtab;
- sqlite3_module *pModule = (sqlite3_module *)pVtab->pModule;
-
- assert(pVtab && pModule);
+#if 0 /* local variables moved into u.cj */
+ 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);
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- rc = pModule->xOpen(pVtab, &pVtabCursor);
+ rc = u.cj.pModule->xOpen(u.cj.pVtab, &u.cj.pVtabCursor);
sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = pVtab->zErrMsg;
- pVtab->zErrMsg = 0;
+ p->zErrMsg = u.cj.pVtab->zErrMsg;
+ u.cj.pVtab->zErrMsg = 0;
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
if( SQLITE_OK==rc ){
/* Initialize sqlite3_vtab_cursor base class */
- pVtabCursor->pVtab = pVtab;
+ u.cj.pVtabCursor->pVtab = u.cj.pVtab;
/* Initialise vdbe cursor object */
- pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
- if( pCur ){
- pCur->pVtabCursor = pVtabCursor;
- pCur->pModule = pVtabCursor->pVtab->pModule;
- }else{
- db->mallocFailed = 1;
- pModule->xClose(pVtabCursor);
+ 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;
+ }else{
+ db->mallocFailed = 1;
+ u.cj.pModule->xClose(u.cj.pVtabCursor);
}
}
break;
}
@@ -55086,58 +56128,64 @@
**
** 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 */
int nArg;
int iQuery;
const sqlite3_module *pModule;
- Mem *pQuery = &p->aMem[pOp->p3];
- Mem *pArgc = &pQuery[1];
+ Mem *pQuery;
+ Mem *pArgc;
sqlite3_vtab_cursor *pVtabCursor;
sqlite3_vtab *pVtab;
-
- VdbeCursor *pCur = p->apCsr[pOp->p1];
-
- REGISTER_TRACE(pOp->p3, pQuery);
- assert( pCur->pVtabCursor );
- pVtabCursor = pCur->pVtabCursor;
- pVtab = pVtabCursor->pVtab;
- pModule = pVtab->pModule;
+ 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;
/* Grab the index number and argc parameters */
- assert( (pQuery->flags&MEM_Int)!=0 && pArgc->flags==MEM_Int );
- nArg = (int)pArgc->u.i;
- iQuery = (int)pQuery->u.i;
+ 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;
/* Invoke the xFilter method */
{
- int res = 0;
- int i;
- Mem **apArg = p->apArg;
- for(i = 0; i<nArg; i++){
- apArg[i] = &pArgc[i+1];
- storeTypeInfo(apArg[i], 0);
+ 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);
}
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- sqlite3VtabLock(pVtab);
+ sqlite3VtabLock(u.ck.pVtab);
p->inVtabMethod = 1;
- rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
+ rc = u.ck.pModule->xFilter(u.ck.pVtabCursor, u.ck.iQuery, pOp->p4.z, u.ck.nArg, u.ck.apArg);
p->inVtabMethod = 0;
sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = pVtab->zErrMsg;
- pVtab->zErrMsg = 0;
- sqlite3VtabUnlock(db, pVtab);
- if( rc==SQLITE_OK ){
- res = pModule->xEof(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.pVtabCursor);
}
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
- if( res ){
+ if( u.ck.res ){
pc = pOp->p2 - 1;
}
}
- pCur->nullRow = 0;
+ u.ck.pCur->nullRow = 0;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -55149,53 +56197,55 @@
** 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 */
sqlite3_vtab *pVtab;
const sqlite3_module *pModule;
Mem *pDest;
sqlite3_context sContext;
+#endif /* local variables moved into u.cl */
VdbeCursor *pCur = p->apCsr[pOp->p1];
assert( pCur->pVtabCursor );
assert( pOp->p3>0 && pOp->p3<=p->nMem );
- pDest = &p->aMem[pOp->p3];
+ u.cl.pDest = &p->aMem[pOp->p3];
if( pCur->nullRow ){
- sqlite3VdbeMemSetNull(pDest);
+ sqlite3VdbeMemSetNull(u.cl.pDest);
break;
}
- pVtab = pCur->pVtabCursor->pVtab;
- pModule = pVtab->pModule;
- assert( pModule->xColumn );
- memset(&sContext, 0, sizeof(sContext));
+ 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));
/* The output cell may already have a buffer allocated. Move
- ** the current contents to sContext.s so in case the user-function
+ ** the current contents to u.cl.sContext.s so in case the user-function
** can use the already allocated buffer instead of allocating a
** new one.
*/
- sqlite3VdbeMemMove(&sContext.s, pDest);
- MemSetTypeFlag(&sContext.s, MEM_Null);
+ sqlite3VdbeMemMove(&u.cl.sContext.s, u.cl.pDest);
+ MemSetTypeFlag(&u.cl.sContext.s, MEM_Null);
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2);
+ rc = u.cl.pModule->xColumn(pCur->pVtabCursor, &u.cl.sContext, pOp->p2);
sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = pVtab->zErrMsg;
- pVtab->zErrMsg = 0;
+ p->zErrMsg = u.cl.pVtab->zErrMsg;
+ u.cl.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 sContext.s (a Mem struct) is released.
- */
- sqlite3VdbeChangeEncoding(&sContext.s, encoding);
- REGISTER_TRACE(pOp->p3, pDest);
- sqlite3VdbeMemMove(pDest, &sContext.s);
- UPDATE_MAX_BLOBSIZE(pDest);
+ ** 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);
if( sqlite3SafetyOn(db) ){
goto abort_due_to_misuse;
}
- if( sqlite3VdbeMemTooBig(pDest) ){
+ if( sqlite3VdbeMemTooBig(u.cl.pDest) ){
goto too_big;
}
break;
}
@@ -55208,20 +56258,24 @@
** 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 */
sqlite3_vtab *pVtab;
const sqlite3_module *pModule;
- int res = 0;
-
- VdbeCursor *pCur = p->apCsr[pOp->p1];
- assert( pCur->pVtabCursor );
- if( pCur->nullRow ){
+ 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 ){
break;
}
- pVtab = pCur->pVtabCursor->pVtab;
- pModule = pVtab->pModule;
- assert( pModule->xNext );
+ u.cm.pVtab = u.cm.pCur->pVtabCursor->pVtab;
+ u.cm.pModule = u.cm.pVtab->pModule;
+ assert( u.cm.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
@@ -55228,22 +56282,22 @@
** 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(pVtab);
+ sqlite3VtabLock(u.cm.pVtab);
p->inVtabMethod = 1;
- rc = pModule->xNext(pCur->pVtabCursor);
+ rc = u.cm.pModule->xNext(u.cm.pCur->pVtabCursor);
p->inVtabMethod = 0;
sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = pVtab->zErrMsg;
- pVtab->zErrMsg = 0;
- sqlite3VtabUnlock(db, pVtab);
- if( rc==SQLITE_OK ){
- res = pModule->xEof(pCur->pVtabCursor);
+ 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);
}
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
- if( !res ){
+ if( !u.cm.res ){
/* If there is data, jump to P2 */
pc = pOp->p2 - 1;
}
break;
@@ -55257,22 +56311,27 @@
** 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: {
- sqlite3_vtab *pVtab = pOp->p4.pVtab;
- Mem *pName = &p->aMem[pOp->p1];
- assert( pVtab->pModule->xRename );
- REGISTER_TRACE(pOp->p1, pName);
-
- Stringify(pName, encoding);
+#if 0 /* local variables moved into u.cn */
+ 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);
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- sqlite3VtabLock(pVtab);
- rc = pVtab->pModule->xRename(pVtab, pName->z);
+ sqlite3VtabLock(u.cn.pVtab);
+ rc = u.cn.pVtab->pModule->xRename(u.cn.pVtab, u.cn.pName->z);
sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = pVtab->zErrMsg;
- pVtab->zErrMsg = 0;
- sqlite3VtabUnlock(db, pVtab);
+ p->zErrMsg = u.cn.pVtab->zErrMsg;
+ u.cn.pVtab->zErrMsg = 0;
+ sqlite3VtabUnlock(db, u.cn.pVtab);
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
break;
}
@@ -55302,36 +56361,44 @@
** 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: {
- sqlite3_vtab *pVtab = pOp->p4.pVtab;
- sqlite3_module *pModule = (sqlite3_module *)pVtab->pModule;
- int nArg = pOp->p2;
+#if 0 /* local variables moved into u.co */
+ 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;
assert( pOp->p4type==P4_VTAB );
- if( pModule->xUpdate==0 ){
+ if( u.co.pModule->xUpdate==0 ){
sqlite3SetString(&p->zErrMsg, db, "read-only table");
rc = SQLITE_ERROR;
}else{
- int i;
- sqlite_int64 rowid;
- Mem **apArg = p->apArg;
- Mem *pX = &p->aMem[pOp->p3];
- for(i=0; i<nArg; i++){
- storeTypeInfo(pX, 0);
- apArg[i] = pX;
- pX++;
+ 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( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- sqlite3VtabLock(pVtab);
- rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid);
+ sqlite3VtabLock(u.co.pVtab);
+ rc = u.co.pModule->xUpdate(u.co.pVtab, u.co.nArg, u.co.apArg, &u.co.rowid);
sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = pVtab->zErrMsg;
- pVtab->zErrMsg = 0;
- sqlite3VtabUnlock(db, pVtab);
+ p->zErrMsg = u.co.pVtab->zErrMsg;
+ u.co.pVtab->zErrMsg = 0;
+ sqlite3VtabUnlock(db, u.co.pVtab);
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
if( pOp->p1 && rc==SQLITE_OK ){
- assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) );
- db->lastRowid = rowid;
+ assert( u.co.nArg>1 && u.co.apArg[0] && (u.co.apArg[0]->flags&MEM_Null) );
+ db->lastRowid = u.co.rowid;
}
p->nChange++;
}
break;
@@ -55343,16 +56410,20 @@
**
** Write the current number of pages in database P1 to memory cell P2.
*/
case OP_Pagecount: { /* out2-prerelease */
- int p1 = pOp->p1;
+#if 0 /* local variables moved into u.cp */
+ int p1;
int nPage;
- Pager *pPager = sqlite3BtreePager(db->aDb[p1].pBt);
-
- rc = sqlite3PagerPagecount(pPager, &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 ){
pOut->flags = MEM_Int;
- pOut->u.i = nPage;
+ pOut->u.i = u.cp.nPage;
}
break;
}
#endif
@@ -55363,16 +56434,20 @@
** 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: {
- char *zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql);
- if( zTrace ){
+#if 0 /* local variables moved into u.cq */
+ char *zTrace;
+#endif /* local variables moved into u.cq */
+
+ u.cq.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql);
+ if( u.cq.zTrace ){
if( db->xTrace ){
- db->xTrace(db->pTraceArg, zTrace);
+ db->xTrace(db->pTraceArg, u.cq.zTrace);
}
#ifdef SQLITE_DEBUG
if( (db->flags & SQLITE_SqlTrace)!=0 ){
- sqlite3DebugPrintf("SQL-trace: %s\n", zTrace);
+ sqlite3DebugPrintf("SQL-trace: %s\n", u.cq.zTrace);
}
#endif /* SQLITE_DEBUG */
}
break;
@@ -55513,9 +56588,9 @@
*************************************************************************
**
** This file contains code used to implement incremental BLOB I/O.
**
-** $Id: vdbeblob.c,v 1.31 2009/03/24 15:08:10 drh Exp $
+** $Id: vdbeblob.c,v 1.33 2009/06/01 19:53:31 drh Exp $
*/
#ifndef SQLITE_OMIT_INCRBLOB
@@ -55582,41 +56657,48 @@
};
Vdbe *v = 0;
int rc = SQLITE_OK;
- char zErr[128];
-
- zErr[0] = 0;
- sqlite3_mutex_enter(db->mutex);
+ char *zErr = 0;
+ Table *pTab;
+ Parse *pParse;
+
+ *ppBlob = 0;
+ sqlite3_mutex_enter(db->mutex);
+ pParse = sqlite3StackAllocRaw(db, sizeof(*pParse));
+ if( pParse==0 ){
+ rc = SQLITE_NOMEM;
+ goto blob_open_out;
+ }
do {
- Parse sParse;
- Table *pTab;
-
- memset(&sParse, 0, sizeof(Parse));
- sParse.db = db;
+ memset(pParse, 0, sizeof(Parse));
+ pParse->db = db;
if( sqlite3SafetyOn(db) ){
+ sqlite3DbFree(db, zErr);
+ sqlite3StackFree(db, pParse);
sqlite3_mutex_leave(db->mutex);
return SQLITE_MISUSE;
}
sqlite3BtreeEnterAll(db);
- pTab = sqlite3LocateTable(&sParse, 0, zTable, zDb);
+ pTab = sqlite3LocateTable(pParse, 0, zTable, zDb);
if( pTab && IsVirtual(pTab) ){
pTab = 0;
- sqlite3ErrorMsg(&sParse, "cannot open virtual table: %s", zTable);
+ sqlite3ErrorMsg(pParse, "cannot open virtual table: %s", zTable);
}
#ifndef SQLITE_OMIT_VIEW
if( pTab && pTab->pSelect ){
pTab = 0;
- sqlite3ErrorMsg(&sParse, "cannot open view: %s", zTable);
+ sqlite3ErrorMsg(pParse, "cannot open view: %s", zTable);
}
#endif
if( !pTab ){
- if( sParse.zErrMsg ){
- sqlite3_snprintf(sizeof(zErr), zErr, "%s", sParse.zErrMsg);
- }
- sqlite3DbFree(db, sParse.zErrMsg);
+ if( pParse->zErrMsg ){
+ sqlite3DbFree(db, zErr);
+ zErr = pParse->zErrMsg;
+ pParse->zErrMsg = 0;
+ }
rc = SQLITE_ERROR;
(void)sqlite3SafetyOff(db);
sqlite3BtreeLeaveAll(db);
goto blob_open_out;
@@ -55628,9 +56710,10 @@
break;
}
}
if( iCol==pTab->nCol ){
- sqlite3_snprintf(sizeof(zErr), zErr, "no such column: \"%s\"", zColumn);
+ sqlite3DbFree(db, zErr);
+ zErr = sqlite3MPrintf(db, "no such column: \"%s\"", zColumn);
rc = SQLITE_ERROR;
(void)sqlite3SafetyOff(db);
sqlite3BtreeLeaveAll(db);
goto blob_open_out;
@@ -55645,9 +56728,10 @@
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
int j;
for(j=0; j<pIdx->nColumn; j++){
if( pIdx->aiColumn[j]==iCol ){
- sqlite3_snprintf(sizeof(zErr), zErr,
+ sqlite3DbFree(db, zErr);
+ zErr = sqlite3MPrintf(db,
"cannot open indexed column for writing");
rc = SQLITE_ERROR;
(void)sqlite3SafetyOff(db);
sqlite3BtreeLeaveAll(db);
@@ -55675,11 +56759,12 @@
/* Remove either the OP_OpenWrite or OpenRead. Set the P2
** parameter of the other to pTab->tnum.
*/
- sqlite3VdbeChangeToNoop(v, (flags ? 2 : 3), 1);
- sqlite3VdbeChangeP2(v, (flags ? 3 : 2), pTab->tnum);
- sqlite3VdbeChangeP3(v, (flags ? 3 : 2), iDb);
+ flags = !!flags;
+ sqlite3VdbeChangeToNoop(v, 3 - flags, 1);
+ sqlite3VdbeChangeP2(v, 2 + flags, pTab->tnum);
+ sqlite3VdbeChangeP3(v, 2 + flags, iDb);
/* Configure the number of columns. Configure the cursor to
** think that the table has one more column than it really
** does. An OP_Column to retrieve this imaginary column will
@@ -55686,9 +56771,9 @@
** always return an SQL NULL. This is useful because it means
** we can invoke OP_Column to fill in the vdbe cursors type
** and offset cache without causing any IO.
*/
- sqlite3VdbeChangeP4(v, flags ? 3 : 2, SQLITE_INT_TO_PTR(pTab->nCol+1), P4_INT32);
+ sqlite3VdbeChangeP4(v, 2+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32);
sqlite3VdbeChangeP2(v, 6, pTab->nCol);
if( !db->mallocFailed ){
sqlite3VdbeMakeReady(v, 1, 1, 1, 0);
}
@@ -55695,9 +56780,9 @@
}
sqlite3BtreeLeaveAll(db);
rc = sqlite3SafetyOff(db);
- if( rc!=SQLITE_OK || db->mallocFailed ){
+ if( NEVER(rc!=SQLITE_OK) || db->mallocFailed ){
goto blob_open_out;
}
sqlite3_bind_int64((sqlite3_stmt *)v, 1, iRow);
@@ -55704,9 +56789,10 @@
rc = sqlite3_step((sqlite3_stmt *)v);
if( rc!=SQLITE_ROW ){
nAttempt++;
rc = sqlite3_finalize((sqlite3_stmt *)v);
- sqlite3_snprintf(sizeof(zErr), zErr, sqlite3_errmsg(db));
+ sqlite3DbFree(db, zErr);
+ zErr = sqlite3MPrintf(db, sqlite3_errmsg(db));
v = 0;
}
} while( nAttempt<5 && rc==SQLITE_SCHEMA );
@@ -55718,9 +56804,10 @@
Incrblob *pBlob;
u32 type = v->apCsr[0]->aType[iCol];
if( type<12 ){
- sqlite3_snprintf(sizeof(zErr), zErr, "cannot open value of type %s",
+ sqlite3DbFree(db, zErr);
+ zErr = sqlite3MPrintf(db, "cannot open value of type %s",
type==0?"null": type==7?"real": "integer"
);
rc = SQLITE_ERROR;
goto blob_open_out;
@@ -55741,18 +56828,20 @@
pBlob->db = db;
*ppBlob = (sqlite3_blob *)pBlob;
rc = SQLITE_OK;
}else if( rc==SQLITE_OK ){
- sqlite3_snprintf(sizeof(zErr), zErr, "no such rowid: %lld", iRow);
+ sqlite3DbFree(db, zErr);
+ zErr = sqlite3MPrintf(db, "no such rowid: %lld", iRow);
rc = SQLITE_ERROR;
}
blob_open_out:
- zErr[sizeof(zErr)-1] = '\0';
if( v && (rc!=SQLITE_OK || db->mallocFailed) ){
sqlite3VdbeFinalize(v);
}
- sqlite3Error(db, rc, (rc==SQLITE_OK?0:zErr));
+ sqlite3Error(db, rc, zErr);
+ sqlite3DbFree(db, zErr);
+ sqlite3StackFree(db, pParse);
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
}
@@ -55765,13 +56854,17 @@
Incrblob *p = (Incrblob *)pBlob;
int rc;
sqlite3 *db;
- db = p->db;
- sqlite3_mutex_enter(db->mutex);
- rc = sqlite3_finalize(p->pStmt);
- sqlite3DbFree(db, p);
- sqlite3_mutex_leave(db->mutex);
+ if( p ){
+ db = p->db;
+ sqlite3_mutex_enter(db->mutex);
+ rc = sqlite3_finalize(p->pStmt);
+ sqlite3DbFree(db, p);
+ sqlite3_mutex_leave(db->mutex);
+ }else{
+ rc = SQLITE_OK;
+ }
return rc;
}
/*
@@ -55786,10 +56879,12 @@
){
int rc;
Incrblob *p = (Incrblob *)pBlob;
Vdbe *v;
- sqlite3 *db = p->db;
-
+ sqlite3 *db;
+
+ if( p==0 ) return SQLITE_MISUSE;
+ db = p->db;
sqlite3_mutex_enter(db->mutex);
v = (Vdbe*)p->pStmt;
if( n<0 || iOffset<0 || (iOffset+n)>p->nByte ){
@@ -55843,9 +56938,9 @@
** so no mutex is required for access.
*/
SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *pBlob){
Incrblob *p = (Incrblob *)pBlob;
- return p->nByte;
+ return p ? p->nByte : 0;
}
#endif /* #ifndef SQLITE_OMIT_INCRBLOB */
@@ -56367,9 +57462,9 @@
*************************************************************************
** This file contains routines used for walking the parser tree for
** an SQL statement.
**
-** $Id: walker.c,v 1.4 2009/04/08 13:51:52 drh Exp $
+** $Id: walker.c,v 1.6 2009/05/28 01:00:55 drh Exp $
*/
/*
@@ -56394,13 +57489,12 @@
SQLITE_PRIVATE int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){
int rc;
if( pExpr==0 ) return WRC_Continue;
testcase( ExprHasProperty(pExpr, EP_TokenOnly) );
- testcase( ExprHasProperty(pExpr, EP_SpanToken) );
testcase( ExprHasProperty(pExpr, EP_Reduced) );
rc = pWalker->xExprCallback(pWalker, pExpr);
if( rc==WRC_Continue
- && !ExprHasAnyProperty(pExpr,EP_TokenOnly|EP_SpanToken) ){
+ && !ExprHasAnyProperty(pExpr,EP_TokenOnly) ){
if( sqlite3WalkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
if( sqlite3WalkExpr(pWalker, pExpr->pRight) ) return WRC_Abort;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
@@ -56508,9 +57602,9 @@
** 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.22 2009/05/05 15:46:43 drh Exp $
+** $Id: resolve.c,v 1.28 2009/06/01 16:53:10 shane Exp $
*/
/*
** Turn the pExpr expression into an alias for the iCol-th column of the
@@ -56554,18 +57648,30 @@
pOrig = pEList->a[iCol].pExpr;
assert( pOrig!=0 );
assert( pOrig->flags & EP_Resolved );
db = pParse->db;
- pDup = sqlite3ExprDup(db, pOrig, 0);
- if( pDup==0 ) return;
- sqlite3TokenCopy(db, &pDup->token, &pOrig->token);
- if( pDup->op!=TK_COLUMN && zType[0]!='G' ){
+ if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){
+ pDup = sqlite3ExprDup(db, pOrig, 0);
pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0);
if( pDup==0 ) return;
if( pEList->a[iCol].iAlias==0 ){
pEList->a[iCol].iAlias = (u16)(++pParse->nAlias);
}
pDup->iTable = pEList->a[iCol].iAlias;
+ }else if( ExprHasProperty(pOrig, EP_IntValue) || pOrig->u.zToken==0 ){
+ pDup = sqlite3ExprDup(db, pOrig, 0);
+ if( pDup==0 ) return;
+ }else{
+ char *zToken = pOrig->u.zToken;
+ 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);
+ }
}
if( pExpr->flags & EP_ExpCollate ){
pDup->pColl = pExpr->pColl;
pDup->flags |= EP_ExpCollate;
@@ -56591,12 +57697,12 @@
** pExpr->op Set to TK_COLUMN.
** pExpr->pLeft Any expression this points to is deleted
** pExpr->pRight Any expression this points to is deleted.
**
-** The pDbToken is the name of the database (the "X"). This value may be
+** The zDb variable is the name of the database (the "X"). This value may be
** NULL meaning that name is of the form Y.Z or Z. Any available database
-** can be used. The pTableToken is the name of the table (the "Y"). This
-** value can be NULL if pDbToken is also NULL. If pTableToken is NULL it
+** can be used. The zTable variable is the name of the table (the "Y"). This
+** value can be NULL if zDb is also NULL. If zTable is NULL it
** means that the form of the name is Z and that columns from any table
** can be used.
**
** If the name cannot be resolved unambiguously, leave an error message
@@ -56603,17 +57709,14 @@
** in pParse and return non-zero. Return zero on success.
*/
static int lookupName(
Parse *pParse, /* The parsing context */
- Token *pDbToken, /* Name of the database containing table, or NULL */
- Token *pTableToken, /* Name of table containing column, or NULL */
- Token *pColumnToken, /* Name of the column. */
+ const char *zDb, /* Name of the database containing table, or NULL */
+ const char *zTab, /* Name of table containing column, or NULL */
+ const char *zCol, /* Name of the column. */
NameContext *pNC, /* The name context used to resolve the name */
Expr *pExpr /* Make this EXPR node point to the selected column */
){
- char *zDb = 0; /* Name of the database. The "X" in X.Y.Z */
- char *zTab = 0; /* Name of the table. The "Y" in X.Y.Z or Y.Z */
- char *zCol = 0; /* Name of the column. The "Z" */
int i, j; /* Loop counters */
int cnt = 0; /* Number of matching column names */
int cntTab = 0; /* Number of matching table names */
sqlite3 *db = pParse->db; /* The database connection */
@@ -56621,22 +57724,16 @@
struct SrcList_item *pMatch = 0; /* The matching pSrcList item */
NameContext *pTopNC = pNC; /* First namecontext in the list */
Schema *pSchema = 0; /* Schema of the expression */
- assert( pNC ); /* the name context cannot be NULL. */
- assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */
-
- /* Dequote and zero-terminate the names */
- zDb = sqlite3NameFromToken(db, pDbToken);
- zTab = sqlite3NameFromToken(db, pTableToken);
- zCol = sqlite3NameFromToken(db, pColumnToken);
- if( db->mallocFailed ){
- goto lookupname_end;
- }
+ assert( pNC ); /* the name context cannot be NULL. */
+ assert( zCol ); /* The Z in X.Y.Z cannot be NULL */
+ assert( ~ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
/* Initialize the node to no-match */
pExpr->iTable = -1;
pExpr->pTab = 0;
+ ExprSetIrreducible(pExpr);
/* Start at the inner-most context and move outward until a match is found */
while( pNC && cnt==0 ){
ExprList *pEList;
@@ -56678,9 +57775,9 @@
pExpr->pTab = pTab;
pMatch = pItem;
pSchema = pTab->pSchema;
/* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
- pExpr->iColumn = j==pTab->iPKey ? -1 : j;
+ pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j;
if( i<pSrcList->nSrc-1 ){
if( pItem[1].jointype & JT_NATURAL ){
/* If this match occurred in the left table of a natural join,
** then skip the right table to avoid a duplicate match */
@@ -56734,9 +57831,9 @@
cntTab++;
for(iCol=0; iCol < pTab->nCol; iCol++, pCol++) {
if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
cnt++;
- pExpr->iColumn = iCol==pTab->iPKey ? -1 : iCol;
+ pExpr->iColumn = iCol==pTab->iPKey ? -1 : (i16)iCol;
pExpr->pTab = pTab;
if( iCol>=0 ){
testcase( iCol==31 );
testcase( iCol==32 );
@@ -56784,16 +57881,15 @@
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);
- sqlite3DbFree(db, zCol);
return 2;
}
resolveAlias(pParse, pEList, j, pExpr, "");
cnt = 1;
pMatch = 0;
assert( zTab==0 && zDb==0 );
- goto lookupname_end_2;
+ goto lookupname_end;
}
}
}
@@ -56815,9 +57911,8 @@
** Because no reference was made to outer contexts, the pNC->nRef
** fields are not changed in any context.
*/
if( cnt==0 && zTab==0 && ExprHasProperty(pExpr,EP_DblQuoted) ){
- sqlite3DbFree(db, zCol);
pExpr->op = TK_STRING;
pExpr->pTab = 0;
return 0;
}
@@ -56854,20 +57949,16 @@
assert( pMatch->iCursor==pExpr->iTable );
pMatch->colUsed |= ((Bitmask)1)<<n;
}
-lookupname_end:
/* Clean up and return
*/
- sqlite3DbFree(db, zDb);
- sqlite3DbFree(db, zTab);
sqlite3ExprDelete(db, pExpr->pLeft);
pExpr->pLeft = 0;
sqlite3ExprDelete(db, pExpr->pRight);
pExpr->pRight = 0;
pExpr->op = TK_COLUMN;
-lookupname_end_2:
- sqlite3DbFree(db, zCol);
+lookupname_end:
if( cnt==1 ){
assert( pNC!=0 );
sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
/* Increment the nRef value on all name contexts from TopNC up to
@@ -56938,34 +58029,34 @@
/* A lone identifier is the name of a column.
*/
case TK_ID: {
- lookupName(pParse, 0, 0, &pExpr->token, pNC, pExpr);
+ lookupName(pParse, 0, 0, pExpr->u.zToken, pNC, pExpr);
return WRC_Prune;
}
/* A table name and column name: ID.ID
** Or a database, table and column: ID.ID.ID
*/
case TK_DOT: {
- Token *pColumn;
- Token *pTable;
- Token *pDb;
+ const char *zColumn;
+ const char *zTable;
+ const char *zDb;
Expr *pRight;
/* if( pSrcList==0 ) break; */
pRight = pExpr->pRight;
if( pRight->op==TK_ID ){
- pDb = 0;
- pTable = &pExpr->pLeft->token;
- pColumn = &pRight->token;
+ zDb = 0;
+ zTable = pExpr->pLeft->u.zToken;
+ zColumn = pRight->u.zToken;
}else{
assert( pRight->op==TK_DOT );
- pDb = &pExpr->pLeft->token;
- pTable = &pRight->pLeft->token;
- pColumn = &pRight->pRight->token;
- }
- lookupName(pParse, pDb, pTable, pColumn, pNC, pExpr);
+ 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;
}
/* Resolve function names
@@ -56983,10 +58074,10 @@
FuncDef *pDef; /* Information about the function */
u8 enc = ENC(pParse->db); /* The database encoding */
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- zId = (char*)pExpr->token.z;
- nId = pExpr->token.n;
+ zId = pExpr->u.zToken;
+ nId = sqlite3Strlen30(zId);
pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
if( pDef==0 ){
pDef = sqlite3FindFunction(pParse->db, zId, nId, -1, enc, 0);
if( pDef==0 ){
@@ -57085,22 +58176,18 @@
Expr *pE /* Expression we are trying to match */
){
int i; /* Loop counter */
- if( pE->op==TK_ID || (pE->op==TK_STRING && pE->token.z[0]!='\'') ){
- sqlite3 *db = pParse->db;
- char *zCol = sqlite3NameFromToken(db, &pE->token);
- if( zCol==0 ){
- return -1;
- }
+ UNUSED_PARAMETER(pParse);
+
+ if( pE->op==TK_ID || (pE->op==TK_STRING && pE->u.zToken[0]!='\'') ){
+ 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 ){
- sqlite3DbFree(db, zCol);
return i+1;
}
}
- sqlite3DbFree(db, zCol);
}
return 0;
}
@@ -57249,13 +58336,13 @@
if( iCol>0 ){
CollSeq *pColl = pE->pColl;
int flags = pE->flags & EP_ExpCollate;
sqlite3ExprDelete(db, pE);
- pItem->pExpr = pE = sqlite3Expr(db, TK_INTEGER, 0, 0, 0);
+ pItem->pExpr = pE = sqlite3Expr(db, TK_INTEGER, 0);
if( pE==0 ) return 1;
pE->pColl = pColl;
pE->flags |= EP_IntValue | flags;
- pE->iTable = iCol;
+ pE->u.iValue = iCol;
pItem->iCol = (u16)iCol;
pItem->done = 1;
}else{
moreToDo = 1;
@@ -57627,9 +58714,9 @@
sqlite3WalkExpr(&w, pExpr);
#if SQLITE_MAX_EXPR_DEPTH>0
pNC->pParse->nHeight -= pExpr->nHeight;
#endif
- if( pNC->nErr>0 ){
+ if( pNC->nErr>0 || w.pParse->nErr>0 ){
ExprSetProperty(pExpr, EP_Error);
}
if( pNC->hasAgg ){
ExprSetProperty(pExpr, EP_Agg);
@@ -57682,9 +58769,9 @@
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
-** $Id: expr.c,v 1.432.2.1 2009/05/25 12:02:24 drh Exp $
+** $Id: expr.c,v 1.445 2009/06/01 16:53:10 shane Exp $
*/
/*
** Return the 'affinity' of the expression pExpr if any.
@@ -57709,9 +58796,10 @@
return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
}
#ifndef SQLITE_OMIT_CAST
if( op==TK_CAST ){
- return sqlite3AffinityType(&pExpr->token);
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ return sqlite3AffinityType(pExpr->u.zToken);
}
#endif
if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER)
&& pExpr->pTab!=0
@@ -57738,9 +58826,9 @@
CollSeq *pColl;
sqlite3 *db = pParse->db;
zColl = sqlite3NameFromToken(db, pCollName);
if( pExpr && zColl ){
- pColl = sqlite3LocateCollSeq(pParse, zColl, -1);
+ pColl = sqlite3LocateCollSeq(pParse, zColl);
if( pColl ){
pExpr->pColl = pColl;
pExpr->flags |= EP_ExpCollate;
}
@@ -57755,9 +58843,9 @@
*/
SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
CollSeq *pColl = 0;
Expr *p = pExpr;
- while( p ){
+ while( ALWAYS(p) ){
int op;
pColl = p->pColl;
if( pColl ) break;
op = p->op;
@@ -57768,9 +58856,9 @@
int j = p->iColumn;
if( j>=0 ){
sqlite3 *db = pParse->db;
zColl = p->pTab->aCol[j].zColl;
- pColl = sqlite3FindCollSeq(db, ENC(db), zColl, -1, 0);
+ pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
pExpr->pColl = pColl;
}
break;
}
@@ -58045,72 +59133,124 @@
#define exprSetHeight(y)
#endif /* SQLITE_MAX_EXPR_DEPTH>0 */
/*
+** This routine is the core allocator for Expr nodes.
+**
** Construct a new expression node and return a pointer to it. Memory
-** for this node is obtained from sqlite3_malloc(). The calling function
+** for this node and for the pToken argument is a single allocation
+** obtained from sqlite3DbMalloc(). The calling function
** is responsible for making sure the node eventually gets freed.
-*/
-SQLITE_PRIVATE Expr *sqlite3Expr(
+**
+** If dequote is true, then the token (if it exists) is dequoted.
+** If dequote is false, no dequoting is performance. The deQuote
+** parameter is ignored if pToken is NULL or if the token does not
+** appear to be quoted. If the quotes were of the form "..." (double-quotes)
+** then the EP_DblQuoted flag is set on the expression node.
+**
+** Special case: If op==TK_INTEGER and pToken points to a string that
+** can be translated into a 32-bit integer, then the token is not
+** stored in u.zToken. Instead, the integer values is written
+** into u.iValue and the EP_IntValue flag is set. No extra storage
+** is allocated to hold the integer text and the dequote flag is ignored.
+*/
+SQLITE_PRIVATE Expr *sqlite3ExprAlloc(
sqlite3 *db, /* Handle for sqlite3DbMallocZero() (may be null) */
int op, /* Expression opcode */
- Expr *pLeft, /* Left operand */
- Expr *pRight, /* Right operand */
- const Token *pToken /* Argument token */
+ const Token *pToken, /* Token argument. Might be NULL */
+ int dequote /* True to dequote */
){
Expr *pNew;
- pNew = sqlite3DbMallocZero(db, sizeof(Expr));
- if( pNew==0 ){
- /* When malloc fails, delete pLeft and pRight. Expressions passed to
- ** this function must always be allocated with sqlite3Expr() for this
- ** reason.
- */
- sqlite3ExprDelete(db, pLeft);
- sqlite3ExprDelete(db, pRight);
- return 0;
- }
- pNew->op = (u8)op;
- pNew->pLeft = pLeft;
- pNew->pRight = pRight;
- pNew->iAgg = -1;
- pNew->span.z = (u8*)"";
+ int nExtra = 0;
+ int iValue = 0;
+
if( pToken ){
- int c;
- assert( pToken->dyn==0 );
- pNew->span = *pToken;
- if( pToken->n>=2
- && ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){
- sqlite3TokenCopy(db, &pNew->token, pToken);
- if( pNew->token.z ){
- pNew->token.n = sqlite3Dequote((char*)pNew->token.z);
- assert( pNew->token.n==(unsigned)sqlite3Strlen30((char*)pNew->token.z) );
- }
- if( c=='"' ) pNew->flags |= EP_DblQuoted;
- }else{
- pNew->token = *pToken;
- }
- pNew->token.quoted = 0;
- }else if( pLeft ){
- if( pRight ){
- if( pRight->span.dyn==0 && pLeft->span.dyn==0 ){
- sqlite3ExprSpan(pNew, &pLeft->span, &pRight->span);
- }
- if( pRight->flags & EP_ExpCollate ){
- pNew->flags |= EP_ExpCollate;
- pNew->pColl = pRight->pColl;
- }
- }
- if( pLeft->flags & EP_ExpCollate ){
- pNew->flags |= EP_ExpCollate;
- pNew->pColl = pLeft->pColl;
- }
- }
-
- exprSetHeight(pNew);
+ if( op!=TK_INTEGER || pToken->z==0
+ || sqlite3GetInt32(pToken->z, &iValue)==0 ){
+ nExtra = pToken->n+1;
+ }
+ }
+ pNew = sqlite3DbMallocZero(db, sizeof(Expr)+nExtra);
+ if( pNew ){
+ pNew->op = (u8)op;
+ pNew->iAgg = -1;
+ if( pToken ){
+ if( nExtra==0 ){
+ pNew->flags |= EP_IntValue;
+ pNew->u.iValue = iValue;
+ }else{
+ int c;
+ pNew->u.zToken = (char*)&pNew[1];
+ memcpy(pNew->u.zToken, pToken->z, pToken->n);
+ pNew->u.zToken[pToken->n] = 0;
+ if( dequote && nExtra>=3
+ && ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){
+ sqlite3Dequote(pNew->u.zToken);
+ if( c=='"' ) pNew->flags |= EP_DblQuoted;
+ }
+ }
+ }
+#if SQLITE_MAX_EXPR_DEPTH>0
+ pNew->nHeight = 1;
+#endif
+ }
return pNew;
}
/*
+** Allocate a new expression node from a zero-terminated token that has
+** already been dequoted.
+*/
+SQLITE_PRIVATE Expr *sqlite3Expr(
+ sqlite3 *db, /* Handle for sqlite3DbMallocZero() (may be null) */
+ int op, /* Expression opcode */
+ const char *zToken /* Token argument. Might be NULL */
+){
+ Token x;
+ x.z = zToken;
+ x.n = zToken ? sqlite3Strlen30(zToken) : 0;
+ return sqlite3ExprAlloc(db, op, &x, 0);
+}
+
+/*
+** Attach subtrees pLeft and pRight to the Expr node pRoot.
+**
+** If pRoot==NULL that means that a memory allocation error has occurred.
+** In that case, delete the subtrees pLeft and pRight.
+*/
+SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(
+ sqlite3 *db,
+ Expr *pRoot,
+ Expr *pLeft,
+ Expr *pRight
+){
+ if( pRoot==0 ){
+ assert( db->mallocFailed );
+ sqlite3ExprDelete(db, pLeft);
+ sqlite3ExprDelete(db, pRight);
+ }else{
+ if( pRight ){
+ pRoot->pRight = pRight;
+ if( pRight->flags & EP_ExpCollate ){
+ pRoot->flags |= EP_ExpCollate;
+ pRoot->pColl = pRight->pColl;
+ }
+ }
+ if( pLeft ){
+ pRoot->pLeft = pLeft;
+ if( pLeft->flags & EP_ExpCollate ){
+ pRoot->flags |= EP_ExpCollate;
+ pRoot->pColl = pLeft->pColl;
+ }
+ }
+ exprSetHeight(pRoot);
+ }
+}
+
+/*
+** Allocate a Expr node which joins 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.
*/
SQLITE_PRIVATE Expr *sqlite3PExpr(
@@ -58119,38 +59259,10 @@
Expr *pLeft, /* Left operand */
Expr *pRight, /* Right operand */
const Token *pToken /* Argument token */
){
- Expr *p = sqlite3Expr(pParse->db, op, pLeft, pRight, pToken);
- if( p ){
- sqlite3ExprCheckHeight(pParse, p->nHeight);
- }
- return p;
-}
-
-/*
-** When doing a nested parse, you can include terms in an expression
-** that look like this: #1 #2 ... These terms refer to registers
-** in the virtual machine. #N is the N-th register.
-**
-** This routine is called by the parser to deal with on of those terms.
-** It immediately generates code to store the value in a memory location.
-** The returns an expression that will code to extract the value from
-** that memory location as needed.
-*/
-SQLITE_PRIVATE Expr *sqlite3RegisterExpr(Parse *pParse, Token *pToken){
- Vdbe *v = pParse->pVdbe;
- Expr *p;
- if( pParse->nested==0 ){
- sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", pToken);
- return sqlite3PExpr(pParse, TK_NULL, 0, 0, 0);
- }
- if( v==0 ) return 0;
- p = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, pToken);
- if( p==0 ){
- return 0; /* Malloc failed */
- }
- p->iTable = atoi((char*)&pToken->z[1]);
+ Expr *p = sqlite3ExprAlloc(pParse->db, op, pToken, 1);
+ sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
return p;
}
/*
@@ -58162,26 +59274,11 @@
return pRight;
}else if( pRight==0 ){
return pLeft;
}else{
- return sqlite3Expr(db, TK_AND, pLeft, pRight, 0);
- }
-}
-
-/*
-** Set the Expr.span field of the given expression to span all
-** text between the two given tokens. Both tokens must be pointing
-** at the same string.
-*/
-SQLITE_PRIVATE void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
- assert( pRight!=0 );
- assert( pLeft!=0 );
- if( pExpr ){
- pExpr->span.z = pLeft->z;
- /* The following assert() may fail when this is called
- ** via sqlite3PExpr()/sqlite3Expr() from addWhereTerm(). */
- /* assert(pRight->z >= pLeft->z); */
- pExpr->span.n = pRight->n + (unsigned)(pRight->z - pLeft->z);
+ Expr *pNew = sqlite3ExprAlloc(db, TK_AND, 0, 0);
+ sqlite3ExprAttachSubtrees(db, pNew, pLeft, pRight);
+ return pNew;
}
}
/*
@@ -58191,19 +59288,15 @@
SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){
Expr *pNew;
sqlite3 *db = pParse->db;
assert( pToken );
- pNew = sqlite3DbMallocZero(db, sizeof(Expr) );
+ pNew = sqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1);
if( pNew==0 ){
sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */
return 0;
}
- pNew->op = TK_FUNCTION;
pNew->x.pList = pList;
assert( !ExprHasProperty(pNew, EP_xIsSelect) );
- assert( pToken->dyn==0 );
- pNew->span = *pToken;
- sqlite3TokenCopy(db, &pNew->token, pToken);
sqlite3ExprSetHeight(pParse, pNew);
return pNew;
}
@@ -58217,30 +59310,31 @@
** Wildcards of the form "?nnn" are assigned the number "nnn". We make
** sure "nnn" is not too be to avoid a denial of service attack when
** the SQL statement comes from an external source.
**
-** Wildcards of the form ":aaa" or "$aaa" are assigned the same number
+** Wildcards of the form ":aaa", "@aaa", or "$aaa" are assigned the same number
** as the previous instance of the same wildcard. Or if this is the first
** instance of the wildcard, the next sequenial variable number is
** assigned.
*/
SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
- Token *pToken;
- sqlite3 *db = pParse->db;
+ sqlite3 *db = pParse->db;
+ const char *z;
if( pExpr==0 ) return;
- pToken = &pExpr->token;
- assert( pToken->n>=1 );
- assert( pToken->z!=0 );
- assert( pToken->z[0]!=0 );
- if( pToken->n==1 ){
+ assert( !ExprHasAnyProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) );
+ z = pExpr->u.zToken;
+ assert( z!=0 );
+ assert( z[0]!=0 );
+ if( z[1]==0 ){
/* Wildcard of the form "?". Assign the next variable number */
+ assert( z[0]=='?' );
pExpr->iTable = ++pParse->nVar;
- }else if( pToken->z[0]=='?' ){
+ }else if( z[0]=='?' ){
/* Wildcard of the form "?nnn". Convert "nnn" to an integer and
** use it as the variable number */
int i;
- pExpr->iTable = i = atoi((char*)&pToken->z[1]);
+ pExpr->iTable = i = atoi((char*)&z[1]);
testcase( i==0 );
testcase( i==1 );
testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] );
@@ -58251,20 +59345,19 @@
if( i>pParse->nVar ){
pParse->nVar = i;
}
}else{
- /* Wildcards of the form ":aaa" or "$aaa". Reuse the same variable
+ /* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable
** number as the prior appearance of the same name, or if the name
** has never appeared before, reuse the same variable number
*/
int i;
u32 n;
- n = pToken->n;
+ n = sqlite3Strlen30(z);
for(i=0; i<pParse->nVarExpr; i++){
- Expr *pE;
- if( (pE = pParse->apVarExpr[i])!=0
- && pE->token.n==n
- && memcmp(pE->token.z, pToken->z, n)==0 ){
+ Expr *pE = pParse->apVarExpr[i];
+ assert( pE!=0 );
+ if( memcmp(pE->u.zToken, z, n)==0 && pE->u.zToken[n]==0 ){
pExpr->iTable = pE->iTable;
break;
}
}
@@ -58294,21 +59387,15 @@
** Clear an expression structure without deleting the structure itself.
** Substructure is deleted.
*/
SQLITE_PRIVATE void sqlite3ExprClear(sqlite3 *db, Expr *p){
- if( p->token.dyn ) sqlite3DbFree(db, (char*)p->token.z);
- if( !ExprHasAnyProperty(p, EP_TokenOnly|EP_SpanToken) ){
- if( p->span.dyn ) sqlite3DbFree(db, (char*)p->span.z);
- if( ExprHasProperty(p, EP_Reduced) ){
- /* Subtrees are part of the same memory allocation when EP_Reduced set */
- if( p->pLeft ) sqlite3ExprClear(db, p->pLeft);
- if( p->pRight ) sqlite3ExprClear(db, p->pRight);
- }else{
- /* Subtrees are separate allocations when EP_Reduced is clear */
- sqlite3ExprDelete(db, p->pLeft);
- sqlite3ExprDelete(db, p->pRight);
- }
- /* x.pSelect and x.pList are always separately allocated */
+ assert( p!=0 );
+ if( !ExprHasAnyProperty(p, EP_TokenOnly) ){
+ sqlite3ExprDelete(db, p->pLeft);
+ sqlite3ExprDelete(db, p->pRight);
+ if( !ExprHasProperty(p, EP_Reduced) && (p->flags2 & EP2_MallocedToken)!=0 ){
+ sqlite3DbFree(db, p->u.zToken);
+ }
if( ExprHasProperty(p, EP_xIsSelect) ){
sqlite3SelectDelete(db, p->x.pSelect);
}else{
sqlite3ExprListDelete(db, p->x.pList);
@@ -58321,9 +59408,11 @@
*/
SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
if( p==0 ) return;
sqlite3ExprClear(db, p);
- sqlite3DbFree(db, p);
+ if( !ExprHasProperty(p, EP_Static) ){
+ sqlite3DbFree(db, p);
+ }
}
/*
** Return the number of bytes allocated for the expression structure
@@ -58331,46 +59420,74 @@
** EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE.
*/
static int exprStructSize(Expr *p){
if( ExprHasProperty(p, EP_TokenOnly) ) return EXPR_TOKENONLYSIZE;
- if( ExprHasProperty(p, EP_SpanToken) ) return EXPR_SPANTOKENSIZE;
if( ExprHasProperty(p, EP_Reduced) ) return EXPR_REDUCEDSIZE;
return EXPR_FULLSIZE;
}
/*
-** sqlite3ExprDup() has been called to create a copy of expression p with
-** the EXPRDUP_XXX flags passed as the second argument. This function
-** returns the space required for the copy of the Expr structure only.
-** This is always one of EXPR_FULLSIZE, EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE.
+** The dupedExpr*Size() routines each return the number of bytes required
+** to store a copy of an expression or expression tree. They differ in
+** how much of the tree is measured.
+**
+** dupedExprStructSize() Size of only the Expr structure
+** dupedExprNodeSize() Size of Expr + space for token
+** dupedExprSize() Expr + token + subtree components
+**
+***************************************************************************
+**
+** The dupedExprStructSize() function returns two values OR-ed together:
+** (1) the space required for a copy of the Expr structure only and
+** (2) the EP_xxx flags that indicate what the structure size should be.
+** The return values is always one of:
+**
+** EXPR_FULLSIZE
+** EXPR_REDUCEDSIZE | EP_Reduced
+** EXPR_TOKENONLYSIZE | EP_TokenOnly
+**
+** The size of the structure can be found by masking the return value
+** of this routine with 0xfff. The flags can be found by masking the
+** return value with EP_Reduced|EP_TokenOnly.
+**
+** Note that with flags==EXPRDUP_REDUCE, this routines works on full-size
+** (unreduced) Expr objects as they or originally constructed by the parser.
+** During expression analysis, extra information is computed and moved into
+** later parts of teh Expr object and that extra information might get chopped
+** off if the expression is reduced. Note also that it does not work to
+** make a EXPRDUP_REDUCE copy of a reduced expression. It is only legal
+** to reduce a pristine expression tree from the parser. The implementation
+** of dupedExprStructSize() contain multiple assert() statements that attempt
+** to enforce this constraint.
*/
static int dupedExprStructSize(Expr *p, int flags){
int nSize;
+ assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
if( 0==(flags&EXPRDUP_REDUCE) ){
nSize = EXPR_FULLSIZE;
- }else if( p->pLeft || p->pRight || p->pColl || p->x.pList ){
- nSize = EXPR_REDUCEDSIZE;
- }else if( flags&EXPRDUP_SPAN ){
- nSize = EXPR_SPANTOKENSIZE;
- }else{
- nSize = EXPR_TOKENONLYSIZE;
+ }else{
+ assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) );
+ assert( !ExprHasProperty(p, EP_FromJoin) );
+ assert( (p->flags2 & EP2_MallocedToken)==0 );
+ assert( (p->flags2 & EP2_Irreducible)==0 );
+ if( p->pLeft || p->pRight || p->pColl || p->x.pList ){
+ nSize = EXPR_REDUCEDSIZE | EP_Reduced;
+ }else{
+ nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly;
+ }
}
return nSize;
}
/*
-** sqlite3ExprDup() has been called to create a copy of expression p with
-** the EXPRDUP_XXX passed as the second argument. This function returns
-** the space in bytes required to store the copy of the Expr structure
-** and the copies of the Expr.token.z and Expr.span.z (if applicable)
-** string buffers.
+** This function returns the space in bytes required to store the copy
+** of the Expr structure and a copy of the Expr.u.zToken string (if that
+** string is defined.)
*/
static int dupedExprNodeSize(Expr *p, int flags){
- int nByte = dupedExprStructSize(p, flags) + (p->token.z ? p->token.n + 1 : 0);
- if( (flags&EXPRDUP_SPAN)!=0
- && (p->token.z!=p->span.z || p->token.n!=p->span.n)
- ){
- nByte += p->span.n;
+ int nByte = dupedExprStructSize(p, flags) & 0xfff;
+ if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
+ nByte += sqlite3Strlen30(p->u.zToken)+1;
}
return ROUND8(nByte);
}
@@ -58379,11 +59496,9 @@
** expression passed as the first argument. The second argument is a
** mask containing EXPRDUP_XXX flags.
**
** The value returned includes space to create a copy of the Expr struct
-** itself and the buffer referred to by Expr.token, if any. If the
-** EXPRDUP_SPAN flag is set, then space to create a copy of the buffer
-** refered to by Expr.span is also included.
+** itself and the buffer referred to by Expr.u.zToken, if any.
**
** If the EXPRDUP_REDUCE flag is set, then the return value includes
** space to duplicate all Expr nodes in the tree formed by Expr.pLeft
** and Expr.pRight variables (but not for any structures pointed to or
@@ -58393,10 +59508,9 @@
int nByte = 0;
if( p ){
nByte = dupedExprNodeSize(p, flags);
if( flags&EXPRDUP_REDUCE ){
- int f = flags&(~EXPRDUP_SPAN);
- nByte += dupedExprSize(p->pLeft, f) + dupedExprSize(p->pRight, f);
+ nByte += dupedExprSize(p->pLeft, flags) + dupedExprSize(p->pRight, flags);
}
}
return nByte;
}
@@ -58403,25 +59517,26 @@
/*
** This function is similar to sqlite3ExprDup(), except that if pzBuffer
** is not NULL then *pzBuffer is assumed to point to a buffer large enough
-** to store the copy of expression p, the copies of p->token and p->span
+** to store the copy of expression p, the copies of p->u.zToken
** (if applicable), and the copies of the p->pLeft and p->pRight expressions,
** if any. Before returning, *pzBuffer is set to the first byte passed the
** portion of the buffer copied into by this function.
*/
static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
Expr *pNew = 0; /* Value to return */
if( p ){
- const int isRequireSpan = (flags&EXPRDUP_SPAN);
const int isReduced = (flags&EXPRDUP_REDUCE);
u8 *zAlloc;
+ u32 staticFlag = 0;
assert( pzBuffer==0 || isReduced );
/* Figure out where to write the new Expr structure. */
if( pzBuffer ){
zAlloc = *pzBuffer;
+ staticFlag = EP_Static;
}else{
zAlloc = sqlite3DbMallocRaw(db, dupedExprSize(p, flags));
}
pNew = (Expr *)zAlloc;
@@ -58429,12 +59544,18 @@
if( pNew ){
/* Set nNewSize to the size allocated for the structure pointed to
** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or
** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed
- ** by the copy of the p->token.z string (if any).
- */
- const int nNewSize = dupedExprStructSize(p, flags);
- const int nToken = (p->token.z ? p->token.n + 1 : 0);
+ ** by the copy of the p->u.zToken string (if any).
+ */
+ const unsigned nStructSize = dupedExprStructSize(p, flags);
+ const int nNewSize = nStructSize & 0xfff;
+ int nToken;
+ if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
+ nToken = sqlite3Strlen30(p->u.zToken) + 1;
+ }else{
+ nToken = 0;
+ }
if( isReduced ){
assert( ExprHasProperty(p, EP_Reduced)==0 );
memcpy(zAlloc, p, nNewSize);
}else{
@@ -58442,43 +59563,20 @@
memcpy(zAlloc, p, nSize);
memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize);
}
- /* Set the EP_Reduced and EP_TokenOnly flags appropriately. */
- pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_SpanToken);
- switch( nNewSize ){
- case EXPR_REDUCEDSIZE: pNew->flags |= EP_Reduced; break;
- case EXPR_TOKENONLYSIZE: pNew->flags |= EP_TokenOnly; break;
- case EXPR_SPANTOKENSIZE: pNew->flags |= EP_SpanToken; break;
- }
-
- /* Copy the p->token string, if any. */
+ /* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */
+ pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static);
+ pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
+ pNew->flags |= staticFlag;
+
+ /* Copy the p->u.zToken string, if any. */
if( nToken ){
- unsigned char *zToken = &zAlloc[nNewSize];
- memcpy(zToken, p->token.z, nToken-1);
- zToken[nToken-1] = '\0';
- pNew->token.dyn = 0;
- pNew->token.z = zToken;
- }
-
- if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){
- /* Fill in the pNew->span token, if required. */
- if( isRequireSpan ){
- if( p->token.z!=p->span.z || p->token.n!=p->span.n ){
- pNew->span.z = &zAlloc[nNewSize+nToken];
- memcpy((char *)pNew->span.z, p->span.z, p->span.n);
- pNew->span.dyn = 0;
- }else{
- pNew->span.z = pNew->token.z;
- pNew->span.n = pNew->token.n;
- }
- }else{
- pNew->span.z = 0;
- pNew->span.n = 0;
- }
- }
-
- if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_SpanToken)) ){
+ char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize];
+ memcpy(zToken, p->u.zToken, nToken);
+ }
+
+ if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){
/* Fill in the pNew->x.pSelect or pNew->x.pList member. */
if( ExprHasProperty(p, EP_xIsSelect) ){
pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, isReduced);
}else{
@@ -58486,9 +59584,9 @@
}
}
/* Fill in pNew->pLeft and pNew->pRight. */
- if( ExprHasAnyProperty(pNew, EP_Reduced|EP_TokenOnly|EP_SpanToken) ){
+ if( ExprHasAnyProperty(pNew, EP_Reduced|EP_TokenOnly) ){
zAlloc += dupedExprNodeSize(p, flags);
if( ExprHasProperty(pNew, EP_Reduced) ){
pNew->pLeft = exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc);
pNew->pRight = exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc);
@@ -58495,12 +59593,16 @@
}
if( pzBuffer ){
*pzBuffer = zAlloc;
}
- }else if( !ExprHasAnyProperty(p, EP_TokenOnly|EP_SpanToken) ){
- pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
- pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
- }
+ }else{
+ pNew->flags2 = 0;
+ if( !ExprHasAnyProperty(p, EP_TokenOnly) ){
+ pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
+ pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
+ }
+ }
+
}
}
return pNew;
}
@@ -58516,30 +59618,15 @@
** by subsequent calls to sqlite*ListAppend() routines.
**
** Any tables that the SrcList might point to are not duplicated.
**
-** The flags parameter contains a combination of the EXPRDUP_XXX flags. If
-** the EXPRDUP_SPAN flag is set in the argument parameter, then the
-** Expr.span field of the input expression is copied. If EXPRDUP_SPAN is
-** clear, then the Expr.span field of the returned expression structure
-** is zeroed.
-**
+** The flags parameter contains a combination of the EXPRDUP_XXX flags.
** If the EXPRDUP_REDUCE flag is set, then the structure returned is a
** truncated version of the usual Expr structure that will be stored as
** part of the in-memory representation of the database schema.
*/
SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3 *db, Expr *p, int flags){
return exprDup(db, p, flags, 0);
-}
-SQLITE_PRIVATE void sqlite3TokenCopy(sqlite3 *db, Token *pTo, const Token *pFrom){
- if( pTo->dyn ) sqlite3DbFree(db, (char*)pTo->z);
- if( pFrom->z ){
- pTo->n = pFrom->n;
- pTo->z = (u8*)sqlite3DbStrNDup(db, (char*)pFrom->z, pFrom->n);
- pTo->dyn = 1;
- }else{
- pTo->z = 0;
- }
}
SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){
ExprList *pNew;
struct ExprList_item *pItem, *pOldItem;
@@ -58559,8 +59646,9 @@
Expr *pNewExpr;
Expr *pOldExpr = pOldItem->pExpr;
pItem->pExpr = pNewExpr = sqlite3ExprDup(db, pOldExpr, flags);
pItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
+ pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan);
pItem->sortOrder = pOldItem->sortOrder;
pItem->done = 0;
pItem->iCol = pOldItem->iCol;
pItem->iAlias = pOldItem->iAlias;
@@ -58633,12 +59721,9 @@
Select *pNew;
if( p==0 ) return 0;
pNew = sqlite3DbMallocRaw(db, sizeof(*p) );
if( pNew==0 ) return 0;
- /* Always make a copy of the span for top-level expressions in the
- ** expression list. The logic in SELECT processing that determines
- ** the names of columns in the result set needs this information */
- pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags|EXPRDUP_SPAN);
+ pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags);
pNew->pSrc = sqlite3SrcListDup(db, p->pSrc, flags);
pNew->pWhere = sqlite3ExprDup(db, p->pWhere, flags);
pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy, flags);
pNew->pHaving = sqlite3ExprDup(db, p->pHaving, flags);
@@ -58666,14 +59751,17 @@
/*
** Add a new element to the end of an expression list. If pList is
** initially NULL, then create a new expression list.
+**
+** If a memory allocation error occurs, the entire list is freed and
+** NULL is returned. If non-NULL is returned, then it is guaranteed
+** that the new entry was successfully appended.
*/
SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(
Parse *pParse, /* Parsing context */
ExprList *pList, /* List to which to append. Might be NULL */
- Expr *pExpr, /* Expression to be appended */
- Token *pName /* AS keyword for the expression */
+ Expr *pExpr /* Expression to be appended. Might be NULL */
){
sqlite3 *db = pParse->db;
if( pList==0 ){
pList = sqlite3DbMallocZero(db, sizeof(ExprList) );
@@ -58692,14 +59780,12 @@
pList->a = a;
pList->nAlloc = sqlite3DbMallocSize(db, a)/sizeof(a[0]);
}
assert( pList->a!=0 );
- if( pExpr || pName ){
+ if( 1 ){
struct ExprList_item *pItem = &pList->a[pList->nExpr++];
memset(pItem, 0, sizeof(*pItem));
- pItem->zName = sqlite3NameFromToken(db, pName);
- pItem->pExpr = pExpr;
- pItem->iAlias = 0;
+ pItem->pExpr = pExpr;
}
return pList;
no_mem:
@@ -58706,8 +59792,58 @@
/* Avoid leaking memory if malloc has failed. */
sqlite3ExprDelete(db, pExpr);
sqlite3ExprListDelete(db, pList);
return 0;
+}
+
+/*
+** Set the ExprList.a[].zName element of the most recently added item
+** on the expression list.
+**
+** pList might be NULL following an OOM error. But pName should never be
+** NULL. If a memory allocation fails, the pParse->db->mallocFailed flag
+** is set.
+*/
+SQLITE_PRIVATE void sqlite3ExprListSetName(
+ Parse *pParse, /* Parsing context */
+ ExprList *pList, /* List to which to add the span. */
+ Token *pName, /* Name to be added */
+ int dequote /* True to cause the name to be dequoted */
+){
+ assert( pList!=0 || pParse->db->mallocFailed!=0 );
+ if( pList ){
+ struct ExprList_item *pItem;
+ assert( pList->nExpr>0 );
+ pItem = &pList->a[pList->nExpr-1];
+ assert( pItem->zName==0 );
+ pItem->zName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
+ if( dequote && pItem->zName ) sqlite3Dequote(pItem->zName);
+ }
+}
+
+/*
+** Set the ExprList.a[].zSpan element of the most recently added item
+** on the expression list.
+**
+** pList might be NULL following an OOM error. But pSpan should never be
+** NULL. If a memory allocation fails, the pParse->db->mallocFailed flag
+** is set.
+*/
+SQLITE_PRIVATE void sqlite3ExprListSetSpan(
+ Parse *pParse, /* Parsing context */
+ ExprList *pList, /* List to which to add the span. */
+ ExprSpan *pSpan /* The span to be added */
+){
+ sqlite3 *db = pParse->db;
+ assert( pList!=0 || db->mallocFailed!=0 );
+ if( pList ){
+ struct ExprList_item *pItem = &pList->a[pList->nExpr-1];
+ assert( pList->nExpr>0 );
+ assert( db->mallocFailed || pItem->pExpr==pSpan->pExpr );
+ sqlite3DbFree(db, pItem->zSpan);
+ pItem->zSpan = sqlite3DbStrNDup(db, (char*)pSpan->zStart,
+ (int)(pSpan->zEnd - pSpan->zStart));
+ }
}
/*
** If the expression list pEList contains more than iLimit elements,
@@ -58737,8 +59873,9 @@
assert( pList->nExpr<=pList->nAlloc );
for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
sqlite3ExprDelete(db, pItem->pExpr);
sqlite3DbFree(db, pItem->zName);
+ sqlite3DbFree(db, pItem->zSpan);
}
sqlite3DbFree(db, pList->a);
sqlite3DbFree(db, pList);
}
@@ -58775,21 +59912,17 @@
case TK_ID:
case TK_COLUMN:
case TK_AGG_FUNCTION:
case TK_AGG_COLUMN:
-#ifndef SQLITE_OMIT_SUBQUERY
- case TK_SELECT:
- case TK_EXISTS:
- testcase( pExpr->op==TK_SELECT );
- testcase( pExpr->op==TK_EXISTS );
-#endif
testcase( pExpr->op==TK_ID );
testcase( pExpr->op==TK_COLUMN );
testcase( pExpr->op==TK_AGG_FUNCTION );
testcase( pExpr->op==TK_AGG_COLUMN );
pWalker->u.i = 0;
return WRC_Abort;
default:
+ testcase( pExpr->op==TK_SELECT ); /* selectNodeIsConstant will disallow */
+ testcase( pExpr->op==TK_EXISTS ); /* selectNodeIsConstant will disallow */
return WRC_Continue;
}
}
static int selectNodeIsConstant(Walker *pWalker, Select *NotUsed){
@@ -58849,14 +59982,15 @@
*/
SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){
int rc = 0;
if( p->flags & EP_IntValue ){
- *pValue = p->iTable;
+ *pValue = p->u.iValue;
return 1;
}
switch( p->op ){
case TK_INTEGER: {
- rc = sqlite3GetInt32((char*)p->token.z, pValue);
+ rc = sqlite3GetInt32(p->u.zToken, pValue);
+ assert( rc==0 );
break;
}
case TK_UPLUS: {
rc = sqlite3ExprIsInteger(p->pLeft, pValue);
@@ -58872,11 +60006,13 @@
}
default: break;
}
if( rc ){
+ assert( ExprHasAnyProperty(p, EP_Reduced|EP_TokenOnly)
+ || (p->flags2 & EP2_MallocedToken)==0 );
p->op = TK_INTEGER;
p->flags |= EP_IntValue;
- p->iTable = *pValue;
+ p->u.iValue = *pValue;
}
return rc;
}
@@ -58890,16 +60026,18 @@
return 0;
}
/*
-** Return true if the IN operator optimization is enabled and
-** the SELECT statement p exists and is of the
-** simple form:
-**
-** SELECT <column> FROM <table>
-**
-** If this is the case, it may be possible to use an existing table
-** or index instead of generating an epheremal table.
+** Return true if we are able to the IN operator optimization on a
+** query of the form
+**
+** x IN (SELECT ...)
+**
+** Where the SELECT... clause is as specified by the parameter to this
+** routine.
+**
+** The Select object passed in has already been preprocessed and no
+** errors have been found.
*/
#ifndef SQLITE_OMIT_SUBQUERY
static int isCandidateForInOpt(Select *p){
SrcList *pSrc;
@@ -58907,21 +60045,23 @@
Table *pTab;
if( p==0 ) return 0; /* right-hand side of IN is SELECT */
if( p->pPrior ) return 0; /* Not a compound SELECT */
if( p->selFlags & (SF_Distinct|SF_Aggregate) ){
- return 0; /* No DISTINCT keyword and no aggregate functions */
- }
- if( p->pGroupBy ) return 0; /* Has no GROUP BY clause */
+ testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
+ testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
+ return 0; /* No DISTINCT keyword and no aggregate functions */
+ }
+ assert( p->pGroupBy==0 ); /* Has no GROUP BY clause */
if( p->pLimit ) return 0; /* Has no LIMIT clause */
- if( p->pOffset ) return 0;
+ assert( p->pOffset==0 ); /* No LIMIT means no OFFSET */
if( p->pWhere ) return 0; /* Has no WHERE clause */
pSrc = p->pSrc;
assert( pSrc!=0 );
if( pSrc->nSrc!=1 ) return 0; /* Single term in FROM clause */
- if( pSrc->a[0].pSelect ) return 0; /* FROM clause is not a subquery */
+ if( pSrc->a[0].pSelect ) return 0; /* FROM is not a subquery or view */
pTab = pSrc->a[0].pTab;
- if( pTab==0 ) return 0;
- if( pTab->pSelect ) return 0; /* FROM clause is not a view */
+ if( NEVER(pTab==0) ) return 0;
+ assert( pTab->pSelect==0 ); /* FROM clause is not a view */
if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */
pEList = p->pEList;
if( pEList->nExpr!=1 ) return 0; /* One column in the result set */
if( pEList->a[0].pExpr->op!=TK_COLUMN ) return 0; /* Result is a column */
@@ -58934,47 +60074,47 @@
** It's job is to find or create a b-tree structure that may be used
** either to test for membership of the (...) set or to iterate through
** its members, skipping duplicates.
**
-** The cursor opened on the structure (database table, database index
+** The index of the cursor opened on the b-tree (database table, database index
** or ephermal table) is stored in pX->iTable before this function returns.
-** The returned value indicates the structure type, as follows:
+** The returned value of this function indicates the b-tree type, as follows:
**
** IN_INDEX_ROWID - The cursor was opened on a database table.
** IN_INDEX_INDEX - The cursor was opened on a database index.
** IN_INDEX_EPH - The cursor was opened on a specially created and
** populated epheremal table.
**
-** An existing structure may only be used if the SELECT is of the simple
+** An existing b-tree may only be used if the SELECT is of the simple
** form:
**
** SELECT <column> FROM <table>
**
-** If prNotFound parameter is 0, then the structure will be used to iterate
+** If the prNotFound parameter is 0, then the b-tree will be used to iterate
** through the set members, skipping any duplicates. In this case an
** epheremal table must be used unless the selected <column> is guaranteed
** to be unique - either because it is an INTEGER PRIMARY KEY or it
-** is unique by virtue of a constraint or implicit index.
-**
-** If the prNotFound parameter is not 0, then the structure will be used
+** has a UNIQUE constraint or UNIQUE index.
+**
+** If the prNotFound parameter is not 0, then the b-tree will be used
** for fast set membership tests. In this case an epheremal table must
** be used unless <column> is an INTEGER PRIMARY KEY or an index can
** be found with <column> as its left-most column.
**
-** When the structure is being used for set membership tests, the user
+** When the b-tree is being used for membership tests, the calling function
** needs to know whether or not the structure contains an SQL NULL
** value in order to correctly evaluate expressions like "X IN (Y, Z)".
-** If there is a chance that the structure may contain a NULL value at
+** If there is a chance that the b-tree might contain a NULL value at
** runtime, then a register is allocated and the register number written
-** to *prNotFound. If there is no chance that the structure contains a
+** to *prNotFound. If there is no chance that the b-tree contains a
** NULL value, then *prNotFound is left unchanged.
**
** If a register is allocated and its location stored in *prNotFound, then
-** its initial value is NULL. If the structure does not remain constant
-** for the duration of the query (i.e. the set is a correlated sub-select),
-** the value of the allocated register is reset to NULL each time the
-** structure is repopulated. This allows the caller to use vdbe code
-** equivalent to the following:
+** its initial value is NULL. If the b-tree does not remain constant
+** for the duration of the query (i.e. the SELECT that generates the b-tree
+** is a correlated subquery) then the value of the allocated register is
+** reset to NULL each time the b-tree is repopulated. This allows the
+** caller to use vdbe code equivalent to the following:
**
** if( register==NULL ){
** has_null = <test if data structure contains null>
** register = 1
@@ -58984,23 +60124,19 @@
** test more often than is necessary.
*/
#ifndef SQLITE_OMIT_SUBQUERY
SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
- Select *p;
- int eType = 0;
- int iTab = pParse->nTab++;
- int mustBeUnique = !prNotFound;
-
- /* The follwing if(...) expression is true if the SELECT is of the
- ** simple form:
- **
- ** SELECT <column> FROM <table>
- **
- ** If this is the case, it may be possible to use an existing table
- ** or index instead of generating an epheremal table.
+ Select *p; /* SELECT to the right of IN operator */
+ int eType = 0; /* Type of RHS table. IN_INDEX_* */
+ int iTab = pParse->nTab++; /* Cursor of the RHS table */
+ int mustBeUnique = (prNotFound==0); /* True if RHS must be unique */
+
+ /* Check to see if an existing table or index can be used to
+ ** satisfy the query. This is preferable to generating a new
+ ** ephemeral table.
*/
p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
- if( isCandidateForInOpt(p) ){
+ if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){
sqlite3 *db = pParse->db; /* Database connection */
Expr *pExpr = p->pEList->a[0].pExpr; /* Expression <column> */
int iCol = pExpr->iColumn; /* Index of column <column> */
Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */
@@ -59045,9 +60181,9 @@
int affinity_ok = (pTab->aCol[iCol].affinity==aff||aff==SQLITE_AFF_NONE);
for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){
if( (pIdx->aiColumn[0]==iCol)
- && (pReq==sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], -1, 0))
+ && sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq
&& (!mustBeUnique || (pIdx->nColumn==1 && pIdx->onError!=OE_None))
){
int iMem = ++pParse->nMem;
int iAddr;
@@ -59074,8 +60210,11 @@
}
}
if( eType==0 ){
+ /* Could not found an existing able or index to use as the RHS b-tree.
+ ** We will have to generate an ephemeral table to do the job.
+ */
int rMayHaveNull = 0;
eType = IN_INDEX_EPH;
if( prNotFound ){
*prNotFound = rMayHaveNull = ++pParse->nMem;
@@ -59106,19 +60245,31 @@
** to be of the form "<rowid> IN (?, ?, ?)", where <rowid> is a reference
** to some integer key column of a table B-Tree. In this case, use an
** intkey B-Tree to store the set of IN(...) values instead of the usual
** (slower) variable length keys B-Tree.
+**
+** If rMayHaveNull is non-zero, that means that the operation is an IN
+** (not a SELECT or EXISTS) and that the RHS might contains NULLs.
+** Furthermore, the IN is in a WHERE clause and that we really want
+** to iterate over the RHS of the IN operator in order to quickly locate
+** all corresponding LHS elements. All this routine does is initialize
+** the register given by rMayHaveNull to NULL. Calling routines will take
+** care of changing this register value to non-NULL if the RHS is NULL-free.
+**
+** If rMayHaveNull is zero, that means that the subquery is being used
+** for membership testing only. There is no need to initialize any
+** registers to indicate the presense or absence of NULLs on the RHS.
*/
#ifndef SQLITE_OMIT_SUBQUERY
SQLITE_PRIVATE void sqlite3CodeSubselect(
- Parse *pParse,
- Expr *pExpr,
- int rMayHaveNull,
- int isRowid
+ Parse *pParse, /* Parsing context */
+ Expr *pExpr, /* The IN, SELECT, or EXISTS operator */
+ int rMayHaveNull, /* Register that records whether NULLs exist in RHS */
+ int isRowid /* If true, LHS of IN operator is a rowid */
){
int testAddr = 0; /* One-time test address */
Vdbe *v = sqlite3GetVdbe(pParse);
- if( v==0 ) return;
+ if( NEVER(v==0) ) return;
sqlite3ExprCachePush(pParse);
/* This code must be run in its entirety every time it is encountered
** if any of the following is true:
@@ -59184,13 +60335,13 @@
if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){
return;
}
pEList = pExpr->x.pSelect->pEList;
- if( pEList && pEList->nExpr>0 ){
+ if( ALWAYS(pEList!=0 && pEList->nExpr>0) ){
keyInfo.aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
pEList->a[0].pExpr);
}
- }else if( pExpr->x.pList ){
+ }else if( pExpr->x.pList!=0 ){
/* Case 2: expr IN (exprlist)
**
** For each expression, build an index key from the evaluation and
** store it in the temporary table. If <expr> is a column, then use
@@ -59244,16 +60395,23 @@
break;
}
case TK_EXISTS:
- case TK_SELECT: {
- /* This has to be a scalar SELECT. Generate code to put the
+ case TK_SELECT:
+ default: {
+ /* If this has to be a scalar SELECT. Generate code to put the
** value of this select in a memory cell and record the number
- ** of the memory cell in iColumn.
- */
- static const Token one = { (u8*)"1", 0, 0, 1 };
- Select *pSel;
- SelectDest dest;
+ ** of the memory cell in iColumn. If this is an EXISTS, write
+ ** an integer 0 (not exists) or 1 (exists) into a memory cell
+ ** and record that memory cell in iColumn.
+ */
+ static const Token one = { "1", 1 }; /* Token for literal value 1 */
+ Select *pSel; /* SELECT statement to encode */
+ SelectDest dest; /* How to deal with SELECt result */
+
+ testcase( pExpr->op==TK_EXISTS );
+ testcase( pExpr->op==TK_SELECT );
+ assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
assert( ExprHasProperty(pExpr, EP_xIsSelect) );
pSel = pExpr->x.pSelect;
sqlite3SelectDestInit(&dest, 0, ++pParse->nMem);
@@ -59270,9 +60428,10 @@
pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &one);
if( sqlite3Select(pParse, pSel, &dest) ){
return;
}
- pExpr->iColumn = dest.iParm;
+ pExpr->iColumn = (i16)dest.iParm;
+ ExprSetIrreducible(pExpr);
break;
}
}
@@ -59303,13 +60462,10 @@
** The z[] string will probably not be zero-terminated. But the
** z[n] character is guaranteed to be something that does not look
** like the continuation of the number.
*/
-static void codeReal(Vdbe *v, const char *z, int n, int negateFlag, int iMem){
- assert( z || v==0 || sqlite3VdbeDb(v)->mallocFailed );
- assert( !z || !sqlite3Isdigit(z[n]) );
- UNUSED_PARAMETER(n);
- if( z ){
+static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){
+ if( ALWAYS(z!=0) ){
double value;
char *zV;
sqlite3AtoF(z, &value);
if( sqlite3IsNaN(value) ){
@@ -59331,29 +60487,24 @@
** z[n] character is guaranteed to be something that does not look
** like the continuation of the number.
*/
static void codeInteger(Vdbe *v, Expr *pExpr, int negFlag, int iMem){
- const char *z;
if( pExpr->flags & EP_IntValue ){
- int i = pExpr->iTable;
+ int i = pExpr->u.iValue;
if( negFlag ) i = -i;
sqlite3VdbeAddOp2(v, OP_Integer, i, iMem);
- }else if( (z = (char*)pExpr->token.z)!=0 ){
- int i;
- int n = pExpr->token.n;
- assert( !sqlite3Isdigit(z[n]) );
- if( sqlite3GetInt32(z, &i) ){
- if( negFlag ) i = -i;
- sqlite3VdbeAddOp2(v, OP_Integer, i, iMem);
- }else if( sqlite3FitsIn64Bits(z, negFlag) ){
+ }else{
+ const char *z = pExpr->u.zToken;
+ assert( z!=0 );
+ if( sqlite3FitsIn64Bits(z, negFlag) ){
i64 value;
char *zV;
sqlite3Atoi64(z, &value);
if( negFlag ) value = -value;
zV = dup8bytes(v, (char*)&value);
sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64);
}else{
- codeReal(v, z, n, negFlag, iMem);
+ codeReal(v, z, negFlag, iMem);
}
}
}
@@ -59379,8 +60530,11 @@
int minLru;
int idxLru;
struct yColCache *p;
+ assert( iReg>0 ); /* Register numbers are always positive */
+ assert( iCol>=-1 && iCol<32768 ); /* Finite column numbers */
+
/* First replace any existing entry */
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
if( p->iReg && p->iTable==iTab && p->iColumn==iCol ){
cacheEntryClear(pParse, p);
@@ -59390,9 +60544,8 @@
p->lru = pParse->iCacheCnt++;
return;
}
}
- if( iReg<=0 ) return;
/* Find an empty slot and replace it */
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
if( p->iReg==0 ){
@@ -59415,9 +60568,9 @@
idxLru = i;
minLru = p->lru;
}
}
- if( idxLru>=0 ){
+ if( ALWAYS(idxLru>=0) ){
p = &pParse->aColCache[idxLru];
p->iLevel = pParse->iCacheLevel;
p->iTable = iTab;
p->iColumn = iCol;
@@ -59517,12 +60670,8 @@
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
if( p->iReg>0 && p->iTable==iTable && p->iColumn==iColumn
&& (!p->affChange || allowAffChng) ){
-#if 0
- sqlite3VdbeAddOp0(v, OP_Noop);
- VdbeComment((v, "OPT: tab%d.col%d -> r%d", iTable, iColumn, p->iReg));
-#endif
p->lru = pParse->iCacheCnt++;
sqlite3ExprCachePinRegister(pParse, p->iReg);
return p->iReg;
}
@@ -59529,11 +60678,9 @@
}
assert( v!=0 );
if( iColumn<0 ){
sqlite3VdbeAddOp2(v, OP_Rowid, iTable, iReg);
- }else if( pTab==0 ){
- sqlite3VdbeAddOp3(v, OP_Column, iTable, iColumn, iReg);
- }else{
+ }else if( ALWAYS(pTab!=0) ){
int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;
sqlite3VdbeAddOp3(v, op, iTable, iColumn, iReg);
sqlite3ColumnDefault(v, pTab, iColumn);
#ifndef SQLITE_OMIT_FLOATING_POINT
@@ -59583,9 +60730,9 @@
*/
SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
int i;
struct yColCache *p;
- if( iFrom==iTo ) return;
+ if( NEVER(iFrom==iTo) ) return;
sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg);
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
int x = p->iReg;
if( x>=iFrom && x<iFrom+nReg ){
@@ -59599,9 +60746,9 @@
** over to iTo..iTo+nReg-1.
*/
SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse *pParse, int iFrom, int iTo, int nReg){
int i;
- if( iFrom==iTo ) return;
+ if( NEVER(iFrom==iTo) ) return;
for(i=0; i<nReg; i++){
sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, iFrom+i, iTo+i);
}
}
@@ -59625,17 +60772,17 @@
** the registers in the nReg registers beginning with iReg, then
** convert the last instruction from OP_SCopy to OP_Copy.
*/
SQLITE_PRIVATE void sqlite3ExprHardCopy(Parse *pParse, int iReg, int nReg){
- int addr;
VdbeOp *pOp;
Vdbe *v;
+ assert( pParse->db->mallocFailed==0 );
v = pParse->pVdbe;
- addr = sqlite3VdbeCurrentAddr(v);
- pOp = sqlite3VdbeGetOp(v, addr-1);
- assert( pOp || pParse->db->mallocFailed );
- if( pOp && pOp->opcode==OP_SCopy && pOp->p1>=iReg && pOp->p1<iReg+nReg ){
+ assert( v!=0 );
+ pOp = sqlite3VdbeGetOp(v, -1);
+ assert( pOp!=0 );
+ if( pOp->opcode==OP_SCopy && pOp->p1>=iReg && pOp->p1<iReg+nReg ){
pOp->opcode = OP_Copy;
}
}
@@ -59704,14 +60851,15 @@
int inReg = target; /* Results stored in register inReg */
int regFree1 = 0; /* If non-zero free this temporary register */
int regFree2 = 0; /* If non-zero free this temporary register */
int r1, r2, r3, r4; /* Various register numbers */
- sqlite3 *db;
-
- db = pParse->db;
- assert( v!=0 || db->mallocFailed );
+ sqlite3 *db = pParse->db; /* The database connection */
+
assert( target>0 && target<=pParse->nMem );
- if( v==0 ) return 0;
+ if( v==0 ){
+ assert( pParse->db->mallocFailed );
+ return 0;
+ }
if( pExpr==0 ){
op = TK_NULL;
}else{
@@ -59749,14 +60897,15 @@
codeInteger(v, pExpr, 0, target);
break;
}
case TK_FLOAT: {
- codeReal(v, (char*)pExpr->token.z, pExpr->token.n, 0, target);
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ codeReal(v, pExpr->u.zToken, 0, target);
break;
}
case TK_STRING: {
- sqlite3VdbeAddOp4(v, OP_String8, 0, target, 0,
- (char*)pExpr->token.z, pExpr->token.n);
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ sqlite3VdbeAddOp4(v, OP_String8, 0, target, 0, pExpr->u.zToken, 0);
break;
}
case TK_NULL: {
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
@@ -59766,25 +60915,26 @@
case TK_BLOB: {
int n;
const char *z;
char *zBlob;
- assert( pExpr->token.n>=3 );
- assert( pExpr->token.z[0]=='x' || pExpr->token.z[0]=='X' );
- assert( pExpr->token.z[1]=='\'' );
- assert( pExpr->token.z[pExpr->token.n-1]=='\'' );
- n = pExpr->token.n - 3;
- z = (char*)pExpr->token.z + 2;
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' );
+ assert( pExpr->u.zToken[1]=='\'' );
+ z = &pExpr->u.zToken[2];
+ n = sqlite3Strlen30(z) - 1;
+ assert( z[n]=='\'' );
zBlob = sqlite3HexToBlob(sqlite3VdbeDb(v), z, n);
sqlite3VdbeAddOp4(v, OP_Blob, n/2, target, 0, zBlob, P4_DYNAMIC);
break;
}
#endif
case TK_VARIABLE: {
- int iPrior;
VdbeOp *pOp;
- if( pExpr->token.n<=1
- && (iPrior = sqlite3VdbeCurrentAddr(v)-1)>=0
- && (pOp = sqlite3VdbeGetOp(v, iPrior))->opcode==OP_Variable
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ assert( pExpr->u.zToken!=0 );
+ assert( pExpr->u.zToken[0]!=0 );
+ if( pExpr->u.zToken[1]==0
+ && (pOp = sqlite3VdbeGetOp(v, -1))->opcode==OP_Variable
&& pOp->p1+pOp->p3==pExpr->iTable
&& pOp->p2+pOp->p3==target
&& pOp->p4.z==0
){
@@ -59795,10 +60945,10 @@
*/
pOp->p3++;
}else{
sqlite3VdbeAddOp3(v, OP_Variable, pExpr->iTable, target, 1);
- if( pExpr->token.n>1 ){
- sqlite3VdbeChangeP4(v, -1, (char*)pExpr->token.z, pExpr->token.n);
+ if( pExpr->u.zToken[1]!=0 ){
+ sqlite3VdbeChangeP4(v, -1, pExpr->u.zToken, 0);
}
}
break;
}
@@ -59814,9 +60964,10 @@
case TK_CAST: {
/* Expressions of the form: CAST(pLeft AS token) */
int aff, to_op;
inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
- aff = sqlite3AffinityType(&pExpr->token);
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ aff = sqlite3AffinityType(pExpr->u.zToken);
to_op = aff - SQLITE_AFF_TEXT + OP_ToText;
assert( to_op==OP_ToText || aff!=SQLITE_AFF_TEXT );
assert( to_op==OP_ToBlob || aff!=SQLITE_AFF_NONE );
assert( to_op==OP_ToNumeric || aff!=SQLITE_AFF_NUMERIC );
@@ -59907,9 +61058,10 @@
case TK_UMINUS: {
Expr *pLeft = pExpr->pLeft;
assert( pLeft );
if( pLeft->op==TK_FLOAT ){
- codeReal(v, (char*)pLeft->token.z, pLeft->token.n, 1, target);
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ codeReal(v, pLeft->u.zToken, 1, target);
}else if( pLeft->op==TK_INTEGER ){
codeInteger(v, pLeft, 1, target);
}else{
regFree1 = r1 = sqlite3GetTempReg(pParse);
@@ -59950,10 +61102,10 @@
}
case TK_AGG_FUNCTION: {
AggInfo *pInfo = pExpr->pAggInfo;
if( pInfo==0 ){
- sqlite3ErrorMsg(pParse, "misuse of aggregate: %T",
- &pExpr->span);
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken);
}else{
inReg = pInfo->aFunc[pExpr->iAgg].iMem;
}
break;
@@ -59972,16 +61124,17 @@
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
testcase( op==TK_CONST_FUNC );
testcase( op==TK_FUNCTION );
- if( ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_SpanToken) ){
+ if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ){
pFarg = 0;
}else{
pFarg = pExpr->x.pList;
}
nFarg = pFarg ? pFarg->nExpr : 0;
- zId = (char*)pExpr->token.z;
- nId = pExpr->token.n;
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ zId = pExpr->u.zToken;
+ nId = sqlite3Strlen30(zId);
pDef = sqlite3FindFunction(db, zId, nId, nFarg, enc, 0);
assert( pDef!=0 );
if( pFarg ){
r1 = sqlite3GetTempRange(pParse, nFarg);
@@ -60007,10 +61160,10 @@
}else if( nFarg>0 ){
pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr);
}
#endif
- for(i=0; i<nFarg && i<32; i++){
- if( sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){
+ for(i=0; i<nFarg; i++){
+ if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){
constMask |= (1<<i);
}
if( (pDef->flags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){
pColl = sqlite3ExprCollSeq(pParse, pFarg->a[i].pExpr);
@@ -60033,11 +61186,9 @@
case TK_EXISTS:
case TK_SELECT: {
testcase( op==TK_EXISTS );
testcase( op==TK_SELECT );
- if( pExpr->iColumn==0 ){
- sqlite3CodeSubselect(pParse, pExpr, 0, 0);
- }
+ sqlite3CodeSubselect(pParse, pExpr, 0, 0);
inReg = pExpr->iColumn;
break;
}
case TK_IN: {
@@ -60190,9 +61341,9 @@
** The result of the expression is the Ri for the first matching Ei,
** or if there is no matching Ei, the ELSE term Y, or if there is
** no ELSE term, NULL.
*/
- case TK_CASE: {
+ default: assert( op==TK_CASE ); {
int endLabel; /* GOTO label for end of CASE stmt */
int nextCase; /* GOTO label for next WHEN clause */
int nExpr; /* 2x number of WHEN terms */
int i; /* Loop counter */
@@ -60212,9 +61363,10 @@
nExpr = pEList->nExpr;
endLabel = sqlite3VdbeMakeLabel(v);
if( (pX = pExpr->pLeft)!=0 ){
cacheX = *pX;
- testcase( pX->op==TK_COLUMN || pX->op==TK_REGISTER );
+ testcase( pX->op==TK_COLUMN );
+ testcase( pX->op==TK_REGISTER );
cacheX.iTable = sqlite3ExprCodeTemp(pParse, pX, ®Free1);
testcase( regFree1==0 );
cacheX.op = TK_REGISTER;
opCompare.op = TK_EQ;
@@ -60229,9 +61381,9 @@
}else{
pTest = aListelem[i].pExpr;
}
nextCase = sqlite3VdbeMakeLabel(v);
- testcase( pTest->op==TK_COLUMN || pTest->op==TK_REGISTER );
+ testcase( pTest->op==TK_COLUMN );
sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL);
testcase( aListelem[i+1].pExpr->op==TK_COLUMN );
testcase( aListelem[i+1].pExpr->op==TK_REGISTER );
sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target);
@@ -60261,10 +61413,11 @@
if( pExpr->affinity!=OE_Ignore ){
assert( pExpr->affinity==OE_Rollback ||
pExpr->affinity == OE_Abort ||
pExpr->affinity == OE_Fail );
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, pExpr->affinity, 0,
- (char*)pExpr->token.z, pExpr->token.n);
+ pExpr->u.zToken, 0);
} else {
assert( pExpr->affinity == OE_Ignore );
sqlite3VdbeAddOp2(v, OP_ContextPop, 0, 0);
sqlite3VdbeAddOp2(v, OP_Goto, 0, pParse->trigStack->ignoreJump);
@@ -60333,9 +61486,15 @@
Vdbe *v = pParse->pVdbe;
int inReg;
inReg = sqlite3ExprCode(pParse, pExpr, target);
assert( target>0 );
- if( pExpr->op!=TK_REGISTER ){
+ /* This routine is called for terms to INSERT or UPDATE. And the only
+ ** other place where expressions can be converted into TK_REGISTER is
+ ** in WHERE clause processing. So as currently implemented, there is
+ ** no way for a TK_REGISTER to exist here. But it seems prudent to
+ ** keep the ALWAYS() in case the conditions above change with future
+ ** modifications or enhancements. */
+ if( ALWAYS(pExpr->op!=TK_REGISTER) ){
int iMem;
iMem = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Copy, inReg, iMem);
pExpr->iTable = iMem;
@@ -60390,12 +61549,12 @@
** register. */
return 0;
}
case TK_UMINUS: {
- if( p->pLeft->op==TK_FLOAT || p->pLeft->op==TK_INTEGER ){
- return 0;
- }
- break;
+ if( p->pLeft->op==TK_FLOAT || p->pLeft->op==TK_INTEGER ){
+ return 0;
+ }
+ break;
}
default: {
break;
}
@@ -60412,9 +61571,9 @@
static int evalConstExpr(Walker *pWalker, Expr *pExpr){
Parse *pParse = pWalker->pParse;
switch( pExpr->op ){
case TK_REGISTER: {
- return 1;
+ return WRC_Prune;
}
case TK_FUNCTION:
case TK_AGG_FUNCTION:
case TK_CONST_FUNC: {
@@ -60427,9 +61586,9 @@
if( pList ){
int i = pList->nExpr;
struct ExprList_item *pItem = pList->a;
for(; i>0; i--, pItem++){
- if( pItem->pExpr ) pItem->pExpr->flags |= EP_FixedDest;
+ if( ALWAYS(pItem->pExpr) ) pItem->pExpr->flags |= EP_FixedDest;
}
}
break;
}
@@ -60437,9 +61596,9 @@
if( isAppropriateForFactoring(pExpr) ){
int r1 = ++pParse->nMem;
int r2;
r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
- if( r1!=r2 ) sqlite3ReleaseTempReg(pParse, r1);
+ if( NEVER(r1!=r2) ) sqlite3ReleaseTempReg(pParse, r1);
pExpr->op = TK_REGISTER;
pExpr->iTable = r2;
return WRC_Prune;
}
@@ -60486,9 +61645,9 @@
}
}else{
sqlite3ExprCode(pParse, pItem->pExpr, target+i);
}
- if( doHardCopy ){
+ if( doHardCopy && !pParse->db->mallocFailed ){
sqlite3ExprHardCopy(pParse, target, n);
}
}
return n;
@@ -60515,9 +61674,10 @@
int regFree2 = 0;
int r1, r2;
assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
- if( v==0 || pExpr==0 ) return;
+ if( NEVER(v==0) ) return; /* Existance of VDBE checked by caller */
+ if( NEVER(pExpr==0) ) return; /* No way this can happen */
op = pExpr->op;
switch( op ){
case TK_AND: {
int d2 = sqlite3VdbeMakeLabel(v);
@@ -60639,9 +61799,10 @@
int regFree2 = 0;
int r1, r2;
assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
- if( v==0 || pExpr==0 ) return;
+ if( NEVER(v==0) ) return; /* Existance of VDBE checked by caller */
+ if( pExpr==0 ) return;
/* The value of pExpr->op and op are related as follows:
**
** pExpr->op op
@@ -60787,8 +61948,10 @@
int i;
if( pA==0||pB==0 ){
return pB==pA;
}
+ assert( !ExprHasAnyProperty(pA, EP_TokenOnly|EP_Reduced) );
+ assert( !ExprHasAnyProperty(pB, EP_TokenOnly|EP_Reduced) );
if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){
return 0;
}
if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 0;
@@ -60807,12 +61970,15 @@
return 0;
}
if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 0;
- if( pA->op!=TK_COLUMN && pA->token.z ){
- if( pB->token.z==0 ) return 0;
- if( pB->token.n!=pA->token.n ) return 0;
- if( sqlite3StrNICmp((char*)pA->token.z,(char*)pB->token.z,pB->token.n)!=0 ){
+ if( ExprHasProperty(pA, EP_IntValue) ){
+ if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){
+ return 0;
+ }
+ }else if( pA->op!=TK_COLUMN && pA->u.zToken ){
+ if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 0;
+ if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ){
return 0;
}
}
return 1;
@@ -60873,12 +62039,13 @@
testcase( pExpr->op==TK_AGG_COLUMN );
testcase( pExpr->op==TK_COLUMN );
/* Check to see if the column is in one of the tables in the FROM
** clause of the aggregate query */
- if( pSrcList ){
+ if( ALWAYS(pSrcList!=0) ){
struct SrcList_item *pItem = pSrcList->a;
for(i=0; i<pSrcList->nSrc; i++, pItem++){
struct AggInfo_col *pCol;
+ assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
if( pExpr->iTable==pItem->iCursor ){
/* If we reach this point, it means that pExpr refers to a table
** that is in the FROM clause of the aggregate query.
**
@@ -60925,11 +62092,12 @@
** because it was there before or because we just created it).
** Convert the pExpr to be a TK_AGG_COLUMN referring to that
** pAggInfo->aCol[] entry.
*/
+ ExprSetIrreducible(pExpr);
pExpr->pAggInfo = pAggInfo;
pExpr->op = TK_AGG_COLUMN;
- pExpr->iAgg = k;
+ pExpr->iAgg = (i16)k;
break;
} /* endif pExpr->iTable==pItem->iCursor */
} /* end loop over pSrcList */
}
@@ -60957,10 +62125,11 @@
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
pItem = &pAggInfo->aFunc[i];
pItem->pExpr = pExpr;
pItem->iMem = ++pParse->nMem;
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
pItem->pFunc = sqlite3FindFunction(pParse->db,
- (char*)pExpr->token.z, pExpr->token.n,
+ pExpr->u.zToken, sqlite3Strlen30(pExpr->u.zToken),
pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0);
if( pExpr->flags & EP_Distinct ){
pItem->iDistinct = pParse->nTab++;
}else{
@@ -60969,9 +62138,11 @@
}
}
/* Make pExpr point to the appropriate pAggInfo->aFunc[] entry
*/
- pExpr->iAgg = i;
+ assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
+ ExprSetIrreducible(pExpr);
+ pExpr->iAgg = (i16)i;
pExpr->pAggInfo = pAggInfo;
return WRC_Prune;
}
}
@@ -61002,8 +62173,9 @@
Walker w;
w.xExprCallback = analyzeAggregate;
w.xSelectCallback = analyzeAggregatesInSelect;
w.u.pNC = pNC;
+ assert( pNC->pSrcList!=0 );
sqlite3WalkExpr(&w, pExpr);
}
/*
@@ -61092,9 +62264,9 @@
*************************************************************************
** This file contains C code routines that used to generate VDBE code
** that implements the ALTER TABLE command.
**
-** $Id: alter.c,v 1.57 2009/04/16 16:30:18 drh Exp $
+** $Id: alter.c,v 1.61 2009/06/03 11:25:07 danielk1977 Exp $
*/
/*
** The code in this file only exists if we are not omitting the
@@ -61145,9 +62317,9 @@
return;
}
/* Store the token that zCsr points to in tname. */
- tname.z = zCsr;
+ tname.z = (char*)zCsr;
tname.n = len;
/* Advance zCsr to the next token. Store that token type in 'token',
** and its length in 'len' (to be used next iteration of this loop).
@@ -61158,9 +62330,9 @@
} while( token==TK_SPACE );
assert( len>0 );
} while( token!=TK_LP && token!=TK_USING );
- zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", tname.z - zSql, zSql,
+ zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql,
zTableName, tname.z+tname.n);
sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
}
}
@@ -61204,9 +62376,9 @@
return;
}
/* Store the token that zCsr points to in tname. */
- tname.z = zCsr;
+ tname.z = (char*)zCsr;
tname.n = len;
/* Advance zCsr to the next token. Store that token type in 'token',
** and its length in 'len' (to be used next iteration of this loop).
@@ -61234,9 +62406,9 @@
/* Variable tname now contains the token that is the old table-name
** in the CREATE TRIGGER statement.
*/
- zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", tname.z - zSql, zSql,
+ zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql,
zTableName, tname.z+tname.n);
sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
}
}
@@ -61506,8 +62678,33 @@
}
/*
+** Generate code to make sure the file format number is at least minFormat.
+** The generated code will increase the file format number if necessary.
+*/
+SQLITE_PRIVATE void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){
+ Vdbe *v;
+ v = sqlite3GetVdbe(pParse);
+ /* The VDBE should have been allocated before this routine is called.
+ ** If that allocation failed, we would have quit before reaching this
+ ** point */
+ if( ALWAYS(v) ){
+ int r1 = sqlite3GetTempReg(pParse);
+ int r2 = sqlite3GetTempReg(pParse);
+ int j1;
+ sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT);
+ sqlite3VdbeUsesBtree(v, iDb);
+ sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2);
+ j1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1);
+ sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, r2);
+ sqlite3VdbeJumpHere(v, j1);
+ sqlite3ReleaseTempReg(pParse, r1);
+ sqlite3ReleaseTempReg(pParse, r2);
+ }
+}
+
+/*
** This function is called after an "ALTER TABLE ... ADD" statement
** has been parsed. Argument pColDef contains the text of the new
** column definition.
**
@@ -61690,8 +62887,9 @@
pCol->zName = sqlite3DbStrDup(db, pCol->zName);
pCol->zColl = 0;
pCol->zType = 0;
pCol->pDflt = 0;
+ pCol->zDflt = 0;
}
pNew->pSchema = db->aDb[iDb].pSchema;
pNew->addColOffset = pTab->addColOffset;
pNew->nRef = 1;
@@ -62156,9 +63354,9 @@
**
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
**
-** $Id: attach.c,v 1.90 2009/05/01 06:19:21 danielk1977 Exp $
+** $Id: attach.c,v 1.93 2009/05/31 21:21:41 drh Exp $
*/
#ifndef SQLITE_OMIT_ATTACH
/*
@@ -62185,9 +63383,9 @@
if( pExpr ){
if( pExpr->op!=TK_ID ){
rc = sqlite3ResolveExprNames(pName, pExpr);
if( rc==SQLITE_OK && !sqlite3ExprIsConstant(pExpr) ){
- sqlite3ErrorMsg(pName->pParse, "invalid name: \"%T\"", &pExpr->span);
+ sqlite3ErrorMsg(pName->pParse, "invalid name: \"%s\"", pExpr->u.zToken);
return SQLITE_ERROR;
}
}else{
pExpr->op = TK_STRING;
@@ -62442,23 +63640,8 @@
Vdbe *v;
sqlite3* db = pParse->db;
int regArgs;
-#ifndef SQLITE_OMIT_AUTHORIZATION
- assert( db->mallocFailed || pAuthArg );
- if( pAuthArg ){
- char *zAuthArg = sqlite3NameFromToken(db, &pAuthArg->span);
- if( !zAuthArg ){
- goto attach_end;
- }
- rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0);
- sqlite3DbFree(db, zAuthArg);
- if(rc!=SQLITE_OK ){
- goto attach_end;
- }
- }
-#endif /* SQLITE_OMIT_AUTHORIZATION */
-
memset(&sName, 0, sizeof(NameContext));
sName.pParse = pParse;
if(
@@ -62468,8 +63651,22 @@
){
pParse->nErr++;
goto attach_end;
}
+
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ if( pAuthArg ){
+ char *zAuthArg = pAuthArg->u.zToken;
+ if( NEVER(zAuthArg==0) ){
+ goto attach_end;
+ }
+ rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0);
+ if(rc!=SQLITE_OK ){
+ goto attach_end;
+ }
+ }
+#endif /* SQLITE_OMIT_AUTHORIZATION */
+
v = sqlite3GetVdbe(pParse);
regArgs = sqlite3GetTempRange(pParse, 4);
sqlite3ExprCode(pParse, pFilename, regArgs);
@@ -62631,9 +63828,9 @@
DbFixer *pFix, /* Context of the fixation */
Expr *pExpr /* The expression to be fixed to one database */
){
while( pExpr ){
- if( ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_SpanToken) ) break;
+ if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ) break;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1;
}else{
if( sqlite3FixExprList(pFix, pExpr->x.pList) ) return 1;
@@ -62944,9 +64141,9 @@
** BEGIN TRANSACTION
** COMMIT
** ROLLBACK
**
-** $Id: build.c,v 1.537 2009/05/06 18:42:21 drh Exp $
+** $Id: build.c,v 1.549 2009/06/03 11:25:07 danielk1977 Exp $
*/
/*
** This routine is called when a new SQL statement is beginning to
@@ -62989,12 +64186,9 @@
int i;
int nBytes;
TableLock *p;
- if( iDb<0 ){
- return;
- }
-
+ assert( iDb>=0 );
for(i=0; i<pParse->nTableLock; i++){
p = &pParse->aTableLock[i];
if( p->iDb==iDb && p->iTab==iTab ){
p->isWriteLock = (p->isWriteLock || isWriteLock);
@@ -63024,11 +64218,10 @@
static void codeTableLocks(Parse *pParse){
int i;
Vdbe *pVdbe;
- if( 0==(pVdbe = sqlite3GetVdbe(pParse)) ){
- return;
- }
+ pVdbe = sqlite3GetVdbe(pParse);
+ assert( pVdbe!=0 ); /* sqlite3GetVdbe cannot fail: VDBE already allocated */
for(i=0; i<pParse->nTableLock; i++){
TableLock *p = &pParse->aTableLock[i];
int p1 = p->iDb;
@@ -63106,9 +64299,9 @@
/* Get the VDBE program ready for execution
*/
- if( v && pParse->nErr==0 && !db->mallocFailed ){
+ if( v && ALWAYS(pParse->nErr==0) && !db->mallocFailed ){
#ifdef SQLITE_DEBUG
FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;
sqlite3VdbeTrace(v, trace);
#endif
@@ -63248,13 +64441,11 @@
int nName = sqlite3Strlen30(zName);
for(i=OMIT_TEMPDB; i<db->nDb; i++){
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
Schema *pSchema = db->aDb[j].pSchema;
+ assert( pSchema );
if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue;
- assert( pSchema || (j==1 && !db->aDb[1].pBt) );
- if( pSchema ){
- p = sqlite3HashFind(&pSchema->idxHash, zName, nName);
- }
+ p = sqlite3HashFind(&pSchema->idxHash, zName, nName);
if( p ) break;
}
return p;
}
@@ -63263,8 +64454,9 @@
** Reclaim the memory used by an index
*/
static void freeIndex(Index *p){
sqlite3 *db = p->pTable->dbMem;
+ /* testcase( db==0 ); */
sqlite3DbFree(db, p->zColAff);
sqlite3DbFree(db, p);
}
@@ -63298,15 +64490,21 @@
Hash *pHash = &db->aDb[iDb].pSchema->idxHash;
len = sqlite3Strlen30(zIdxName);
pIndex = sqlite3HashInsert(pHash, zIdxName, len, 0);
- if( pIndex ){
+ /* Justification of ALWAYS(): This routine is only called from the
+ ** OP_DropIndex opcode. And there is no way that opcode will ever run
+ ** unless the corresponding index is in the symbol table. */
+ if( ALWAYS(pIndex) ){
if( pIndex->pTable->pIndex==pIndex ){
pIndex->pTable->pIndex = pIndex->pNext;
}else{
Index *p;
- for(p=pIndex->pTable->pIndex; p && p->pNext!=pIndex; p=p->pNext){}
- if( p && p->pNext==pIndex ){
+ /* Justification of ALWAYS(); The index must be on the list of
+ ** indices. */
+ p = pIndex->pTable->pIndex;
+ while( ALWAYS(p) && p->pNext!=pIndex ){ p = p->pNext; }
+ if( ALWAYS(p && p->pNext==pIndex) ){
p->pNext = pIndex->pNext;
}
}
freeIndex(pIndex);
@@ -63349,15 +64547,8 @@
** opportunity to do this here since we have just deleted all of the
** schema hash tables and therefore do not have to make any changes
** to any of those tables.
*/
- for(i=0; i<db->nDb; i++){
- struct Db *pDb = &db->aDb[i];
- if( pDb->pBt==0 ){
- if( pDb->pAux && pDb->xFreeAux ) pDb->xFreeAux(pDb->pAux);
- pDb->pAux = 0;
- }
- }
for(i=j=2; i<db->nDb; i++){
struct Db *pDb = &db->aDb[i];
if( pDb->pBt==0 ){
sqlite3DbFree(db, pDb->zName);
@@ -63391,13 +64582,15 @@
static void sqliteResetColumnNames(Table *pTable){
int i;
Column *pCol;
sqlite3 *db = pTable->dbMem;
+ testcase( db==0 );
assert( pTable!=0 );
if( (pCol = pTable->aCol)!=0 ){
for(i=0; i<pTable->nCol; i++, pCol++){
sqlite3DbFree(db, pCol->zName);
sqlite3ExprDelete(db, pCol->pDflt);
+ sqlite3DbFree(db, pCol->zDflt);
sqlite3DbFree(db, pCol->zType);
sqlite3DbFree(db, pCol->zColl);
}
sqlite3DbFree(db, pTable->aCol);
@@ -63421,8 +64614,9 @@
sqlite3 *db;
if( pTable==0 ) return;
db = pTable->dbMem;
+ testcase( db==0 );
/* Do not delete the table until the reference count reaches zero. */
pTable->nRef--;
if( pTable->nRef>0 ){
@@ -63493,9 +64687,9 @@
SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3 *db, Token *pName){
char *zName;
if( pName ){
zName = sqlite3DbStrNDup(db, (char*)pName->z, pName->n);
- if( pName->quoted ) sqlite3Dequote(zName);
+ sqlite3Dequote(zName);
}else{
zName = 0;
}
return zName;
@@ -63575,9 +64769,9 @@
){
int iDb; /* Database holding the object */
sqlite3 *db = pParse->db;
- if( pName2 && pName2->n>0 ){
+ if( ALWAYS(pName2!=0) && pName2->n>0 ){
if( db->init.busy ) {
sqlite3ErrorMsg(pParse, "corrupt database");
pParse->nErr++;
return -1;
@@ -63740,10 +64934,10 @@
pTable->zName = zName;
pTable->iPKey = -1;
pTable->pSchema = db->aDb[iDb].pSchema;
pTable->nRef = 1;
- pTable->dbMem = db->lookaside.bEnabled ? db : 0;
- if( pParse->pNewTable ) sqlite3DeleteTable(pParse->pNewTable);
+ pTable->dbMem = 0;
+ assert( pParse->pNewTable==0 );
pParse->pNewTable = pTable;
/* If this is the magic sqlite_sequence table used by autoincrement,
** then record a pointer to this table in the main database structure
@@ -63780,17 +64974,17 @@
*/
reg1 = pParse->regRowid = ++pParse->nMem;
reg2 = pParse->regRoot = ++pParse->nMem;
reg3 = ++pParse->nMem;
- sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, 1); /* file_format */
+ sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT);
sqlite3VdbeUsesBtree(v, iDb);
j1 = sqlite3VdbeAddOp1(v, OP_If, reg3);
fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ?
1 : SQLITE_MAX_FILE_FORMAT;
sqlite3VdbeAddOp2(v, OP_Integer, fileFormat, reg3);
- sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, 1, reg3);
+ sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, reg3);
sqlite3VdbeAddOp2(v, OP_Integer, ENC(db), reg3);
- sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, 4, reg3);
+ sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_TEXT_ENCODING, reg3);
sqlite3VdbeJumpHere(v, j1);
/* This just creates a place-holder record in the sqlite_master table.
** The record created does not contain anything yet. It will be replaced
@@ -63897,12 +65091,11 @@
** the column currently under construction.
*/
SQLITE_PRIVATE void sqlite3AddNotNull(Parse *pParse, int onError){
Table *p;
- int i;
- if( (p = pParse->pNewTable)==0 ) return;
- i = p->nCol-1;
- if( i>=0 ) p->aCol[i].notNull = (u8)onError;
+ p = pParse->pNewTable;
+ if( p==0 || NEVER(p->nCol<1) ) return;
+ p->aCol[p->nCol-1].notNull = (u8)onError;
}
/*
** Scan the column type name zType (length nType) and return the
@@ -63928,16 +65121,14 @@
**
** If none of the substrings in the above table are found,
** SQLITE_AFF_NUMERIC is returned.
*/
-SQLITE_PRIVATE char sqlite3AffinityType(const Token *pType){
+SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn){
u32 h = 0;
char aff = SQLITE_AFF_NUMERIC;
- const unsigned char *zIn = pType->z;
- const unsigned char *zEnd = &pType->z[pType->n];
-
- while( zIn!=zEnd ){
- h = (h<<8) + sqlite3UpperToLower[*zIn];
+
+ if( zIn ) while( zIn[0] ){
+ h = (h<<8) + sqlite3UpperToLower[(*zIn)&0xff];
zIn++;
if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){ /* CHAR */
aff = SQLITE_AFF_TEXT;
}else if( h==(('c'<<24)+('l'<<16)+('o'<<8)+'b') ){ /* CLOB */
@@ -63977,20 +65168,16 @@
** in zType.
*/
SQLITE_PRIVATE void sqlite3AddColumnType(Parse *pParse, Token *pType){
Table *p;
- int i;
Column *pCol;
- sqlite3 *db;
-
- if( (p = pParse->pNewTable)==0 ) return;
- i = p->nCol-1;
- if( i<0 ) return;
- pCol = &p->aCol[i];
- db = pParse->db;
- sqlite3DbFree(db, pCol->zType);
- pCol->zType = sqlite3NameFromToken(db, pType);
- pCol->affinity = sqlite3AffinityType(pType);
+
+ p = pParse->pNewTable;
+ if( p==0 || NEVER(p->nCol<1) ) return;
+ pCol = &p->aCol[p->nCol-1];
+ assert( pCol->zType==0 );
+ pCol->zType = sqlite3NameFromToken(pParse->db, pType);
+ pCol->affinity = sqlite3AffinityType(pCol->zType);
}
/*
** The expression is the default value for the most recently added column
@@ -64001,15 +65188,16 @@
**
** This routine is called by the parser while in the middle of
** parsing a CREATE TABLE statement.
*/
-SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse *pParse, Expr *pExpr){
+SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse *pParse, ExprSpan *pSpan){
Table *p;
Column *pCol;
sqlite3 *db = pParse->db;
- if( (p = pParse->pNewTable)!=0 ){
+ p = pParse->pNewTable;
+ if( p!=0 ){
pCol = &(p->aCol[p->nCol-1]);
- if( !sqlite3ExprIsConstantOrFunction(pExpr) ){
+ if( !sqlite3ExprIsConstantOrFunction(pSpan->pExpr) ){
sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
pCol->zName);
}else{
/* A copy of pExpr is used instead of the original, as pExpr contains
@@ -64016,12 +65204,15 @@
** tokens that point to volatile memory. The 'span' of the expression
** is required by pragma table_info.
*/
sqlite3ExprDelete(db, pCol->pDflt);
- pCol->pDflt = sqlite3ExprDup(db, pExpr, EXPRDUP_REDUCE|EXPRDUP_SPAN);
- }
- }
- sqlite3ExprDelete(db, pExpr);
+ pCol->pDflt = sqlite3ExprDup(db, pSpan->pExpr, EXPRDUP_REDUCE);
+ sqlite3DbFree(db, pCol->zDflt);
+ pCol->zDflt = sqlite3DbStrNDup(db, (char*)pSpan->zStart,
+ (int)(pSpan->zEnd - pSpan->zStart));
+ }
+ }
+ sqlite3ExprDelete(db, pSpan->pExpr);
}
/*
** Designate the PRIMARY KEY for the table. pList is a list of names
@@ -64108,16 +65299,14 @@
sqlite3 *db = pParse->db;
#ifndef SQLITE_OMIT_CHECK
Table *pTab = pParse->pNewTable;
if( pTab && !IN_DECLARE_VTAB ){
- /* The CHECK expression must be duplicated so that tokens refer
- ** to malloced space and not the (ephemeral) text of the CREATE TABLE
- ** statement */
- pTab->pCheck = sqlite3ExprAnd(db, pTab->pCheck,
- sqlite3ExprDup(db, pCheckExpr, 0));
- }
-#endif
- sqlite3ExprDelete(db, pCheckExpr);
+ pTab->pCheck = sqlite3ExprAnd(db, pTab->pCheck, pCheckExpr);
+ }else
+#endif
+ {
+ sqlite3ExprDelete(db, pCheckExpr);
+ }
}
/*
** Set the collation function of the most recently parsed table column
@@ -64134,9 +65323,9 @@
db = pParse->db;
zColl = sqlite3NameFromToken(db, pToken);
if( !zColl ) return;
- if( sqlite3LocateCollSeq(pParse, zColl, -1) ){
+ if( sqlite3LocateCollSeq(pParse, zColl) ){
Index *pIdx;
p->aCol[i].zColl = zColl;
/* If the column is declared as "<name> PRIMARY KEY COLLATE <type>",
@@ -64170,23 +65359,22 @@
**
** This routine is a wrapper around sqlite3FindCollSeq(). This routine
** invokes the collation factory if the named collation cannot be found
** and generates an error message.
-*/
-SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName){
+**
+** See also: sqlite3FindCollSeq(), sqlite3GetCollSeq()
+*/
+SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){
sqlite3 *db = pParse->db;
u8 enc = ENC(db);
u8 initbusy = db->init.busy;
CollSeq *pColl;
- pColl = sqlite3FindCollSeq(db, enc, zName, nName, initbusy);
+ pColl = sqlite3FindCollSeq(db, enc, zName, initbusy);
if( !initbusy && (!pColl || !pColl->xCmp) ){
- pColl = sqlite3GetCollSeq(db, pColl, zName, nName);
+ pColl = sqlite3GetCollSeq(db, pColl, zName);
if( !pColl ){
- if( nName<0 ){
- nName = sqlite3Strlen30(zName);
- }
- sqlite3ErrorMsg(pParse, "no such collation sequence: %.*s", nName, zName);
+ sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
pColl = 0;
}
}
@@ -64214,9 +65402,9 @@
int r1 = sqlite3GetTempReg(pParse);
sqlite3 *db = pParse->db;
Vdbe *v = pParse->pVdbe;
sqlite3VdbeAddOp2(v, OP_Integer, db->aDb[iDb].pSchema->schema_cookie+1, r1);
- sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, 0, r1);
+ sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, r1);
sqlite3ReleaseTempReg(pParse, r1);
}
/*
@@ -64235,63 +65423,8 @@
return n + 2;
}
/*
-** This function is a wrapper around sqlite3GetToken() used by
-** isValidDimension(). This function differs from sqlite3GetToken() in
-** that:
-**
-** * Whitespace is ignored, and
-** * The output variable *peToken is set to 0 if the end of the
-** nul-terminated input string is reached.
-*/
-static int getTokenNoSpace(unsigned char *z, int *peToken){
- int n = 0;
- while( sqlite3Isspace(z[n]) ) n++;
- if( !z[n] ){
- *peToken = 0;
- return 0;
- }
- return n + sqlite3GetToken(&z[n], peToken);
-}
-
-/*
-** Parameter z points to a nul-terminated string. Return true if, when
-** whitespace is ignored, the contents of this string matches one of
-** the following patterns:
-**
-** ""
-** "(number)"
-** "(number,number)"
-*/
-static int isValidDimension(unsigned char *z){
- int eToken;
- int n = 0;
- n += getTokenNoSpace(&z[n], &eToken);
- if( eToken ){
- if( eToken!=TK_LP ) return 0;
- n += getTokenNoSpace(&z[n], &eToken);
- if( eToken==TK_PLUS || eToken==TK_MINUS ){
- n += getTokenNoSpace(&z[n], &eToken);
- }
- if( eToken!=TK_INTEGER && eToken!=TK_FLOAT ) return 0;
- n += getTokenNoSpace(&z[n], &eToken);
- if( eToken==TK_COMMA ){
- n += getTokenNoSpace(&z[n], &eToken);
- if( eToken==TK_PLUS || eToken==TK_MINUS ){
- n += getTokenNoSpace(&z[n], &eToken);
- }
- if( eToken!=TK_INTEGER && eToken!=TK_FLOAT ) return 0;
- n += getTokenNoSpace(&z[n], &eToken);
- }
- if( eToken!=TK_RP ) return 0;
- getTokenNoSpace(&z[n], &eToken);
- }
- if( eToken ) return 0;
- return 1;
-}
-
-/*
** The first parameter is a pointer to an output buffer. The second
** parameter is a pointer to an integer that contains the offset at
** which to write into the output buffer. This function copies the
** nul-terminated string pointed to by the third parameter, zSignedIdent,
@@ -64302,9 +65435,9 @@
** characters, does not begin with a digit and is not an SQL keyword,
** then it is copied to the output buffer exactly as it is. Otherwise,
** it is quoted using double-quotes.
*/
-static void identPut(char *z, int *pIdx, char *zSignedIdent, int isTypename){
+static void identPut(char *z, int *pIdx, char *zSignedIdent){
unsigned char *zIdent = (unsigned char*)zSignedIdent;
int i, j, needQuote;
i = *pIdx;
@@ -64312,23 +65445,9 @@
if( !sqlite3Isalnum(zIdent[j]) && zIdent[j]!='_' ) break;
}
needQuote = sqlite3Isdigit(zIdent[0]) || sqlite3KeywordCode(zIdent, j)!=TK_ID;
if( !needQuote ){
- if( isTypename ){
- /* If this is a type-name, allow a little more flexibility. In SQLite,
- ** a type-name is specified as:
- **
- ** ids [ids] [(number [, number])]
- **
- ** where "ids" is either a quoted string or a simple identifier (in the
- ** above notation, [] means optional). It is a bit tricky to check
- ** for all cases, but it is good to avoid unnecessarily quoting common
- ** typenames like VARCHAR(10).
- */
- needQuote = !isValidDimension(&zIdent[j]);
- }else{
- needQuote = zIdent[j];
- }
+ needQuote = zIdent[j];
}
if( needQuote ) z[i++] = '"';
for(j=0; zIdent[j]; j++){
@@ -64347,17 +65466,13 @@
*/
static char *createTableStmt(sqlite3 *db, Table *p){
int i, k, n;
char *zStmt;
- char *zSep, *zSep2, *zEnd, *z;
+ char *zSep, *zSep2, *zEnd;
Column *pCol;
n = 0;
for(pCol = p->aCol, i=0; i<p->nCol; i++, pCol++){
- n += identLength(pCol->zName);
- z = pCol->zType;
- if( z ){
- n += identLength(z);
- }
+ n += identLength(pCol->zName) + 5;
}
n += identLength(p->zName);
if( n<50 ){
zSep = "";
@@ -64375,20 +65490,40 @@
return 0;
}
sqlite3_snprintf(n, zStmt, "CREATE TABLE ");
k = sqlite3Strlen30(zStmt);
- identPut(zStmt, &k, p->zName, 0);
+ identPut(zStmt, &k, p->zName);
zStmt[k++] = '(';
for(pCol=p->aCol, i=0; i<p->nCol; i++, pCol++){
+ static const char * const azType[] = {
+ /* SQLITE_AFF_TEXT */ " TEXT",
+ /* SQLITE_AFF_NONE */ "",
+ /* SQLITE_AFF_NUMERIC */ " NUM",
+ /* SQLITE_AFF_INTEGER */ " INT",
+ /* SQLITE_AFF_REAL */ " REAL"
+ };
+ int len;
+ const char *zType;
+
sqlite3_snprintf(n-k, &zStmt[k], zSep);
k += sqlite3Strlen30(&zStmt[k]);
zSep = zSep2;
- identPut(zStmt, &k, pCol->zName, 0);
- if( (z = pCol->zType)!=0 ){
- zStmt[k++] = ' ';
- assert( (int)(sqlite3Strlen30(z)+k+1)<=n );
- identPut(zStmt, &k, z, 1);
- }
+ identPut(zStmt, &k, pCol->zName);
+ assert( pCol->affinity-SQLITE_AFF_TEXT >= 0 );
+ assert( pCol->affinity-SQLITE_AFF_TEXT < sizeof(azType)/sizeof(azType[0]) );
+ testcase( pCol->affinity==SQLITE_AFF_TEXT );
+ testcase( pCol->affinity==SQLITE_AFF_NONE );
+ testcase( pCol->affinity==SQLITE_AFF_NUMERIC );
+ testcase( pCol->affinity==SQLITE_AFF_INTEGER );
+ testcase( pCol->affinity==SQLITE_AFF_REAL );
+
+ zType = azType[pCol->affinity - SQLITE_AFF_TEXT];
+ len = sqlite3Strlen30(zType);
+ assert( pCol->affinity==SQLITE_AFF_NONE
+ || pCol->affinity==sqlite3AffinityType(zType) );
+ memcpy(&zStmt[k], zType, len);
+ k += len;
+ assert( k<=n );
}
sqlite3_snprintf(n-k, &zStmt[k], "%s", zEnd);
return zStmt;
}
@@ -64422,9 +65557,9 @@
Table *p;
sqlite3 *db = pParse->db;
int iDb;
- if( (pEnd==0 && pSelect==0) || pParse->nErr || db->mallocFailed ) {
+ if( (pEnd==0 && pSelect==0) || db->mallocFailed ){
return;
}
p = pParse->pNewTable;
if( p==0 ) return;
@@ -64478,9 +65613,9 @@
char *zType2; /* "VIEW" or "TABLE" */
char *zStmt; /* Text of the CREATE TABLE or CREATE VIEW statement */
v = sqlite3GetVdbe(pParse);
- if( v==0 ) return;
+ if( NEVER(v==0) ) return;
sqlite3VdbeAddOp1(v, OP_Close, 0);
/*
@@ -64585,9 +65720,9 @@
/* Add the table to the in-memory representation of the database.
*/
- if( db->init.busy && pParse->nErr==0 ){
+ if( db->init.busy ){
Table *pOld;
Schema *pSchema = p->pSchema;
pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName,
sqlite3Strlen30(p->zName),p);
@@ -64629,9 +65764,9 @@
int noErr /* Suppress error messages if VIEW already exists */
){
Table *p;
int n;
- const unsigned char *z;
+ const char *z;
Token sEnd;
DbFixer sFix;
Token *pName;
int iDb;
@@ -64643,12 +65778,14 @@
return;
}
sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr);
p = pParse->pNewTable;
- if( p==0 || pParse->nErr ){
+ if( p==0 ){
sqlite3SelectDelete(db, pSelect);
return;
}
+ assert( pParse->nErr==0 ); /* If sqlite3StartTable return non-NULL then
+ ** there could not have been an error */
sqlite3TwoPartName(pParse, pName1, pName2, &pName);
iDb = sqlite3SchemaToIndex(db, p->pSchema);
if( sqlite3FixInit(&sFix, pParse, iDb, "view", pName)
&& sqlite3FixSelect(&sFix, pSelect)
@@ -64674,15 +65811,15 @@
/* Locate the end of the CREATE VIEW statement. Make sEnd point to
** the end.
*/
sEnd = pParse->sLastToken;
- if( sEnd.z[0]!=0 && sEnd.z[0]!=';' ){
+ if( ALWAYS(sEnd.z[0]!=0) && sEnd.z[0]!=';' ){
sEnd.z += sEnd.n;
}
sEnd.n = 0;
n = (int)(sEnd.z - pBegin->z);
- z = (const unsigned char*)pBegin->z;
- while( n>0 && (z[n-1]==';' || sqlite3Isspace(z[n-1])) ){ n--; }
+ z = pBegin->z;
+ while( ALWAYS(n>0) && sqlite3Isspace(z[n-1]) ){ n--; }
sEnd.z = &z[n-1];
sEnd.n = 1;
/* Use sqlite3EndTable() to add the view to the SQLITE_MASTER table */
@@ -64726,10 +65863,15 @@
**
** CREATE VIEW one AS SELECT * FROM two;
** CREATE VIEW two AS SELECT * FROM one;
**
- ** Actually, this error is caught previously and so the following test
- ** should always fail. But we will leave it in place just to be safe.
+ ** Actually, the error above is now caught prior to reaching this point.
+ ** But the following test is still important as it does come up
+ ** in the following:
+ **
+ ** CREATE TABLE main.ex1(a);
+ ** CREATE TEMP VIEW ex1 AS SELECT a FROM ex1;
+ ** SELECT * FROM temp.ex1;
*/
if( pTable->nCol<0 ){
sqlite3ErrorMsg(pParse, "view %s is circularly defined", pTable->zName);
return 1;
@@ -64856,9 +65998,10 @@
** location iTable. The following code modifies the sqlite_master table to
** reflect this.
**
** The "#NNN" in the SQL is a special constant that means whatever value
- ** is in register NNN. See sqlite3RegisterExpr().
+ ** is in register NNN. See grammar rules associated with the TK_REGISTER
+ ** token for additional information.
*/
sqlite3NestedParse(pParse,
"UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d",
pParse->db->aDb[iDb].zName, SCHEMA_TABLE(iDb), iTable, r1, r1);
@@ -64934,11 +66077,12 @@
Vdbe *v;
sqlite3 *db = pParse->db;
int iDb;
- if( pParse->nErr || db->mallocFailed ){
+ if( db->mallocFailed ){
goto exit_drop_table;
}
+ assert( pParse->nErr==0 );
assert( pName->nSrc==1 );
pTab = sqlite3LocateTable(pParse, isView,
pName->a[0].zName, pName->a[0].zDatabase);
@@ -65021,11 +66165,9 @@
sqlite3BeginWriteOperation(pParse, 1, iDb);
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( IsVirtual(pTab) ){
- if( v ){
- sqlite3VdbeAddOp0(v, OP_VBegin);
- }
+ sqlite3VdbeAddOp0(v, OP_VBegin);
}
#endif
/* Drop all triggers associated with the table being dropped. Code
@@ -65123,12 +66265,12 @@
int nCol;
char *z;
assert( pTo!=0 );
- if( p==0 || pParse->nErr || IN_DECLARE_VTAB ) goto fk_end;
+ if( p==0 || IN_DECLARE_VTAB ) goto fk_end;
if( pFromCol==0 ){
int iCol = p->nCol-1;
- if( iCol<0 ) goto fk_end;
+ if( NEVER(iCol<0) ) goto fk_end;
if( pToCol && pToCol->nExpr!=1 ){
sqlite3ErrorMsg(pParse, "foreign key on %s"
" should reference only one column of table %T",
p->aCol[iCol].zName, pTo);
@@ -65343,9 +66485,14 @@
int nCol;
int nExtra = 0;
char *zExtra;
- if( pParse->nErr || db->mallocFailed || IN_DECLARE_VTAB ){
+ assert( pStart==0 || pEnd!=0 ); /* pEnd must be non-NULL if pStart is */
+ assert( pParse->nErr==0 ); /* Never called with prior errors */
+ if( db->mallocFailed || IN_DECLARE_VTAB ){
+ goto exit_create_index;
+ }
+ if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
goto exit_create_index;
}
/*
@@ -65367,9 +66514,9 @@
** if initialising a database schema.
*/
if( !db->init.busy ){
pTab = sqlite3SrcListLookup(pParse, pTblName);
- if( pName2 && pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){
+ if( pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){
iDb = 1;
}
}
#endif
@@ -65392,9 +66539,10 @@
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
}
pDb = &db->aDb[iDb];
- if( pTab==0 || pParse->nErr ) goto exit_create_index;
+ assert( pTab!=0 );
+ assert( pParse->nErr==0 );
if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0
&& memcmp(&pTab->zName[7],"altertab_",9)!=0 ){
sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
goto exit_create_index;
@@ -65426,15 +66574,13 @@
** own name.
*/
if( pName ){
zName = sqlite3NameFromToken(db, pName);
- if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index;
if( zName==0 ) goto exit_create_index;
if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
goto exit_create_index;
}
if( !db->init.busy ){
- if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index;
if( sqlite3FindTable(db, zName, 0)!=0 ){
sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
goto exit_create_index;
}
@@ -65475,24 +66621,28 @@
** key out of the last column added to the table under construction.
** So create a fake list to simulate this.
*/
if( pList==0 ){
- nullId.z = (u8*)pTab->aCol[pTab->nCol-1].zName;
+ nullId.z = pTab->aCol[pTab->nCol-1].zName;
nullId.n = sqlite3Strlen30((char*)nullId.z);
- nullId.quoted = 0;
- pList = sqlite3ExprListAppend(pParse, 0, 0, &nullId);
+ pList = sqlite3ExprListAppend(pParse, 0, 0);
if( pList==0 ) goto exit_create_index;
+ sqlite3ExprListSetName(pParse, pList, &nullId, 0);
pList->a[0].sortOrder = (u8)sortOrder;
}
/* Figure out how many bytes of space are required to store explicitly
** specified collation sequence names.
*/
for(i=0; i<pList->nExpr; i++){
- Expr *pExpr;
- CollSeq *pColl;
- if( (pExpr = pList->a[i].pExpr)!=0 && (pColl = pExpr->pColl)!=0 ){
- nExtra += (1 + sqlite3Strlen30(pColl->zName));
+ Expr *pExpr = pList->a[i].pExpr;
+ if( pExpr ){
+ CollSeq *pColl = pExpr->pColl;
+ /* Either pColl!=0 or there was an OOM failure. But if an OOM
+ ** failure we have quit before reaching this point. */
+ if( ALWAYS(pColl) ){
+ nExtra += (1 + sqlite3Strlen30(pColl->zName));
+ }
}
}
/*
@@ -65535,8 +66685,14 @@
/* Scan the names of the columns of the table to be indexed and
** load the column indices into the Index structure. Report an error
** if any column is not found.
+ **
+ ** TODO: Add a test to make sure that the same column is not named
+ ** more than once within the same index. Only the first instance of
+ ** the column will ever be used by the optimizer. Note that using the
+ ** same column more than once cannot be an error because that would
+ ** break backwards compatibility - it needs to be a warning.
*/
for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){
const char *zColName = pListItem->zName;
Column *pTabCol;
@@ -65550,27 +66706,30 @@
sqlite3ErrorMsg(pParse, "table %s has no column named %s",
pTab->zName, zColName);
goto exit_create_index;
}
- /* TODO: Add a test to make sure that the same column is not named
- ** more than once within the same index. Only the first instance of
- ** the column will ever be used by the optimizer. Note that using the
- ** same column more than once cannot be an error because that would
- ** break backwards compatibility - it needs to be a warning.
- */
pIndex->aiColumn[i] = j;
- if( pListItem->pExpr && pListItem->pExpr->pColl ){
- assert( pListItem->pExpr->pColl );
+ /* Justification of the ALWAYS(pListItem->pExpr->pColl): Because of
+ ** the way the "idxlist" non-terminal is constructed by the parser,
+ ** if pListItem->pExpr is not null then either pListItem->pExpr->pColl
+ ** must exist or else there must have been an OOM error. But if there
+ ** was an OOM error, we would never reach this point. */
+ if( pListItem->pExpr && ALWAYS(pListItem->pExpr->pColl) ){
+ int nColl;
+ zColl = pListItem->pExpr->pColl->zName;
+ nColl = sqlite3Strlen30(zColl) + 1;
+ assert( nExtra>=nColl );
+ memcpy(zExtra, zColl, nColl);
zColl = zExtra;
- sqlite3_snprintf(nExtra, zExtra, "%s", pListItem->pExpr->pColl->zName);
- zExtra += (sqlite3Strlen30(zColl) + 1);
+ zExtra += nColl;
+ nExtra -= nColl;
}else{
zColl = pTab->aCol[j].zColl;
if( !zColl ){
zColl = db->pDfltColl->zName;
}
}
- if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl, -1) ){
+ if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){
goto exit_create_index;
}
pIndex->azColl[i] = zColl;
requestedSortOrder = pListItem->sortOrder & sortOrderMask;
@@ -65590,8 +66749,16 @@
** Either way, check to see if the table already has such an index. If
** so, don't bother creating this one. This only applies to
** automatically created indices. Users can do as they wish with
** explicit indices.
+ **
+ ** Two UNIQUE or PRIMARY KEY constraints are considered equivalent
+ ** (and thus suppressing the second one) even if they have different
+ ** sort orders.
+ **
+ ** If there are different collating sequences or if the columns of
+ ** the constraint occur in different orders, then the constraints are
+ ** considered distinct and both result in separate indices.
*/
Index *pIdx;
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
int k;
@@ -65600,12 +66767,13 @@
assert( pIndex->onError!=OE_None );
if( pIdx->nColumn!=pIndex->nColumn ) continue;
for(k=0; k<pIdx->nColumn; k++){
- const char *z1 = pIdx->azColl[k];
- const char *z2 = pIndex->azColl[k];
+ const char *z1;
+ const char *z2;
if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
- if( pIdx->aSortOrder[k]!=pIndex->aSortOrder[k] ) break;
+ z1 = pIdx->azColl[k];
+ z2 = pIndex->azColl[k];
if( z1!=z2 && sqlite3StrICmp(z1, z2) ) break;
}
if( k==pIdx->nColumn ){
if( pIdx->onError!=pIndex->onError ){
@@ -65662,9 +66830,9 @@
** or UNIQUE constraint of a CREATE TABLE statement. Since the table
** has just been created, it contains no data and the index initialization
** step can be skipped.
*/
- else if( db->init.busy==0 ){
+ else{ /* if( db->init.busy==0 ) */
Vdbe *v;
char *zStmt;
int iMem = ++pParse->nMem;
@@ -65679,9 +66847,10 @@
/* Gather the complete text of the CREATE INDEX statement into
** the zStmt variable
*/
- if( pStart && pEnd ){
+ if( pStart ){
+ assert( pEnd!=0 );
/* A named index with an explicit CREATE INDEX statement */
zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s",
onError==OE_None ? "" : " UNIQUE",
pEnd->z - pName->z + 1,
@@ -65717,10 +66886,11 @@
}
/* When adding an index to the list of indices for a table, make
** sure all indices labeled OE_Replace come after all those labeled
- ** OE_Ignore. This is necessary for the correct operation of UPDATE
- ** and INSERT.
+ ** OE_Ignore. This is necessary for the correct constraint check
+ ** processing (in sqlite3GenerateConstraintChecks()) as part of
+ ** UPDATE and INSERT statements.
*/
if( db->init.busy || pTblName==0 ){
if( onError!=OE_Replace || pTab->pIndex==0
|| pTab->pIndex->onError==OE_Replace){
@@ -65746,30 +66916,8 @@
sqlite3ExprListDelete(db, pList);
sqlite3SrcListDelete(db, pTblName);
sqlite3DbFree(db, zName);
return;
-}
-
-/*
-** Generate code to make sure the file format number is at least minFormat.
-** The generated code will increase the file format number if necessary.
-*/
-SQLITE_PRIVATE void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){
- Vdbe *v;
- v = sqlite3GetVdbe(pParse);
- if( v ){
- int r1 = sqlite3GetTempReg(pParse);
- int r2 = sqlite3GetTempReg(pParse);
- int j1;
- sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, 1);
- sqlite3VdbeUsesBtree(v, iDb);
- sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2);
- j1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1);
- sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, 1, r2);
- sqlite3VdbeJumpHere(v, j1);
- sqlite3ReleaseTempReg(pParse, r1);
- sqlite3ReleaseTempReg(pParse, r2);
- }
}
/*
** Fill the Index.aiRowEst[] array with default information - information
@@ -65815,9 +66963,10 @@
Vdbe *v;
sqlite3 *db = pParse->db;
int iDb;
- if( pParse->nErr || db->mallocFailed ){
+ assert( pParse->nErr==0 ); /* Never called with prior errors */
+ if( db->mallocFailed ){
goto exit_drop_index;
}
assert( pName->nSrc==1 );
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
@@ -66006,12 +67155,10 @@
/* Sanity checking on calling parameters */
assert( iStart>=0 );
assert( nExtra>=1 );
- if( pSrc==0 || iStart>pSrc->nSrc ){
- assert( db->mallocFailed );
- return pSrc;
- }
+ assert( pSrc!=0 );
+ assert( iStart<=pSrc->nSrc );
/* Allocate additional space if needed */
if( pSrc->nSrc+nExtra>pSrc->nAlloc ){
SrcList *pNew;
@@ -66047,9 +67194,9 @@
/*
** Append a new table name to the given SrcList. Create a new SrcList if
-** need be. A new entry is created in the SrcList even if pToken is NULL.
+** need be. A new entry is created in the SrcList even if pTable is NULL.
**
** A SrcList is returned, or NULL if there is an OOM error. The returned
** SrcList might be the same as the SrcList that was input or it might be
** a new one. If an OOM error does occurs, then the prior value of pList
@@ -66071,9 +67218,15 @@
** like this:
**
** sqlite3SrcListAppend(D,A,B,C);
**
-** Then C is the table name and B is the database name.
+** Then C is the table name and B is the database name. If C is defined
+** then so is B. In other words, we never have a case where:
+**
+** sqlite3SrcListAppend(D,A,0,C);
+**
+** Both pTable and pDatabase are assumed to be quoted. They are dequoted
+** before being added to the SrcList.
*/
SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(
sqlite3 *db, /* Connection to notify of malloc failures */
SrcList *pList, /* Append to this SrcList. NULL creates a new SrcList */
@@ -66080,8 +67233,9 @@
Token *pTable, /* Table to append */
Token *pDatabase /* Database of the table */
){
struct SrcList_item *pItem;
+ assert( pDatabase==0 || pTable!=0 ); /* Cannot have C without B */
if( pList==0 ){
pList = sqlite3DbMallocZero(db, sizeof(SrcList) );
if( pList==0 ) return 0;
pList->nAlloc = 1;
@@ -66094,9 +67248,9 @@
pItem = &pList->a[pList->nSrc-1];
if( pDatabase && pDatabase->z==0 ){
pDatabase = 0;
}
- if( pDatabase && pTable ){
+ if( pDatabase ){
Token *pTemp = pDatabase;
pDatabase = pTable;
pTable = pTemp;
}
@@ -66171,16 +67325,17 @@
){
struct SrcList_item *pItem;
sqlite3 *db = pParse->db;
p = sqlite3SrcListAppend(db, p, pTable, pDatabase);
- if( p==0 || p->nSrc==0 ){
+ if( p==0 || NEVER(p->nSrc==0) ){
sqlite3ExprDelete(db, pOn);
sqlite3IdListDelete(db, pUsing);
sqlite3SelectDelete(db, pSubquery);
return p;
}
pItem = &p->a[p->nSrc-1];
- if( pAlias && pAlias->n ){
+ assert( pAlias!=0 );
+ if( pAlias->n ){
pItem->zAlias = sqlite3NameFromToken(db, pAlias);
}
pItem->pSelect = pSubquery;
pItem->pOn = pOn;
@@ -66192,9 +67347,10 @@
** Add an INDEXED BY or NOT INDEXED clause to the most recently added
** element of the source-list passed as the second argument.
*/
SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){
- if( pIndexedBy && p && p->nSrc>0 ){
+ assert( pIndexedBy!=0 );
+ if( p && ALWAYS(p->nSrc>0) ){
struct SrcList_item *pItem = &p->a[p->nSrc-1];
assert( pItem->notIndexed==0 && pItem->zIndex==0 );
if( pIndexedBy->n==1 && !pIndexedBy->z ){
/* A "NOT INDEXED" clause was supplied. See parse.y
@@ -66238,12 +67394,15 @@
sqlite3 *db;
Vdbe *v;
int i;
- if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
- if( pParse->nErr || db->mallocFailed ) return;
- if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ) return;
-
+ assert( pParse!=0 );
+ db = pParse->db;
+ assert( db!=0 );
+/* if( db->aDb[0].pBt==0 ) return; */
+ if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ){
+ return;
+ }
v = sqlite3GetVdbe(pParse);
if( !v ) return;
if( type!=TK_DEFERRED ){
for(i=0; i<db->nDb; i++){
@@ -66260,12 +67419,15 @@
SQLITE_PRIVATE void sqlite3CommitTransaction(Parse *pParse){
sqlite3 *db;
Vdbe *v;
- if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
- if( pParse->nErr || db->mallocFailed ) return;
- if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ) return;
-
+ assert( pParse!=0 );
+ db = pParse->db;
+ assert( db!=0 );
+/* if( db->aDb[0].pBt==0 ) return; */
+ if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ){
+ return;
+ }
v = sqlite3GetVdbe(pParse);
if( v ){
sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 0);
}
@@ -66277,12 +67439,15 @@
SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse *pParse){
sqlite3 *db;
Vdbe *v;
- if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
- if( pParse->nErr || db->mallocFailed ) return;
- if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ) return;
-
+ assert( pParse!=0 );
+ db = pParse->db;
+ assert( db!=0 );
+/* if( db->aDb[0].pBt==0 ) return; */
+ if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ){
+ return;
+ }
v = sqlite3GetVdbe(pParse);
if( v ){
sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 1);
}
@@ -66400,14 +67565,15 @@
** can be checked before any changes are made to the database, it is never
** necessary to undo a write and the checkpoint should not be set.
*/
SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){
- Vdbe *v = sqlite3GetVdbe(pParse);
- if( v==0 ) return;
sqlite3CodeVerifySchema(pParse, iDb);
pParse->writeMask |= 1<<iDb;
if( setStatement && pParse->nested==0 ){
- sqlite3VdbeAddOp1(v, OP_Statement, iDb);
+ /* Every place where this routine is called with setStatement!=0 has
+ ** already successfully created a VDBE. */
+ assert( pParse->pVdbe );
+ sqlite3VdbeAddOp1(pParse->pVdbe, OP_Statement, iDb);
}
}
/*
@@ -66416,11 +67582,13 @@
*/
#ifndef SQLITE_OMIT_REINDEX
static int collationMatch(const char *zColl, Index *pIndex){
int i;
+ assert( zColl!=0 );
for(i=0; i<pIndex->nColumn; i++){
const char *z = pIndex->azColl[i];
- if( z==zColl || (z && zColl && 0==sqlite3StrICmp(z, zColl)) ){
+ assert( z!=0 );
+ if( 0==sqlite3StrICmp(z, zColl) ){
return 1;
}
}
return 0;
@@ -66497,22 +67665,20 @@
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
return;
}
- if( pName1==0 || pName1->z==0 ){
+ if( pName1==0 ){
reindexDatabases(pParse, 0);
return;
- }else if( pName2==0 || pName2->z==0 ){
+ }else if( NEVER(pName2==0) || pName2->z==0 ){
char *zColl;
assert( pName1->z );
zColl = sqlite3NameFromToken(pParse->db, pName1);
if( !zColl ) return;
- pColl = sqlite3FindCollSeq(db, ENC(db), zColl, -1, 0);
+ pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
if( pColl ){
- if( zColl ){
- reindexDatabases(pParse, zColl);
- sqlite3DbFree(db, zColl);
- }
+ reindexDatabases(pParse, zColl);
+ sqlite3DbFree(db, zColl);
return;
}
sqlite3DbFree(db, zColl);
}
@@ -66561,9 +67727,9 @@
assert( &pKey->aSortOrder[nCol]==&(((u8 *)pKey)[nBytes]) );
for(i=0; i<nCol; i++){
char *zColl = pIdx->azColl[i];
assert( zColl );
- pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl, -1);
+ pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl);
pKey->aSortOrder[i] = pIdx->aSortOrder[i];
}
pKey->nField = (u16)nCol;
}
@@ -66591,9 +67757,9 @@
**
** This file contains functions used to access the internal hash tables
** of user defined functions and collation sequences.
**
-** $Id: callback.c,v 1.39 2009/05/03 20:23:53 drh Exp $
+** $Id: callback.c,v 1.41 2009/05/20 02:40:46 drh Exp $
*/
/*
@@ -66600,13 +67766,12 @@
** Invoke the 'collation needed' callback to request a collation sequence
** in the database text encoding of name zName, length nName.
** If the collation sequence
*/
-static void callCollNeeded(sqlite3 *db, const char *zName, int nName){
+static void callCollNeeded(sqlite3 *db, const char *zName){
assert( !db->xCollNeeded || !db->xCollNeeded16 );
- if( nName<0 ) nName = sqlite3Strlen30(zName);
if( db->xCollNeeded ){
- char *zExternal = sqlite3DbStrNDup(db, zName, nName);
+ char *zExternal = sqlite3DbStrDup(db, zName);
if( !zExternal ) return;
db->xCollNeeded(db->pCollNeededArg, db, (int)ENC(db), zExternal);
sqlite3DbFree(db, zExternal);
}
@@ -66613,9 +67778,9 @@
#ifndef SQLITE_OMIT_UTF16
if( db->xCollNeeded16 ){
char const *zExternal;
sqlite3_value *pTmp = sqlite3ValueNew(db);
- sqlite3ValueSetStr(pTmp, nName, zName, SQLITE_UTF8, SQLITE_STATIC);
+ sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC);
zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE);
if( zExternal ){
db->xCollNeeded16(db->pCollNeededArg, db, (int)ENC(db), zExternal);
}
@@ -66633,13 +67798,12 @@
*/
static int synthCollSeq(sqlite3 *db, CollSeq *pColl){
CollSeq *pColl2;
char *z = pColl->zName;
- int n = sqlite3Strlen30(z);
int i;
static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 };
for(i=0; i<3; i++){
- pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, n, 0);
+ pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, 0);
if( pColl2->xCmp!=0 ){
memcpy(pColl, pColl2, sizeof(CollSeq));
pColl->xDel = 0; /* Do not copy the destructor */
return SQLITE_OK;
@@ -66659,27 +67823,28 @@
**
** The return value is either the collation sequence to be used in database
** db for collation type name zName, length nName, or NULL, if no collation
** sequence can be found.
+**
+** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq()
*/
SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(
- sqlite3* db,
- CollSeq *pColl,
- const char *zName,
- int nName
+ sqlite3* db, /* The database connection */
+ CollSeq *pColl, /* Collating sequence with native encoding, or NULL */
+ const char *zName /* Collating sequence name */
){
CollSeq *p;
p = pColl;
if( !p ){
- p = sqlite3FindCollSeq(db, ENC(db), zName, nName, 0);
+ p = sqlite3FindCollSeq(db, ENC(db), zName, 0);
}
if( !p || !p->xCmp ){
/* No collation sequence of this type for this encoding is registered.
** Call the collation factory to see if it can supply us with one.
*/
- callCollNeeded(db, zName, nName);
- p = sqlite3FindCollSeq(db, ENC(db), zName, nName, 0);
+ callCollNeeded(db, zName);
+ p = sqlite3FindCollSeq(db, ENC(db), zName, 0);
}
if( p && !p->xCmp && synthCollSeq(db, p) ){
p = 0;
}
@@ -66700,9 +67865,9 @@
*/
SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
if( pColl ){
const char *zName = pColl->zName;
- CollSeq *p = sqlite3GetCollSeq(pParse->db, pColl, zName, -1);
+ CollSeq *p = sqlite3GetCollSeq(pParse->db, pColl, zName);
if( !p ){
if( pParse->nErr==0 ){
sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
}
@@ -66729,15 +67894,14 @@
** the collation sequence name. A pointer to this string is stored in
** each collation sequence structure.
*/
static CollSeq *findCollSeqEntry(
- sqlite3 *db,
- const char *zName,
- int nName,
- int create
+ sqlite3 *db, /* Database connection */
+ const char *zName, /* Name of the collating sequence */
+ int create /* Create a new entry if true */
){
CollSeq *pColl;
- if( nName<0 ) nName = sqlite3Strlen30(zName);
+ int nName = sqlite3Strlen30(zName);
pColl = sqlite3HashFind(&db->aCollSeq, zName, nName);
if( 0==pColl && create ){
pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName + 1 );
@@ -66779,19 +67943,20 @@
** A separate function sqlite3LocateCollSeq() is a wrapper around
** this routine. sqlite3LocateCollSeq() invokes the collation factory
** if necessary and generates an error message if the collating sequence
** cannot be found.
+**
+** See also: sqlite3LocateCollSeq(), sqlite3GetCollSeq()
*/
SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(
sqlite3 *db,
u8 enc,
const char *zName,
- int nName,
int create
){
CollSeq *pColl;
if( zName ){
- pColl = findCollSeqEntry(db, zName, nName, create);
+ pColl = findCollSeqEntry(db, zName, create);
}else{
pColl = db->pDfltColl;
}
assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
@@ -66872,8 +68037,9 @@
u8 c1 = (u8)pDef->zName[0];
int h = (sqlite3UpperToLower[c1] + nName) % ArraySize(pHash->a);
pOther = functionSearch(pHash, h, pDef->zName, nName);
if( pOther ){
+ assert( pOther!=pDef && pOther->pNext!=pDef );
pDef->pNext = pOther->pNext;
pOther->pNext = pDef;
}else{
pDef->pNext = 0;
@@ -67045,9 +68211,9 @@
*************************************************************************
** This file contains C code routines that are called by the parser
** in order to generate code for DELETE FROM statements.
**
-** $Id: delete.c,v 1.201 2009/05/01 21:13:37 drh Exp $
+** $Id: delete.c,v 1.203 2009/05/28 01:00:55 drh Exp $
*/
/*
** Look up every table that is named in pSrc. If any table is not found,
@@ -67114,15 +68280,20 @@
pDup = sqlite3SelectDup(db, pView->pSelect, 0);
if( pWhere ){
SrcList *pFrom;
- Token viewName;
pWhere = sqlite3ExprDup(db, pWhere, 0);
- viewName.z = (u8*)pView->zName;
- viewName.n = (unsigned int)sqlite3Strlen30((const char*)viewName.z);
- viewName.quoted = 0;
- pFrom = sqlite3SrcListAppendFromTerm(pParse, 0, 0, 0, &viewName, pDup, 0,0);
+ pFrom = sqlite3SrcListAppend(db, 0, 0, 0);
+ if( pFrom ){
+ assert( pFrom->nSrc==1 );
+ pFrom->a[0].zAlias = sqlite3DbStrDup(db, pView->zName);
+ pFrom->a[0].pSelect = pDup;
+ assert( pFrom->a[0].pOn==0 );
+ assert( pFrom->a[0].pUsing==0 );
+ }else{
+ sqlite3SelectDelete(db, pDup);
+ }
pDup = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0);
}
sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
sqlite3Select(pParse, pDup, &dest);
@@ -67180,11 +68351,11 @@
** SELECT rowid FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1
** );
*/
- pSelectRowid = sqlite3Expr(pParse->db, TK_ROW, 0, 0, 0);
+ pSelectRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0);
if( pSelectRowid == 0 ) goto limit_where_cleanup_2;
- pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid, 0);
+ pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid);
if( pEList == 0 ) goto limit_where_cleanup_2;
/* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
** and the SELECT subtree. */
@@ -67199,9 +68370,9 @@
pOrderBy,0,pLimit,pOffset);
if( pSelect == 0 ) return 0;
/* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */
- pWhereRowid = sqlite3Expr(pParse->db, TK_ROW, 0, 0, 0);
+ pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0);
if( pWhereRowid == 0 ) goto limit_where_cleanup_1;
pInClause = sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0);
if( pInClause == 0 ) goto limit_where_cleanup_1;
@@ -67663,9 +68834,9 @@
** 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.234 2009/04/20 12:07:37 drh Exp $
+** $Id: func.c,v 1.237 2009/06/03 01:24:54 drh Exp $
*/
/*
** Return the collating function associated with a function.
@@ -67890,9 +69061,9 @@
#ifndef SQLITE_OMIT_FLOATING_POINT
static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
int n = 0;
double r;
- char zBuf[500]; /* larger than the %f representation of the largest double */
+ char *zBuf;
assert( argc==1 || argc==2 );
if( argc==2 ){
if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return;
n = sqlite3_value_int(argv[1]);
@@ -67900,11 +69071,16 @@
if( n<0 ) n = 0;
}
if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
r = sqlite3_value_double(argv[0]);
- sqlite3_snprintf(sizeof(zBuf),zBuf,"%.*f",n,r);
- sqlite3AtoF(zBuf, &r);
- sqlite3_result_double(context, r);
+ zBuf = sqlite3_mprintf("%.*f",n,r);
+ if( zBuf==0 ){
+ sqlite3_result_error_nomem(context);
+ }else{
+ sqlite3AtoF(zBuf, &r);
+ sqlite3_free(zBuf);
+ sqlite3_result_double(context, r);
+ }
}
#endif
/*
@@ -69011,10 +70187,11 @@
){
return 0;
}
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- pDef = sqlite3FindFunction(db, (char*)pExpr->token.z, pExpr->token.n, 2,
- SQLITE_UTF8, 0);
+ pDef = sqlite3FindFunction(db, pExpr->u.zToken,
+ sqlite3Strlen30(pExpr->u.zToken),
+ 2, SQLITE_UTF8, 0);
if( NEVER(pDef==0) || (pDef->flags & SQLITE_FUNC_LIKE)==0 ){
return 0;
}
@@ -69136,9 +70313,9 @@
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
-** $Id: insert.c,v 1.267 2009/05/04 11:42:30 danielk1977 Exp $
+** $Id: insert.c,v 1.268 2009/05/29 19:00:13 drh Exp $
*/
/*
** Generate code that will open a table for reading.
@@ -69985,9 +71162,9 @@
sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+keyColumn, regRowid);
}else{
VdbeOp *pOp;
sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, regRowid);
- pOp = sqlite3VdbeGetOp(v, sqlite3VdbeCurrentAddr(v) - 1);
+ pOp = sqlite3VdbeGetOp(v, -1);
if( ALWAYS(pOp) && pOp->opcode==OP_Null && !IsVirtual(pTab) ){
appendFlag = 1;
pOp->opcode = OP_NewRowid;
pOp->p1 = baseCur;
@@ -71043,9 +72220,9 @@
*************************************************************************
** This file contains code used to dynamically load extensions into
** the SQLite library.
**
-** $Id: loadext.c,v 1.58 2009/01/20 16:53:40 danielk1977 Exp $
+** $Id: loadext.c,v 1.60 2009/06/03 01:24:54 drh Exp $
*/
#ifndef SQLITE_CORE
#define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */
@@ -71766,8 +72943,11 @@
void *handle;
int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
char *zErrmsg = 0;
void **aHandle;
+ const int nMsg = 300;
+
+ if( pzErrMsg ) *pzErrMsg = 0;
/* Ticket #1863. To avoid a creating security problems for older
** applications that relink against newer versions of SQLite, the
** ability to run load_extension is turned off by default. One
@@ -71787,27 +72967,31 @@
handle = sqlite3OsDlOpen(pVfs, zFile);
if( handle==0 ){
if( pzErrMsg ){
- char zErr[256];
- zErr[sizeof(zErr)-1] = '\0';
- sqlite3_snprintf(sizeof(zErr)-1, zErr,
- "unable to open shared library [%s]", zFile);
- sqlite3OsDlError(pVfs, sizeof(zErr)-1, zErr);
- *pzErrMsg = sqlite3DbStrDup(0, zErr);
+ zErrmsg = sqlite3StackAllocZero(db, nMsg);
+ if( zErrmsg ){
+ sqlite3_snprintf(nMsg, zErrmsg,
+ "unable to open shared library [%s]", zFile);
+ sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
+ *pzErrMsg = sqlite3DbStrDup(0, zErrmsg);
+ sqlite3StackFree(db, zErrmsg);
+ }
}
return SQLITE_ERROR;
}
xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
sqlite3OsDlSym(pVfs, handle, zProc);
if( xInit==0 ){
if( pzErrMsg ){
- char zErr[256];
- zErr[sizeof(zErr)-1] = '\0';
- sqlite3_snprintf(sizeof(zErr)-1, zErr,
- "no entry point [%s] in shared library [%s]", zProc,zFile);
- sqlite3OsDlError(pVfs, sizeof(zErr)-1, zErr);
- *pzErrMsg = sqlite3DbStrDup(0, zErr);
+ zErrmsg = sqlite3StackAllocZero(db, nMsg);
+ if( zErrmsg ){
+ sqlite3_snprintf(nMsg, zErrmsg,
+ "no entry point [%s] in shared library [%s]", zProc,zFile);
+ sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
+ *pzErrMsg = sqlite3DbStrDup(0, zErrmsg);
+ sqlite3StackFree(db, zErrmsg);
+ }
sqlite3OsDlClose(pVfs, handle);
}
return SQLITE_ERROR;
}else if( xInit(db, &zErrmsg, &sqlite3Apis) ){
@@ -71841,8 +73025,9 @@
){
int rc;
sqlite3_mutex_enter(db->mutex);
rc = sqlite3LoadExtension(db, zFile, zProc, pzErrMsg);
+ rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
}
@@ -71977,22 +73162,23 @@
}
/*
** Load all automatic extensions.
-*/
-SQLITE_PRIVATE int sqlite3AutoLoadExtensions(sqlite3 *db){
- int i;
- int go = 1;
- int rc = SQLITE_OK;
+**
+** If anything goes wrong, set an error in the database connection.
+*/
+SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
+ int i;
+ int go = 1;
int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
wsdAutoextInit;
if( wsdAutoext.nExt==0 ){
/* Common case: early out without every having to acquire a mutex */
- return SQLITE_OK;
+ return;
}
for(i=0; go; i++){
- char *zErrmsg = 0;
+ char *zErrmsg;
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
#endif
sqlite3_mutex_enter(mutex);
@@ -72003,17 +73189,16 @@
xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
wsdAutoext.aExt[i];
}
sqlite3_mutex_leave(mutex);
+ zErrmsg = 0;
if( xInit && xInit(db, &zErrmsg, &sqlite3Apis) ){
sqlite3Error(db, SQLITE_ERROR,
"automatic extension loading failed: %s", zErrmsg);
go = 0;
- rc = SQLITE_ERROR;
- sqlite3_free(zErrmsg);
- }
- }
- return rc;
+ }
+ sqlite3_free(zErrmsg);
+ }
}
/************** End of loadext.c *********************************************/
/************** Begin file pragma.c ******************************************/
@@ -72029,9 +73214,9 @@
**
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
-** $Id: pragma.c,v 1.209 2009/04/07 22:05:43 drh Exp $
+** $Id: pragma.c,v 1.212 2009/06/03 11:25:07 danielk1977 Exp $
*/
/* Ignore this whole file if pragmas are disabled
*/
@@ -72335,9 +73520,9 @@
** and a positive value means synchronous is on.
*/
if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){
static const VdbeOpList getCacheSize[] = {
- { OP_ReadCookie, 0, 1, 2}, /* 0 */
+ { OP_ReadCookie, 0, 1, BTREE_DEFAULT_CACHE_SIZE}, /* 0 */
{ OP_IfPos, 1, 6, 0},
{ OP_Integer, 0, 2, 0},
{ OP_Subtract, 1, 2, 1},
{ OP_IfPos, 1, 6, 0},
@@ -72358,13 +73543,13 @@
int size = atoi(zRight);
if( size<0 ) size = -size;
sqlite3BeginWriteOperation(pParse, 0, iDb);
sqlite3VdbeAddOp2(v, OP_Integer, size, 1);
- sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, 2, 2);
+ sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, 2, BTREE_DEFAULT_CACHE_SIZE);
addr = sqlite3VdbeAddOp2(v, OP_IfPos, 2, 0);
sqlite3VdbeAddOp2(v, OP_Integer, -size, 1);
sqlite3VdbeJumpHere(v, addr);
- sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, 2, 1);
+ sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, 1);
pDb->pSchema->cache_size = size;
sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
}
}else
@@ -72599,14 +73784,14 @@
** file. Before writing to meta[6], check that meta[3] indicates
** that this really is an auto-vacuum capable database.
*/
static const VdbeOpList setMeta6[] = {
- { OP_Transaction, 0, 1, 0}, /* 0 */
- { OP_ReadCookie, 0, 1, 3}, /* 1 */
- { OP_If, 1, 0, 0}, /* 2 */
- { OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */
- { OP_Integer, 0, 1, 0}, /* 4 */
- { OP_SetCookie, 0, 6, 1}, /* 5 */
+ { OP_Transaction, 0, 1, 0}, /* 0 */
+ { OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE},
+ { OP_If, 1, 0, 0}, /* 2 */
+ { OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */
+ { OP_Integer, 0, 1, 0}, /* 4 */
+ { OP_SetCookie, 0, BTREE_INCR_VACUUM, 1}, /* 5 */
};
int iAddr;
iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6);
sqlite3VdbeChangeP1(v, iAddr, iDb);
@@ -72857,12 +74042,10 @@
sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pCol->zName, 0);
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
pCol->zType ? pCol->zType : "", 0);
sqlite3VdbeAddOp2(v, OP_Integer, (pCol->notNull ? 1 : 0), 4);
- if( pCol->pDflt ){
- const Token *p = &pCol->pDflt->span;
- assert( p->z );
- sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, (char*)p->z, p->n);
+ if( pCol->zDflt ){
+ sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, (char*)pCol->zDflt, 0);
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, 5);
}
sqlite3VdbeAddOp2(v, OP_Integer, pCol->isPrimKey, 6);
@@ -73292,25 +74475,23 @@
if( sqlite3StrICmp(zLeft, "schema_version")==0
|| sqlite3StrICmp(zLeft, "user_version")==0
|| sqlite3StrICmp(zLeft, "freelist_count")==0
){
- int iCookie; /* Cookie index. 0 for schema-cookie, 6 for user-cookie. */
+ int iCookie; /* Cookie index. 1 for schema-cookie, 6 for user-cookie. */
sqlite3VdbeUsesBtree(v, iDb);
switch( zLeft[0] ){
- case 's': case 'S':
- iCookie = 0;
- break;
case 'f': case 'F':
- iCookie = 1;
- iDb = (-1*(iDb+1));
- assert(iDb<=0);
+ iCookie = BTREE_FREE_PAGE_COUNT;
+ break;
+ case 's': case 'S':
+ iCookie = BTREE_SCHEMA_VERSION;
break;
default:
- iCookie = 5;
- break;
- }
-
- if( zRight && iDb>=0 ){
+ iCookie = BTREE_USER_VERSION;
+ break;
+ }
+
+ if( zRight && iCookie!=BTREE_FREE_PAGE_COUNT ){
/* Write the specified cookie value */
static const VdbeOpList setCookie[] = {
{ OP_Transaction, 0, 1, 0}, /* 0 */
{ OP_Integer, 0, 1, 0}, /* 1 */
@@ -73463,9 +74644,9 @@
** 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.117 2009/04/20 17:43:03 drh Exp $
+** $Id: prepare.c,v 1.121 2009/06/04 00:11:56 drh Exp $
*/
/*
** Fill the InitData structure with an error message that indicates
@@ -73582,9 +74763,9 @@
int size;
Table *pTab;
Db *pDb;
char const *azArg[4];
- int meta[10];
+ int meta[5];
InitData initData;
char const *zMasterSchema;
char const *zMasterName = SCHEMA_TABLE(iDb);
@@ -73667,12 +74848,8 @@
}
sqlite3BtreeEnter(pDb->pBt);
rc = sqlite3BtreeCursor(pDb->pBt, MASTER_ROOT, 0, 0, curMain);
if( rc==SQLITE_EMPTY ) rc = SQLITE_OK;
- if( rc!=SQLITE_OK ){
- sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
- goto initone_error_out;
- }
/* Get the database meta information.
**
** Meta values are as follows:
@@ -73680,39 +74857,37 @@
** 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[4] Db text encoding. 1:UTF-8 2:UTF-16LE 3:UTF-16BE
- ** meta[5] The user cookie. Used by the application.
- ** meta[6] Incremental-vacuum flag.
- ** meta[7]
- ** meta[8]
- ** meta[9]
**
** Note: The #defined SQLITE_UTF* symbols in sqliteInt.h correspond to
** the possible values of meta[4].
*/
- for(i=0; i<ArraySize(meta); i++){
+ for(i=0; rc==SQLITE_OK && i<ArraySize(meta); i++){
rc = sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]);
- if( rc ){
- sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
- goto initone_error_out;
- }
- }
- pDb->pSchema->schema_cookie = meta[0];
+ }
+ if( rc ){
+ sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
+ goto initone_error_out;
+ }
+ pDb->pSchema->schema_cookie = meta[BTREE_SCHEMA_VERSION-1];
/* If opening a non-empty database, check the text encoding. For the
** main database, set sqlite3.enc to the encoding of the main database.
** For an attached db, it is an error if the encoding is not the same
** as sqlite3.enc.
*/
- if( meta[4] ){ /* text encoding */
+ if( meta[BTREE_TEXT_ENCODING-1] ){ /* text encoding */
if( iDb==0 ){
+ u8 encoding;
/* If opening the main database, set ENC(db). */
- ENC(db) = (u8)meta[4];
- db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0);
+ encoding = (u8)meta[BTREE_TEXT_ENCODING-1] & 3;
+ if( encoding==0 ) encoding = SQLITE_UTF8;
+ ENC(db) = encoding;
+ db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0);
}else{
/* If opening an attached database, the encoding much match ENC(db) */
- if( meta[4]!=ENC(db) ){
+ if( meta[BTREE_TEXT_ENCODING-1]!=ENC(db) ){
sqlite3SetString(pzErrMsg, db, "attached databases must use the same"
" text encoding as main database");
rc = SQLITE_ERROR;
goto initone_error_out;
@@ -73723,9 +74898,9 @@
}
pDb->pSchema->enc = ENC(db);
if( pDb->pSchema->cache_size==0 ){
- size = meta[2];
+ size = meta[BTREE_DEFAULT_CACHE_SIZE-1];
if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; }
if( size<0 ) size = -size;
pDb->pSchema->cache_size = size;
sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
@@ -73736,9 +74911,9 @@
** file_format==2 Version 3.1.3. // ALTER TABLE ADD COLUMN
** file_format==3 Version 3.1.4. // ditto but with non-NULL defaults
** file_format==4 Version 3.3.0. // DESC indices. Boolean constants
*/
- pDb->pSchema->file_format = (u8)meta[1];
+ pDb->pSchema->file_format = (u8)meta[BTREE_FILE_FORMAT-1];
if( pDb->pSchema->file_format==0 ){
pDb->pSchema->file_format = 1;
}
if( pDb->pSchema->file_format>SQLITE_MAX_FILE_FORMAT ){
@@ -73751,9 +74926,9 @@
** clear the legacy_file_format pragma flag so that a VACUUM will
** not downgrade the database and thus invalidate any descending
** indices that the user might have created.
*/
- if( iDb==0 && meta[1]>=4 ){
+ if( iDb==0 && meta[BTREE_FILE_FORMAT-1]>=4 ){
db->flags &= ~SQLITE_LegacyFileFmt;
}
/* Read the schema information out of the schema tables
@@ -73907,9 +75082,9 @@
if( pBt==0 ) continue;
memset(curTemp, 0, sqlite3BtreeCursorSize());
rc = sqlite3BtreeCursor(pBt, MASTER_ROOT, 0, 0, curTemp);
if( rc==SQLITE_OK ){
- rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&cookie);
+ rc = sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie);
if( rc==SQLITE_OK && cookie!=db->aDb[iDb].pSchema->schema_cookie ){
allOk = 0;
}
sqlite3BtreeCloseCursor(curTemp);
@@ -73969,14 +75144,24 @@
int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
const char **pzTail /* OUT: End of parsed string */
){
- Parse sParse;
- char *zErrMsg = 0;
- int rc = SQLITE_OK;
- int i;
-
- if( sqlite3SafetyOn(db) ) return SQLITE_MISUSE;
+ Parse *pParse; /* Parsing context */
+ char *zErrMsg = 0; /* Error message */
+ int rc = SQLITE_OK; /* Result code */
+ int i; /* Loop counter */
+
+ /* Allocate the parsing context */
+ pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
+ if( pParse==0 ){
+ rc = SQLITE_NOMEM;
+ goto end_prepare;
+ }
+
+ if( sqlite3SafetyOn(db) ){
+ rc = SQLITE_MISUSE;
+ goto end_prepare;
+ }
assert( ppStmt && *ppStmt==0 );
assert( !db->mallocFailed );
assert( sqlite3_mutex_held(db->mutex) );
@@ -74012,70 +75197,73 @@
const char *zDb = db->aDb[i].zName;
sqlite3Error(db, rc, "database schema is locked: %s", zDb);
(void)sqlite3SafetyOff(db);
testcase( db->flags & SQLITE_ReadUncommitted );
- return sqlite3ApiExit(db, rc);
- }
- }
- }
-
- memset(&sParse, 0, sizeof(sParse));
- sParse.db = db;
+ goto end_prepare;
+ }
+ }
+ }
+
+
+ pParse->db = db;
if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
char *zSqlCopy;
int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
if( nBytes>mxLen ){
sqlite3Error(db, SQLITE_TOOBIG, "statement too long");
(void)sqlite3SafetyOff(db);
- return sqlite3ApiExit(db, SQLITE_TOOBIG);
+ rc = sqlite3ApiExit(db, SQLITE_TOOBIG);
+ goto end_prepare;
}
zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes);
if( zSqlCopy ){
- sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg);
+ sqlite3RunParser(pParse, zSqlCopy, &zErrMsg);
sqlite3DbFree(db, zSqlCopy);
- sParse.zTail = &zSql[sParse.zTail-zSqlCopy];
- }else{
- sParse.zTail = &zSql[nBytes];
- }
- }else{
- sqlite3RunParser(&sParse, zSql, &zErrMsg);
- }
-
- if( db->mallocFailed ){
- sParse.rc = SQLITE_NOMEM;
- }
- if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
- if( sParse.checkSchema && !schemaIsValid(db) ){
- sParse.rc = SQLITE_SCHEMA;
- }
- if( sParse.rc==SQLITE_SCHEMA ){
+ pParse->zTail = &zSql[pParse->zTail-zSqlCopy];
+ }else{
+ pParse->zTail = &zSql[nBytes];
+ }
+ }else{
+ sqlite3RunParser(pParse, zSql, &zErrMsg);
+ }
+
+ if( db->mallocFailed ){
+ pParse->rc = SQLITE_NOMEM;
+ }
+ if( pParse->rc==SQLITE_DONE ) pParse->rc = SQLITE_OK;
+ if( pParse->checkSchema && !schemaIsValid(db) ){
+ pParse->rc = SQLITE_SCHEMA;
+ }
+ if( pParse->rc==SQLITE_SCHEMA ){
sqlite3ResetInternalSchema(db, 0);
}
if( db->mallocFailed ){
- sParse.rc = SQLITE_NOMEM;
+ pParse->rc = SQLITE_NOMEM;
}
if( pzTail ){
- *pzTail = sParse.zTail;
- }
- rc = sParse.rc;
+ *pzTail = pParse->zTail;
+ }
+ rc = pParse->rc;
#ifndef SQLITE_OMIT_EXPLAIN
- if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
- if( sParse.explain==2 ){
- sqlite3VdbeSetNumCols(sParse.pVdbe, 3);
- sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "order", SQLITE_STATIC);
- sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "from", SQLITE_STATIC);
- sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "detail", SQLITE_STATIC);
- }else{
- sqlite3VdbeSetNumCols(sParse.pVdbe, 8);
- sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "addr", SQLITE_STATIC);
- sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "opcode", SQLITE_STATIC);
- sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "p1", SQLITE_STATIC);
- sqlite3VdbeSetColName(sParse.pVdbe, 3, COLNAME_NAME, "p2", SQLITE_STATIC);
- sqlite3VdbeSetColName(sParse.pVdbe, 4, COLNAME_NAME, "p3", SQLITE_STATIC);
- sqlite3VdbeSetColName(sParse.pVdbe, 5, COLNAME_NAME, "p4", SQLITE_STATIC);
- sqlite3VdbeSetColName(sParse.pVdbe, 6, COLNAME_NAME, "p5", SQLITE_STATIC);
- sqlite3VdbeSetColName(sParse.pVdbe, 7, COLNAME_NAME, "comment", SQLITE_STATIC);
+ if( rc==SQLITE_OK && pParse->pVdbe && pParse->explain ){
+ static const char * const azColName[] = {
+ "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
+ "order", "from", "detail"
+ };
+ int iFirst, mx;
+ if( pParse->explain==2 ){
+ sqlite3VdbeSetNumCols(pParse->pVdbe, 3);
+ iFirst = 8;
+ mx = 11;
+ }else{
+ sqlite3VdbeSetNumCols(pParse->pVdbe, 8);
+ iFirst = 0;
+ mx = 8;
+ }
+ for(i=iFirst; i<mx; i++){
+ sqlite3VdbeSetColName(pParse->pVdbe, i-iFirst, COLNAME_NAME,
+ azColName[i], SQLITE_STATIC);
}
}
#endif
@@ -74084,16 +75272,16 @@
}
assert( db->init.busy==0 || saveSqlFlag==0 );
if( db->init.busy==0 ){
- Vdbe *pVdbe = sParse.pVdbe;
- sqlite3VdbeSetSql(pVdbe, zSql, (int)(sParse.zTail-zSql), saveSqlFlag);
- }
- if( sParse.pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){
- sqlite3VdbeFinalize(sParse.pVdbe);
+ Vdbe *pVdbe = pParse->pVdbe;
+ sqlite3VdbeSetSql(pVdbe, zSql, (int)(pParse->zTail-zSql), saveSqlFlag);
+ }
+ if( pParse->pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){
+ sqlite3VdbeFinalize(pParse->pVdbe);
assert(!(*ppStmt));
}else{
- *ppStmt = (sqlite3_stmt*)sParse.pVdbe;
+ *ppStmt = (sqlite3_stmt*)pParse->pVdbe;
}
if( zErrMsg ){
sqlite3Error(db, rc, "%s", zErrMsg);
@@ -74101,8 +75289,11 @@
}else{
sqlite3Error(db, rc, 0);
}
+end_prepare:
+
+ sqlite3StackFree(db, pParse);
rc = sqlite3ApiExit(db, rc);
assert( (rc&db->errMask)==rc );
return rc;
}
@@ -74295,9 +75486,9 @@
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
-** $Id: select.c,v 1.512 2009/05/03 20:23:54 drh Exp $
+** $Id: select.c,v 1.523 2009/06/01 16:53:10 shane Exp $
*/
/*
@@ -74353,9 +75544,9 @@
pNew = &standin;
memset(pNew, 0, sizeof(*pNew));
}
if( pEList==0 ){
- pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ALL,0,0,0), 0);
+ pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ALL,0));
}
pNew->pEList = pEList;
pNew->pSrc = pSrc;
pNew->pWhere = pWhere;
@@ -74365,8 +75556,9 @@
pNew->selFlags = isDistinct ? SF_Distinct : 0;
pNew->op = TK_SELECT;
pNew->pLimit = pLimit;
pNew->pOffset = pOffset;
+ assert( pOffset==0 || pLimit!=0 );
pNew->addrOpenEphm[0] = -1;
pNew->addrOpenEphm[1] = -1;
pNew->addrOpenEphm[2] = -1;
if( db->mallocFailed ) {
@@ -74407,35 +75599,38 @@
SQLITE_PRIVATE int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){
int jointype = 0;
Token *apAll[3];
Token *p;
+ /* 0123456789 123456789 123456789 123 */
+ static const char zKeyText[] = "naturaleftouterightfullinnercross";
static const struct {
- const char zKeyword[8];
- u8 nChar;
- u8 code;
- } keywords[] = {
- { "natural", 7, JT_NATURAL },
- { "left", 4, JT_LEFT|JT_OUTER },
- { "right", 5, JT_RIGHT|JT_OUTER },
- { "full", 4, JT_LEFT|JT_RIGHT|JT_OUTER },
- { "outer", 5, JT_OUTER },
- { "inner", 5, JT_INNER },
- { "cross", 5, JT_INNER|JT_CROSS },
+ u8 i; /* Beginning of keyword text in zKeyText[] */
+ u8 nChar; /* Length of the keyword in characters */
+ u8 code; /* Join type mask */
+ } aKeyword[] = {
+ /* natural */ { 0, 7, JT_NATURAL },
+ /* left */ { 6, 4, JT_LEFT|JT_OUTER },
+ /* outer */ { 10, 5, JT_OUTER },
+ /* right */ { 14, 5, JT_RIGHT|JT_OUTER },
+ /* full */ { 19, 4, JT_LEFT|JT_RIGHT|JT_OUTER },
+ /* inner */ { 23, 5, JT_INNER },
+ /* cross */ { 28, 5, JT_INNER|JT_CROSS },
};
int i, j;
apAll[0] = pA;
apAll[1] = pB;
apAll[2] = pC;
for(i=0; i<3 && apAll[i]; i++){
p = apAll[i];
- for(j=0; j<ArraySize(keywords); j++){
- if( p->n==keywords[j].nChar
- && sqlite3StrNICmp((char*)p->z, keywords[j].zKeyword, p->n)==0 ){
- jointype |= keywords[j].code;
- break;
- }
- }
- if( j>=ArraySize(keywords) ){
+ for(j=0; j<ArraySize(aKeyword); j++){
+ if( p->n==aKeyword[j].nChar
+ && sqlite3StrNICmp((char*)p->z, &zKeyText[aKeyword[j].i], p->n)==0 ){
+ jointype |= aKeyword[j].code;
+ break;
+ }
+ }
+ testcase( j==0 || j==1 || j==2 || j==3 || j==4 || j==5 || j==6 );
+ if( j>=ArraySize(aKeyword) ){
jointype |= JT_ERROR;
break;
}
}
@@ -74448,9 +75643,10 @@
if( pC==0 ){ zSp++; }
sqlite3ErrorMsg(pParse, "unknown or unsupported join type: "
"%T %T%s%T", pA, pB, zSp, pC);
jointype = JT_INNER;
- }else if( jointype & JT_RIGHT ){
+ }else if( (jointype & JT_OUTER)!=0
+ && (jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ){
sqlite3ErrorMsg(pParse,
"RIGHT and FULL OUTER JOINs are not currently supported");
jointype = JT_INNER;
}
@@ -74469,24 +75665,12 @@
return -1;
}
/*
-** Set the value of a token to a '\000'-terminated string.
-*/
-static void setToken(Token *p, const char *z){
- p->z = (u8*)z;
- p->n = z ? sqlite3Strlen30(z) : 0;
- p->dyn = 0;
- p->quoted = 0;
-}
-
-/*
** Create an expression node for an identifier with the name of zName
*/
SQLITE_PRIVATE Expr *sqlite3CreateIdExpr(Parse *pParse, const char *zName){
- Token dummy;
- setToken(&dummy, zName);
- return sqlite3PExpr(pParse, TK_ID, 0, 0, &dummy);
+ return sqlite3Expr(pParse->db, TK_ID, zName);
}
/*
** Add a term to the WHERE expression in *ppExpr that requires the
@@ -74521,9 +75705,11 @@
pE2c = sqlite3PExpr(pParse, TK_DOT, pE2b, pE2a, 0);
pE = sqlite3PExpr(pParse, TK_EQ, pE1c, pE2c, 0);
if( pE && isOuterJoin ){
ExprSetProperty(pE, EP_FromJoin);
- pE->iRightJoinTable = iRightJoinTable;
+ assert( !ExprHasAnyProperty(pE, EP_TokenOnly|EP_Reduced) );
+ ExprSetIrreducible(pE);
+ pE->iRightJoinTable = (i16)iRightJoinTable;
}
*ppExpr = sqlite3ExprAnd(pParse->db,*ppExpr, pE);
}
@@ -74555,9 +75741,11 @@
*/
static void setJoinExpr(Expr *p, int iTable){
while( p ){
ExprSetProperty(p, EP_FromJoin);
- p->iRightJoinTable = iTable;
+ assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) );
+ ExprSetIrreducible(p);
+ p->iRightJoinTable = (i16)iTable;
setJoinExpr(p->pLeft, iTable);
p = p->pRight;
}
}
@@ -74872,8 +76060,10 @@
*/
case SRT_Table:
case SRT_EphemTab: {
int r1 = sqlite3GetTempReg(pParse);
+ testcase( eDest==SRT_Table );
+ testcase( eDest==SRT_EphemTab );
sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
if( pOrderBy ){
pushOntoSorter(pParse, pOrderBy, p, r1);
}else{
@@ -74940,8 +76130,10 @@
** popping the data from the stack.
*/
case SRT_Coroutine:
case SRT_Output: {
+ testcase( eDest==SRT_Coroutine );
+ testcase( eDest==SRT_Output );
if( pOrderBy ){
int r1 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
pushOntoSorter(pParse, pOrderBy, p, r1);
@@ -75081,11 +76273,11 @@
/* The LIMIT clause will terminate the loop for us */
break;
}
#endif
- case SRT_Output:
- case SRT_Coroutine: {
+ default: {
int i;
+ assert( eDest==SRT_Output || eDest==SRT_Coroutine );
testcase( eDest==SRT_Output );
testcase( eDest==SRT_Coroutine );
sqlite3VdbeAddOp2(v, OP_Integer, 1, regRowid);
sqlite3VdbeAddOp3(v, OP_Insert, pseudoTab, regRow, regRowid);
@@ -75098,12 +76290,8 @@
sqlite3ExprCacheAffinityChange(pParse, pDest->iMem, nColumn);
}else{
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm);
}
- break;
- }
- default: {
- /* Do nothing */
break;
}
}
sqlite3ReleaseTempReg(pParse, regRow);
@@ -75152,9 +76340,9 @@
char const *zOriginDb = 0;
char const *zOriginTab = 0;
char const *zOriginCol = 0;
int j;
- if( pExpr==0 || pNC->pSrcList==0 ) return 0;
+ if( NEVER(pExpr==0) || pNC->pSrcList==0 ) return 0;
switch( pExpr->op ){
case TK_AGG_COLUMN:
case TK_COLUMN: {
@@ -75164,8 +76352,10 @@
*/
Table *pTab = 0; /* Table structure column is extracted from */
Select *pS = 0; /* Select the column is extracted from */
int iCol = pExpr->iColumn; /* Index of column in pTab */
+ testcase( pExpr->op==TK_AGG_COLUMN );
+ testcase( pExpr->op==TK_COLUMN );
while( pNC && !pTab ){
SrcList *pTabList = pNC->pSrcList;
for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++);
if( j<pTabList->nSrc ){
@@ -75317,9 +76507,8 @@
return;
}
#endif
- assert( v!=0 );
if( pParse->colNamesSet || NEVER(v==0) || db->mallocFailed ) return;
pParse->colNamesSet = 1;
fullNames = (db->flags & SQLITE_FullColNames)!=0;
shortNames = (db->flags & SQLITE_ShortColNames)!=0;
@@ -75326,9 +76515,9 @@
sqlite3VdbeSetNumCols(v, pEList->nExpr);
for(i=0; i<pEList->nExpr; i++){
Expr *p;
p = pEList->a[i].pExpr;
- if( p==0 ) continue;
+ if( NEVER(p==0) ) continue;
if( pEList->a[i].zName ){
char *zName = pEList->a[i].zName;
sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT);
}else if( (p->op==TK_COLUMN || p->op==TK_AGG_COLUMN) && pTabList ){
@@ -75348,9 +76537,9 @@
zCol = pTab->aCol[iCol].zName;
}
if( !shortNames && !fullNames ){
sqlite3VdbeSetColName(v, i, COLNAME_NAME,
- sqlite3DbStrNDup(db, (char*)p->span.z, p->span.n), SQLITE_DYNAMIC);
+ sqlite3DbStrDup(db, pEList->a[i].zSpan), SQLITE_DYNAMIC);
}else if( fullNames ){
char *zName = 0;
zName = sqlite3MPrintf(db, "%s.%s", pTab->zName, zCol);
sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_DYNAMIC);
@@ -75358,9 +76547,9 @@
sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, SQLITE_TRANSIENT);
}
}else{
sqlite3VdbeSetColName(v, i, COLNAME_NAME,
- sqlite3DbStrNDup(db, (char*)p->span.z, p->span.n), SQLITE_DYNAMIC);
+ sqlite3DbStrDup(db, pEList->a[i].zSpan), SQLITE_DYNAMIC);
}
}
generateColumnTypes(pParse, pTabList, pEList);
}
@@ -75415,26 +76604,30 @@
for(i=0, pCol=aCol; i<nCol; i++, pCol++){
/* Get an appropriate name for the column
*/
p = pEList->a[i].pExpr;
- assert( p->pRight==0 || p->pRight->token.z==0 || p->pRight->token.z[0]!=0 );
+ assert( p->pRight==0 || ExprHasProperty(p->pRight, EP_IntValue)
+ || p->pRight->u.zToken==0 || p->pRight->u.zToken[0]!=0 );
if( (zName = pEList->a[i].zName)!=0 ){
/* If the column contains an "AS <name>" phrase, use <name> as the name */
zName = sqlite3DbStrDup(db, zName);
}else{
Expr *pColExpr = p; /* The expression that is the result column name */
Table *pTab; /* Table associated with this expression */
while( pColExpr->op==TK_DOT ) pColExpr = pColExpr->pRight;
- if( pColExpr->op==TK_COLUMN && (pTab = pColExpr->pTab)!=0 ){
+ if( pColExpr->op==TK_COLUMN && ALWAYS(pColExpr->pTab!=0) ){
/* For columns use the column name name */
int iCol = pColExpr->iColumn;
+ pTab = pColExpr->pTab;
if( iCol<0 ) iCol = pTab->iPKey;
zName = sqlite3MPrintf(db, "%s",
iCol>=0 ? pTab->aCol[iCol].zName : "rowid");
+ }else if( pColExpr->op==TK_ID ){
+ assert( !ExprHasProperty(pColExpr, EP_IntValue) );
+ zName = sqlite3MPrintf(db, "%s", pColExpr->u.zToken);
}else{
/* Use the original text of the column expression as its name */
- Token *pToken = (pColExpr->span.z?&pColExpr->span:&pColExpr->token);
- zName = sqlite3MPrintf(db, "%T", pToken);
+ zName = sqlite3MPrintf(db, "%s", pEList->a[i].zSpan);
}
}
if( db->mallocFailed ){
sqlite3DbFree(db, zName);
@@ -75505,8 +76698,9 @@
for(i=0, pCol=aCol; i<nCol; i++, pCol++){
p = a[i].pExpr;
pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p, 0, 0, 0));
pCol->affinity = sqlite3ExprAffinity(p);
+ if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_NONE;
pColl = sqlite3ExprCollSeq(pParse, p);
if( pColl ){
pCol->zColl = sqlite3DbStrDup(db, pColl->zName);
}
@@ -75532,9 +76726,12 @@
pTab = sqlite3DbMallocZero(db, sizeof(Table) );
if( pTab==0 ){
return 0;
}
- pTab->dbMem = db->lookaside.bEnabled ? db : 0;
+ /* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside
+ ** is disabled, so we might as well hard-code pTab->dbMem to NULL. */
+ assert( db->lookaside.bEnabled==0 );
+ pTab->dbMem = 0;
pTab->nRef = 1;
pTab->zName = 0;
selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSelect);
@@ -75595,31 +76792,26 @@
** The current implementation interprets "LIMIT 0" to mean
** no rows.
*/
sqlite3ExprCacheClear(pParse);
+ assert( p->pOffset==0 || p->pLimit!=0 );
if( p->pLimit ){
p->iLimit = iLimit = ++pParse->nMem;
v = sqlite3GetVdbe(pParse);
- if( v==0 ) return;
+ if( NEVER(v==0) ) return; /* VDBE should have already been allocated */
sqlite3ExprCode(pParse, p->pLimit, iLimit);
sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit);
VdbeComment((v, "LIMIT counter"));
sqlite3VdbeAddOp2(v, OP_IfZero, iLimit, iBreak);
- }
- if( p->pOffset ){
- p->iOffset = iOffset = ++pParse->nMem;
- if( p->pLimit ){
+ if( p->pOffset ){
+ p->iOffset = iOffset = ++pParse->nMem;
pParse->nMem++; /* Allocate an extra register for limit+offset */
- }
- v = sqlite3GetVdbe(pParse);
- if( v==0 ) return;
- sqlite3ExprCode(pParse, p->pOffset, iOffset);
- sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset);
- VdbeComment((v, "OFFSET counter"));
- addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iOffset);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, iOffset);
- sqlite3VdbeJumpHere(v, addr1);
- if( p->pLimit ){
+ sqlite3ExprCode(pParse, p->pOffset, iOffset);
+ sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset);
+ VdbeComment((v, "OFFSET counter"));
+ addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iOffset);
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, iOffset);
+ sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp3(v, OP_Add, iLimit, iOffset, iOffset+1);
VdbeComment((v, "LIMIT+OFFSET"));
addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iLimit);
sqlite3VdbeAddOp2(v, OP_Integer, -1, iOffset+1);
@@ -75775,13 +76967,11 @@
addr = sqlite3VdbeAddOp1(v, OP_IfZero, p->iLimit);
VdbeComment((v, "Jump ahead if LIMIT reached"));
}
rc = sqlite3Select(pParse, p, &dest);
+ testcase( rc!=SQLITE_OK );
pDelete = p->pPrior;
p->pPrior = pPrior;
- if( rc ){
- goto multi_select_end;
- }
if( addr ){
sqlite3VdbeJumpHere(v, addr);
}
break;
@@ -75794,8 +76984,10 @@
Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */
int addr;
SelectDest uniondest;
+ testcase( p->op==TK_EXCEPT );
+ testcase( p->op==TK_UNION );
priorOp = SRT_Union;
if( dest.eDest==priorOp && ALWAYS(!p->pLimit &&!p->pOffset) ){
/* We can reuse a temporary table generated by a SELECT to our
** right.
@@ -75841,8 +77033,9 @@
pOffset = p->pOffset;
p->pOffset = 0;
uniondest.eDest = op;
rc = sqlite3Select(pParse, p, &uniondest);
+ testcase( rc!=SQLITE_OK );
/* Query flattening in sqlite3Select() might refill p->pOrderBy.
** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
sqlite3ExprListDelete(db, p->pOrderBy);
pDelete = p->pPrior;
@@ -75852,17 +77045,14 @@
p->pLimit = pLimit;
p->pOffset = pOffset;
p->iLimit = 0;
p->iOffset = 0;
- if( rc ){
- goto multi_select_end;
- }
-
/* Convert the data in the temporary table into whatever form
** it is that we currently need.
*/
- if( dest.eDest!=priorOp || unionTab!=dest.iParm ){
+ assert( unionTab==dest.iParm || dest.eDest!=priorOp );
+ if( dest.eDest!=priorOp ){
int iCont, iBreak, iStart;
assert( p->pEList );
if( dest.eDest==SRT_Output ){
Select *pFirst = p;
@@ -75882,9 +77072,9 @@
sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0);
}
break;
}
- case TK_INTERSECT: {
+ default: assert( p->op==TK_INTERSECT ); {
int tab1, tab2;
int iCont, iBreak, iStart;
Expr *pLimit, *pOffset;
int addr;
@@ -75924,16 +77114,14 @@
pOffset = p->pOffset;
p->pOffset = 0;
intersectdest.iParm = tab2;
rc = sqlite3Select(pParse, p, &intersectdest);
+ testcase( rc!=SQLITE_OK );
pDelete = p->pPrior;
p->pPrior = pPrior;
sqlite3ExprDelete(db, p->pLimit);
p->pLimit = pLimit;
p->pOffset = pOffset;
- if( rc ){
- goto multi_select_end;
- }
/* Generate code to take the intersection of the two temporary
** tables.
*/
@@ -76084,8 +77272,10 @@
case SRT_Table:
case SRT_EphemTab: {
int r1 = sqlite3GetTempReg(pParse);
int r2 = sqlite3GetTempReg(pParse);
+ testcase( pDest->eDest==SRT_Table );
+ testcase( pDest->eDest==SRT_EphemTab );
sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iMem, pIn->nMem, r1);
sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iParm, r2);
sqlite3VdbeAddOp3(v, OP_Insert, pDest->iParm, r1, r2);
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
@@ -76146,28 +77336,22 @@
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm);
break;
}
- /* Results are stored in a sequence of registers. Then the
- ** OP_ResultRow opcode is used to cause sqlite3_step() to return
- ** the next row of result.
- */
- case SRT_Output: {
+ /* If none of the above, then the result destination must be
+ ** SRT_Output. This routine is never called with any other
+ ** destination other than the ones handled above or SRT_Output.
+ **
+ ** For SRT_Output, results are stored in a sequence of registers.
+ ** Then the OP_ResultRow opcode is used to cause sqlite3_step() to
+ ** return the next row of result.
+ */
+ default: {
+ assert( pDest->eDest==SRT_Output );
sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iMem, pIn->nMem);
sqlite3ExprCacheAffinityChange(pParse, pIn->iMem, pIn->nMem);
break;
}
-
-#if !defined(SQLITE_OMIT_TRIGGER)
- /* Discard the results. This is used for SELECT statements inside
- ** the body of a TRIGGER. The purpose of such selects is to call
- ** user-defined functions that have side effects. We do not care
- ** about the actual results of the select.
- */
- default: {
- break;
- }
-#endif
}
/* Jump to the end of the loop if the LIMIT is reached.
*/
@@ -76314,9 +77498,9 @@
assert( p->pOrderBy!=0 );
assert( pKeyDup==0 ); /* "Managed" code needs this. Ticket #3382. */
db = pParse->db;
v = pParse->pVdbe;
- if( v==0 ) return SQLITE_NOMEM;
+ assert( v!=0 ); /* Already thrown the error if VDBE alloc failed */
labelEnd = sqlite3VdbeMakeLabel(v);
labelCmpr = sqlite3VdbeMakeLabel(v);
@@ -76340,13 +77524,13 @@
assert( pItem->iCol>0 );
if( pItem->iCol==i ) break;
}
if( j==nOrderBy ){
- Expr *pNew = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, 0);
+ Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
if( pNew==0 ) return SQLITE_NOMEM;
pNew->flags |= EP_IntValue;
- pNew->iTable = i;
- pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew, 0);
+ pNew->u.iValue = i;
+ pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
pOrderBy->a[nOrderBy++].iCol = (u16)i;
}
}
}
@@ -76629,54 +77813,36 @@
** FORM clause entry is iTable. This routine make the necessary
** changes to pExpr so that it refers directly to the source table
** of the subquery rather the result set of the subquery.
*/
-static void substExpr(
+static Expr *substExpr(
sqlite3 *db, /* Report malloc errors to this connection */
Expr *pExpr, /* Expr in which substitution occurs */
int iTable, /* Table to be substituted */
ExprList *pEList /* Substitute expressions */
){
- if( pExpr==0 ) return;
+ if( pExpr==0 ) return 0;
if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){
if( pExpr->iColumn<0 ){
pExpr->op = TK_NULL;
}else{
Expr *pNew;
assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
assert( pExpr->pLeft==0 && pExpr->pRight==0 );
- pNew = pEList->a[pExpr->iColumn].pExpr;
- assert( pNew!=0 );
- pExpr->op = pNew->op;
- assert( pExpr->pLeft==0 );
- pExpr->pLeft = sqlite3ExprDup(db, pNew->pLeft, 0);
- assert( pExpr->pRight==0 );
- pExpr->pRight = sqlite3ExprDup(db, pNew->pRight, 0);
- pExpr->iTable = pNew->iTable;
- pExpr->pTab = pNew->pTab;
- pExpr->iColumn = pNew->iColumn;
- pExpr->iAgg = pNew->iAgg;
- sqlite3TokenCopy(db, &pExpr->token, &pNew->token);
- sqlite3TokenCopy(db, &pExpr->span, &pNew->span);
- assert( pExpr->x.pList==0 && pExpr->x.pSelect==0 );
- if( ExprHasProperty(pNew, EP_xIsSelect) ){
- pExpr->x.pSelect = sqlite3SelectDup(db, pNew->x.pSelect, 0);
- }else{
- pExpr->x.pList = sqlite3ExprListDup(db, pNew->x.pList, 0);
- }
- pExpr->flags = pNew->flags;
- pExpr->pAggInfo = pNew->pAggInfo;
- pNew->pAggInfo = 0;
- }
- }else{
- substExpr(db, pExpr->pLeft, iTable, pEList);
- substExpr(db, pExpr->pRight, iTable, pEList);
+ pNew = sqlite3ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0);
+ sqlite3ExprDelete(db, pExpr);
+ pExpr = pNew;
+ }
+ }else{
+ pExpr->pLeft = substExpr(db, pExpr->pLeft, iTable, pEList);
+ pExpr->pRight = substExpr(db, pExpr->pRight, iTable, pEList);
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
substSelect(db, pExpr->x.pSelect, iTable, pEList);
}else{
substExprList(db, pExpr->x.pList, iTable, pEList);
}
}
+ return pExpr;
}
static void substExprList(
sqlite3 *db, /* Report malloc errors here */
ExprList *pList, /* List to scan and in which to make substitutes */
@@ -76685,9 +77851,9 @@
){
int i;
if( pList==0 ) return;
for(i=0; i<pList->nExpr; i++){
- substExpr(db, pList->a[i].pExpr, iTable, pEList);
+ pList->a[i].pExpr = substExpr(db, pList->a[i].pExpr, iTable, pEList);
}
}
static void substSelect(
sqlite3 *db, /* Report malloc errors here */
@@ -76701,10 +77867,10 @@
if( !p ) return;
substExprList(db, p->pEList, iTable, pEList);
substExprList(db, p->pGroupBy, iTable, pEList);
substExprList(db, p->pOrderBy, iTable, pEList);
- substExpr(db, p->pHaving, iTable, pEList);
- substExpr(db, p->pWhere, iTable, pEList);
+ p->pHaving = substExpr(db, p->pHaving, iTable, pEList);
+ p->pWhere = substExpr(db, p->pWhere, iTable, pEList);
substSelect(db, p->pPrior, iTable, pEList);
pSrc = p->pSrc;
assert( pSrc ); /* Even for (SELECT 1) we have: pSrc!=0 but pSrc->nSrc==0 */
if( ALWAYS(pSrc) ){
@@ -76928,11 +78094,13 @@
if( isAgg || (p->selFlags & SF_Distinct)!=0 || pSrc->nSrc!=1 ){
return 0;
}
for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){
+ testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
+ testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0
|| (pSub1->pPrior && pSub1->op!=TK_ALL)
- || !pSub1->pSrc || pSub1->pSrc->nSrc!=1
+ || NEVER(pSub1->pSrc==0) || pSub1->pSrc->nSrc!=1
){
return 0;
}
}
@@ -77030,10 +78198,12 @@
/* Defer deleting the Table object associated with the
** subquery until code generation is
** complete, since there may still exist Expr.pTab entries that
** refer to the subquery even after flattening. Ticket #3346.
- */
- if( pSubitem->pTab!=0 ){
+ **
+ ** pSubitem->pTab is always non-NULL by test restrictions and tests above.
+ */
+ if( ALWAYS(pSubitem->pTab!=0) ){
Table *pTabToDel = pSubitem->pTab;
if( pTabToDel->nRef==1 ){
pTabToDel->pNextZombie = pParse->pZombieTab;
pParse->pZombieTab = pTabToDel;
@@ -77119,18 +78289,19 @@
** "a" we substitute "x*3" and every place we see "b" we substitute "y+10".
*/
pList = pParent->pEList;
for(i=0; i<pList->nExpr; i++){
- Expr *pExpr;
- if( pList->a[i].zName==0 && (pExpr = pList->a[i].pExpr)->span.z!=0 ){
- pList->a[i].zName =
- sqlite3DbStrNDup(db, (char*)pExpr->span.z, pExpr->span.n);
+ if( pList->a[i].zName==0 ){
+ const char *zSpan = pList->a[i].zSpan;
+ if( ALWAYS(zSpan) ){
+ pList->a[i].zName = sqlite3DbStrDup(db, zSpan);
+ }
}
}
substExprList(db, pParent->pEList, iParent, pSub->pEList);
if( isAgg ){
substExprList(db, pParent->pGroupBy, iParent, pSub->pEList);
- substExpr(db, pParent->pHaving, iParent, pSub->pEList);
+ pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
}
if( pSub->pOrderBy ){
assert( pParent->pOrderBy==0 );
pParent->pOrderBy = pSub->pOrderBy;
@@ -77146,15 +78317,15 @@
if( subqueryIsAgg ){
assert( pParent->pHaving==0 );
pParent->pHaving = pParent->pWhere;
pParent->pWhere = pWhere;
- substExpr(db, pParent->pHaving, iParent, pSub->pEList);
+ pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
pParent->pHaving = sqlite3ExprAnd(db, pParent->pHaving,
sqlite3ExprDup(db, pSub->pHaving, 0));
assert( pParent->pGroupBy==0 );
pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0);
}else{
- substExpr(db, pParent->pWhere, iParent, pSub->pEList);
+ pParent->pWhere = substExpr(db, pParent->pWhere, iParent, pSub->pEList);
pParent->pWhere = sqlite3ExprAnd(db, pParent->pWhere, pWhere);
}
/* The flattened query is distinct if either the inner or the
@@ -77199,16 +78370,17 @@
ExprList *pEList = p->pEList;
if( pEList->nExpr!=1 ) return WHERE_ORDERBY_NORMAL;
pExpr = pEList->a[0].pExpr;
- if( ExprHasProperty(pExpr, EP_xIsSelect) ) return 0;
+ if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
+ if( NEVER(ExprHasProperty(pExpr, EP_xIsSelect)) ) return 0;
pEList = pExpr->x.pList;
- if( pExpr->op!=TK_AGG_FUNCTION || pEList==0 || pEList->nExpr!=1 ) return 0;
+ if( pEList==0 || pEList->nExpr!=1 ) return 0;
if( pEList->a[0].pExpr->op!=TK_AGG_COLUMN ) return WHERE_ORDERBY_NORMAL;
- if( pExpr->token.n!=3 ) return WHERE_ORDERBY_NORMAL;
- if( sqlite3StrNICmp((char*)pExpr->token.z,"min",3)==0 ){
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ if( sqlite3StrICmp(pExpr->u.zToken,"min")==0 ){
return WHERE_ORDERBY_MIN;
- }else if( sqlite3StrNICmp((char*)pExpr->token.z,"max",3)==0 ){
+ }else if( sqlite3StrICmp(pExpr->u.zToken,"max")==0 ){
return WHERE_ORDERBY_MAX;
}
return WHERE_ORDERBY_NORMAL;
}
@@ -77306,9 +78478,9 @@
if( db->mallocFailed ){
return WRC_Abort;
}
- if( p->pSrc==0 || (p->selFlags & SF_Expanded)!=0 ){
+ if( NEVER(p->pSrc==0) || (p->selFlags & SF_Expanded)!=0 ){
return WRC_Prune;
}
p->selFlags |= SF_Expanded;
pTabList = p->pSrc;
@@ -77358,18 +78530,11 @@
#if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
if( pTab->pSelect || IsVirtual(pTab) ){
/* We reach here if the named table is a really a view */
if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
-
- /* If pFrom->pSelect!=0 it means we are dealing with a
- ** view within a view. The SELECT structure has already been
- ** copied by the outer view so we can skip the copy step here
- ** in the inner view.
- */
- if( pFrom->pSelect==0 ){
- pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
- sqlite3WalkSelect(pWalker, pFrom->pSelect);
- }
+ assert( pFrom->pSelect==0 );
+ pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
+ sqlite3WalkSelect(pWalker, pFrom->pSelect);
}
#endif
}
@@ -77397,10 +78562,11 @@
*/
for(k=0; k<pEList->nExpr; k++){
Expr *pE = pEList->a[k].pExpr;
if( pE->op==TK_ALL ) break;
- if( pE->op==TK_DOT && pE->pRight && pE->pRight->op==TK_ALL
- && pE->pLeft && pE->pLeft->op==TK_ID ) break;
+ assert( pE->op!=TK_DOT || pE->pRight!=0 );
+ assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) );
+ if( pE->op==TK_DOT && pE->pRight->op==TK_ALL ) break;
}
if( k<pEList->nExpr ){
/*
** If we get here it means the result set contains one or more "*"
@@ -77414,32 +78580,36 @@
&& (flags & SQLITE_ShortColNames)==0;
for(k=0; k<pEList->nExpr; k++){
Expr *pE = a[k].pExpr;
- if( pE->op!=TK_ALL &&
- (pE->op!=TK_DOT || pE->pRight==0 || pE->pRight->op!=TK_ALL) ){
+ assert( pE->op!=TK_DOT || pE->pRight!=0 );
+ if( pE->op!=TK_ALL && (pE->op!=TK_DOT || pE->pRight->op!=TK_ALL) ){
/* This particular expression does not need to be expanded.
*/
- pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr, 0);
+ pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr);
if( pNew ){
pNew->a[pNew->nExpr-1].zName = a[k].zName;
- }
- a[k].pExpr = 0;
- a[k].zName = 0;
+ pNew->a[pNew->nExpr-1].zSpan = a[k].zSpan;
+ a[k].zName = 0;
+ a[k].zSpan = 0;
+ }
+ a[k].pExpr = 0;
}else{
/* This expression is a "*" or a "TABLE.*" and needs to be
** expanded. */
int tableSeen = 0; /* Set to 1 when TABLE matches */
char *zTName; /* text of name of TABLE */
- if( pE->op==TK_DOT && pE->pLeft ){
- zTName = sqlite3NameFromToken(db, &pE->pLeft->token);
+ if( pE->op==TK_DOT ){
+ assert( pE->pLeft!=0 );
+ assert( !ExprHasProperty(pE->pLeft, EP_IntValue) );
+ zTName = pE->pLeft->u.zToken;
}else{
zTName = 0;
}
for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
Table *pTab = pFrom->pTab;
char *zTabName = pFrom->zAlias;
- if( zTabName==0 || zTabName[0]==0 ){
+ if( zTabName==0 ){
zTabName = pTab->zName;
}
if( db->mallocFailed ) break;
if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
@@ -77448,8 +78618,11 @@
tableSeen = 1;
for(j=0; j<pTab->nCol; j++){
Expr *pExpr, *pRight;
char *zName = pTab->aCol[j].zName;
+ char *zColname; /* The computed column name */
+ char *zToFree; /* Malloced string that needs to be freed */
+ Token sColname; /* Computed column name as a token */
/* If a column is marked as 'hidden' (currently only possible
** for virtual tables), do not include it in the expanded
** result-set list.
@@ -77472,32 +78645,27 @@
** using clause from the table on the right. */
continue;
}
}
- pRight = sqlite3PExpr(pParse, TK_ID, 0, 0, 0);
- if( pRight==0 ) break;
- setToken(&pRight->token, zName);
+ pRight = sqlite3Expr(db, TK_ID, zName);
+ zColname = zName;
+ zToFree = 0;
if( longNames || pTabList->nSrc>1 ){
- Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, 0);
+ Expr *pLeft;
+ pLeft = sqlite3Expr(db, TK_ID, zTabName);
pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
- if( pExpr==0 ) break;
- setToken(&pLeft->token, zTabName);
- setToken(&pExpr->span,
- sqlite3MPrintf(db, "%s.%s", zTabName, zName));
- pExpr->span.dyn = 1;
- pExpr->token.z = 0;
- pExpr->token.n = 0;
- pExpr->token.dyn = 0;
+ if( longNames ){
+ zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName);
+ zToFree = zColname;
+ }
}else{
pExpr = pRight;
- pExpr->span = pExpr->token;
- pExpr->span.dyn = 0;
- }
- if( longNames ){
- pNew = sqlite3ExprListAppend(pParse, pNew, pExpr, &pExpr->span);
- }else{
- pNew = sqlite3ExprListAppend(pParse, pNew, pExpr, &pRight->token);
- }
+ }
+ pNew = sqlite3ExprListAppend(pParse, pNew, pExpr);
+ sColname.z = zColname;
+ sColname.n = sqlite3Strlen30(zColname);
+ sqlite3ExprListSetName(pParse, pNew, &sColname, 0);
+ sqlite3DbFree(db, zToFree);
}
}
if( !tableSeen ){
if( zTName ){
@@ -77505,9 +78673,8 @@
}else{
sqlite3ErrorMsg(pParse, "no tables specified");
}
}
- sqlite3DbFree(db, zTName);
}
}
sqlite3ExprListDelete(db, pEList);
p->pEList = pNew;
@@ -77576,21 +78743,20 @@
SrcList *pTabList;
struct SrcList_item *pFrom;
assert( p->selFlags & SF_Resolved );
- if( (p->selFlags & SF_HasTypeInfo)==0 ){
- p->selFlags |= SF_HasTypeInfo;
- pParse = pWalker->pParse;
- pTabList = p->pSrc;
- for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
- Table *pTab = pFrom->pTab;
- if( pTab && (pTab->tabFlags & TF_Ephemeral)!=0 ){
- /* A sub-query in the FROM clause of a SELECT */
- Select *pSel = pFrom->pSelect;
- assert( pSel );
- while( pSel->pPrior ) pSel = pSel->pPrior;
- selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSel);
- }
+ assert( (p->selFlags & SF_HasTypeInfo)==0 );
+ p->selFlags |= SF_HasTypeInfo;
+ pParse = pWalker->pParse;
+ pTabList = p->pSrc;
+ for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
+ Table *pTab = pFrom->pTab;
+ if( ALWAYS(pTab!=0) && (pTab->tabFlags & TF_Ephemeral)!=0 ){
+ /* A sub-query in the FROM clause of a SELECT */
+ Select *pSel = pFrom->pSelect;
+ assert( pSel );
+ while( pSel->pPrior ) pSel = pSel->pPrior;
+ selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSel);
}
}
return WRC_Continue;
}
@@ -77632,12 +78798,11 @@
Select *p, /* The SELECT statement being coded. */
NameContext *pOuterNC /* Name context for container */
){
sqlite3 *db;
- if( p==0 ) return;
+ if( NEVER(p==0) ) return;
db = pParse->db;
if( p->selFlags & SF_HasTypeInfo ) return;
- if( pParse->nErr || db->mallocFailed ) return;
sqlite3SelectExpand(pParse, p);
if( pParse->nErr || db->mallocFailed ) return;
sqlite3ResolveSelectNames(pParse, p, pOuterNC);
if( pParse->nErr || db->mallocFailed ) return;
@@ -77839,40 +79004,26 @@
}
if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
memset(&sAggInfo, 0, sizeof(sAggInfo));
- pOrderBy = p->pOrderBy;
- if( IgnorableOrderby(pDest) ){
- p->pOrderBy = 0;
-
- /* In these cases the DISTINCT operator makes no difference to the
- ** results, so remove it if it were specified.
- */
+ if( IgnorableOrderby(pDest) ){
assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union ||
pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard);
+ /* If ORDER BY makes no difference in the output then neither does
+ ** DISTINCT so it can be removed too. */
+ sqlite3ExprListDelete(db, p->pOrderBy);
+ p->pOrderBy = 0;
p->selFlags &= ~SF_Distinct;
}
sqlite3SelectPrep(pParse, p, 0);
+ pOrderBy = p->pOrderBy;
pTabList = p->pSrc;
pEList = p->pEList;
if( pParse->nErr || db->mallocFailed ){
goto select_end;
}
- p->pOrderBy = pOrderBy;
isAgg = (p->selFlags & SF_Aggregate)!=0;
- if( pEList==0 ) goto select_end;
-
- /*
- ** Do not even attempt to generate any code if we have already seen
- ** errors before this routine starts.
- */
- if( pParse->nErr>0 ) goto select_end;
-
- /* ORDER BY is ignored for some destinations.
- */
- if( IgnorableOrderby(pDest) ){
- pOrderBy = 0;
- }
+ assert( pEList!=0 );
/* Begin generating code.
*/
v = sqlite3GetVdbe(pParse);
@@ -77911,9 +79062,9 @@
assert( pItem->isPopulated==0 );
sqlite3Select(pParse, pSub, &dest);
pItem->isPopulated = 1;
}
- if( pParse->nErr || db->mallocFailed ){
+ if( /*pParse->nErr ||*/ db->mallocFailed ){
goto select_end;
}
pParse->nHeight -= sqlite3SelectExprHeight(p);
pTabList = p->pSrc;
@@ -77962,9 +79113,10 @@
/* If possible, rewrite the query to use GROUP BY instead of DISTINCT.
** GROUP BY might use an index, DISTINCT never does.
*/
- if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct && !p->pGroupBy ){
+ assert( p->pGroupBy==0 || (p->selFlags & SF_Aggregate)!=0 );
+ if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ){
p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
pGroupBy = p->pGroupBy;
p->selFlags &= ~SF_Distinct;
isDistinct = 0;
@@ -78280,11 +79432,9 @@
sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2);
VdbeComment((v, "Groupby result generator entry point"));
sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
finalizeAggFunctions(pParse, &sAggInfo);
- if( pHaving ){
- sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
- }
+ sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy,
distinct, pDest,
addrOutputRow+1, addrSetAbort);
sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
@@ -78295,9 +79445,9 @@
sqlite3VdbeResolveLabel(v, addrReset);
resetAccumulator(pParse, &sAggInfo);
sqlite3VdbeAddOp1(v, OP_Return, regReset);
- } /* endif pGroupBy */
+ } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
else {
ExprList *pDel = 0;
#ifndef SQLITE_OMIT_BTREECOUNT
Table *pTab;
@@ -78413,11 +79563,9 @@
finalizeAggFunctions(pParse, &sAggInfo);
}
pOrderBy = 0;
- if( pHaving ){
- sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL);
- }
+ sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL);
selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, -1,
pDest, addrEnd, addrEnd);
sqlite3ExprListDelete(db, pDel);
}
@@ -78472,10 +79620,10 @@
** code base. Then are intended to be called from within the debugger
** or from temporary "printf" statements inserted for debugging.
*/
SQLITE_PRIVATE void sqlite3PrintExpr(Expr *p){
- if( p->token.z && p->token.n>0 ){
- sqlite3DebugPrintf("(%.*s", p->token.n, p->token.z);
+ if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
+ sqlite3DebugPrintf("(%s", p->u.zToken);
}else{
sqlite3DebugPrintf("(%d", p->op);
}
if( p->pLeft ){
@@ -78765,9 +79913,9 @@
**
*************************************************************************
**
**
-** $Id: trigger.c,v 1.138 2009/05/06 18:42:21 drh Exp $
+** $Id: trigger.c,v 1.141 2009/05/28 01:00:55 drh Exp $
*/
#ifndef SQLITE_OMIT_TRIGGER
/*
@@ -78777,9 +79925,8 @@
while( pTriggerStep ){
TriggerStep * pTmp = pTriggerStep;
pTriggerStep = pTriggerStep->pNext;
- if( pTmp->target.dyn ) sqlite3DbFree(db, (char*)pTmp->target.z);
sqlite3ExprDelete(db, pTmp->pWhere);
sqlite3ExprListDelete(db, pTmp->pExprList);
sqlite3SelectDelete(db, pTmp->pSelect);
sqlite3IdListDelete(db, pTmp->pIdList);
@@ -78790,8 +79937,18 @@
/*
** Given table pTab, return a list of all the triggers attached to
** the table. The list is connected by Trigger.pNext pointers.
+**
+** All of the triggers on pTab that are in the same database as pTab
+** are already attached to pTab->pTrigger. But there might be additional
+** triggers on pTab in the TEMP schema. This routine prepends all
+** TEMP triggers on pTab to the beginning of the pTab->pTrigger list
+** and returns the combined list.
+**
+** To state it another way: This routine returns a list of all triggers
+** that fire off of pTab. The list will include any TEMP triggers on
+** pTab as well as the triggers lised in pTab->pTrigger.
*/
SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){
Schema * const pTmpSchema = pParse->db->aDb[1].pSchema;
Trigger *pList = 0; /* List of triggers to return */
@@ -78962,9 +80119,8 @@
pTrigger->op = (u8)op;
pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER;
pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);
pTrigger->pColumns = sqlite3IdListDup(db, pColumns);
- sqlite3TokenCopy(db, &pTrigger->nameToken,pName);
assert( pParse->pNewTrigger==0 );
pParse->pNewTrigger = pTrigger;
trigger_cleanup:
@@ -78992,20 +80148,23 @@
char *zName; /* Name of trigger */
sqlite3 *db = pParse->db; /* The database */
DbFixer sFix;
int iDb; /* Database containing the trigger */
+ Token nameToken; /* Trigger name for error reporting */
pTrig = pParse->pNewTrigger;
pParse->pNewTrigger = 0;
- if( pParse->nErr || !pTrig ) goto triggerfinish_cleanup;
+ if( NEVER(pParse->nErr) || !pTrig ) goto triggerfinish_cleanup;
zName = pTrig->name;
iDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
pTrig->step_list = pStepList;
while( pStepList ){
pStepList->pTrig = pTrig;
pStepList = pStepList->pNext;
}
- if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", &pTrig->nameToken)
+ nameToken.z = pTrig->name;
+ nameToken.n = sqlite3Strlen30(nameToken.z);
+ if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken)
&& sqlite3FixTriggerStep(&sFix, pTrig->step_list) ){
goto triggerfinish_cleanup;
}
@@ -79054,45 +80213,8 @@
sqlite3DeleteTriggerStep(db, pStepList);
}
/*
-** Make a copy of all components of the given trigger step. This has
-** the effect of copying all Expr.token.z values into memory obtained
-** from sqlite3_malloc(). As initially created, the Expr.token.z values
-** all point to the input string that was fed to the parser. But that
-** string is ephemeral - it will go away as soon as the sqlite3_exec()
-** call that started the parser exits. This routine makes a persistent
-** copy of all the Expr.token.z strings so that the TriggerStep structure
-** will be valid even after the sqlite3_exec() call returns.
-*/
-static void sqlitePersistTriggerStep(sqlite3 *db, TriggerStep *p){
- if( p->target.z ){
- p->target.z = (u8*)sqlite3DbStrNDup(db, (char*)p->target.z, p->target.n);
- p->target.dyn = 1;
- }
- if( p->pSelect ){
- Select *pNew = sqlite3SelectDup(db, p->pSelect, 1);
- sqlite3SelectDelete(db, p->pSelect);
- p->pSelect = pNew;
- }
- if( p->pWhere ){
- Expr *pNew = sqlite3ExprDup(db, p->pWhere, EXPRDUP_REDUCE);
- sqlite3ExprDelete(db, p->pWhere);
- p->pWhere = pNew;
- }
- if( p->pExprList ){
- ExprList *pNew = sqlite3ExprListDup(db, p->pExprList, 1);
- sqlite3ExprListDelete(db, p->pExprList);
- p->pExprList = pNew;
- }
- if( p->pIdList ){
- IdList *pNew = sqlite3IdListDup(db, p->pIdList);
- sqlite3IdListDelete(db, p->pIdList);
- p->pIdList = pNew;
- }
-}
-
-/*
** Turn a SELECT statement (that the pSelect parameter points to) into
** a trigger step. Return a pointer to a TriggerStep structure.
**
** The parser calls this routine when it finds a SELECT statement in
@@ -79103,14 +80225,35 @@
if( pTriggerStep==0 ) {
sqlite3SelectDelete(db, pSelect);
return 0;
}
-
pTriggerStep->op = TK_SELECT;
pTriggerStep->pSelect = pSelect;
pTriggerStep->orconf = OE_Default;
- sqlitePersistTriggerStep(db, pTriggerStep);
-
+ return pTriggerStep;
+}
+
+/*
+** Allocate space to hold a new trigger step. The allocated space
+** holds both the TriggerStep object and the TriggerStep.target.z string.
+**
+** If an OOM error occurs, NULL is returned and db->mallocFailed is set.
+*/
+static TriggerStep *triggerStepAllocate(
+ sqlite3 *db, /* Database connection */
+ int op, /* Trigger opcode */
+ Token *pName /* The target name */
+){
+ TriggerStep *pTriggerStep;
+
+ pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n);
+ if( pTriggerStep ){
+ char *z = (char*)&pTriggerStep[1];
+ memcpy(z, pName->z, pName->n);
+ pTriggerStep->target.z = z;
+ pTriggerStep->target.n = pName->n;
+ pTriggerStep->op = op;
+ }
return pTriggerStep;
}
/*
@@ -79132,22 +80275,19 @@
assert(pEList == 0 || pSelect == 0);
assert(pEList != 0 || pSelect != 0 || db->mallocFailed);
- pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep));
+ pTriggerStep = triggerStepAllocate(db, TK_INSERT, pTableName);
if( pTriggerStep ){
- pTriggerStep->op = TK_INSERT;
- pTriggerStep->pSelect = pSelect;
- pTriggerStep->target = *pTableName;
+ pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
pTriggerStep->pIdList = pColumn;
- pTriggerStep->pExprList = pEList;
- pTriggerStep->orconf = orconf;
- sqlitePersistTriggerStep(db, pTriggerStep);
+ pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE);
+ pTriggerStep->orconf = orconf;
}else{
sqlite3IdListDelete(db, pColumn);
- sqlite3ExprListDelete(db, pEList);
- sqlite3SelectDelete(db, pSelect);
- }
+ }
+ sqlite3ExprListDelete(db, pEList);
+ sqlite3SelectDelete(db, pSelect);
return pTriggerStep;
}
@@ -79162,22 +80302,18 @@
ExprList *pEList, /* The SET clause: list of column and new values */
Expr *pWhere, /* The WHERE clause */
int orconf /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
){
- TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep));
- if( pTriggerStep==0 ){
- sqlite3ExprListDelete(db, pEList);
- sqlite3ExprDelete(db, pWhere);
- return 0;
- }
-
- pTriggerStep->op = TK_UPDATE;
- pTriggerStep->target = *pTableName;
- pTriggerStep->pExprList = pEList;
- pTriggerStep->pWhere = pWhere;
- pTriggerStep->orconf = orconf;
- sqlitePersistTriggerStep(db, pTriggerStep);
-
+ TriggerStep *pTriggerStep;
+
+ pTriggerStep = triggerStepAllocate(db, TK_UPDATE, pTableName);
+ if( pTriggerStep ){
+ pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE);
+ pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
+ pTriggerStep->orconf = orconf;
+ }
+ sqlite3ExprListDelete(db, pEList);
+ sqlite3ExprDelete(db, pWhere);
return pTriggerStep;
}
/*
@@ -79189,20 +80325,16 @@
sqlite3 *db, /* Database connection */
Token *pTableName, /* The table from which rows are deleted */
Expr *pWhere /* The WHERE clause */
){
- TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep));
- if( pTriggerStep==0 ){
- sqlite3ExprDelete(db, pWhere);
- return 0;
- }
-
- pTriggerStep->op = TK_DELETE;
- pTriggerStep->target = *pTableName;
- pTriggerStep->pWhere = pWhere;
- pTriggerStep->orconf = OE_Default;
- sqlitePersistTriggerStep(db, pTriggerStep);
-
+ TriggerStep *pTriggerStep;
+
+ pTriggerStep = triggerStepAllocate(db, TK_DELETE, pTableName);
+ if( pTriggerStep ){
+ pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
+ pTriggerStep->orconf = OE_Default;
+ }
+ sqlite3ExprDelete(db, pWhere);
return pTriggerStep;
}
/*
@@ -79214,9 +80346,8 @@
sqlite3DbFree(db, pTrigger->name);
sqlite3DbFree(db, pTrigger->table);
sqlite3ExprDelete(db, pTrigger->pWhen);
sqlite3IdListDelete(db, pTrigger->pColumns);
- if( pTrigger->nameToken.dyn ) sqlite3DbFree(db, (char*)pTrigger->nameToken.z);
sqlite3DbFree(db, pTrigger);
}
/*
@@ -79336,9 +80467,9 @@
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){
Hash *pHash = &(db->aDb[iDb].pSchema->trigHash);
Trigger *pTrigger;
pTrigger = sqlite3HashInsert(pHash, zName, sqlite3Strlen30(zName), 0);
- if( pTrigger ){
+ if( ALWAYS(pTrigger) ){
if( pTrigger->pSchema==pTrigger->pTabSchema ){
Table *pTab = tableOfTrigger(pTrigger);
Trigger **pp;
for(pp=&pTab->pTrigger; *pp!=pTrigger; pp=&((*pp)->pNext));
@@ -79357,11 +80488,11 @@
** wildcard that matches anything. Likewise if pEList==NULL then
** it matches anything so always return true. Return false only
** if there is no match.
*/
-static int checkColumnOverLap(IdList *pIdList, ExprList *pEList){
+static int checkColumnOverlap(IdList *pIdList, ExprList *pEList){
int e;
- if( !pIdList || !pEList ) return 1;
+ if( pIdList==0 || NEVER(pEList==0) ) return 1;
for(e=0; e<pEList->nExpr; e++){
if( sqlite3IdListIndex(pIdList, pEList->a[e].zName)>=0 ) return 1;
}
return 0;
@@ -79384,9 +80515,9 @@
Trigger *pList = sqlite3TriggerList(pParse, pTab);
Trigger *p;
assert( pList==0 || IsVirtual(pTab)==0 );
for(p=pList; p; p=p->pNext){
- if( p->op==op && checkColumnOverLap(p->pColumns, pChanges) ){
+ if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){
mask |= p->tr_tm;
}
}
if( pMask ){
@@ -79408,21 +80539,21 @@
static SrcList *targetSrcList(
Parse *pParse, /* The parsing context */
TriggerStep *pStep /* The trigger containing the target token */
){
- Token sDb; /* Dummy database name token */
int iDb; /* Index of the database to use */
SrcList *pSrc; /* SrcList to be returned */
- iDb = sqlite3SchemaToIndex(pParse->db, pStep->pTrig->pSchema);
- if( iDb==0 || iDb>=2 ){
- assert( iDb<pParse->db->nDb );
- sDb.z = (u8*)pParse->db->aDb[iDb].zName;
- sDb.n = sqlite3Strlen30((char*)sDb.z);
- sDb.quoted = 0;
- pSrc = sqlite3SrcListAppend(pParse->db, 0, &sDb, &pStep->target);
- } else {
- pSrc = sqlite3SrcListAppend(pParse->db, 0, &pStep->target, 0);
+ pSrc = sqlite3SrcListAppend(pParse->db, 0, &pStep->target, 0);
+ if( pSrc ){
+ assert( pSrc->nSrc>0 );
+ assert( pSrc->a!=0 );
+ iDb = sqlite3SchemaToIndex(pParse->db, pStep->pTrig->pSchema);
+ if( iDb==0 || iDb>=2 ){
+ sqlite3 *db = pParse->db;
+ assert( iDb<pParse->db->nDb );
+ pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName);
+ }
}
return pSrc;
}
@@ -79448,19 +80579,8 @@
sqlite3ExprCacheClear(pParse);
orconf = (orconfin == OE_Default)?pTriggerStep->orconf:orconfin;
pParse->trigStack->orconf = orconf;
switch( pTriggerStep->op ){
- case TK_SELECT: {
- Select *ss = sqlite3SelectDup(db, pTriggerStep->pSelect, 0);
- if( ss ){
- SelectDest dest;
-
- sqlite3SelectDestInit(&dest, SRT_Discard, 0);
- sqlite3Select(pParse, ss, &dest);
- sqlite3SelectDelete(db, ss);
- }
- break;
- }
case TK_UPDATE: {
SrcList *pSrc;
pSrc = targetSrcList(pParse, pTriggerStep);
sqlite3VdbeAddOp2(v, OP_ResetCount, 0, 0);
@@ -79489,10 +80609,19 @@
sqlite3ExprDup(db, pTriggerStep->pWhere, 0));
sqlite3VdbeAddOp2(v, OP_ResetCount, 1, 0);
break;
}
- default:
- assert(0);
+ default: assert( pTriggerStep->op==TK_SELECT ); {
+ Select *ss = sqlite3SelectDup(db, pTriggerStep->pSelect, 0);
+ if( ss ){
+ SelectDest dest;
+
+ sqlite3SelectDestInit(&dest, SRT_Discard, 0);
+ sqlite3Select(pParse, ss, &dest);
+ sqlite3SelectDelete(db, ss);
+ }
+ break;
+ }
}
pTriggerStep = pTriggerStep->pNext;
}
sqlite3VdbeAddOp2(v, OP_ContextPop, 0, 0);
@@ -79556,14 +80685,20 @@
for(p=pTrigger; p; p=p->pNext){
int fire_this = 0;
+ /* Sanity checking: The schema for the trigger and for the table are
+ ** always defined. The trigger must be in the same schema as the table
+ ** or else it must be a TEMP trigger. */
+ assert( p->pSchema!=0 );
+ assert( p->pTabSchema!=0 );
+ assert( p->pSchema==p->pTabSchema || p->pSchema==db->aDb[1].pSchema );
+
/* Determine whether we should code this trigger */
if(
p->op==op &&
p->tr_tm==tr_tm &&
- (p->pSchema==p->pTabSchema || p->pSchema==db->aDb[1].pSchema) &&
- (op!=TK_UPDATE||!p->pColumns||checkColumnOverLap(p->pColumns,pChanges))
+ checkColumnOverlap(p->pColumns,pChanges)
){
TriggerStack *pS; /* Pointer to trigger-stack entry */
for(pS=pParse->trigStack; pS && p!=pS->pTrigger; pS=pS->pNext){}
if( !pS ){
@@ -79643,9 +80778,9 @@
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
-** $Id: update.c,v 1.200 2009/05/05 15:46:10 drh Exp $
+** $Id: update.c,v 1.202 2009/05/28 01:00:55 drh Exp $
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Forward declaration */
@@ -80260,12 +81395,12 @@
/* Construct the SELECT statement that will find the new values for
** all updated rows.
*/
pEList = sqlite3ExprListAppend(pParse, 0,
- sqlite3CreateIdExpr(pParse, "_rowid_"), 0);
+ sqlite3CreateIdExpr(pParse, "_rowid_"));
if( pRowid ){
pEList = sqlite3ExprListAppend(pParse, pEList,
- sqlite3ExprDup(db, pRowid, 0), 0);
+ sqlite3ExprDup(db, pRowid, 0));
}
assert( pTab->iPKey<0 );
for(i=0; i<pTab->nCol; i++){
if( aXRef[i]>=0 ){
@@ -80272,9 +81407,9 @@
pExpr = sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr, 0);
}else{
pExpr = sqlite3CreateIdExpr(pParse, pTab->aCol[i].zName);
}
- pEList = sqlite3ExprListAppend(pParse, pEList, pExpr, 0);
+ pEList = sqlite3ExprListAppend(pParse, pEList, pExpr);
}
pSelect = sqlite3SelectNew(pParse, pEList, pSrc, pWhere, 0, 0, 0, 0, 0, 0);
/* Create the ephemeral table into which the update results will
@@ -80332,9 +81467,9 @@
**
** Most of the code in this file may be omitted by defining the
** SQLITE_OMIT_VACUUM macro.
**
-** $Id: vacuum.c,v 1.88 2009/05/05 17:37:23 drh Exp $
+** $Id: vacuum.c,v 1.90 2009/06/03 11:25:07 danielk1977 Exp $
*/
#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
/*
@@ -80399,16 +81534,15 @@
*/
SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
int rc = SQLITE_OK; /* Return code from service routines */
Btree *pMain; /* The database being vacuumed */
- Pager *pMainPager; /* Pager for database being vacuumed */
Btree *pTemp; /* The temporary database we vacuum into */
char *zSql = 0; /* SQL statements */
int saved_flags; /* Saved value of the db->flags */
int saved_nChange; /* Saved value of db->nChange */
int saved_nTotalChange; /* Saved value of db->nTotalChange */
Db *pDb = 0; /* Database to detach at end of vacuum */
- int isMemDb; /* True is vacuuming a :memory: database */
+ int isMemDb; /* True if vacuuming a :memory: database */
int nRes;
if( !db->autoCommit ){
sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
@@ -80421,10 +81555,9 @@
saved_nTotalChange = db->nTotalChange;
db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
pMain = db->aDb[0].pBt;
- pMainPager = sqlite3BtreePager(pMain);
- isMemDb = sqlite3PagerFile(pMainPager)->pMethods==0;
+ isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));
/* Attach the temporary database as 'vacuum_db'. The synchronous pragma
** can be set to 'off' for this file, as it is not recovered if a crash
** occurs anyway. The integrity of the database is maintained by a
@@ -80559,12 +81692,12 @@
** The increment is used to increase the schema cookie so that other
** connections to the same database will know to reread the schema.
*/
static const unsigned char aCopy[] = {
- 1, 1, /* Add one to the old schema cookie */
- 3, 0, /* Preserve the default page cache size */
- 5, 0, /* Preserve the default text encoding */
- 6, 0, /* Preserve the user version */
+ BTREE_SCHEMA_VERSION, 1, /* Add one to the old schema cookie */
+ BTREE_DEFAULT_CACHE_SIZE, 0, /* Preserve the default page cache size */
+ BTREE_TEXT_ENCODING, 0, /* Preserve the text encoding */
+ BTREE_USER_VERSION, 0, /* Preserve the user version */
};
assert( 1==sqlite3BtreeIsInTrans(pTemp) );
assert( 1==sqlite3BtreeIsInTrans(pMain) );
@@ -80632,9 +81765,9 @@
**
*************************************************************************
** This file contains code used to help implement virtual tables.
**
-** $Id: vtab.c,v 1.86 2009/04/28 13:01:09 drh Exp $
+** $Id: vtab.c,v 1.90 2009/06/02 21:31:39 drh Exp $
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
@@ -80727,13 +81860,16 @@
pVtab->nRef--;
assert(db);
assert( sqlite3SafetyCheckOk(db) );
if( pVtab->nRef==0 ){
+#ifdef SQLITE_DEBUG
if( db->magic==SQLITE_MAGIC_BUSY ){
(void)sqlite3SafetyOff(db);
pVtab->pModule->xDisconnect(pVtab);
(void)sqlite3SafetyOn(db);
- } else {
+ } else
+#endif
+ {
pVtab->pModule->xDisconnect(pVtab);
}
}
}
@@ -80808,9 +81944,9 @@
}
sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, 0);
pTable = pParse->pNewTable;
- if( pTable==0 || pParse->nErr ) return;
+ if( pTable==0 ) return;
assert( 0==pTable->pIndex );
db = pParse->db;
iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
@@ -80841,9 +81977,9 @@
** in pParse->zArg[] and appends it to the list of arguments on the
** virtual table currently under construction in pParse->pTable.
*/
static void addArgumentToVtab(Parse *pParse){
- if( pParse->sArg.z && pParse->pNewTable ){
+ if( pParse->sArg.z && ALWAYS(pParse->pNewTable) ){
const char *z = (const char*)pParse->sArg.z;
int n = pParse->sArg.n;
sqlite3 *db = pParse->db;
addModuleArgument(db, pParse->pNewTable, sqlite3DbStrNDup(db, z, n));
@@ -80997,9 +82133,12 @@
rc = sqlite3SafetyOff(db);
assert( rc==SQLITE_OK );
rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVtab, &zErr);
rc2 = sqlite3SafetyOn(db);
- if( rc==SQLITE_OK && pVtab ){
+ if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
+ /* Justification of ALWAYS(): A correct vtab constructor must allocate
+ ** the sqlite3_vtab object if successful. */
+ if( rc==SQLITE_OK && ALWAYS(pVtab) ){
pVtab->pModule = pMod->pModule;
pVtab->nRef = 1;
pTab->pVtab = pVtab;
}
@@ -81072,9 +82211,10 @@
SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
Module *pMod;
int rc = SQLITE_OK;
- if( !pTab || (pTab->tabFlags & TF_Virtual)==0 || pTab->pVtab ){
+ assert( pTab );
+ if( (pTab->tabFlags & TF_Virtual)==0 || pTab->pVtab ){
return SQLITE_OK;
}
pMod = pTab->pMod;
@@ -81148,9 +82288,11 @@
}else{
rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xCreate, pzErr);
}
- if( rc==SQLITE_OK && pTab->pVtab ){
+ /* Justification of ALWAYS(): The xConstructor method is required to
+ ** create a valid sqlite3_vtab if it returns SQLITE_OK. */
+ if( rc==SQLITE_OK && ALWAYS(pTab->pVtab) ){
rc = addToVTrans(db, pTab->pVtab);
}
return rc;
@@ -81161,9 +82303,9 @@
** valid to call this function from within the xCreate() or xConnect() of a
** virtual table module.
*/
SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
- Parse sParse;
+ Parse *pParse;
int rc = SQLITE_OK;
Table *pTab;
char *zErr = 0;
@@ -81176,35 +82318,39 @@
return SQLITE_MISUSE;
}
assert((pTab->tabFlags & TF_Virtual)!=0 && pTab->nCol==0 && pTab->aCol==0);
- memset(&sParse, 0, sizeof(Parse));
- sParse.declareVtab = 1;
- sParse.db = db;
-
- if(
- SQLITE_OK == sqlite3RunParser(&sParse, zCreateTable, &zErr) &&
- sParse.pNewTable &&
- !sParse.pNewTable->pSelect &&
- (sParse.pNewTable->tabFlags & TF_Virtual)==0
- ){
- pTab->aCol = sParse.pNewTable->aCol;
- pTab->nCol = sParse.pNewTable->nCol;
- sParse.pNewTable->nCol = 0;
- sParse.pNewTable->aCol = 0;
- db->pVTab = 0;
- } else {
- sqlite3Error(db, SQLITE_ERROR, zErr);
- sqlite3DbFree(db, zErr);
- rc = SQLITE_ERROR;
- }
- sParse.declareVtab = 0;
-
- if( sParse.pVdbe ){
- sqlite3VdbeFinalize(sParse.pVdbe);
- }
- sqlite3DeleteTable(sParse.pNewTable);
- sParse.pNewTable = 0;
+ pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
+ if( pParse==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ pParse->declareVtab = 1;
+ pParse->db = db;
+
+ if(
+ SQLITE_OK == sqlite3RunParser(pParse, zCreateTable, &zErr) &&
+ pParse->pNewTable &&
+ !pParse->pNewTable->pSelect &&
+ (pParse->pNewTable->tabFlags & TF_Virtual)==0
+ ){
+ pTab->aCol = pParse->pNewTable->aCol;
+ pTab->nCol = pParse->pNewTable->nCol;
+ pParse->pNewTable->nCol = 0;
+ pParse->pNewTable->aCol = 0;
+ db->pVTab = 0;
+ } else {
+ sqlite3Error(db, SQLITE_ERROR, zErr);
+ sqlite3DbFree(db, zErr);
+ rc = SQLITE_ERROR;
+ }
+ pParse->declareVtab = 0;
+
+ if( pParse->pVdbe ){
+ sqlite3VdbeFinalize(pParse->pVdbe);
+ }
+ sqlite3DeleteTable(pParse->pNewTable);
+ sqlite3StackFree(db, pParse);
+ }
assert( (rc&0xff)==rc );
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
@@ -81217,22 +82363,18 @@
** when a DROP TABLE is mentioned.
**
** This call is a no-op if zTab is not a virtual table.
*/
-SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab)
-{
+SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
int rc = SQLITE_OK;
Table *pTab;
pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName);
- assert(pTab);
- if( pTab->pVtab ){
+ if( ALWAYS(pTab!=0 && pTab->pVtab!=0) ){
int (*xDestroy)(sqlite3_vtab *pVTab) = pTab->pMod->pModule->xDestroy;
rc = sqlite3SafetyOff(db);
assert( rc==SQLITE_OK );
- if( xDestroy ){
- rc = xDestroy(pTab->pVtab);
- }
+ rc = xDestroy(pTab->pVtab);
(void)sqlite3SafetyOn(db);
if( rc==SQLITE_OK ){
int i;
for(i=0; i<db->nVTrans; i++){
@@ -81258,11 +82400,13 @@
*/
static void callFinaliser(sqlite3 *db, int offset){
int i;
if( db->aVTrans ){
- for(i=0; i<db->nVTrans && db->aVTrans[i]; i++){
+ for(i=0; i<db->nVTrans; i++){
sqlite3_vtab *pVtab = db->aVTrans[i];
int (*x)(sqlite3_vtab *);
+
+ assert( pVtab!=0 );
x = *(int (**)(sqlite3_vtab *))((char *)pVtab->pModule + offset);
if( x ) x(pVtab);
sqlite3VtabUnlock(db, pVtab);
}
@@ -81287,11 +82431,12 @@
sqlite3_vtab **aVTrans = db->aVTrans;
rc = sqlite3SafetyOff(db);
db->aVTrans = 0;
- for(i=0; rc==SQLITE_OK && i<db->nVTrans && aVTrans[i]; i++){
+ for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){
sqlite3_vtab *pVtab = aVTrans[i];
int (*x)(sqlite3_vtab *);
+ assert( pVtab!=0 );
x = pVtab->pModule->xSync;
if( x ){
rc = x(pVtab);
sqlite3DbFree(db, *pzErrmsg);
@@ -81340,9 +82485,9 @@
/* Special case: If db->aVTrans is NULL and db->nVTrans is greater
** than zero, then this function is being called from within a
** virtual module xSync() callback. It is illegal to write to
- ** virtual module tables in this case, so return SQLITE_MISUSE.
+ ** virtual module tables in this case, so return SQLITE_LOCKED.
*/
if( sqlite3VtabInSync(db) ){
return SQLITE_LOCKED;
}
@@ -81355,9 +82500,9 @@
int i;
/* If pVtab is already in the aVTrans array, return early */
- for(i=0; (i<db->nVTrans) && 0!=db->aVTrans[i]; i++){
+ for(i=0; i<db->nVTrans; i++){
if( db->aVTrans[i]==pVtab ){
return SQLITE_OK;
}
}
@@ -81401,12 +82546,12 @@
unsigned char *z;
/* Check to see the left operand is a column in a virtual table */
- if( pExpr==0 ) return pDef;
+ if( NEVER(pExpr==0) ) return pDef;
if( pExpr->op!=TK_COLUMN ) return pDef;
pTab = pExpr->pTab;
- if( pTab==0 ) return pDef;
+ if( NEVER(pTab==0) ) return pDef;
if( (pTab->tabFlags & TF_Virtual)==0 ) return pDef;
pVtab = pTab->pVtab;
assert( pVtab!=0 );
assert( pVtab->pModule!=0 );
@@ -81422,13 +82567,8 @@
*z = sqlite3UpperToLower[*z];
}
rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xFunc, &pArg);
sqlite3DbFree(db, zLowerName);
- if( pVtab->zErrMsg ){
- sqlite3Error(db, rc, "%s", pVtab->zErrMsg);
- sqlite3DbFree(db, pVtab->zErrMsg);
- pVtab->zErrMsg = 0;
- }
}
if( rc==0 ){
return pDef;
}
@@ -81456,15 +82596,18 @@
** is a no-op.
*/
SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){
int i, n;
+ Table **apVtabLock;
+
assert( IsVirtual(pTab) );
for(i=0; i<pParse->nVtabLock; i++){
if( pTab==pParse->apVtabLock[i] ) return;
}
n = (pParse->nVtabLock+1)*sizeof(pParse->apVtabLock[0]);
- pParse->apVtabLock = sqlite3_realloc(pParse->apVtabLock, n);
- if( pParse->apVtabLock ){
+ apVtabLock = sqlite3_realloc(pParse->apVtabLock, n);
+ if( apVtabLock ){
+ pParse->apVtabLock = apVtabLock;
pParse->apVtabLock[pParse->nVtabLock++] = pTab;
}else{
pParse->db->mallocFailed = 1;
}
@@ -81491,9 +82634,9 @@
** 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.396 2009/05/06 19:03:14 drh Exp $
+** $Id: where.c,v 1.401 2009/06/06 15:17:28 drh Exp $
*/
/*
** Trace output macros
@@ -81601,13 +82744,18 @@
*/
struct WhereClause {
Parse *pParse; /* The parser context */
WhereMaskSet *pMaskSet; /* Mapping of table cursor numbers to bitmasks */
+ Bitmask vmask; /* Bitmask identifying virtual table cursors */
u8 op; /* Split operator. TK_AND or TK_OR */
int nTerm; /* Number of terms */
int nSlot; /* Number of entries in a[] */
WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */
- WhereTerm aStatic[4]; /* Initial static space for a[] */
+#if defined(SQLITE_SMALL_STACK)
+ WhereTerm aStatic[1]; /* Initial static space for a[] */
+#else
+ WhereTerm aStatic[8]; /* Initial static space for a[] */
+#endif
};
/*
** A WhereTerm with eOperator==WO_OR has its u.pOrInfo pointer set to
@@ -81728,8 +82876,9 @@
pWC->pMaskSet = pMaskSet;
pWC->nTerm = 0;
pWC->nSlot = ArraySize(pWC->aStatic);
pWC->a = pWC->aStatic;
+ pWC->vmask = 0;
}
/* Forward reference */
static void whereClauseClear(WhereClause*);
@@ -82100,9 +83249,8 @@
const char *z; /* String on RHS of LIKE operator */
Expr *pRight, *pLeft; /* Right and left size of LIKE operator */
ExprList *pList; /* List of operands to the LIKE operator */
int c; /* One character in z[] */
- int n; /* Length of string z[] */
int cnt; /* Number of non-wildcard prefix characters */
char wc[3]; /* Wildcard characters */
CollSeq *pColl; /* Collating sequence for LHS */
sqlite3 *db = pParse->db; /* Database connection */
@@ -82123,25 +83271,21 @@
return 0;
}
pColl = sqlite3ExprCollSeq(pParse, pLeft);
assert( pColl!=0 || pLeft->iColumn==-1 );
- if( pColl==0 ){
- /* No collation is defined for the ROWID. Use the default. */
- pColl = db->pDfltColl;
- }
+ if( pColl==0 ) return 0;
if( (pColl->type!=SQLITE_COLL_BINARY || *pnoCase) &&
(pColl->type!=SQLITE_COLL_NOCASE || !*pnoCase) ){
return 0;
}
- z = (const char*)pRight->token.z;
+ z = pRight->u.zToken;
cnt = 0;
- if( z ){
- n = pRight->token.n;
- while( cnt<n && (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
+ if( ALWAYS(z) ){
+ while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
cnt++;
}
}
- if( cnt==0 || 255==(u8)z[cnt-1] ){
+ if( cnt==0 || c==0 || 255==(u8)z[cnt-1] ){
return 0;
}
*pisComplete = z[cnt]==wc[0] && z[cnt+1]==0;
*pnPattern = cnt;
@@ -82165,10 +83309,9 @@
if( pExpr->op!=TK_FUNCTION ){
return 0;
}
- if( pExpr->token.n!=5 ||
- sqlite3StrNICmp((const char*)pExpr->token.z,"match",5)!=0 ){
+ if( sqlite3StrICmp(pExpr->u.zToken,"match")!=0 ){
return 0;
}
pList = pExpr->x.pList;
if( pList->nExpr!=2 ){
@@ -82303,9 +83446,10 @@
/*
** Compute the set of tables that might satisfy cases 1 or 2.
*/
- indexable = chngToIN = ~(Bitmask)0;
+ indexable = ~(Bitmask)0;
+ chngToIN = ~(pWC->vmask);
for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0 && indexable; i--, pOrTerm++){
if( (pOrTerm->eOperator & WO_SINGLE)==0 ){
WhereAndInfo *pAndInfo;
assert( pOrTerm->eOperator==0 );
@@ -82434,14 +83578,14 @@
assert( pOrTerm->eOperator==WO_EQ );
assert( pOrTerm->leftCursor==iCursor );
assert( pOrTerm->u.leftColumn==iColumn );
pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0);
- pList = sqlite3ExprListAppend(pWC->pParse, pList, pDup, 0);
+ pList = sqlite3ExprListAppend(pWC->pParse, pList, pDup);
pLeft = pOrTerm->pExpr->pLeft;
}
assert( pLeft!=0 );
pDup = sqlite3ExprDup(db, pLeft, 0);
- pNew = sqlite3Expr(db, TK_IN, pDup, 0, 0);
+ pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0, 0);
if( pNew ){
int idxNew;
transferJoinMarkings(pNew, pExpr);
assert( !ExprHasProperty(pNew, EP_xIsSelect) );
@@ -82592,9 +83736,10 @@
assert( pList->nExpr==2 );
for(i=0; i<2; i++){
Expr *pNewExpr;
int idxNew;
- pNewExpr = sqlite3Expr(db, ops[i], sqlite3ExprDup(db, pExpr->pLeft, 0),
+ pNewExpr = sqlite3PExpr(pParse, ops[i],
+ sqlite3ExprDup(db, pExpr->pLeft, 0),
sqlite3ExprDup(db, pList->a[i].pExpr, 0), 0);
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew==0 );
exprAnalyze(pSrc, pWC, idxNew);
@@ -82634,18 +83779,14 @@
int idxNew1, idxNew2;
pLeft = pExpr->x.pList->a[1].pExpr;
pRight = pExpr->x.pList->a[0].pExpr;
- pStr1 = sqlite3PExpr(pParse, TK_STRING, 0, 0, 0);
- if( pStr1 ){
- sqlite3TokenCopy(db, &pStr1->token, &pRight->token);
- pStr1->token.n = nPattern;
- }
+ 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;
- /* assert( pStr2->token.dyn ); */
- pC = (u8*)&pStr2->token.z[nPattern-1];
+ pC = (u8*)&pStr2->u.zToken[nPattern-1];
c = *pC;
if( noCase ){
if( c=='@' ) isComplete = 0;
c = sqlite3UpperToLower[c];
@@ -82687,9 +83828,10 @@
prereqExpr = exprTableUsage(pMaskSet, pRight);
prereqColumn = exprTableUsage(pMaskSet, pLeft);
if( (prereqExpr & prereqColumn)==0 ){
Expr *pNewExpr;
- pNewExpr = sqlite3Expr(db, TK_MATCH, 0, sqlite3ExprDup(db, pRight, 0), 0);
+ pNewExpr = sqlite3PExpr(pParse, TK_MATCH,
+ 0, sqlite3ExprDup(db, pRight, 0), 0);
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew==0 );
pNewTerm = &pWC->a[idxNew];
pNewTerm->prereqRight = prereqExpr;
@@ -83767,9 +84909,8 @@
iReg = iTarget;
eType = sqlite3FindInIndex(pParse, pX, 0);
iTab = pX->iTable;
sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
- VdbeComment((v, "%.*s", pX->span.n, pX->span.z));
assert( pLevel->plan.wsFlags & WHERE_IN_ABLE );
if( pLevel->u.in.nIn==0 ){
pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
}
@@ -84640,11 +85781,20 @@
** its Expr.iRightJoinTable value to find the bitmask of the right table
** of the join. Subtracting one from the right table bitmask gives a
** bitmask for all tables to the left of the join. Knowing the bitmask
** for all tables to the left of a left join is important. Ticket #3015.
- */
+ **
+ ** Configure the WhereClause.vmask variable so that bits that correspond
+ ** to virtual table cursors are set. This is used to selectively disable
+ ** the OR-to-IN transformation in exprAnalyzeOrTerm(). It is not helpful
+ ** with virtual tables.
+ */
+ 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) ){
+ pWC->vmask |= ((Bitmask)1 << i);
+ }
}
#ifndef NDEBUG
{
Bitmask toTheLeft = 0;
@@ -85015,9 +86165,9 @@
** directly. This loop scans all that code looking for opcodes
** that reference the table and converts them into opcodes that
** reference the index.
*/
- if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){
+ if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 && !db->mallocFailed){
int k, j, last;
VdbeOp *pOp;
Index *pIdx = pLevel->plan.u.pIdx;
int useIndexOnly = pLevel->plan.wsFlags & WHERE_IDX_ONLY;
@@ -85094,8 +86244,70 @@
** An instance of this structure holds the ATTACH key and the key type.
*/
struct AttachKey { int type; Token key; };
+
+ /* This is a utility routine used to set the ExprSpan.zStart and
+ ** ExprSpan.zEnd values of pOut so that the span covers the complete
+ ** range of text beginning with pStart and going to the end of pEnd.
+ */
+ static void spanSet(ExprSpan *pOut, Token *pStart, Token *pEnd){
+ pOut->zStart = pStart->z;
+ pOut->zEnd = &pEnd->z[pEnd->n];
+ }
+
+ /* Construct a new Expr object from a single identifier. Use the
+ ** new Expr to populate pOut. Set the span of pOut to be the identifier
+ ** that created the expression.
+ */
+ static void spanExpr(ExprSpan *pOut, Parse *pParse, int op, Token *pValue){
+ pOut->pExpr = sqlite3PExpr(pParse, op, 0, 0, pValue);
+ pOut->zStart = pValue->z;
+ pOut->zEnd = &pValue->z[pValue->n];
+ }
+
+ /* This routine constructs a binary expression node out of two ExprSpan
+ ** objects and uses the result to populate a new ExprSpan object.
+ */
+ static void spanBinaryExpr(
+ ExprSpan *pOut, /* Write the result here */
+ Parse *pParse, /* The parsing context. Errors accumulate here */
+ int op, /* The binary operation */
+ ExprSpan *pLeft, /* The left operand */
+ ExprSpan *pRight /* The right operand */
+ ){
+ pOut->pExpr = sqlite3PExpr(pParse, op, pLeft->pExpr, pRight->pExpr, 0);
+ pOut->zStart = pLeft->zStart;
+ pOut->zEnd = pRight->zEnd;
+ }
+
+ /* Construct an expression node for a unary postfix operator
+ */
+ static void spanUnaryPostfix(
+ ExprSpan *pOut, /* Write the new expression node here */
+ Parse *pParse, /* Parsing context to record errors */
+ int op, /* The operator */
+ ExprSpan *pOperand, /* The operand */
+ Token *pPostOp /* The operand token for setting the span */
+ ){
+ pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0);
+ pOut->zStart = pOperand->zStart;
+ pOut->zEnd = &pPostOp->z[pPostOp->n];
+ }
+
+ /* Construct an expression node for a unary prefix operator
+ */
+ static void spanUnaryPrefix(
+ ExprSpan *pOut, /* Write the new expression node here */
+ Parse *pParse, /* Parsing context to record errors */
+ int op, /* The operator */
+ ExprSpan *pOperand, /* The operand */
+ Token *pPreOp /* The operand token for setting the span */
+ ){
+ pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0);
+ pOut->zStart = pPreOp->z;
+ pOut->zEnd = pOperand->zEnd;
+ }
/* Next is all token values, in a form suitable for use by makeheaders.
** This section will be null unless lemon is run with the -m switch.
*/
/*
@@ -85155,8 +86367,9 @@
Expr* yy72;
TriggerStep* yy145;
ExprList* yy148;
SrcList* yy185;
+ ExprSpan yy190;
int yy194;
Select* yy243;
IdList* yy254;
struct TrigEvent yy332;
@@ -85170,10 +86383,10 @@
#define sqlite3ParserARG_SDECL Parse *pParse;
#define sqlite3ParserARG_PDECL ,Parse *pParse
#define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
#define sqlite3ParserARG_STORE yypParser->pParse = pParse
-#define YYNSTATE 616
-#define YYNRULE 323
+#define YYNSTATE 619
+#define YYNRULE 324
#define YYFALLBACK 1
#define YY_NO_ACTION (YYNSTATE+YYNRULE+2)
#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1)
#define YY_ERROR_ACTION (YYNSTATE+YYNRULE)
@@ -85230,158 +86443,159 @@
** shifting non-terminals after a reduce.
** yy_default[] Default action for each state.
*/
static const YYACTIONTYPE yy_action[] = {
- /* 0 */ 304, 940, 176, 615, 2, 150, 214, 439, 24, 24,
- /* 10 */ 24, 24, 488, 26, 26, 26, 26, 27, 27, 28,
- /* 20 */ 28, 28, 29, 216, 413, 414, 212, 413, 414, 446,
- /* 30 */ 452, 31, 26, 26, 26, 26, 27, 27, 28, 28,
- /* 40 */ 28, 29, 216, 30, 483, 32, 134, 23, 22, 308,
- /* 50 */ 456, 457, 453, 453, 25, 25, 24, 24, 24, 24,
- /* 60 */ 436, 26, 26, 26, 26, 27, 27, 28, 28, 28,
- /* 70 */ 29, 216, 304, 216, 311, 439, 512, 490, 45, 26,
+ /* 0 */ 305, 944, 176, 618, 2, 150, 214, 441, 24, 24,
+ /* 10 */ 24, 24, 490, 26, 26, 26, 26, 27, 27, 28,
+ /* 20 */ 28, 28, 29, 216, 415, 416, 212, 415, 416, 448,
+ /* 30 */ 454, 31, 26, 26, 26, 26, 27, 27, 28, 28,
+ /* 40 */ 28, 29, 216, 30, 485, 32, 134, 23, 22, 311,
+ /* 50 */ 458, 459, 455, 455, 25, 25, 24, 24, 24, 24,
+ /* 60 */ 438, 26, 26, 26, 26, 27, 27, 28, 28, 28,
+ /* 70 */ 29, 216, 305, 216, 314, 441, 514, 492, 45, 26,
/* 80 */ 26, 26, 26, 27, 27, 28, 28, 28, 29, 216,
- /* 90 */ 413, 414, 416, 417, 156, 416, 417, 360, 363, 364,
- /* 100 */ 311, 446, 452, 385, 514, 21, 186, 495, 365, 27,
- /* 110 */ 27, 28, 28, 28, 29, 216, 413, 414, 415, 23,
- /* 120 */ 22, 308, 456, 457, 453, 453, 25, 25, 24, 24,
- /* 130 */ 24, 24, 555, 26, 26, 26, 26, 27, 27, 28,
- /* 140 */ 28, 28, 29, 216, 304, 228, 504, 135, 468, 218,
- /* 150 */ 548, 145, 132, 256, 358, 261, 359, 153, 416, 417,
- /* 160 */ 241, 598, 331, 30, 265, 32, 134, 439, 596, 597,
- /* 170 */ 230, 228, 490, 446, 452, 57, 506, 328, 132, 256,
- /* 180 */ 358, 261, 359, 153, 416, 417, 435, 78, 408, 405,
- /* 190 */ 265, 23, 22, 308, 456, 457, 453, 453, 25, 25,
- /* 200 */ 24, 24, 24, 24, 342, 26, 26, 26, 26, 27,
- /* 210 */ 27, 28, 28, 28, 29, 216, 304, 214, 534, 547,
- /* 220 */ 307, 127, 489, 595, 30, 331, 32, 134, 345, 387,
- /* 230 */ 429, 63, 331, 355, 415, 439, 507, 331, 415, 535,
- /* 240 */ 328, 215, 193, 594, 593, 446, 452, 328, 18, 435,
- /* 250 */ 85, 16, 328, 183, 190, 556, 435, 78, 309, 463,
- /* 260 */ 464, 435, 85, 23, 22, 308, 456, 457, 453, 453,
- /* 270 */ 25, 25, 24, 24, 24, 24, 436, 26, 26, 26,
- /* 280 */ 26, 27, 27, 28, 28, 28, 29, 216, 304, 347,
- /* 290 */ 221, 313, 595, 191, 378, 331, 472, 234, 345, 381,
- /* 300 */ 324, 410, 220, 344, 592, 217, 213, 415, 112, 331,
- /* 310 */ 328, 4, 594, 399, 211, 554, 529, 446, 452, 435,
- /* 320 */ 79, 217, 553, 515, 328, 334, 513, 459, 459, 469,
- /* 330 */ 441, 572, 432, 435, 78, 23, 22, 308, 456, 457,
- /* 340 */ 453, 453, 25, 25, 24, 24, 24, 24, 436, 26,
+ /* 90 */ 415, 416, 418, 419, 156, 418, 419, 362, 365, 366,
+ /* 100 */ 314, 448, 454, 387, 516, 21, 186, 497, 367, 27,
+ /* 110 */ 27, 28, 28, 28, 29, 216, 415, 416, 417, 23,
+ /* 120 */ 22, 311, 458, 459, 455, 455, 25, 25, 24, 24,
+ /* 130 */ 24, 24, 557, 26, 26, 26, 26, 27, 27, 28,
+ /* 140 */ 28, 28, 29, 216, 305, 228, 506, 135, 470, 218,
+ /* 150 */ 550, 145, 132, 256, 360, 261, 361, 153, 418, 419,
+ /* 160 */ 241, 600, 333, 30, 265, 32, 134, 441, 598, 599,
+ /* 170 */ 230, 228, 492, 448, 454, 57, 508, 330, 132, 256,
+ /* 180 */ 360, 261, 361, 153, 418, 419, 437, 78, 410, 407,
+ /* 190 */ 265, 23, 22, 311, 458, 459, 455, 455, 25, 25,
+ /* 200 */ 24, 24, 24, 24, 344, 26, 26, 26, 26, 27,
+ /* 210 */ 27, 28, 28, 28, 29, 216, 305, 214, 536, 549,
+ /* 220 */ 308, 127, 491, 597, 30, 333, 32, 134, 347, 389,
+ /* 230 */ 431, 63, 333, 357, 417, 441, 509, 333, 417, 537,
+ /* 240 */ 330, 215, 193, 596, 595, 448, 454, 330, 18, 437,
+ /* 250 */ 85, 16, 330, 183, 190, 558, 437, 78, 312, 465,
+ /* 260 */ 466, 437, 85, 23, 22, 311, 458, 459, 455, 455,
+ /* 270 */ 25, 25, 24, 24, 24, 24, 438, 26, 26, 26,
+ /* 280 */ 26, 27, 27, 28, 28, 28, 29, 216, 305, 349,
+ /* 290 */ 221, 316, 597, 191, 380, 333, 474, 234, 347, 383,
+ /* 300 */ 326, 412, 220, 346, 594, 217, 213, 417, 112, 333,
+ /* 310 */ 330, 4, 596, 401, 211, 556, 531, 448, 454, 437,
+ /* 320 */ 79, 217, 555, 517, 330, 336, 515, 461, 461, 471,
+ /* 330 */ 443, 574, 434, 437, 78, 23, 22, 311, 458, 459,
+ /* 340 */ 455, 455, 25, 25, 24, 24, 24, 24, 438, 26,
/* 350 */ 26, 26, 26, 27, 27, 28, 28, 28, 29, 216,
- /* 360 */ 304, 443, 443, 443, 156, 468, 218, 360, 363, 364,
- /* 370 */ 331, 247, 395, 398, 217, 349, 331, 30, 365, 32,
- /* 380 */ 134, 388, 282, 281, 39, 328, 41, 430, 545, 446,
- /* 390 */ 452, 328, 214, 531, 435, 93, 542, 601, 1, 404,
- /* 400 */ 435, 93, 413, 414, 495, 40, 536, 23, 22, 308,
- /* 410 */ 456, 457, 453, 453, 25, 25, 24, 24, 24, 24,
- /* 420 */ 573, 26, 26, 26, 26, 27, 27, 28, 28, 28,
- /* 430 */ 29, 216, 304, 276, 331, 179, 508, 490, 210, 547,
- /* 440 */ 319, 413, 414, 222, 192, 385, 320, 240, 415, 328,
- /* 450 */ 557, 63, 413, 414, 415, 616, 408, 405, 435, 71,
- /* 460 */ 415, 446, 452, 611, 572, 28, 28, 28, 29, 216,
- /* 470 */ 416, 417, 436, 336, 463, 464, 401, 43, 436, 23,
- /* 480 */ 22, 308, 456, 457, 453, 453, 25, 25, 24, 24,
- /* 490 */ 24, 24, 495, 26, 26, 26, 26, 27, 27, 28,
- /* 500 */ 28, 28, 29, 216, 304, 612, 209, 135, 511, 416,
- /* 510 */ 417, 431, 233, 64, 388, 282, 281, 439, 66, 542,
- /* 520 */ 416, 417, 413, 414, 156, 214, 403, 360, 363, 364,
- /* 530 */ 547, 252, 490, 446, 452, 491, 217, 8, 365, 495,
- /* 540 */ 436, 606, 63, 537, 299, 415, 492, 470, 546, 200,
- /* 550 */ 196, 23, 22, 308, 456, 457, 453, 453, 25, 25,
- /* 560 */ 24, 24, 24, 24, 386, 26, 26, 26, 26, 27,
- /* 570 */ 27, 28, 28, 28, 29, 216, 304, 477, 254, 354,
- /* 580 */ 528, 60, 517, 518, 436, 439, 389, 331, 356, 7,
- /* 590 */ 416, 417, 331, 478, 328, 208, 197, 137, 460, 499,
- /* 600 */ 447, 448, 328, 435, 9, 446, 452, 328, 479, 485,
- /* 610 */ 519, 435, 72, 567, 415, 434, 435, 67, 486, 433,
- /* 620 */ 520, 450, 451, 23, 22, 308, 456, 457, 453, 453,
- /* 630 */ 25, 25, 24, 24, 24, 24, 331, 26, 26, 26,
- /* 640 */ 26, 27, 27, 28, 28, 28, 29, 216, 304, 331,
- /* 650 */ 449, 328, 268, 390, 461, 331, 65, 331, 368, 434,
- /* 660 */ 435, 76, 310, 433, 328, 150, 427, 439, 473, 331,
- /* 670 */ 328, 499, 328, 435, 97, 29, 216, 446, 452, 435,
- /* 680 */ 96, 435, 101, 353, 328, 372, 415, 334, 154, 459,
- /* 690 */ 459, 352, 569, 435, 99, 23, 22, 308, 456, 457,
- /* 700 */ 453, 453, 25, 25, 24, 24, 24, 24, 331, 26,
+ /* 360 */ 305, 445, 445, 445, 156, 470, 218, 362, 365, 366,
+ /* 370 */ 333, 247, 397, 400, 217, 351, 333, 30, 367, 32,
+ /* 380 */ 134, 390, 282, 281, 39, 330, 41, 432, 547, 448,
+ /* 390 */ 454, 330, 214, 533, 437, 93, 544, 603, 1, 406,
+ /* 400 */ 437, 93, 415, 416, 497, 40, 538, 23, 22, 311,
+ /* 410 */ 458, 459, 455, 455, 25, 25, 24, 24, 24, 24,
+ /* 420 */ 575, 26, 26, 26, 26, 27, 27, 28, 28, 28,
+ /* 430 */ 29, 216, 305, 276, 333, 179, 510, 492, 210, 549,
+ /* 440 */ 322, 415, 416, 222, 192, 387, 323, 240, 417, 330,
+ /* 450 */ 559, 63, 415, 416, 417, 619, 410, 407, 437, 71,
+ /* 460 */ 417, 448, 454, 539, 574, 28, 28, 28, 29, 216,
+ /* 470 */ 418, 419, 438, 338, 465, 466, 403, 43, 438, 23,
+ /* 480 */ 22, 311, 458, 459, 455, 455, 25, 25, 24, 24,
+ /* 490 */ 24, 24, 497, 26, 26, 26, 26, 27, 27, 28,
+ /* 500 */ 28, 28, 29, 216, 305, 429, 209, 135, 513, 418,
+ /* 510 */ 419, 433, 233, 64, 390, 282, 281, 441, 66, 544,
+ /* 520 */ 418, 419, 415, 416, 156, 214, 405, 362, 365, 366,
+ /* 530 */ 549, 252, 492, 448, 454, 493, 217, 8, 367, 497,
+ /* 540 */ 438, 608, 63, 208, 299, 417, 494, 472, 548, 200,
+ /* 550 */ 196, 23, 22, 311, 458, 459, 455, 455, 25, 25,
+ /* 560 */ 24, 24, 24, 24, 388, 26, 26, 26, 26, 27,
+ /* 570 */ 27, 28, 28, 28, 29, 216, 305, 479, 254, 356,
+ /* 580 */ 530, 60, 519, 520, 438, 441, 391, 333, 358, 7,
+ /* 590 */ 418, 419, 333, 480, 330, 374, 197, 137, 462, 501,
+ /* 600 */ 449, 450, 330, 437, 9, 448, 454, 330, 481, 487,
+ /* 610 */ 521, 437, 72, 569, 417, 436, 437, 67, 488, 435,
+ /* 620 */ 522, 452, 453, 23, 22, 311, 458, 459, 455, 455,
+ /* 630 */ 25, 25, 24, 24, 24, 24, 333, 26, 26, 26,
+ /* 640 */ 26, 27, 27, 28, 28, 28, 29, 216, 305, 333,
+ /* 650 */ 451, 330, 268, 392, 463, 333, 65, 333, 370, 436,
+ /* 660 */ 437, 76, 313, 435, 330, 150, 185, 441, 475, 333,
+ /* 670 */ 330, 501, 330, 437, 97, 29, 216, 448, 454, 437,
+ /* 680 */ 96, 437, 101, 355, 330, 242, 417, 336, 154, 461,
+ /* 690 */ 461, 354, 571, 437, 99, 23, 22, 311, 458, 459,
+ /* 700 */ 455, 455, 25, 25, 24, 24, 24, 24, 333, 26,
/* 710 */ 26, 26, 26, 27, 27, 28, 28, 28, 29, 216,
- /* 720 */ 304, 331, 248, 328, 264, 56, 334, 331, 459, 459,
- /* 730 */ 861, 333, 435, 104, 376, 439, 328, 415, 331, 415,
- /* 740 */ 565, 331, 328, 306, 564, 435, 105, 185, 265, 446,
- /* 750 */ 452, 435, 126, 328, 570, 518, 328, 334, 377, 459,
- /* 760 */ 459, 314, 435, 128, 194, 435, 59, 23, 22, 308,
- /* 770 */ 456, 457, 453, 453, 25, 25, 24, 24, 24, 24,
- /* 780 */ 331, 26, 26, 26, 26, 27, 27, 28, 28, 28,
- /* 790 */ 29, 216, 304, 331, 136, 328, 242, 477, 436, 331,
- /* 800 */ 350, 331, 609, 303, 435, 102, 201, 137, 328, 415,
- /* 810 */ 454, 178, 331, 478, 328, 415, 328, 435, 77, 440,
- /* 820 */ 249, 446, 452, 435, 100, 435, 68, 328, 479, 465,
- /* 830 */ 341, 613, 931, 484, 931, 415, 435, 98, 467, 23,
- /* 840 */ 22, 308, 456, 457, 453, 453, 25, 25, 24, 24,
- /* 850 */ 24, 24, 331, 26, 26, 26, 26, 27, 27, 28,
- /* 860 */ 28, 28, 29, 216, 304, 331, 397, 328, 164, 264,
- /* 870 */ 205, 331, 264, 332, 610, 339, 435, 129, 407, 2,
- /* 880 */ 328, 322, 175, 331, 415, 214, 328, 415, 415, 435,
- /* 890 */ 130, 466, 466, 446, 452, 435, 131, 396, 328, 257,
- /* 900 */ 334, 487, 459, 459, 436, 154, 229, 435, 69, 315,
- /* 910 */ 258, 23, 33, 308, 456, 457, 453, 453, 25, 25,
- /* 920 */ 24, 24, 24, 24, 331, 26, 26, 26, 26, 27,
- /* 930 */ 27, 28, 28, 28, 29, 216, 304, 331, 497, 328,
- /* 940 */ 151, 264, 412, 331, 264, 470, 337, 200, 435, 80,
- /* 950 */ 250, 155, 328, 523, 524, 331, 415, 415, 328, 415,
- /* 960 */ 306, 435, 81, 533, 532, 446, 452, 435, 70, 47,
- /* 970 */ 328, 613, 930, 259, 930, 418, 419, 420, 316, 435,
- /* 980 */ 82, 317, 206, 539, 22, 308, 456, 457, 453, 453,
- /* 990 */ 25, 25, 24, 24, 24, 24, 331, 26, 26, 26,
- /* 1000 */ 26, 27, 27, 28, 28, 28, 29, 216, 304, 331,
- /* 1010 */ 209, 328, 529, 540, 610, 331, 436, 563, 375, 563,
- /* 1020 */ 435, 83, 362, 538, 328, 155, 541, 331, 499, 526,
- /* 1030 */ 328, 331, 575, 435, 84, 424, 543, 446, 452, 435,
- /* 1040 */ 86, 290, 328, 415, 436, 267, 328, 155, 394, 141,
- /* 1050 */ 415, 435, 87, 588, 411, 435, 88, 308, 456, 457,
- /* 1060 */ 453, 453, 25, 25, 24, 24, 24, 24, 386, 26,
+ /* 720 */ 305, 333, 248, 330, 264, 56, 336, 333, 461, 461,
+ /* 730 */ 864, 335, 437, 104, 378, 441, 330, 417, 333, 417,
+ /* 740 */ 567, 333, 330, 307, 566, 437, 105, 442, 265, 448,
+ /* 750 */ 454, 437, 126, 330, 572, 520, 330, 336, 379, 461,
+ /* 760 */ 461, 317, 437, 128, 194, 437, 59, 23, 22, 311,
+ /* 770 */ 458, 459, 455, 455, 25, 25, 24, 24, 24, 24,
+ /* 780 */ 333, 26, 26, 26, 26, 27, 27, 28, 28, 28,
+ /* 790 */ 29, 216, 305, 333, 136, 330, 467, 479, 438, 333,
+ /* 800 */ 352, 333, 611, 303, 437, 102, 201, 137, 330, 417,
+ /* 810 */ 456, 178, 333, 480, 330, 417, 330, 437, 77, 486,
+ /* 820 */ 249, 448, 454, 437, 100, 437, 68, 330, 481, 469,
+ /* 830 */ 343, 616, 934, 341, 934, 417, 437, 98, 489, 23,
+ /* 840 */ 22, 311, 458, 459, 455, 455, 25, 25, 24, 24,
+ /* 850 */ 24, 24, 333, 26, 26, 26, 26, 27, 27, 28,
+ /* 860 */ 28, 28, 29, 216, 305, 333, 399, 330, 164, 264,
+ /* 870 */ 205, 333, 264, 334, 612, 250, 437, 129, 409, 2,
+ /* 880 */ 330, 325, 175, 333, 417, 214, 330, 417, 417, 437,
+ /* 890 */ 130, 468, 468, 448, 454, 437, 131, 398, 330, 257,
+ /* 900 */ 336, 259, 461, 461, 438, 154, 229, 437, 69, 318,
+ /* 910 */ 258, 23, 33, 311, 458, 459, 455, 455, 25, 25,
+ /* 920 */ 24, 24, 24, 24, 333, 26, 26, 26, 26, 27,
+ /* 930 */ 27, 28, 28, 28, 29, 216, 305, 333, 155, 330,
+ /* 940 */ 531, 264, 414, 333, 264, 472, 339, 200, 437, 80,
+ /* 950 */ 542, 499, 330, 151, 541, 333, 417, 417, 330, 417,
+ /* 960 */ 307, 437, 81, 535, 534, 448, 454, 437, 70, 47,
+ /* 970 */ 330, 616, 933, 543, 933, 420, 421, 422, 319, 437,
+ /* 980 */ 82, 320, 304, 613, 22, 311, 458, 459, 455, 455,
+ /* 990 */ 25, 25, 24, 24, 24, 24, 333, 26, 26, 26,
+ /* 1000 */ 26, 27, 27, 28, 28, 28, 29, 216, 305, 333,
+ /* 1010 */ 209, 330, 364, 206, 612, 333, 528, 565, 377, 565,
+ /* 1020 */ 437, 83, 525, 526, 330, 615, 545, 333, 501, 577,
+ /* 1030 */ 330, 333, 290, 437, 84, 426, 396, 448, 454, 437,
+ /* 1040 */ 86, 590, 330, 417, 438, 141, 330, 438, 413, 423,
+ /* 1050 */ 417, 437, 87, 424, 327, 437, 88, 311, 458, 459,
+ /* 1060 */ 455, 455, 25, 25, 24, 24, 24, 24, 388, 26,
/* 1070 */ 26, 26, 26, 27, 27, 28, 28, 28, 29, 216,
- /* 1080 */ 35, 338, 286, 3, 331, 270, 331, 327, 414, 421,
- /* 1090 */ 382, 318, 276, 422, 325, 35, 338, 335, 3, 328,
- /* 1100 */ 423, 328, 327, 414, 142, 144, 276, 415, 435, 73,
- /* 1110 */ 435, 74, 335, 331, 6, 340, 425, 331, 326, 331,
- /* 1120 */ 367, 415, 155, 437, 289, 472, 287, 274, 328, 272,
- /* 1130 */ 340, 415, 328, 47, 328, 277, 276, 435, 89, 348,
- /* 1140 */ 472, 435, 90, 435, 91, 38, 37, 243, 331, 582,
- /* 1150 */ 244, 415, 426, 276, 36, 329, 330, 46, 245, 441,
- /* 1160 */ 38, 37, 505, 328, 202, 203, 204, 415, 415, 36,
- /* 1170 */ 329, 330, 435, 92, 441, 198, 568, 214, 155, 584,
- /* 1180 */ 235, 236, 237, 143, 239, 346, 133, 581, 438, 246,
- /* 1190 */ 443, 443, 443, 444, 445, 10, 585, 276, 20, 42,
- /* 1200 */ 172, 415, 294, 331, 288, 443, 443, 443, 444, 445,
- /* 1210 */ 10, 295, 415, 35, 338, 219, 3, 149, 328, 482,
- /* 1220 */ 327, 414, 331, 170, 276, 572, 48, 435, 75, 169,
- /* 1230 */ 335, 19, 171, 251, 442, 413, 414, 328, 331, 415,
- /* 1240 */ 586, 343, 276, 177, 351, 496, 435, 17, 340, 415,
- /* 1250 */ 481, 253, 255, 328, 276, 502, 415, 415, 472, 331,
- /* 1260 */ 503, 357, 435, 94, 576, 415, 151, 231, 312, 415,
- /* 1270 */ 577, 516, 54, 472, 328, 393, 291, 281, 38, 37,
- /* 1280 */ 494, 305, 521, 435, 95, 232, 214, 36, 329, 330,
- /* 1290 */ 526, 498, 441, 188, 189, 415, 500, 292, 522, 262,
- /* 1300 */ 530, 260, 263, 513, 549, 269, 415, 441, 589, 400,
- /* 1310 */ 54, 415, 525, 527, 415, 415, 271, 415, 273, 415,
- /* 1320 */ 415, 275, 280, 443, 443, 443, 444, 445, 10, 107,
- /* 1330 */ 380, 415, 383, 415, 384, 283, 415, 415, 443, 443,
- /* 1340 */ 443, 284, 285, 580, 300, 415, 591, 415, 293, 415,
- /* 1350 */ 415, 296, 297, 605, 226, 550, 415, 415, 415, 225,
- /* 1360 */ 608, 415, 302, 415, 551, 227, 415, 415, 415, 301,
- /* 1370 */ 544, 552, 369, 158, 373, 558, 159, 278, 371, 160,
- /* 1380 */ 51, 207, 560, 561, 161, 140, 379, 117, 571, 163,
- /* 1390 */ 391, 392, 181, 180, 321, 602, 578, 118, 119, 120,
- /* 1400 */ 121, 123, 55, 587, 58, 603, 604, 607, 62, 174,
- /* 1410 */ 103, 224, 111, 409, 238, 428, 199, 323, 657, 658,
- /* 1420 */ 659, 146, 147, 455, 458, 34, 474, 462, 471, 182,
- /* 1430 */ 195, 148, 475, 476, 480, 5, 12, 493, 44, 11,
- /* 1440 */ 106, 138, 509, 510, 501, 223, 49, 361, 108, 109,
- /* 1450 */ 152, 266, 50, 110, 157, 258, 370, 184, 559, 139,
- /* 1460 */ 151, 113, 279, 162, 115, 374, 15, 574, 116, 165,
- /* 1470 */ 52, 13, 366, 579, 53, 167, 168, 166, 583, 124,
- /* 1480 */ 114, 122, 562, 566, 14, 61, 599, 600, 125, 173,
- /* 1490 */ 298, 590, 187, 406, 941, 614, 941, 402,
+ /* 1080 */ 35, 340, 286, 3, 333, 270, 333, 329, 416, 142,
+ /* 1090 */ 384, 321, 276, 425, 144, 35, 340, 337, 3, 330,
+ /* 1100 */ 6, 330, 329, 416, 304, 614, 276, 417, 437, 73,
+ /* 1110 */ 437, 74, 337, 333, 328, 342, 427, 333, 439, 333,
+ /* 1120 */ 540, 417, 155, 47, 289, 474, 287, 274, 330, 272,
+ /* 1130 */ 342, 417, 330, 350, 330, 277, 276, 437, 89, 243,
+ /* 1140 */ 474, 437, 90, 437, 91, 38, 37, 615, 333, 584,
+ /* 1150 */ 244, 417, 428, 276, 36, 331, 332, 46, 245, 443,
+ /* 1160 */ 38, 37, 507, 330, 202, 203, 204, 417, 417, 36,
+ /* 1170 */ 331, 332, 437, 92, 443, 198, 267, 214, 155, 586,
+ /* 1180 */ 235, 236, 237, 143, 239, 348, 133, 583, 440, 246,
+ /* 1190 */ 445, 445, 445, 446, 447, 10, 587, 276, 20, 42,
+ /* 1200 */ 172, 417, 294, 333, 288, 445, 445, 445, 446, 447,
+ /* 1210 */ 10, 295, 417, 35, 340, 219, 3, 149, 330, 484,
+ /* 1220 */ 329, 416, 333, 170, 276, 574, 48, 437, 75, 169,
+ /* 1230 */ 337, 19, 171, 251, 444, 415, 416, 330, 333, 417,
+ /* 1240 */ 588, 345, 276, 177, 353, 498, 437, 17, 342, 417,
+ /* 1250 */ 483, 253, 255, 330, 276, 496, 417, 417, 474, 333,
+ /* 1260 */ 504, 505, 437, 94, 369, 417, 155, 231, 359, 417,
+ /* 1270 */ 417, 518, 523, 474, 330, 395, 291, 281, 38, 37,
+ /* 1280 */ 500, 306, 315, 437, 95, 232, 214, 36, 331, 332,
+ /* 1290 */ 524, 502, 443, 188, 189, 417, 262, 292, 532, 263,
+ /* 1300 */ 551, 260, 269, 515, 271, 273, 417, 443, 570, 402,
+ /* 1310 */ 155, 417, 527, 417, 417, 417, 275, 417, 280, 417,
+ /* 1320 */ 417, 382, 385, 445, 445, 445, 446, 447, 10, 528,
+ /* 1330 */ 386, 417, 283, 417, 284, 285, 417, 417, 445, 445,
+ /* 1340 */ 445, 582, 593, 293, 107, 417, 296, 417, 297, 417,
+ /* 1350 */ 417, 607, 578, 529, 151, 300, 417, 417, 417, 226,
+ /* 1360 */ 579, 417, 54, 417, 158, 591, 417, 54, 225, 610,
+ /* 1370 */ 227, 302, 546, 552, 301, 553, 554, 371, 560, 159,
+ /* 1380 */ 375, 373, 207, 160, 51, 562, 563, 161, 117, 278,
+ /* 1390 */ 381, 140, 573, 163, 181, 393, 394, 118, 119, 120,
+ /* 1400 */ 180, 580, 121, 123, 324, 605, 604, 606, 55, 609,
+ /* 1410 */ 589, 309, 224, 62, 58, 103, 411, 111, 238, 430,
+ /* 1420 */ 199, 174, 660, 661, 662, 146, 147, 460, 310, 457,
+ /* 1430 */ 34, 476, 464, 473, 182, 195, 148, 477, 5, 478,
+ /* 1440 */ 482, 12, 138, 44, 11, 106, 495, 511, 512, 503,
+ /* 1450 */ 223, 49, 363, 108, 109, 152, 266, 50, 110, 157,
+ /* 1460 */ 258, 372, 184, 561, 139, 113, 151, 162, 279, 115,
+ /* 1470 */ 376, 15, 576, 116, 165, 52, 13, 368, 581, 53,
+ /* 1480 */ 167, 166, 585, 122, 124, 114, 592, 564, 568, 168,
+ /* 1490 */ 14, 61, 601, 602, 173, 298, 125, 408, 187, 617,
+ /* 1500 */ 945, 945, 404,
};
static const YYCODETYPE yy_lookahead[] = {
/* 0 */ 19, 142, 143, 144, 145, 24, 116, 26, 75, 76,
/* 10 */ 77, 78, 25, 80, 81, 82, 83, 84, 85, 86,
@@ -85428,77 +86642,77 @@
/* 420 */ 11, 80, 81, 82, 83, 84, 85, 86, 87, 88,
/* 430 */ 89, 90, 19, 150, 150, 23, 23, 25, 160, 150,
/* 440 */ 220, 26, 27, 205, 160, 150, 220, 158, 165, 165,
/* 450 */ 161, 162, 26, 27, 165, 0, 1, 2, 174, 175,
- /* 460 */ 165, 48, 49, 23, 55, 86, 87, 88, 89, 90,
+ /* 460 */ 165, 48, 49, 183, 55, 86, 87, 88, 89, 90,
/* 470 */ 94, 95, 194, 169, 170, 171, 193, 136, 194, 66,
/* 480 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
/* 490 */ 77, 78, 166, 80, 81, 82, 83, 84, 85, 86,
- /* 500 */ 87, 88, 89, 90, 19, 65, 160, 95, 23, 94,
+ /* 500 */ 87, 88, 89, 90, 19, 153, 160, 95, 23, 94,
/* 510 */ 95, 173, 217, 22, 105, 106, 107, 26, 22, 181,
/* 520 */ 94, 95, 26, 27, 96, 116, 243, 99, 100, 101,
/* 530 */ 150, 205, 120, 48, 49, 120, 232, 22, 110, 166,
- /* 540 */ 194, 161, 162, 183, 163, 165, 120, 166, 167, 168,
+ /* 540 */ 194, 161, 162, 236, 163, 165, 120, 166, 167, 168,
/* 550 */ 160, 66, 67, 68, 69, 70, 71, 72, 73, 74,
/* 560 */ 75, 76, 77, 78, 218, 80, 81, 82, 83, 84,
/* 570 */ 85, 86, 87, 88, 89, 90, 19, 12, 205, 150,
/* 580 */ 23, 235, 190, 191, 194, 94, 240, 150, 86, 74,
- /* 590 */ 94, 95, 150, 28, 165, 236, 206, 207, 23, 150,
+ /* 590 */ 94, 95, 150, 28, 165, 237, 206, 207, 23, 150,
/* 600 */ 48, 49, 165, 174, 175, 48, 49, 165, 43, 31,
/* 610 */ 45, 174, 175, 21, 165, 113, 174, 175, 40, 117,
/* 620 */ 55, 69, 70, 66, 67, 68, 69, 70, 71, 72,
/* 630 */ 73, 74, 75, 76, 77, 78, 150, 80, 81, 82,
/* 640 */ 83, 84, 85, 86, 87, 88, 89, 90, 19, 150,
/* 650 */ 98, 165, 23, 61, 23, 150, 25, 150, 19, 113,
- /* 660 */ 174, 175, 213, 117, 165, 24, 153, 26, 23, 150,
+ /* 660 */ 174, 175, 213, 117, 165, 24, 196, 26, 23, 150,
/* 670 */ 165, 150, 165, 174, 175, 89, 90, 48, 49, 174,
- /* 680 */ 175, 174, 175, 19, 165, 237, 165, 112, 49, 114,
+ /* 680 */ 175, 174, 175, 19, 165, 198, 165, 112, 49, 114,
/* 690 */ 115, 27, 100, 174, 175, 66, 67, 68, 69, 70,
/* 700 */ 71, 72, 73, 74, 75, 76, 77, 78, 150, 80,
/* 710 */ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
/* 720 */ 19, 150, 150, 165, 150, 24, 112, 150, 114, 115,
/* 730 */ 138, 19, 174, 175, 213, 94, 165, 165, 150, 165,
- /* 740 */ 29, 150, 165, 104, 33, 174, 175, 196, 109, 48,
+ /* 740 */ 29, 150, 165, 104, 33, 174, 175, 166, 109, 48,
/* 750 */ 49, 174, 175, 165, 190, 191, 165, 112, 47, 114,
/* 760 */ 115, 187, 174, 175, 160, 174, 175, 66, 67, 68,
/* 770 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
/* 780 */ 150, 80, 81, 82, 83, 84, 85, 86, 87, 88,
- /* 790 */ 89, 90, 19, 150, 150, 165, 198, 12, 194, 150,
+ /* 790 */ 89, 90, 19, 150, 150, 165, 233, 12, 194, 150,
/* 800 */ 150, 150, 248, 249, 174, 175, 206, 207, 165, 165,
- /* 810 */ 98, 23, 150, 28, 165, 165, 165, 174, 175, 166,
+ /* 810 */ 98, 23, 150, 28, 165, 165, 165, 174, 175, 177,
/* 820 */ 150, 48, 49, 174, 175, 174, 175, 165, 43, 233,
- /* 830 */ 45, 22, 23, 177, 25, 165, 174, 175, 233, 66,
+ /* 830 */ 45, 22, 23, 228, 25, 165, 174, 175, 177, 66,
/* 840 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
/* 850 */ 77, 78, 150, 80, 81, 82, 83, 84, 85, 86,
/* 860 */ 87, 88, 89, 90, 19, 150, 97, 165, 25, 150,
- /* 870 */ 160, 150, 150, 150, 65, 228, 174, 175, 144, 145,
+ /* 870 */ 160, 150, 150, 150, 65, 209, 174, 175, 144, 145,
/* 880 */ 165, 246, 247, 150, 165, 116, 165, 165, 165, 174,
/* 890 */ 175, 129, 130, 48, 49, 174, 175, 128, 165, 98,
/* 900 */ 112, 177, 114, 115, 194, 49, 187, 174, 175, 187,
/* 910 */ 109, 66, 67, 68, 69, 70, 71, 72, 73, 74,
/* 920 */ 75, 76, 77, 78, 150, 80, 81, 82, 83, 84,
- /* 930 */ 85, 86, 87, 88, 89, 90, 19, 150, 23, 165,
- /* 940 */ 25, 150, 150, 150, 150, 166, 167, 168, 174, 175,
- /* 950 */ 209, 25, 165, 7, 8, 150, 165, 165, 165, 165,
+ /* 930 */ 85, 86, 87, 88, 89, 90, 19, 150, 25, 165,
+ /* 940 */ 182, 150, 150, 150, 150, 166, 167, 168, 174, 175,
+ /* 950 */ 166, 23, 165, 25, 177, 150, 165, 165, 165, 165,
/* 960 */ 104, 174, 175, 97, 98, 48, 49, 174, 175, 126,
/* 970 */ 165, 22, 23, 177, 25, 7, 8, 9, 187, 174,
- /* 980 */ 175, 187, 160, 177, 67, 68, 69, 70, 71, 72,
+ /* 980 */ 175, 187, 22, 23, 67, 68, 69, 70, 71, 72,
/* 990 */ 73, 74, 75, 76, 77, 78, 150, 80, 81, 82,
/* 1000 */ 83, 84, 85, 86, 87, 88, 89, 90, 19, 150,
- /* 1010 */ 160, 165, 182, 166, 65, 150, 194, 105, 106, 107,
- /* 1020 */ 174, 175, 178, 23, 165, 25, 177, 150, 150, 103,
- /* 1030 */ 165, 150, 199, 174, 175, 150, 166, 48, 49, 174,
- /* 1040 */ 175, 209, 165, 165, 194, 23, 165, 25, 209, 6,
- /* 1050 */ 165, 174, 175, 199, 149, 174, 175, 68, 69, 70,
+ /* 1010 */ 160, 165, 178, 160, 65, 150, 103, 105, 106, 107,
+ /* 1020 */ 174, 175, 7, 8, 165, 65, 166, 150, 150, 199,
+ /* 1030 */ 165, 150, 209, 174, 175, 150, 209, 48, 49, 174,
+ /* 1040 */ 175, 199, 165, 165, 194, 6, 165, 194, 149, 149,
+ /* 1050 */ 165, 174, 175, 149, 149, 174, 175, 68, 69, 70,
/* 1060 */ 71, 72, 73, 74, 75, 76, 77, 78, 218, 80,
/* 1070 */ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
- /* 1080 */ 19, 20, 16, 22, 150, 16, 150, 26, 27, 149,
- /* 1090 */ 240, 213, 150, 149, 149, 19, 20, 36, 22, 165,
- /* 1100 */ 13, 165, 26, 27, 151, 151, 150, 165, 174, 175,
- /* 1110 */ 174, 175, 36, 150, 25, 54, 150, 150, 159, 150,
- /* 1120 */ 23, 165, 25, 194, 58, 64, 60, 58, 165, 60,
- /* 1130 */ 54, 165, 165, 126, 165, 193, 150, 174, 175, 123,
- /* 1140 */ 64, 174, 175, 174, 175, 84, 85, 199, 150, 193,
+ /* 1080 */ 19, 20, 16, 22, 150, 16, 150, 26, 27, 151,
+ /* 1090 */ 240, 213, 150, 13, 151, 19, 20, 36, 22, 165,
+ /* 1100 */ 25, 165, 26, 27, 22, 23, 150, 165, 174, 175,
+ /* 1110 */ 174, 175, 36, 150, 159, 54, 150, 150, 194, 150,
+ /* 1120 */ 23, 165, 25, 126, 58, 64, 60, 58, 165, 60,
+ /* 1130 */ 54, 165, 165, 123, 165, 193, 150, 174, 175, 199,
+ /* 1140 */ 64, 174, 175, 174, 175, 84, 85, 65, 150, 193,
/* 1150 */ 200, 165, 150, 150, 93, 94, 95, 124, 201, 98,
/* 1160 */ 84, 85, 86, 165, 105, 106, 107, 165, 165, 93,
/* 1170 */ 94, 95, 174, 175, 98, 5, 23, 116, 25, 193,
/* 1180 */ 10, 11, 12, 13, 14, 122, 150, 17, 203, 202,
@@ -85507,36 +86721,37 @@
/* 1210 */ 134, 41, 165, 19, 20, 227, 22, 118, 165, 157,
/* 1220 */ 26, 27, 150, 53, 150, 55, 104, 174, 175, 59,
/* 1230 */ 36, 22, 62, 210, 150, 26, 27, 165, 150, 165,
/* 1240 */ 193, 150, 150, 157, 121, 211, 174, 175, 54, 165,
- /* 1250 */ 150, 210, 210, 165, 150, 211, 165, 165, 64, 150,
- /* 1260 */ 211, 104, 174, 175, 23, 165, 25, 193, 46, 165,
- /* 1270 */ 23, 176, 25, 64, 165, 105, 106, 107, 84, 85,
- /* 1280 */ 150, 111, 176, 174, 175, 193, 116, 93, 94, 95,
- /* 1290 */ 103, 150, 98, 84, 85, 165, 150, 193, 184, 150,
+ /* 1250 */ 150, 210, 210, 165, 150, 150, 165, 165, 64, 150,
+ /* 1260 */ 211, 211, 174, 175, 23, 165, 25, 193, 104, 165,
+ /* 1270 */ 165, 176, 176, 64, 165, 105, 106, 107, 84, 85,
+ /* 1280 */ 150, 111, 46, 174, 175, 193, 116, 93, 94, 95,
+ /* 1290 */ 184, 150, 98, 84, 85, 165, 150, 193, 150, 150,
/* 1300 */ 150, 176, 150, 94, 150, 150, 165, 98, 23, 139,
- /* 1310 */ 25, 165, 178, 176, 165, 165, 150, 165, 150, 165,
- /* 1320 */ 165, 150, 150, 129, 130, 131, 132, 133, 134, 22,
+ /* 1310 */ 25, 165, 178, 165, 165, 165, 150, 165, 150, 165,
+ /* 1320 */ 165, 150, 150, 129, 130, 131, 132, 133, 134, 103,
/* 1330 */ 150, 165, 150, 165, 150, 150, 165, 165, 129, 130,
- /* 1340 */ 131, 150, 150, 150, 179, 165, 150, 165, 150, 165,
- /* 1350 */ 165, 150, 150, 150, 90, 176, 165, 165, 165, 230,
- /* 1360 */ 23, 165, 25, 165, 176, 230, 165, 165, 165, 179,
- /* 1370 */ 184, 176, 18, 156, 44, 157, 156, 238, 157, 156,
- /* 1380 */ 135, 157, 157, 239, 156, 66, 157, 22, 189, 189,
- /* 1390 */ 157, 18, 219, 219, 157, 39, 199, 192, 192, 192,
- /* 1400 */ 192, 189, 241, 199, 241, 157, 157, 37, 244, 247,
- /* 1410 */ 164, 180, 180, 1, 15, 23, 22, 250, 118, 118,
- /* 1420 */ 118, 118, 118, 98, 113, 22, 11, 23, 23, 22,
- /* 1430 */ 22, 25, 23, 23, 23, 34, 34, 120, 25, 25,
- /* 1440 */ 22, 118, 23, 23, 27, 50, 22, 50, 22, 22,
- /* 1450 */ 34, 23, 22, 22, 102, 109, 19, 24, 20, 38,
- /* 1460 */ 25, 104, 138, 104, 22, 42, 5, 1, 108, 127,
- /* 1470 */ 74, 22, 50, 1, 74, 16, 121, 119, 20, 108,
- /* 1480 */ 51, 119, 57, 51, 22, 16, 23, 23, 127, 15,
- /* 1490 */ 140, 128, 22, 3, 251, 4, 251, 63,
+ /* 1340 */ 131, 150, 150, 150, 22, 165, 150, 165, 150, 165,
+ /* 1350 */ 165, 150, 23, 176, 25, 179, 165, 165, 165, 90,
+ /* 1360 */ 23, 165, 25, 165, 156, 23, 165, 25, 230, 23,
+ /* 1370 */ 230, 25, 184, 176, 179, 176, 176, 18, 157, 156,
+ /* 1380 */ 44, 157, 157, 156, 135, 157, 239, 156, 22, 238,
+ /* 1390 */ 157, 66, 189, 189, 219, 157, 18, 192, 192, 192,
+ /* 1400 */ 219, 199, 192, 189, 157, 157, 39, 157, 241, 37,
+ /* 1410 */ 199, 250, 180, 244, 241, 164, 1, 180, 15, 23,
+ /* 1420 */ 22, 247, 118, 118, 118, 118, 118, 113, 250, 98,
+ /* 1430 */ 22, 11, 23, 23, 22, 22, 25, 23, 34, 23,
+ /* 1440 */ 23, 34, 118, 25, 25, 22, 120, 23, 23, 27,
+ /* 1450 */ 50, 22, 50, 22, 22, 34, 23, 22, 22, 102,
+ /* 1460 */ 109, 19, 24, 20, 38, 104, 25, 104, 138, 22,
+ /* 1470 */ 42, 5, 1, 108, 127, 74, 22, 50, 1, 74,
+ /* 1480 */ 16, 119, 20, 119, 108, 51, 128, 57, 51, 121,
+ /* 1490 */ 22, 16, 23, 23, 15, 140, 127, 3, 22, 4,
+ /* 1500 */ 251, 251, 63,
};
#define YY_SHIFT_USE_DFLT (-111)
-#define YY_SHIFT_MAX 406
+#define YY_SHIFT_MAX 408
static const short yy_shift_ofst[] = {
/* 0 */ 187, 1061, 1170, 1061, 1194, 1194, -2, 64, 64, -19,
/* 10 */ 1194, 1194, 1194, 1194, 1194, 276, 1, 125, 1076, 1194,
/* 20 */ 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194,
@@ -85558,30 +86773,30 @@
/* 180 */ 769, 101, -110, -110, -110, -111, -111, -111, 232, 232,
/* 190 */ 268, 428, 213, 575, 645, 785, 788, 412, 968, 502,
/* 200 */ 491, 52, 183, 183, 183, 614, 614, 711, 912, 614,
/* 210 */ 614, 614, 614, 229, 546, -13, 141, 762, 762, 249,
- /* 220 */ 578, 578, 664, 578, 856, 578, 141, 578, 141, 926,
- /* 230 */ 843, 664, 664, 843, 1043, 1043, 1043, 1043, 1087, 1087,
- /* 240 */ 1089, -110, 1007, 1016, 1033, 1063, 1073, 1064, 1099, 1099,
- /* 250 */ 1122, 1123, 1122, 1123, 1122, 1123, 1157, 1157, 1222, 1157,
- /* 260 */ 1187, 1157, 1307, 1264, 1264, 1222, 1157, 1157, 1157, 1307,
- /* 270 */ 1354, 1099, 1354, 1099, 1354, 1099, 1099, 1330, 1245, 1354,
- /* 280 */ 1099, 1319, 1319, 1365, 1007, 1099, 1373, 1373, 1373, 1373,
- /* 290 */ 1007, 1319, 1365, 1099, 1356, 1356, 1099, 1099, 1370, -111,
- /* 300 */ -111, -111, -111, -111, 552, 1066, 1059, 1069, 712, 631,
- /* 310 */ 915, 801, 946, 866, 1000, 1022, 1097, 1153, 1241, 1247,
- /* 320 */ 1285, 515, 1337, 440, 1412, 1399, 1392, 1394, 1300, 1301,
- /* 330 */ 1302, 1303, 1304, 1325, 1311, 1403, 1404, 1405, 1407, 1415,
- /* 340 */ 1408, 1409, 1406, 1410, 1411, 1413, 1401, 1414, 1402, 1413,
- /* 350 */ 1317, 1418, 1416, 1417, 1323, 1419, 1420, 1421, 1395, 1424,
- /* 360 */ 1397, 1426, 1428, 1427, 1430, 1422, 1431, 1352, 1346, 1437,
- /* 370 */ 1438, 1433, 1357, 1423, 1425, 1429, 1435, 1432, 1324, 1359,
- /* 380 */ 1442, 1461, 1466, 1360, 1396, 1400, 1342, 1449, 1358, 1472,
- /* 390 */ 1459, 1355, 1458, 1362, 1371, 1361, 1462, 1363, 1463, 1464,
- /* 400 */ 1469, 1434, 1474, 1350, 1470, 1490, 1491,
+ /* 220 */ 578, 578, 664, 578, 856, 578, 141, 578, 141, 913,
+ /* 230 */ 843, 664, 664, 843, 1039, 1039, 1039, 1039, 1080, 1080,
+ /* 240 */ 1075, -110, 997, 1010, 1033, 1063, 1073, 1064, 1099, 1099,
+ /* 250 */ 1122, 1123, 1122, 1123, 1122, 1123, 1164, 1164, 1236, 1164,
+ /* 260 */ 1226, 1164, 1322, 1269, 1269, 1236, 1164, 1164, 1164, 1322,
+ /* 270 */ 1359, 1099, 1359, 1099, 1359, 1099, 1099, 1336, 1249, 1359,
+ /* 280 */ 1099, 1325, 1325, 1366, 997, 1099, 1378, 1378, 1378, 1378,
+ /* 290 */ 997, 1325, 1366, 1099, 1367, 1367, 1099, 1099, 1372, -111,
+ /* 300 */ -111, -111, -111, -111, -111, 552, 1066, 1059, 1069, 960,
+ /* 310 */ 1082, 712, 631, 928, 801, 1015, 866, 1097, 1153, 1241,
+ /* 320 */ 1285, 1329, 1337, 1342, 515, 1346, 1415, 1403, 1396, 1398,
+ /* 330 */ 1304, 1305, 1306, 1307, 1308, 1331, 1314, 1408, 1409, 1410,
+ /* 340 */ 1412, 1420, 1413, 1414, 1411, 1416, 1417, 1418, 1404, 1419,
+ /* 350 */ 1407, 1418, 1326, 1423, 1421, 1422, 1324, 1424, 1425, 1426,
+ /* 360 */ 1400, 1429, 1402, 1431, 1433, 1432, 1435, 1427, 1436, 1357,
+ /* 370 */ 1351, 1442, 1443, 1438, 1361, 1428, 1430, 1434, 1441, 1437,
+ /* 380 */ 1330, 1363, 1447, 1466, 1471, 1365, 1401, 1405, 1347, 1454,
+ /* 390 */ 1362, 1477, 1464, 1368, 1462, 1364, 1376, 1369, 1468, 1358,
+ /* 400 */ 1469, 1470, 1475, 1439, 1479, 1355, 1476, 1494, 1495,
};
#define YY_REDUCE_USE_DFLT (-180)
-#define YY_REDUCE_MAX 303
+#define YY_REDUCE_MAX 304
static const short yy_reduce_ofst[] = {
/* 0 */ -141, 82, 154, 284, 12, 75, 69, 73, 142, -59,
/* 10 */ 145, 87, 159, 220, 226, 346, 289, 155, 429, 437,
/* 20 */ 442, 486, 499, 505, 507, 519, 558, 571, 577, 588,
@@ -85596,88 +86811,88 @@
/* 110 */ 791, 134, 65, 942, 521, 794, -47, 878, 956, 986,
/* 120 */ 1003, 1047, 1074, 1092, 295, 1104, 2, 779, 2, 2,
/* 130 */ 2, 2, 158, 338, 572, 644, 650, 670, 723, 392,
/* 140 */ 564, 792, 885, 966, 1002, 1036, 723, 1084, 1091, 1100,
- /* 150 */ 1130, 1141, 1146, 1149, 1150, 1152, 1154, 1155, 1166, 1168,
- /* 160 */ 1171, 1172, 1180, 1182, 1184, 1185, 1191, 1192, 1193, 1196,
- /* 170 */ 1198, 1201, 1202, 1203, 554, 554, 734, 238, 326, 373,
- /* 180 */ -134, 278, 604, 710, 822, 44, 600, 635, -98, -70,
+ /* 150 */ 1105, 1130, 1141, 1146, 1148, 1149, 1150, 1152, 1154, 1155,
+ /* 160 */ 1166, 1168, 1171, 1172, 1180, 1182, 1184, 1185, 1191, 1192,
+ /* 170 */ 1193, 1196, 1198, 1201, 554, 554, 734, 238, 326, 373,
+ /* 180 */ -134, 278, 604, 710, 853, 44, 600, 635, -98, -70,
/* 190 */ -54, -36, -35, -35, -35, 13, -35, 14, 149, 115,
- /* 200 */ 163, 14, 210, 223, 360, -35, -35, 359, 448, -35,
- /* 210 */ -35, -35, -35, 513, 551, 598, 653, 596, 605, 647,
- /* 220 */ 656, 724, 741, 796, 830, 806, 847, 849, 870, 844,
- /* 230 */ 833, 832, 839, 854, 905, 940, 944, 945, 953, 954,
- /* 240 */ 959, 929, 948, 950, 957, 987, 985, 988, 1062, 1086,
- /* 250 */ 1023, 1034, 1041, 1044, 1042, 1049, 1095, 1106, 1114, 1125,
- /* 260 */ 1134, 1137, 1165, 1129, 1135, 1186, 1179, 1188, 1195, 1190,
- /* 270 */ 1217, 1218, 1220, 1221, 1223, 1224, 1225, 1139, 1144, 1228,
- /* 280 */ 1229, 1199, 1200, 1173, 1197, 1233, 1205, 1206, 1207, 1208,
- /* 290 */ 1204, 1212, 1174, 1237, 1161, 1163, 1248, 1249, 1164, 1246,
- /* 300 */ 1231, 1232, 1162, 1167,
+ /* 200 */ 163, 14, 210, 223, 280, -35, -35, 307, 358, -35,
+ /* 210 */ -35, -35, -35, 352, 470, 487, 581, 563, 596, 605,
+ /* 220 */ 642, 661, 666, 724, 758, 777, 784, 796, 860, 834,
+ /* 230 */ 830, 823, 827, 842, 899, 900, 904, 905, 938, 943,
+ /* 240 */ 955, 924, 940, 950, 957, 987, 985, 988, 1062, 1086,
+ /* 250 */ 1023, 1034, 1041, 1049, 1042, 1050, 1095, 1096, 1106, 1125,
+ /* 260 */ 1134, 1177, 1176, 1138, 1140, 1188, 1197, 1199, 1200, 1195,
+ /* 270 */ 1208, 1221, 1223, 1224, 1227, 1225, 1228, 1151, 1147, 1231,
+ /* 280 */ 1233, 1203, 1204, 1175, 1202, 1238, 1205, 1206, 1207, 1210,
+ /* 290 */ 1211, 1214, 1181, 1247, 1167, 1173, 1248, 1250, 1169, 1251,
+ /* 300 */ 1232, 1237, 1174, 1161, 1178,
};
static const YYACTIONTYPE yy_default[] = {
- /* 0 */ 621, 856, 939, 939, 856, 939, 939, 885, 885, 744,
- /* 10 */ 854, 939, 939, 939, 939, 939, 939, 914, 939, 939,
- /* 20 */ 939, 939, 939, 939, 939, 939, 939, 939, 939, 939,
- /* 30 */ 939, 939, 939, 939, 939, 939, 939, 939, 939, 939,
- /* 40 */ 939, 939, 939, 939, 939, 939, 939, 939, 939, 939,
- /* 50 */ 939, 939, 939, 939, 939, 939, 939, 939, 939, 828,
- /* 60 */ 939, 939, 939, 660, 885, 885, 748, 779, 939, 939,
- /* 70 */ 939, 939, 939, 939, 939, 939, 780, 939, 858, 853,
- /* 80 */ 849, 851, 850, 857, 781, 770, 777, 784, 759, 898,
- /* 90 */ 786, 787, 793, 794, 915, 913, 816, 815, 834, 818,
- /* 100 */ 840, 817, 827, 652, 819, 820, 939, 939, 939, 939,
- /* 110 */ 939, 713, 647, 939, 939, 939, 939, 939, 939, 939,
- /* 120 */ 939, 939, 939, 939, 939, 939, 821, 939, 822, 835,
- /* 130 */ 836, 837, 939, 939, 939, 939, 939, 939, 939, 939,
- /* 140 */ 939, 627, 939, 939, 939, 939, 939, 939, 939, 939,
- /* 150 */ 939, 939, 939, 939, 939, 939, 939, 939, 939, 939,
- /* 160 */ 939, 939, 939, 939, 939, 939, 939, 939, 939, 869,
- /* 170 */ 939, 918, 920, 939, 939, 939, 621, 744, 744, 744,
- /* 180 */ 939, 939, 939, 939, 939, 738, 748, 932, 939, 939,
- /* 190 */ 704, 939, 939, 939, 939, 939, 939, 939, 629, 736,
- /* 200 */ 662, 746, 939, 939, 939, 649, 725, 891, 939, 905,
- /* 210 */ 903, 727, 789, 939, 736, 745, 939, 939, 939, 852,
- /* 220 */ 773, 773, 761, 773, 683, 773, 939, 773, 939, 686,
- /* 230 */ 783, 761, 761, 783, 626, 626, 626, 626, 637, 637,
- /* 240 */ 703, 939, 783, 774, 776, 766, 778, 939, 752, 752,
- /* 250 */ 760, 765, 760, 765, 760, 765, 715, 715, 700, 715,
- /* 260 */ 686, 715, 862, 866, 866, 700, 715, 715, 715, 862,
- /* 270 */ 644, 752, 644, 752, 644, 752, 752, 895, 897, 644,
- /* 280 */ 752, 717, 717, 795, 783, 752, 724, 724, 724, 724,
- /* 290 */ 783, 717, 795, 752, 917, 917, 752, 752, 925, 670,
- /* 300 */ 688, 688, 932, 937, 939, 939, 939, 939, 939, 939,
- /* 310 */ 939, 939, 939, 939, 939, 939, 939, 939, 939, 939,
- /* 320 */ 939, 871, 939, 939, 939, 635, 939, 654, 802, 807,
- /* 330 */ 803, 939, 804, 939, 730, 939, 939, 939, 939, 939,
- /* 340 */ 939, 939, 939, 939, 939, 855, 939, 767, 939, 775,
- /* 350 */ 939, 939, 939, 939, 939, 939, 939, 939, 939, 939,
- /* 360 */ 939, 939, 939, 939, 939, 939, 939, 939, 939, 939,
- /* 370 */ 939, 939, 939, 939, 939, 893, 894, 939, 939, 939,
- /* 380 */ 939, 939, 939, 939, 939, 939, 939, 939, 939, 939,
- /* 390 */ 939, 939, 939, 939, 939, 939, 939, 939, 939, 939,
- /* 400 */ 939, 924, 939, 939, 927, 622, 939, 617, 619, 620,
- /* 410 */ 624, 625, 628, 654, 655, 657, 658, 659, 630, 631,
- /* 420 */ 632, 633, 634, 636, 640, 638, 639, 641, 648, 650,
- /* 430 */ 669, 671, 673, 734, 735, 799, 728, 729, 733, 656,
- /* 440 */ 810, 801, 805, 806, 808, 809, 823, 824, 826, 832,
- /* 450 */ 839, 842, 825, 830, 831, 833, 838, 841, 731, 732,
- /* 460 */ 845, 663, 664, 667, 668, 881, 883, 882, 884, 666,
- /* 470 */ 665, 811, 814, 847, 848, 906, 907, 908, 909, 910,
- /* 480 */ 843, 753, 846, 829, 768, 771, 772, 769, 737, 747,
- /* 490 */ 755, 756, 757, 758, 742, 743, 749, 764, 797, 798,
- /* 500 */ 762, 763, 750, 751, 739, 740, 741, 844, 800, 812,
- /* 510 */ 813, 674, 675, 807, 676, 677, 678, 716, 719, 720,
- /* 520 */ 721, 679, 698, 701, 702, 680, 687, 681, 682, 689,
- /* 530 */ 690, 691, 694, 695, 696, 697, 692, 693, 863, 864,
- /* 540 */ 867, 865, 684, 685, 699, 672, 661, 653, 705, 708,
- /* 550 */ 709, 710, 711, 712, 714, 706, 707, 651, 642, 645,
- /* 560 */ 754, 887, 896, 892, 888, 889, 890, 646, 859, 860,
- /* 570 */ 718, 791, 792, 886, 899, 901, 796, 902, 904, 900,
- /* 580 */ 929, 643, 722, 723, 726, 868, 911, 782, 785, 788,
- /* 590 */ 790, 870, 872, 874, 876, 877, 878, 879, 880, 873,
- /* 600 */ 875, 912, 916, 919, 921, 922, 923, 926, 928, 933,
- /* 610 */ 934, 935, 938, 936, 623, 618,
+ /* 0 */ 624, 859, 943, 943, 859, 943, 943, 888, 888, 747,
+ /* 10 */ 857, 943, 943, 943, 943, 943, 943, 917, 943, 943,
+ /* 20 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 943,
+ /* 30 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 943,
+ /* 40 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 943,
+ /* 50 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 831,
+ /* 60 */ 943, 943, 943, 663, 888, 888, 751, 782, 943, 943,
+ /* 70 */ 943, 943, 943, 943, 943, 943, 783, 943, 861, 856,
+ /* 80 */ 852, 854, 853, 860, 784, 773, 780, 787, 762, 901,
+ /* 90 */ 789, 790, 796, 797, 918, 916, 819, 818, 837, 821,
+ /* 100 */ 843, 820, 830, 655, 822, 823, 943, 943, 943, 943,
+ /* 110 */ 943, 716, 650, 943, 943, 943, 943, 943, 943, 943,
+ /* 120 */ 943, 943, 943, 943, 943, 943, 824, 943, 825, 838,
+ /* 130 */ 839, 840, 943, 943, 943, 943, 943, 943, 943, 943,
+ /* 140 */ 943, 630, 943, 943, 943, 943, 943, 943, 943, 943,
+ /* 150 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 943,
+ /* 160 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 872,
+ /* 170 */ 943, 921, 923, 943, 943, 943, 624, 747, 747, 747,
+ /* 180 */ 943, 943, 943, 943, 943, 741, 751, 935, 943, 943,
+ /* 190 */ 707, 943, 943, 943, 943, 943, 943, 943, 632, 739,
+ /* 200 */ 665, 749, 943, 943, 943, 652, 728, 894, 943, 908,
+ /* 210 */ 906, 730, 792, 943, 739, 748, 943, 943, 943, 855,
+ /* 220 */ 776, 776, 764, 776, 686, 776, 943, 776, 943, 689,
+ /* 230 */ 786, 764, 764, 786, 629, 629, 629, 629, 640, 640,
+ /* 240 */ 706, 943, 786, 777, 779, 769, 781, 943, 755, 755,
+ /* 250 */ 763, 768, 763, 768, 763, 768, 718, 718, 703, 718,
+ /* 260 */ 689, 718, 865, 869, 869, 703, 718, 718, 718, 865,
+ /* 270 */ 647, 755, 647, 755, 647, 755, 755, 898, 900, 647,
+ /* 280 */ 755, 720, 720, 798, 786, 755, 727, 727, 727, 727,
+ /* 290 */ 786, 720, 798, 755, 920, 920, 755, 755, 928, 673,
+ /* 300 */ 691, 691, 935, 940, 940, 943, 943, 943, 943, 943,
+ /* 310 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 943,
+ /* 320 */ 943, 943, 943, 943, 874, 943, 943, 638, 943, 657,
+ /* 330 */ 805, 810, 806, 943, 807, 943, 733, 943, 943, 943,
+ /* 340 */ 943, 943, 943, 943, 943, 943, 943, 858, 943, 770,
+ /* 350 */ 943, 778, 943, 943, 943, 943, 943, 943, 943, 943,
+ /* 360 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 943,
+ /* 370 */ 943, 943, 943, 943, 943, 943, 943, 896, 897, 943,
+ /* 380 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 943,
+ /* 390 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 943,
+ /* 400 */ 943, 943, 943, 927, 943, 943, 930, 625, 943, 620,
+ /* 410 */ 622, 623, 627, 628, 631, 657, 658, 660, 661, 662,
+ /* 420 */ 633, 634, 635, 636, 637, 639, 643, 641, 642, 644,
+ /* 430 */ 651, 653, 672, 674, 676, 737, 738, 802, 731, 732,
+ /* 440 */ 736, 659, 813, 804, 808, 809, 811, 812, 826, 827,
+ /* 450 */ 829, 835, 842, 845, 828, 833, 834, 836, 841, 844,
+ /* 460 */ 734, 735, 848, 666, 667, 670, 671, 884, 886, 885,
+ /* 470 */ 887, 669, 668, 814, 817, 850, 851, 909, 910, 911,
+ /* 480 */ 912, 913, 846, 756, 849, 832, 771, 774, 775, 772,
+ /* 490 */ 740, 750, 758, 759, 760, 761, 745, 746, 752, 767,
+ /* 500 */ 800, 801, 765, 766, 753, 754, 742, 743, 744, 847,
+ /* 510 */ 803, 815, 816, 677, 678, 810, 679, 680, 681, 719,
+ /* 520 */ 722, 723, 724, 682, 701, 704, 705, 683, 690, 684,
+ /* 530 */ 685, 692, 693, 694, 697, 698, 699, 700, 695, 696,
+ /* 540 */ 866, 867, 870, 868, 687, 688, 702, 675, 664, 656,
+ /* 550 */ 708, 711, 712, 713, 714, 715, 717, 709, 710, 654,
+ /* 560 */ 645, 648, 757, 890, 899, 895, 891, 892, 893, 649,
+ /* 570 */ 862, 863, 721, 794, 795, 889, 902, 904, 799, 905,
+ /* 580 */ 907, 903, 932, 646, 725, 726, 729, 871, 914, 785,
+ /* 590 */ 788, 791, 793, 873, 875, 877, 879, 880, 881, 882,
+ /* 600 */ 883, 876, 878, 915, 919, 922, 924, 925, 926, 929,
+ /* 610 */ 931, 936, 937, 938, 941, 942, 939, 626, 621,
};
#define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0]))
/* The next table maps tokens into fallback tokens. If a construct
@@ -86301,9 +87516,10 @@
/* 318 */ "vtabargtoken ::= ANY",
/* 319 */ "vtabargtoken ::= lp anylist RP",
/* 320 */ "lp ::= LP",
/* 321 */ "anylist ::=",
- /* 322 */ "anylist ::= anylist ANY",
+ /* 322 */ "anylist ::= anylist LP anylist RP",
+ /* 323 */ "anylist ::= anylist ANY",
};
#endif /* NDEBUG */
@@ -86388,19 +87604,11 @@
}
break;
case 174: /* term */
case 175: /* expr */
- case 199: /* where_opt */
- case 201: /* having_opt */
- case 210: /* on_opt */
- case 215: /* sortitem */
case 223: /* escape */
- case 226: /* case_operand */
- case 228: /* case_else */
- case 239: /* when_clause */
- case 242: /* key_opt */
-{
-sqlite3ExprDelete(pParse->db, (yypminor->yy72));
+{
+sqlite3ExprDelete(pParse->db, (yypminor->yy190).pExpr);
}
break;
case 179: /* idxlist_opt */
case 187: /* idxlist */
@@ -86423,8 +87631,20 @@
case 206: /* seltablist */
case 207: /* stl_prefix */
{
sqlite3SrcListDelete(pParse->db, (yypminor->yy185));
+}
+ break;
+ case 199: /* where_opt */
+ case 201: /* having_opt */
+ case 210: /* on_opt */
+ case 215: /* sortitem */
+ case 226: /* case_operand */
+ case 228: /* case_else */
+ case 239: /* when_clause */
+ case 242: /* key_opt */
+{
+sqlite3ExprDelete(pParse->db, (yypminor->yy72));
}
break;
case 211: /* using_opt */
case 213: /* inscollist */
@@ -86995,8 +88215,9 @@
{ 248, 1 },
{ 248, 3 },
{ 249, 1 },
{ 250, 0 },
+ { 250, 4 },
{ 250, 2 },
};
static void yy_accept(yyParser*); /* Forward Declaration */
@@ -87087,8 +88308,10 @@
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 ::= */
@@ -87186,10 +88409,8 @@
case 36: /* column ::= columnid type carglist */
{
yygotominor.yy0.z = yymsp[-2].minor.yy0.z;
yygotominor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-2].minor.yy0.z) + pParse->sLastToken.n;
- yygotominor.yy0.quoted = 0;
- yygotominor.yy0.dyn = 0;
}
break;
case 37: /* columnid ::= nm */
{
@@ -87239,24 +88460,27 @@
{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 */
-{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy72);}
+{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy190);}
break;
case 58: /* ccons ::= DEFAULT LP expr RP */
-{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy72);}
+{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy190);}
break;
case 60: /* ccons ::= DEFAULT MINUS term */
{
- Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy72, 0, 0);
- sqlite3ExprSpan(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy72->span);
- sqlite3AddDefaultValue(pParse,p);
+ ExprSpan v;
+ v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy190.pExpr, 0, 0);
+ v.zStart = yymsp[-1].minor.yy0.z;
+ v.zEnd = yymsp[0].minor.yy190.zEnd;
+ sqlite3AddDefaultValue(pParse,&v);
}
break;
case 61: /* ccons ::= DEFAULT id */
{
- Expr *p = sqlite3PExpr(pParse, TK_STRING, 0, 0, &yymsp[0].minor.yy0);
- sqlite3AddDefaultValue(pParse,p);
+ ExprSpan v;
+ spanExpr(&v, pParse, TK_STRING, &yymsp[0].minor.yy0);
+ sqlite3AddDefaultValue(pParse,&v);
}
break;
case 63: /* ccons ::= NOT NULL onconf */
{sqlite3AddNotNull(pParse, yymsp[0].minor.yy194);}
@@ -87267,9 +88491,9 @@
case 65: /* ccons ::= UNIQUE onconf */
{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy194,0,0,0,0);}
break;
case 66: /* ccons ::= CHECK LP expr RP */
-{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy72);}
+{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy190.pExpr);}
break;
case 67: /* ccons ::= REFERENCES nm idxlist_opt refargs */
{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy148,yymsp[0].minor.yy194);}
break;
@@ -87330,9 +88554,9 @@
case 94: /* tcons ::= UNIQUE LP idxlist RP onconf */
{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy148,yymsp[0].minor.yy194,0,0,0,0);}
break;
case 95: /* tcons ::= CHECK LP expr RP onconf */
-{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy72);}
+{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy190.pExpr);}
break;
case 96: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt */
{
sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy148, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy148, yymsp[-1].minor.yy194);
@@ -87406,23 +88630,25 @@
{yygotominor.yy148 = 0;}
break;
case 123: /* selcollist ::= sclp expr as */
{
- yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[-1].minor.yy72,yymsp[0].minor.yy0.n?&yymsp[0].minor.yy0:0);
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy148, yymsp[-1].minor.yy190.pExpr);
+ if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yygotominor.yy148, &yymsp[0].minor.yy0, 1);
+ sqlite3ExprListSetSpan(pParse,yygotominor.yy148,&yymsp[-1].minor.yy190);
}
break;
case 124: /* selcollist ::= sclp STAR */
{
- Expr *p = sqlite3PExpr(pParse, TK_ALL, 0, 0, 0);
- yygotominor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy148, p, 0);
+ Expr *p = sqlite3Expr(pParse->db, TK_ALL, 0);
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy148, p);
}
break;
case 125: /* selcollist ::= sclp nm DOT STAR */
{
Expr *pRight = sqlite3PExpr(pParse, TK_ALL, 0, 0, &yymsp[0].minor.yy0);
Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
- yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148, pDot, 0);
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148, pDot);
}
break;
case 128: /* as ::= */
{yygotominor.yy0.n = 0;}
@@ -87490,18 +88716,15 @@
case 143: /* on_opt ::= ON expr */
case 154: /* sortitem ::= expr */
case 161: /* having_opt ::= HAVING expr */
case 168: /* where_opt ::= WHERE expr */
- case 183: /* expr ::= term */
- case 211: /* escape ::= ESCAPE expr */
case 235: /* case_else ::= ELSE expr */
case 237: /* case_operand ::= expr */
-{yygotominor.yy72 = yymsp[0].minor.yy72;}
+{yygotominor.yy72 = yymsp[0].minor.yy190.pExpr;}
break;
case 144: /* on_opt ::= */
case 160: /* having_opt ::= */
case 167: /* where_opt ::= */
- case 212: /* escape ::= */
case 236: /* case_else ::= */
case 238: /* case_operand ::= */
{yygotominor.yy72 = 0;}
break;
@@ -87522,15 +88745,15 @@
{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,0);
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148,yymsp[-1].minor.yy72);
if( yygotominor.yy148 ) yygotominor.yy148->a[yygotominor.yy148->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy194;
}
break;
case 153: /* sortlist ::= sortitem sortorder */
{
- yygotominor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy72,0);
+ 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;
}
break;
case 155: /* sortorder ::= ASC */
@@ -87543,15 +88766,15 @@
case 162: /* limit_opt ::= */
{yygotominor.yy354.pLimit = 0; yygotominor.yy354.pOffset = 0;}
break;
case 163: /* limit_opt ::= LIMIT expr */
-{yygotominor.yy354.pLimit = yymsp[0].minor.yy72; yygotominor.yy354.pOffset = 0;}
+{yygotominor.yy354.pLimit = yymsp[0].minor.yy190.pExpr; yygotominor.yy354.pOffset = 0;}
break;
case 164: /* limit_opt ::= LIMIT expr OFFSET expr */
-{yygotominor.yy354.pLimit = yymsp[-2].minor.yy72; yygotominor.yy354.pOffset = yymsp[0].minor.yy72;}
+{yygotominor.yy354.pLimit = yymsp[-2].minor.yy190.pExpr; yygotominor.yy354.pOffset = yymsp[0].minor.yy190.pExpr;}
break;
case 165: /* limit_opt ::= LIMIT expr COMMA expr */
-{yygotominor.yy354.pOffset = yymsp[-2].minor.yy72; yygotominor.yy354.pLimit = yymsp[0].minor.yy72;}
+{yygotominor.yy354.pOffset = yymsp[-2].minor.yy190.pExpr; yygotominor.yy354.pLimit = yymsp[0].minor.yy190.pExpr;}
break;
case 166: /* cmd ::= DELETE FROM fullname indexed_opt where_opt */
{
sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy185, &yymsp[-1].minor.yy0);
@@ -87565,12 +88788,18 @@
sqlite3Update(pParse,yymsp[-4].minor.yy185,yymsp[-1].minor.yy148,yymsp[0].minor.yy72,yymsp[-5].minor.yy194);
}
break;
case 170: /* setlist ::= setlist COMMA nm EQ expr */
-{yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148,yymsp[0].minor.yy72,&yymsp[-2].minor.yy0);}
+{
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy148, yymsp[0].minor.yy190.pExpr);
+ sqlite3ExprListSetName(pParse, yygotominor.yy148, &yymsp[-2].minor.yy0, 1);
+}
break;
case 171: /* setlist ::= nm EQ expr */
-{yygotominor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy72,&yymsp[-2].minor.yy0);}
+{
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy190.pExpr);
+ sqlite3ExprListSetName(pParse, yygotominor.yy148, &yymsp[-2].minor.yy0, 1);
+}
break;
case 172: /* cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP */
{sqlite3Insert(pParse, yymsp[-5].minor.yy185, yymsp[-1].minor.yy148, 0, yymsp[-4].minor.yy254, yymsp[-7].minor.yy194);}
break;
@@ -87581,37 +88810,42 @@
{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 */
-{yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[0].minor.yy72,0);}
+{yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[0].minor.yy190.pExpr);}
break;
case 178: /* itemlist ::= expr */
case 242: /* nexprlist ::= expr */
-{yygotominor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy72,0);}
+{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 */
+{yygotominor.yy190 = yymsp[0].minor.yy190;}
+ break;
case 184: /* expr ::= LP expr RP */
-{yygotominor.yy72 = yymsp[-1].minor.yy72; sqlite3ExprSpan(yygotominor.yy72,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); }
+{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 */
-{yygotominor.yy72 = sqlite3PExpr(pParse, yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);}
+{spanExpr(&yygotominor.yy190, pParse, yymsp[0].major, &yymsp[0].minor.yy0);}
break;
case 186: /* expr ::= id */
case 187: /* expr ::= JOIN_KW */
-{yygotominor.yy72 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);}
+{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);
Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
+ yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
+ spanSet(&yygotominor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
}
break;
case 189: /* expr ::= nm DOT nm DOT nm */
{
@@ -87618,59 +88852,74 @@
Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-4].minor.yy0);
Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0);
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
+ yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
+ spanSet(&yygotominor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
}
break;
case 192: /* expr ::= REGISTER */
-{yygotominor.yy72 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);}
+{
+ /* When doing a nested parse, one can include terms in an expression
+ ** that look like this: #1 #2 ... These terms refer to registers
+ ** in the virtual machine. #N is the N-th register. */
+ if( pParse->nested==0 ){
+ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &yymsp[0].minor.yy0);
+ yygotominor.yy190.pExpr = 0;
+ }else{
+ yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &yymsp[0].minor.yy0);
+ if( yygotominor.yy190.pExpr ) sqlite3GetInt32(&yymsp[0].minor.yy0.z[1], &yygotominor.yy190.pExpr->iTable);
+ }
+ spanSet(&yygotominor.yy190, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
+}
break;
case 193: /* expr ::= VARIABLE */
{
- Token *pToken = &yymsp[0].minor.yy0;
- Expr *pExpr = yygotominor.yy72 = sqlite3PExpr(pParse, TK_VARIABLE, 0, 0, pToken);
- sqlite3ExprAssignVarNumber(pParse, pExpr);
+ spanExpr(&yygotominor.yy190, pParse, TK_VARIABLE, &yymsp[0].minor.yy0);
+ sqlite3ExprAssignVarNumber(pParse, yygotominor.yy190.pExpr);
+ spanSet(&yygotominor.yy190, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
}
break;
case 194: /* expr ::= expr COLLATE ids */
{
- yygotominor.yy72 = sqlite3ExprSetColl(pParse, yymsp[-2].minor.yy72, &yymsp[0].minor.yy0);
+ yygotominor.yy190.pExpr = sqlite3ExprSetColl(pParse, yymsp[-2].minor.yy190.pExpr, &yymsp[0].minor.yy0);
+ yygotominor.yy190.zStart = yymsp[-2].minor.yy190.zStart;
+ yygotominor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 195: /* expr ::= CAST LP expr AS typetoken RP */
{
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy72, 0, &yymsp[-1].minor.yy0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
+ yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy190.pExpr, 0, &yymsp[-1].minor.yy0);
+ 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 ){
sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
}
- yygotominor.yy72 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy148, &yymsp[-4].minor.yy0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
- if( yymsp[-2].minor.yy194 && yygotominor.yy72 ){
- yygotominor.yy72->flags |= EP_Distinct;
+ 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 ){
+ yygotominor.yy190.pExpr->flags |= EP_Distinct;
}
}
break;
case 197: /* expr ::= ID LP STAR RP */
{
- yygotominor.yy72 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
+ yygotominor.yy190.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
+ spanSet(&yygotominor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
}
break;
case 198: /* term ::= CTIME_KW */
{
/* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are
** treated as functions that return constants */
- yygotominor.yy72 = sqlite3ExprFunction(pParse, 0,&yymsp[0].minor.yy0);
- if( yygotominor.yy72 ){
- yygotominor.yy72->op = TK_CONST_FUNC;
- yygotominor.yy72->span = yymsp[0].minor.yy0;
- }
+ yygotominor.yy190.pExpr = sqlite3ExprFunction(pParse, 0,&yymsp[0].minor.yy0);
+ if( yygotominor.yy190.pExpr ){
+ yygotominor.yy190.pExpr->op = TK_CONST_FUNC;
+ }
+ spanSet(&yygotominor.yy190, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
}
break;
case 199: /* expr ::= expr AND expr */
case 200: /* expr ::= expr OR expr */
@@ -87679,9 +88928,9 @@
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 */
-{yygotominor.yy72 = sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy72,yymsp[0].minor.yy72,0);}
+{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 */
{yygotominor.yy392.eOperator = yymsp[0].minor.yy0; yygotominor.yy392.not = 0;}
@@ -87689,169 +88938,159 @@
case 208: /* likeop ::= NOT LIKE_KW */
case 210: /* likeop ::= NOT MATCH */
{yygotominor.yy392.eOperator = yymsp[0].minor.yy0; yygotominor.yy392.not = 1;}
break;
+ case 212: /* escape ::= */
+{memset(&yygotominor.yy190,0,sizeof(yygotominor.yy190));}
+ break;
case 213: /* expr ::= expr likeop expr escape */
{
ExprList *pList;
- pList = sqlite3ExprListAppend(pParse,0, yymsp[-1].minor.yy72, 0);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-3].minor.yy72, 0);
- if( yymsp[0].minor.yy72 ){
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy72, 0);
- }
- yygotominor.yy72 = sqlite3ExprFunction(pParse, pList, &yymsp[-2].minor.yy392.eOperator);
- if( yymsp[-2].minor.yy392.not ) yygotominor.yy72 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy72, 0, 0);
- sqlite3ExprSpan(yygotominor.yy72, &yymsp[-3].minor.yy72->span, &yymsp[-1].minor.yy72->span);
- if( yygotominor.yy72 ) yygotominor.yy72->flags |= EP_InfixFunc;
+ pList = sqlite3ExprListAppend(pParse,0, yymsp[-1].minor.yy190.pExpr);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-3].minor.yy190.pExpr);
+ if( yymsp[0].minor.yy190.pExpr ){
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy190.pExpr);
+ }
+ yygotominor.yy190.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-2].minor.yy392.eOperator);
+ if( yymsp[-2].minor.yy392.not ) yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy190.pExpr, 0, 0);
+ yygotominor.yy190.zStart = yymsp[-3].minor.yy190.zStart;
+ yygotominor.yy190.zEnd = yymsp[-1].minor.yy190.zEnd;
+ if( yygotominor.yy190.pExpr ) yygotominor.yy190.pExpr->flags |= EP_InfixFunc;
}
break;
case 214: /* expr ::= expr ISNULL|NOTNULL */
-{
- yygotominor.yy72 = sqlite3PExpr(pParse, yymsp[0].major, yymsp[-1].minor.yy72, 0, 0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-1].minor.yy72->span,&yymsp[0].minor.yy0);
-}
+{spanUnaryPostfix(&yygotominor.yy190,pParse,yymsp[0].major,&yymsp[-1].minor.yy190,&yymsp[0].minor.yy0);}
break;
case 215: /* expr ::= expr IS NULL */
-{
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_ISNULL, yymsp[-2].minor.yy72, 0, 0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-2].minor.yy72->span,&yymsp[0].minor.yy0);
-}
+{spanUnaryPostfix(&yygotominor.yy190,pParse,TK_ISNULL,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy0);}
break;
case 216: /* expr ::= expr NOT NULL */
-{
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_NOTNULL, yymsp[-2].minor.yy72, 0, 0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-2].minor.yy72->span,&yymsp[0].minor.yy0);
-}
+{spanUnaryPostfix(&yygotominor.yy190,pParse,TK_NOTNULL,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy0);}
break;
case 217: /* expr ::= expr IS NOT NULL */
-{
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_NOTNULL, yymsp[-3].minor.yy72, 0, 0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-3].minor.yy72->span,&yymsp[0].minor.yy0);
-}
+{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 */
-{
- yygotominor.yy72 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy72, 0, 0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy72->span);
-}
+{spanUnaryPrefix(&yygotominor.yy190,pParse,yymsp[-1].major,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);}
break;
case 220: /* expr ::= MINUS expr */
-{
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy72, 0, 0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy72->span);
-}
+{spanUnaryPrefix(&yygotominor.yy190,pParse,TK_UMINUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);}
break;
case 221: /* expr ::= PLUS expr */
-{
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_UPLUS, yymsp[0].minor.yy72, 0, 0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy72->span);
-}
+{spanUnaryPrefix(&yygotominor.yy190,pParse,TK_UPLUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);}
break;
case 224: /* expr ::= expr between_op expr AND expr */
{
- ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy72, 0);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy72, 0);
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy72, 0, 0);
- if( yygotominor.yy72 ){
- yygotominor.yy72->x.pList = pList;
+ ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy190.pExpr);
+ yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy190.pExpr, 0, 0);
+ if( yygotominor.yy190.pExpr ){
+ yygotominor.yy190.pExpr->x.pList = pList;
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
- if( yymsp[-3].minor.yy194 ) yygotominor.yy72 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy72, 0, 0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-4].minor.yy72->span,&yymsp[0].minor.yy72->span);
+ if( yymsp[-3].minor.yy194 ) yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy190.pExpr, 0, 0);
+ yygotominor.yy190.zStart = yymsp[-4].minor.yy190.zStart;
+ yygotominor.yy190.zEnd = yymsp[0].minor.yy190.zEnd;
}
break;
case 227: /* expr ::= expr in_op LP exprlist RP */
{
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy72, 0, 0);
- if( yygotominor.yy72 ){
- yygotominor.yy72->x.pList = yymsp[-1].minor.yy148;
- sqlite3ExprSetHeight(pParse, yygotominor.yy72);
+ yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0, 0);
+ if( yygotominor.yy190.pExpr ){
+ yygotominor.yy190.pExpr->x.pList = yymsp[-1].minor.yy148;
+ sqlite3ExprSetHeight(pParse, yygotominor.yy190.pExpr);
}else{
sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy148);
}
- if( yymsp[-3].minor.yy194 ) yygotominor.yy72 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy72, 0, 0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-4].minor.yy72->span,&yymsp[0].minor.yy0);
+ if( yymsp[-3].minor.yy194 ) yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy190.pExpr, 0, 0);
+ yygotominor.yy190.zStart = yymsp[-4].minor.yy190.zStart;
+ yygotominor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 228: /* expr ::= LP select RP */
{
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
- if( yygotominor.yy72 ){
- yygotominor.yy72->x.pSelect = yymsp[-1].minor.yy243;
- ExprSetProperty(yygotominor.yy72, EP_xIsSelect);
- sqlite3ExprSetHeight(pParse, yygotominor.yy72);
+ yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
+ if( yygotominor.yy190.pExpr ){
+ yygotominor.yy190.pExpr->x.pSelect = yymsp[-1].minor.yy243;
+ ExprSetProperty(yygotominor.yy190.pExpr, EP_xIsSelect);
+ sqlite3ExprSetHeight(pParse, yygotominor.yy190.pExpr);
}else{
sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy243);
}
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
+ yygotominor.yy190.zStart = yymsp[-2].minor.yy0.z;
+ yygotominor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 229: /* expr ::= expr in_op LP select RP */
{
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy72, 0, 0);
- if( yygotominor.yy72 ){
- yygotominor.yy72->x.pSelect = yymsp[-1].minor.yy243;
- ExprSetProperty(yygotominor.yy72, EP_xIsSelect);
- sqlite3ExprSetHeight(pParse, yygotominor.yy72);
+ yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0, 0);
+ if( yygotominor.yy190.pExpr ){
+ yygotominor.yy190.pExpr->x.pSelect = yymsp[-1].minor.yy243;
+ ExprSetProperty(yygotominor.yy190.pExpr, EP_xIsSelect);
+ sqlite3ExprSetHeight(pParse, yygotominor.yy190.pExpr);
}else{
sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy243);
}
- if( yymsp[-3].minor.yy194 ) yygotominor.yy72 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy72, 0, 0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-4].minor.yy72->span,&yymsp[0].minor.yy0);
+ if( yymsp[-3].minor.yy194 ) yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy190.pExpr, 0, 0);
+ yygotominor.yy190.zStart = yymsp[-4].minor.yy190.zStart;
+ yygotominor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 230: /* expr ::= expr in_op nm dbnm */
{
SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy72, 0, 0);
- if( yygotominor.yy72 ){
- yygotominor.yy72->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
- ExprSetProperty(yygotominor.yy72, EP_xIsSelect);
- sqlite3ExprSetHeight(pParse, yygotominor.yy72);
+ yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy190.pExpr, 0, 0);
+ if( yygotominor.yy190.pExpr ){
+ yygotominor.yy190.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
+ ExprSetProperty(yygotominor.yy190.pExpr, EP_xIsSelect);
+ sqlite3ExprSetHeight(pParse, yygotominor.yy190.pExpr);
}else{
sqlite3SrcListDelete(pParse->db, pSrc);
}
- if( yymsp[-2].minor.yy194 ) yygotominor.yy72 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy72, 0, 0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-3].minor.yy72->span,yymsp[0].minor.yy0.z?&yymsp[0].minor.yy0:&yymsp[-1].minor.yy0);
+ if( yymsp[-2].minor.yy194 ) yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy190.pExpr, 0, 0);
+ yygotominor.yy190.zStart = yymsp[-3].minor.yy190.zStart;
+ yygotominor.yy190.zEnd = yymsp[0].minor.yy0.z ? &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] : &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n];
}
break;
case 231: /* expr ::= EXISTS LP select RP */
{
- Expr *p = yygotominor.yy72 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
+ Expr *p = yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
if( p ){
p->x.pSelect = yymsp[-1].minor.yy243;
- ExprSetProperty(yygotominor.yy72, EP_xIsSelect);
- sqlite3ExprSpan(p,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
- sqlite3ExprSetHeight(pParse, yygotominor.yy72);
+ ExprSetProperty(p, EP_xIsSelect);
+ sqlite3ExprSetHeight(pParse, p);
}else{
sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy243);
}
+ yygotominor.yy190.zStart = yymsp[-3].minor.yy0.z;
+ yygotominor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 232: /* expr ::= CASE case_operand case_exprlist case_else END */
{
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy72, yymsp[-1].minor.yy72, 0);
- if( yygotominor.yy72 ){
- yygotominor.yy72->x.pList = yymsp[-2].minor.yy148;
- sqlite3ExprSetHeight(pParse, yygotominor.yy72);
+ yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy72, yymsp[-1].minor.yy72, 0);
+ if( yygotominor.yy190.pExpr ){
+ yygotominor.yy190.pExpr->x.pList = yymsp[-2].minor.yy148;
+ sqlite3ExprSetHeight(pParse, yygotominor.yy190.pExpr);
}else{
sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy148);
}
- sqlite3ExprSpan(yygotominor.yy72, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0);
+ yygotominor.yy190.zStart = yymsp[-4].minor.yy0.z;
+ yygotominor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 233: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
{
- yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, yymsp[-2].minor.yy72, 0);
- yygotominor.yy148 = sqlite3ExprListAppend(pParse,yygotominor.yy148, yymsp[0].minor.yy72, 0);
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, yymsp[-2].minor.yy190.pExpr);
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,yygotominor.yy148, yymsp[0].minor.yy190.pExpr);
}
break;
case 234: /* case_exprlist ::= WHEN expr THEN expr */
{
- yygotominor.yy148 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy72, 0);
- yygotominor.yy148 = sqlite3ExprListAppend(pParse,yygotominor.yy148, yymsp[0].minor.yy72, 0);
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr);
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,yygotominor.yy148, yymsp[0].minor.yy190.pExpr);
}
break;
case 243: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP */
{
@@ -87870,12 +89109,13 @@
case 248: /* idxlist ::= idxlist COMMA nm collate sortorder */
{
Expr *p = 0;
if( yymsp[-1].minor.yy0.n>0 ){
- p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
+ p = sqlite3Expr(pParse->db, TK_COLUMN, 0);
sqlite3ExprSetColl(pParse, p, &yymsp[-1].minor.yy0);
}
- yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, p, &yymsp[-2].minor.yy0);
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, p);
+ sqlite3ExprListSetName(pParse,yygotominor.yy148,&yymsp[-2].minor.yy0,1);
sqlite3ExprListCheckLength(pParse, yygotominor.yy148, "index");
if( yygotominor.yy148 ) yygotominor.yy148->a[yygotominor.yy148->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy194;
}
break;
@@ -87885,9 +89125,10 @@
if( yymsp[-1].minor.yy0.n>0 ){
p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
sqlite3ExprSetColl(pParse, p, &yymsp[-1].minor.yy0);
}
- yygotominor.yy148 = sqlite3ExprListAppend(pParse,0, p, &yymsp[-2].minor.yy0);
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,0, p);
+ sqlite3ExprListSetName(pParse, yygotominor.yy148, &yymsp[-2].minor.yy0, 1);
sqlite3ExprListCheckLength(pParse, yygotominor.yy148, "index");
if( yygotominor.yy148 ) yygotominor.yy148->a[yygotominor.yy148->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy194;
}
break;
@@ -87952,19 +89193,12 @@
{ yygotominor.yy72 = 0; }
break;
case 282: /* when_clause ::= WHEN expr */
case 299: /* key_opt ::= KEY expr */
-{ yygotominor.yy72 = yymsp[0].minor.yy72; }
+{ yygotominor.yy72 = yymsp[0].minor.yy190.pExpr; }
break;
case 283: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
{
-/*
- if( yymsp[-2].minor.yy145 ){
- yymsp[-2].minor.yy145->pLast->pNext = yymsp[-1].minor.yy145;
- }else{
- yymsp[-2].minor.yy145 = yymsp[-1].minor.yy145;
- }
-*/
assert( yymsp[-2].minor.yy145!=0 );
yymsp[-2].minor.yy145->pLast->pNext = yymsp[-1].minor.yy145;
yymsp[-2].minor.yy145->pLast = yymsp[-1].minor.yy145;
yygotominor.yy145 = yymsp[-2].minor.yy145;
@@ -87971,9 +89205,8 @@
}
break;
case 284: /* trigger_cmd_list ::= trigger_cmd SEMI */
{
- /* if( yymsp[-1].minor.yy145 ) */
assert( yymsp[-1].minor.yy145!=0 );
yymsp[-1].minor.yy145->pLast = yymsp[-1].minor.yy145;
yygotominor.yy145 = yymsp[-1].minor.yy145;
}
@@ -87994,22 +89227,24 @@
{yygotominor.yy145 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy243); }
break;
case 290: /* expr ::= RAISE LP IGNORE RP */
{
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
- if( yygotominor.yy72 ){
- yygotominor.yy72->affinity = OE_Ignore;
- sqlite3ExprSpan(yygotominor.yy72, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0);
- }
+ yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
+ if( yygotominor.yy190.pExpr ){
+ yygotominor.yy190.pExpr->affinity = OE_Ignore;
+ }
+ yygotominor.yy190.zStart = yymsp[-3].minor.yy0.z;
+ yygotominor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 291: /* expr ::= RAISE LP raisetype COMMA nm RP */
{
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0);
- if( yygotominor.yy72 ) {
- yygotominor.yy72->affinity = (char)yymsp[-3].minor.yy194;
- sqlite3ExprSpan(yygotominor.yy72, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0);
- }
+ yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0);
+ if( yygotominor.yy190.pExpr ) {
+ yygotominor.yy190.pExpr->affinity = (char)yymsp[-3].minor.yy194;
+ }
+ yygotominor.yy190.zStart = yymsp[-5].minor.yy0.z;
+ yygotominor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 292: /* raisetype ::= ROLLBACK */
{yygotominor.yy194 = OE_Rollback;}
@@ -88023,14 +89258,14 @@
}
break;
case 296: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
{
- sqlite3Attach(pParse, yymsp[-3].minor.yy72, yymsp[-1].minor.yy72, yymsp[0].minor.yy72);
+ sqlite3Attach(pParse, yymsp[-3].minor.yy190.pExpr, yymsp[-1].minor.yy190.pExpr, yymsp[0].minor.yy72);
}
break;
case 297: /* cmd ::= DETACH database_kw_opt expr */
{
- sqlite3Detach(pParse, yymsp[0].minor.yy72);
+ sqlite3Detach(pParse, yymsp[0].minor.yy190.pExpr);
}
break;
case 302: /* cmd ::= REINDEX */
{sqlite3Reindex(pParse, 0, 0);}
@@ -88076,9 +89311,8 @@
break;
case 318: /* vtabargtoken ::= ANY */
case 319: /* vtabargtoken ::= lp anylist RP */
case 320: /* lp ::= LP */
- case 322: /* anylist ::= anylist ANY */
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
break;
};
yygoto = yyRuleInfo[yyruleno].lhs;
@@ -88338,9 +89572,9 @@
** 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.156 2009/05/01 21:13:37 drh Exp $
+** $Id: tokenize.c,v 1.158 2009/05/28 01:00:55 drh Exp $
*/
/*
** The charMap() macro maps alphabetic characters into their
@@ -88995,9 +90229,8 @@
if( pEngine==0 ){
db->mallocFailed = 1;
return SQLITE_NOMEM;
}
- assert( pParse->sLastToken.dyn==0 );
assert( pParse->pNewTable==0 );
assert( pParse->pNewTrigger==0 );
assert( pParse->nVar==0 );
assert( pParse->nVarExpr==0 );
@@ -89004,14 +90237,11 @@
assert( pParse->nVarExprAlloc==0 );
assert( pParse->apVarExpr==0 );
enableLookaside = db->lookaside.bEnabled;
if( db->lookaside.pStart ) db->lookaside.bEnabled = 1;
- pParse->sLastToken.quoted = 1;
while( !db->mallocFailed && zSql[i]!=0 ){
assert( i>=0 );
- pParse->sLastToken.z = (u8*)&zSql[i];
- assert( pParse->sLastToken.dyn==0 );
- assert( pParse->sLastToken.quoted );
+ pParse->sLastToken.z = &zSql[i];
pParse->sLastToken.n = sqlite3GetToken((unsigned char*)&zSql[i],&tokenType);
i += pParse->sLastToken.n;
if( i>mxSqlLen ){
pParse->rc = SQLITE_TOOBIG;
@@ -89410,9 +90640,9 @@
** 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.548 2009/05/06 19:03:14 drh Exp $
+** $Id: main.c,v 1.555 2009/06/01 16:53:10 shane Exp $
*/
#ifdef SQLITE_ENABLE_FTS3
/************** Include fts3.h in the middle of main.c ***********************/
@@ -89793,17 +91023,17 @@
sqlite3GlobalConfig.nScratch = va_arg(ap, int);
break;
}
case SQLITE_CONFIG_PAGECACHE: {
- /* Designate a buffer for scratch memory space */
+ /* Designate a buffer for page cache memory space */
sqlite3GlobalConfig.pPage = va_arg(ap, void*);
sqlite3GlobalConfig.szPage = va_arg(ap, int);
sqlite3GlobalConfig.nPage = va_arg(ap, int);
break;
}
case SQLITE_CONFIG_PCACHE: {
- /* Specify an alternative malloc implementation */
+ /* Specify an alternative page cache implementation */
sqlite3GlobalConfig.pcache = *va_arg(ap, sqlite3_pcache_methods*);
break;
}
@@ -90414,10 +91644,9 @@
(!xFunc && (xFinal && !xStep)) ||
(!xFunc && (!xFinal && xStep)) ||
(nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) ||
(255<(nName = sqlite3Strlen30( zFunctionName))) ){
- sqlite3Error(db, SQLITE_ERROR, "bad parameters");
- return SQLITE_ERROR;
+ return SQLITE_MISUSE;
}
#ifndef SQLITE_OMIT_UTF16
/* If SQLITE_UTF16 is specified as the encoding type, transform this
@@ -90676,9 +91905,10 @@
return ( db->temp_store!=1 );
#endif
#if SQLITE_TEMP_STORE==3
return 1;
-#else
+#endif
+#if SQLITE_TEMP_STORE<1 || SQLITE_TEMP_STORE>3
return 0;
#endif
}
@@ -90845,9 +92075,9 @@
void(*xDel)(void*)
){
CollSeq *pColl;
int enc2;
- int nName;
+ int nName = sqlite3Strlen30(zName);
assert( sqlite3_mutex_held(db->mutex) );
/* If SQLITE_UTF16 is specified as the encoding type, transform this
@@ -90867,10 +92097,9 @@
/* Check if this call is removing or replacing an existing collation
** sequence. If so, and there are active VMs, return busy. If there
** are no active VMs, invalidate any pre-compiled statements.
*/
- nName = sqlite3Strlen30(zName);
- pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, nName, 0);
+ pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 0);
if( pColl && pColl->xCmp ){
if( db->activeVdbeCnt ){
sqlite3Error(db, SQLITE_BUSY,
"unable to delete/modify collation sequence due to active statements");
@@ -90898,9 +92127,9 @@
}
}
}
- pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, nName, 1);
+ pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 1);
if( pColl ){
pColl->xCmp = xCompare;
pColl->pUser = pCtx;
pColl->xDel = xDel;
@@ -91020,10 +92249,18 @@
}else{
isThreadsafe = sqlite3GlobalConfig.bFullMutex;
}
- /* Remove harmful bits from the flags parameter */
+ /* Remove harmful bits from the flags parameter
+ **
+ ** The SQLITE_OPEN_NOMUTEX and SQLITE_OPEN_FULLMUTEX flags were
+ ** dealt with in the previous code block. Besides these, the only
+ ** valid input flags for sqlite3_open_v2() are SQLITE_OPEN_READONLY,
+ ** SQLITE_OPEN_READWRITE, and SQLITE_OPEN_CREATE. Silently mask
+ ** off all other flags.
+ */
flags &= ~( SQLITE_OPEN_DELETEONCLOSE |
+ SQLITE_OPEN_EXCLUSIVE |
SQLITE_OPEN_MAIN_DB |
SQLITE_OPEN_TEMP_DB |
SQLITE_OPEN_TRANSIENT_DB |
SQLITE_OPEN_MAIN_JOURNAL |
@@ -91087,17 +92324,17 @@
createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0);
if( db->mallocFailed ){
goto opendb_out;
}
- db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0);
+ db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0);
assert( db->pDfltColl!=0 );
/* Also add a UTF-8 case-insensitive collation sequence. */
createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
/* Set flags on the built-in collating sequences */
db->pDfltColl->type = SQLITE_COLL_BINARY;
- pColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "NOCASE", 6, 0);
+ pColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "NOCASE", 0);
if( pColl ){
pColl->type = SQLITE_COLL_NOCASE;
}
@@ -91141,10 +92378,11 @@
/* Load automatic extensions - extensions that have been registered
** using the sqlite3_automatic_extension() API.
*/
- (void)sqlite3AutoLoadExtensions(db);
- if( sqlite3_errcode(db)!=SQLITE_OK ){
+ sqlite3AutoLoadExtensions(db);
+ rc = sqlite3_errcode(db);
+ if( rc!=SQLITE_OK ){
goto opendb_out;
}
#ifdef SQLITE_ENABLE_FTS1
@@ -91660,9 +92898,9 @@
break;
}
/*
- ** sqlite3_test_control(PENDING_BYTE, unsigned int X)
+ ** sqlite3_test_control(SQLITE_TESTCTRL_PENDING_BYTE, unsigned int X)
**
** Set the PENDING byte to the value in the argument, if X>0.
** Make no changes if X==0. Return the value of the pending byte
** as it existing before this routine was called.
@@ -91675,8 +92913,60 @@
case SQLITE_TESTCTRL_PENDING_BYTE: {
unsigned int newVal = va_arg(ap, unsigned int);
rc = sqlite3PendingByte;
if( newVal ) sqlite3PendingByte = newVal;
+ break;
+ }
+
+ /*
+ ** sqlite3_test_control(SQLITE_TESTCTRL_ASSERT, int X)
+ **
+ ** This action provides a run-time test to see whether or not
+ ** assert() was enabled at compile-time. If X is true and assert()
+ ** is enabled, then the return value is true. If X is true and
+ ** assert() is disabled, then the return value is zero. If X is
+ ** false and assert() is enabled, then the assertion fires and the
+ ** process aborts. If X is false and assert() is disabled, then the
+ ** return value is zero.
+ */
+ case SQLITE_TESTCTRL_ASSERT: {
+ volatile int x = 0;
+ assert( (x = va_arg(ap,int))!=0 );
+ rc = x;
+ break;
+ }
+
+
+ /*
+ ** sqlite3_test_control(SQLITE_TESTCTRL_ALWAYS, int X)
+ **
+ ** This action provides a run-time test to see how the ALWAYS and
+ ** NEVER macros were defined at compile-time.
+ **
+ ** The return value is ALWAYS(X).
+ **
+ ** The recommended test is X==2. If the return value is 2, that means
+ ** ALWAYS() and NEVER() are both no-op pass-through macros, which is the
+ ** default setting. If the return value is 1, then ALWAYS() is either
+ ** hard-coded to true or else it asserts if its argument is false.
+ ** The first behavior (hard-coded to true) is the case if
+ ** SQLITE_TESTCTRL_ASSERT shows that assert() is disabled and the second
+ ** behavior (assert if the argument to ALWAYS() is false) is the case if
+ ** SQLITE_TESTCTRL_ASSERT shows that assert() is enabled.
+ **
+ ** The run-time test procedure might look something like this:
+ **
+ ** if( sqlite3_test_control(SQLITE_TESTCTRL_ALWAYS, 2)==2 ){
+ ** // ALWAYS() and NEVER() are no-op pass-through macros
+ ** }else if( sqlite3_test_control(SQLITE_TESTCTRL_ASSERT, 1) ){
+ ** // ALWAYS(x) asserts that x is true. NEVER(x) asserts x is false.
+ ** }else{
+ ** // ALWAYS(x) is a constant 1. NEVER(x) is a constant 0.
+ ** }
+ */
+ case SQLITE_TESTCTRL_ALWAYS: {
+ int x = va_arg(ap,int);
+ rc = ALWAYS(x);
break;
}
}
va_end(ap);