Diff
Not logged in

Differences From:

File src/sqlite3.c part of check-in [f84bfc31bf] - Update the version of SQLite used to 3.6.6.2. by drh on 2008-11-27 02:30:29. [view]

To:

File src/sqlite3.c part of check-in [458331b99e] - Upgrade SQLite to version 3.6.7. by drh on 2008-12-16 18:37:58. [view]

@@ -1,7 +1,7 @@
 /******************************************************************************
 ** This file is an amalgamation of many separate C source files from SQLite
-** version 3.6.6.2.  By combining all the individual C code files into this
+** version 3.6.7.  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
-** 6728 lines past this header comment.)  Additional code files may be
+** 6735 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 2008-11-27 02:28:55 UTC.
+** This amalgamation was generated on 2008-12-16 18:01: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.798 2008/11/19 16:52:44 danielk1977 Exp $
+** @(#) $Id: sqliteInt.h,v 1.809 2008/12/10 21:19:57 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
 
@@ -248,9 +248,9 @@
 #pragma warn -rch /* unreachable code */
 #pragma warn -ccc /* Condition is always true or false */
 #pragma warn -aus /* Assigned value is never used */
 #pragma warn -csu /* Comparing signed and unsigned */
-#pragma warn -spa /* Suspicous pointer arithmetic */
+#pragma warn -spa /* Suspicious pointer arithmetic */
 #endif
 
 /* Needed for various definitions... */
 #ifndef _GNU_SOURCE
@@ -333,9 +333,9 @@
 #define SQLITE_INT_TO_PTR(X)   ((void*)&((char*)0)[X])
 #define SQLITE_PTR_TO_INT(X)   ((int)(((char*)X)-(char*)0))
 
 /*
-** These #defines should enable >2GB file support on Posix if the
+** These #defines should enable >2GB file support on POSIX if the
 ** underlying operating system supports it.  If the OS lacks
 ** large file support, or if the OS is windows, these should be no-ops.
 **
 ** Ticket #2739:  The _LARGEFILE_SOURCE macro must appear before any
@@ -343,15 +343,15 @@
 ** code in all source files.
 **
 ** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
 ** on the compiler command line.  This is necessary if you are compiling
-** on a recent machine (ex: RedHat 7.2) but you want your code to work
-** on an older machine (ex: RedHat 6.0).  If you compile on RedHat 7.2
+** on a recent machine (ex: Red Hat 7.2) but you want your code to work
+** on an older machine (ex: Red Hat 6.0).  If you compile on Red Hat 7.2
 ** without this option, LFS is enable.  But LFS does not exist in the kernel
-** in RedHat 6.0, so the code won't work.  Hence, for maximum binary
+** in Red Hat 6.0, so the code won't work.  Hence, for maximum binary
 ** portability you should omit LFS.
 **
-** Similar is true for MacOS.  LFS is only supported on MacOS 9 and later.
+** Similar is true for Mac OS X.  LFS is only supported on Mac OS X 9 and later.
 */
 #ifndef SQLITE_DISABLE_LFS
 # define _LARGE_FILE       1
 # ifndef _FILE_OFFSET_BITS
@@ -376,9 +376,9 @@
 
 /*
 ** The SQLITE_DEFAULT_MEMSTATUS macro must be defined as either 0 or 1.
 ** It determines whether or not the features related to
-** SQLITE_CONFIG_MEMSTATUS are availabe by default or not. This value can
+** SQLITE_CONFIG_MEMSTATUS are available by default or not. This value can
 ** be overridden at runtime using the sqlite3_config() API.
 */
 #if !defined(SQLITE_DEFAULT_MEMSTATUS)
 # define SQLITE_DEFAULT_MEMSTATUS 1
@@ -419,9 +419,9 @@
 #endif
 
 /*
 ** We need to define _XOPEN_SOURCE as follows in order to enable
-** recursive mutexes on most unix systems.  But Mac OS X is different.
+** recursive mutexes on most Unix systems.  But Mac OS X is different.
 ** The _XOPEN_SOURCE define causes problems for Mac OS X we are told,
 ** so it is omitted there.  See ticket #2673.
 **
 ** Later we learn that _XOPEN_SOURCE is poorly or incorrectly
@@ -486,9 +486,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.415 2008/11/19 01:20:26 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.420 2008/12/16 13:46:30 drh Exp $
 */
 #ifndef _SQLITE3_H_
 #define _SQLITE3_H_
 #include <stdarg.h>     /* Needed for the definition of va_list */
@@ -563,10 +563,10 @@
 ** {H10014} The SQLITE_VERSION_NUMBER #define shall resolve to an integer
 **          with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z
 **          are the major version, minor version, and release number.
 */
-#define SQLITE_VERSION         "3.6.6.2"
-#define SQLITE_VERSION_NUMBER  3006006
+#define SQLITE_VERSION         "3.6.7"
+#define SQLITE_VERSION_NUMBER  3006007
 
 /*
 ** CAPI3REF: Run-Time Library Version Numbers {H10020} <S60100>
 ** KEYWORDS: sqlite3_version
@@ -593,9 +593,9 @@
 **
 ** {H10023} The [sqlite3_libversion()] function shall return
 **          a pointer to the [sqlite3_version] string constant.
 */
-SQLITE_API const char sqlite3_version[];
+SQLITE_API const char sqlite3_version[] = SQLITE_VERSION;
 SQLITE_API const char *sqlite3_libversion(void);
 SQLITE_API int sqlite3_libversion_number(void);
 
 /*
@@ -963,8 +963,10 @@
 #define SQLITE_IOERR_NOMEM             (SQLITE_IOERR | (12<<8))
 #define SQLITE_IOERR_ACCESS            (SQLITE_IOERR | (13<<8))
 #define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8))
 #define SQLITE_IOERR_LOCK              (SQLITE_IOERR | (15<<8))
+#define SQLITE_IOERR_CLOSE             (SQLITE_IOERR | (16<<8))
+#define SQLITE_IOERR_DIR_CLOSE         (SQLITE_IOERR | (17<<8))
 
 /*
 ** CAPI3REF: Flags For File Open Operations {H10230} <H11120> <H12700>
 **
@@ -1179,8 +1181,11 @@
 ** is used during testing and only needs to be supported when SQLITE_TEST
 ** is defined.
 */
 #define SQLITE_FCNTL_LOCKSTATE        1
+#define SQLITE_GET_LOCKPROXYFILE      2
+#define SQLITE_SET_LOCKPROXYFILE      3
+#define SQLITE_LAST_ERRNO             4
 
 /*
 ** CAPI3REF: Mutex Handle {H17110} <S20130>
 **
@@ -1226,28 +1231,28 @@
 **
 ** The zName field holds the name of the VFS module.  The name must
 ** be unique across all VFS modules.
 **
-** {H11141} SQLite will guarantee that the zFilename parameter to xOpen
+** SQLite will guarantee that the zFilename parameter to xOpen
 ** is either a NULL pointer or string obtained
 ** from xFullPathname().  SQLite further guarantees that
 ** the string will be valid and unchanged until xClose() is
-** called. {END}  Because of the previous sentense,
+** called. Because of the previous sentense,
 ** the [sqlite3_file] can safely store a pointer to the
 ** filename if it needs to remember the filename for some reason.
 ** If the zFilename parameter is xOpen is a NULL pointer then xOpen
 ** must invite its own temporary name for the file.  Whenever the
 ** xFilename parameter is NULL it will also be the case that the
 ** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE].
 **
-** {H11142} The flags argument to xOpen() includes all bits set in
+** The flags argument to xOpen() includes all bits set in
 ** the flags argument to [sqlite3_open_v2()].  Or if [sqlite3_open()]
 ** or [sqlite3_open16()] is used, then flags includes at least
-** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. {END}
+** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE].
 ** If xOpen() opens a file read-only then it sets *pOutFlags to
 ** include [SQLITE_OPEN_READONLY].  Other bits in *pOutFlags may be set.
 **
-** {H11143} SQLite will also add one of the following flags to the xOpen()
+** SQLite will also add one of the following flags to the xOpen()
 ** call, depending on the object being opened:
 **
 ** <ul>
 ** <li>  [SQLITE_OPEN_MAIN_DB]
@@ -1256,9 +1261,9 @@
 ** <li>  [SQLITE_OPEN_TEMP_JOURNAL]
 ** <li>  [SQLITE_OPEN_TRANSIENT_DB]
 ** <li>  [SQLITE_OPEN_SUBJOURNAL]
 ** <li>  [SQLITE_OPEN_MASTER_JOURNAL]
-** </ul> {END}
+** </ul>
 **
 ** The file I/O implementation can use the object type flags to
 ** change the way it deals with files.  For example, an application
 ** that does not care about crash recovery or rollback might make
@@ -1274,30 +1279,30 @@
 ** <li> [SQLITE_OPEN_DELETEONCLOSE]
 ** <li> [SQLITE_OPEN_EXCLUSIVE]
 ** </ul>
 **
-** {H11145} The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be
-** deleted when it is closed.  {H11146} The [SQLITE_OPEN_DELETEONCLOSE]
+** 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.
 **
-** {H11147} The [SQLITE_OPEN_EXCLUSIVE] flag means the file should be opened
+** 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.
 **
-** {H11148} At least szOsFile bytes of memory are allocated by SQLite
+** At least szOsFile bytes of memory are allocated by SQLite
 ** to hold the  [sqlite3_file] structure passed as the third
-** argument to xOpen. {END}  The xOpen method does not have to
+** argument to xOpen.  The xOpen method does not have to
 ** allocate the structure; it should just fill it in.
 **
-** {H11149} The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS]
+** The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS]
 ** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to
 ** test whether a file is readable and writable, or [SQLITE_ACCESS_READ]
-** to test whether a file is at least readable. {END}  The file can be a
+** to test whether a file is at least readable.   The file can be a
 ** directory.
 **
-** {H11150} SQLite will always allocate at least mxPathname+1 bytes for the
-** output buffer xFullPathname. {H11151} The exact size of the output buffer
-** is also passed as a parameter to both  methods. {END}  If the output buffer
+** SQLite will always allocate at least mxPathname+1 bytes for the
+** output buffer xFullPathname.  The exact size of the output buffer
+** is also passed as a parameter to both  methods. If the output buffer
 ** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is
 ** handled as a fatal error by SQLite, vfs implementations should endeavor
 ** to prevent this by setting mxPathname to a sufficiently large value.
 **
@@ -1309,8 +1314,9 @@
 ** the actual number of bytes of randomness obtained.
 ** The xSleep() method causes the calling thread to sleep for at
 ** least the number of microseconds given.  The xCurrentTime()
 ** method returns a Julian Day Number for the current date and time.
+**
 */
 typedef struct sqlite3_vfs sqlite3_vfs;
 struct sqlite3_vfs {
   int iVersion;            /* Structure version number */
@@ -1325,9 +1331,9 @@
   int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut);
   int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut);
   void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename);
   void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg);
-  void *(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol);
+  void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void);
   void (*xDlClose)(sqlite3_vfs*, void*);
   int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut);
   int (*xSleep)(sqlite3_vfs*, int microseconds);
   int (*xCurrentTime)(sqlite3_vfs*, double*);
@@ -1338,16 +1344,16 @@
 
 /*
 ** CAPI3REF: Flags for the xAccess VFS method {H11190} <H11140>
 **
-** {H11191} These integer constants can be used as the third parameter to
+** These integer constants can be used as the third parameter to
 ** the xAccess method of an [sqlite3_vfs] object. {END}  They determine
 ** what kind of permissions the xAccess method is looking for.
-** {H11192} With SQLITE_ACCESS_EXISTS, the xAccess method
+** With SQLITE_ACCESS_EXISTS, the xAccess method
 ** simply checks whether the file exists.
-** {H11193} With SQLITE_ACCESS_READWRITE, the xAccess method
+** With SQLITE_ACCESS_READWRITE, the xAccess method
 ** checks whether the file is both readable and writable.
-** {H11194} With SQLITE_ACCESS_READ, the xAccess method
+** With SQLITE_ACCESS_READ, the xAccess method
 ** checks whether the file is readable.
 */
 #define SQLITE_ACCESS_EXISTS    0
 #define SQLITE_ACCESS_READWRITE 1
@@ -1500,9 +1506,9 @@
 **          where Z and N are non-negative integers and
 **          S is a pointer to an aligned memory buffer not less than
 **          Z*N bytes in size shall cause S to be used by the
 **          [scratch memory allocator] for as many as N simulataneous
-**          allocations each of size Z.
+**          allocations each of size (Z & ~7).
 **
 ** {H14153} A successful call to [sqlite3_config]([SQLITE_CONFIG_SCRATCH],S,Z,N)
 **          where S is a NULL pointer shall disable the
 **          [scratch memory allocator].
@@ -1512,9 +1518,9 @@
 **          where Z and N are non-negative integers and
 **          S is a pointer to an aligned memory buffer not less than
 **          Z*N bytes in size shall cause S to be used by the
 **          [pagecache memory allocator] for as many as N simulataneous
-**          allocations each of size Z.
+**          allocations each of size (Z & ~7).
 **
 ** {H14159} A successful call to
 **          [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],S,Z,N)
 **          where S is a NULL pointer shall disable the
@@ -1860,20 +1866,20 @@
 /*
 ** CAPI3REF: Last Insert Rowid {H12220} <S10700>
 **
 ** Each entry in an SQLite table has a unique 64-bit signed
-** integer key called the "rowid". The rowid is always available
+** integer key called the [ROWID | "rowid"]. The rowid is always available
 ** as an undeclared column named ROWID, OID, or _ROWID_ as long as those
 ** names are not also used by explicitly declared columns. If
-** the table has a column of type INTEGER PRIMARY KEY then that column
+** the table has a column of type [INTEGER PRIMARY KEY] then that column
 ** is another alias for the rowid.
 **
-** This routine returns the rowid of the most recent
+** This routine returns the [rowid] of the most recent
 ** successful [INSERT] into the database from the [database connection]
 ** in the first argument.  If no successful [INSERT]s
 ** have ever occurred on that database connection, zero is returned.
 **
-** If an [INSERT] occurs within a trigger, then the rowid of the inserted
+** If an [INSERT] occurs within a trigger, then the [rowid] of the inserted
 ** row is returned by this routine as long as the trigger is running.
 ** But once the trigger terminates, the value returned by this routine
 ** reverts to the last value inserted before the trigger fired.
 **
@@ -1891,9 +1897,10 @@
 ** be successful even if it is subsequently rolled back.
 **
 ** INVARIANTS:
 **
-** {H12221} The [sqlite3_last_insert_rowid()] function shall return the rowid
+** {H12221} The [sqlite3_last_insert_rowid()] function shall return
+**          the [rowid]
 **          of the most recent successful [INSERT] performed on the same
 **          [database connection] and within the same or higher level
 **          trigger context, or zero if there have been no qualifying
 **          [INSERT] statements.
@@ -1905,12 +1912,12 @@
 ** ASSUMPTIONS:
 **
 ** {A12232} If a separate thread performs a new [INSERT] on the same
 **          database connection while the [sqlite3_last_insert_rowid()]
-**          function is running and thus changes the last insert rowid,
+**          function is running and thus changes the last insert [rowid],
 **          then the value returned by [sqlite3_last_insert_rowid()] is
 **          unpredictable and might not equal either the old or the new
-**          last insert rowid.
+**          last insert [rowid].
 */
 SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
 
 /*
@@ -2619,10 +2626,10 @@
 /*
 ** CAPI3REF: Pseudo-Random Number Generator {H17390} <S20000>
 **
 ** SQLite contains a high-quality pseudo-random number generator (PRNG) used to
-** select random ROWIDs when inserting new records into a table that
-** already uses the largest possible ROWID.  The PRNG is also used for
+** select random [ROWID | ROWIDs] when inserting new records into a table that
+** already uses the largest possible [ROWID].  The PRNG is also used for
 ** the build-in random() and randomblob() SQL functions.  This interface allows
 ** applications to access the same PRNG for other purposes.
 **
 ** A call to this routine stores N bytes of randomness into buffer P.
@@ -5569,10 +5576,10 @@
 ** or [SQLITE_UPDATE], depending on the operation that caused the callback
 ** to be invoked.
 ** The third and fourth arguments to the callback contain pointers to the
 ** database and table name containing the affected row.
-** The final callback parameter is the rowid of the row. In the case of
-** an update, this is the rowid after the update takes place.
+** The final callback parameter is the [rowid] of the row.
+** In the case of an update, this is the [rowid] after the update takes place.
 **
 ** The update hook is not invoked when internal system tables are
 ** modified (i.e. sqlite_master and sqlite_sequence).
 **
@@ -5613,9 +5620,9 @@
 ** {H12983} The third and fourth arguments to the callback contain pointers
 **          to zero-terminated UTF-8 strings which are the names of the
 **          database and table that is being updated.
 
-** {H12985} The final callback parameter is the rowid of the row after
+** {H12985} The final callback parameter is the [rowid] of the row after
 **          the change occurs.
 */
 SQLITE_API void *sqlite3_update_hook(
   sqlite3*,
@@ -5779,9 +5786,9 @@
 ** <tr><td> 5th <td> const char* <td> Data type
 ** <tr><td> 6th <td> const char* <td> Name of default collation sequence
 ** <tr><td> 7th <td> int         <td> True if column has a NOT NULL constraint
 ** <tr><td> 8th <td> int         <td> True if column is part of the PRIMARY KEY
-** <tr><td> 9th <td> int         <td> True if column is AUTOINCREMENT
+** <tr><td> 9th <td> int         <td> True if column is [AUTOINCREMENT]
 ** </table>
 ** </blockquote>
 **
 ** The memory pointed to by the character pointers returned for the
@@ -5790,11 +5797,11 @@
 **
 ** If the specified table is actually a view, an [error code] is returned.
 **
 ** If the specified column is "rowid", "oid" or "_rowid_" and an
-** INTEGER PRIMARY KEY column has been explicitly declared, then the output
+** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output
 ** parameters are set for the explicitly declared column. If there is no
-** explicitly declared INTEGER PRIMARY KEY column, then the output
+** explicitly declared [INTEGER PRIMARY KEY] column, then the output
 ** parameters are set as follows:
 **
 ** <pre>
 **     data type: "INTEGER"
@@ -5899,9 +5906,9 @@
 **          that is obtained from [sqlite3_malloc()].
 **
 ** {H12644} Automatic extensions apply across all threads.
 */
-SQLITE_API int sqlite3_auto_extension(void *xEntryPoint);
+SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
 
 /*
 ** CAPI3REF: Reset Automatic Extension Loading {H12660} <S20500>
 **
@@ -6216,9 +6223,9 @@
 ** in row iRow, column zColumn, table zTable in database zDb;
 ** in other words, the same BLOB that would be selected by:
 **
 ** <pre>
-**     SELECT zColumn FROM zDb.zTable WHERE rowid = iRow;
+**     SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
 ** </pre> {END}
 **
 ** If the flags parameter is non-zero, the the BLOB is opened for read
 ** and write access. If it is zero, the BLOB is opened for read access.
@@ -7578,9 +7585,9 @@
 ** Macros to determine whether the machine is big or little endian,
 ** evaluated at runtime.
 */
 #ifdef SQLITE_AMALGAMATION
-SQLITE_PRIVATE const int sqlite3one;
+SQLITE_PRIVATE const int sqlite3one = 1;
 #else
 SQLITE_PRIVATE const int sqlite3one;
 #endif
 #if defined(i386) || defined(__i386__) || defined(_M_IX86)\
@@ -7698,8 +7705,9 @@
 */
 typedef struct AggInfo AggInfo;
 typedef struct AuthContext AuthContext;
 typedef struct Bitvec Bitvec;
+typedef struct RowSet RowSet;
 typedef struct CollSeq CollSeq;
 typedef struct Column Column;
 typedef struct Db Db;
 typedef struct Schema Schema;
@@ -8119,11 +8127,11 @@
 #define OP_VNext                                1
 #define OP_Affinity                             2
 #define OP_Column                               3
 #define OP_SetCookie                            4
+#define OP_Seek                                 5
 #define OP_Real                               126   /* same as TK_FLOAT    */
-#define OP_Sequence                             5
-#define OP_MoveGt                               6
+#define OP_Sequence                             6
 #define OP_Ge                                  72   /* same as TK_GE       */
 #define OP_RowKey                               7
 #define OP_SCopy                                8
 #define OP_Eq                                  68   /* same as TK_EQ       */
@@ -8177,41 +8185,41 @@
 #define OP_Divide                              81   /* same as TK_SLASH    */
 #define OP_Integer                             48
 #define OP_ToNumeric                          141   /* same as TK_TO_NUMERIC*/
 #define OP_Prev                                49
+#define OP_RowSetRead                          50
 #define OP_Concat                              83   /* same as TK_CONCAT   */
+#define OP_RowSetAdd                           51
 #define OP_BitAnd                              74   /* same as TK_BITAND   */
-#define OP_VColumn                             50
-#define OP_CreateTable                         51
-#define OP_Last                                52
+#define OP_VColumn                             52
+#define OP_CreateTable                         53
+#define OP_Last                                54
+#define OP_SeekLe                              55
 #define OP_IsNull                              65   /* same as TK_ISNULL   */
-#define OP_IncrVacuum                          53
-#define OP_IdxRowid                            54
+#define OP_IncrVacuum                          56
+#define OP_IdxRowid                            57
 #define OP_ShiftRight                          77   /* same as TK_RSHIFT   */
-#define OP_ResetCount                          55
-#define OP_FifoWrite                           56
-#define OP_ContextPush                         57
-#define OP_Yield                               58
-#define OP_DropTrigger                         59
-#define OP_DropIndex                           62
-#define OP_IdxGE                               63
-#define OP_IdxDelete                           64
-#define OP_Vacuum                              73
-#define OP_MoveLe                              84
-#define OP_IfNot                               85
-#define OP_DropTable                           86
-#define OP_MakeRecord                          89
+#define OP_ResetCount                          58
+#define OP_ContextPush                         59
+#define OP_Yield                               62
+#define OP_DropTrigger                         63
+#define OP_DropIndex                           64
+#define OP_IdxGE                               73
+#define OP_IdxDelete                           84
+#define OP_Vacuum                              85
+#define OP_IfNot                               86
+#define OP_DropTable                           89
+#define OP_SeekLt                              90
+#define OP_MakeRecord                          91
 #define OP_ToBlob                             140   /* same as TK_TO_BLOB  */
-#define OP_ResultRow                           90
-#define OP_Delete                              91
-#define OP_AggFinal                            92
-#define OP_Compare                             93
+#define OP_ResultRow                           92
+#define OP_Delete                              93
+#define OP_AggFinal                            94
+#define OP_Compare                             95
 #define OP_ShiftLeft                           76   /* same as TK_LSHIFT   */
-#define OP_Goto                                94
-#define OP_TableLock                           95
-#define OP_FifoRead                            96
-#define OP_Clear                               97
-#define OP_MoveLt                              98
+#define OP_Goto                                96
+#define OP_TableLock                           97
+#define OP_Clear                               98
 #define OP_Le                                  70   /* same as TK_LE       */
 #define OP_VerifyCookie                        99
 #define OP_AggStep                            100
 #define OP_ToText                             139   /* same as TK_TO_TEXT  */
@@ -8226,12 +8234,12 @@
 #define OP_BitOr                               75   /* same as TK_BITOR    */
 #define OP_Next                               106
 #define OP_IdxInsert                          107
 #define OP_Lt                                  71   /* same as TK_LT       */
-#define OP_Insert                             108
-#define OP_Destroy                            109
-#define OP_ReadCookie                         110
-#define OP_ForceInt                           111
+#define OP_SeekGe                             108
+#define OP_Insert                             109
+#define OP_Destroy                            110
+#define OP_ReadCookie                         111
 #define OP_LoadAnalysis                       112
 #define OP_Explain                            113
 #define OP_OpenPseudo                         114
 #define OP_OpenEphemeral                      115
@@ -8239,9 +8247,9 @@
 #define OP_Move                               117
 #define OP_Blob                               118
 #define OP_Add                                 78   /* same as TK_PLUS     */
 #define OP_Rewind                             119
-#define OP_MoveGe                             120
+#define OP_SeekGt                             120
 #define OP_VBegin                             121
 #define OP_VUpdate                            122
 #define OP_IfZero                             123
 #define OP_BitNot                              87   /* same as TK_BITNOT   */
@@ -8273,22 +8281,22 @@
 #define OPFLG_IN2             0x0008  /* in2:   P2 is an input */
 #define OPFLG_IN3             0x0010  /* in3:   P3 is an input */
 #define OPFLG_OUT3            0x0020  /* out3:  P3 is an output */
 #define OPFLG_INITIALIZER {\
-/*   0 */ 0x00, 0x01, 0x00, 0x00, 0x10, 0x02, 0x11, 0x00,\
+/*   0 */ 0x00, 0x01, 0x00, 0x00, 0x10, 0x08, 0x02, 0x00,\
 /*   8 */ 0x00, 0x00, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00,\
 /*  16 */ 0x04, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05,\
 /*  24 */ 0x00, 0x04, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00,\
 /*  32 */ 0x00, 0x00, 0x02, 0x11, 0x11, 0x02, 0x05, 0x00,\
 /*  40 */ 0x02, 0x11, 0x04, 0x00, 0x00, 0x0c, 0x11, 0x01,\
-/*  48 */ 0x02, 0x01, 0x00, 0x02, 0x01, 0x01, 0x02, 0x00,\
-/*  56 */ 0x04, 0x00, 0x00, 0x00, 0x2c, 0x2c, 0x00, 0x11,\
+/*  48 */ 0x02, 0x01, 0x21, 0x08, 0x00, 0x02, 0x01, 0x11,\
+/*  56 */ 0x01, 0x02, 0x00, 0x00, 0x2c, 0x2c, 0x00, 0x00,\
 /*  64 */ 0x00, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\
-/*  72 */ 0x15, 0x00, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,\
-/*  80 */ 0x2c, 0x2c, 0x2c, 0x2c, 0x11, 0x05, 0x00, 0x04,\
-/*  88 */ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,\
-/*  96 */ 0x01, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x01,\
-/* 104 */ 0x00, 0x00, 0x01, 0x08, 0x00, 0x02, 0x02, 0x05,\
+/*  72 */ 0x15, 0x11, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,\
+/*  80 */ 0x2c, 0x2c, 0x2c, 0x2c, 0x00, 0x00, 0x05, 0x04,\
+/*  88 */ 0x02, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/*  96 */ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,\
+/* 104 */ 0x00, 0x00, 0x01, 0x08, 0x11, 0x00, 0x02, 0x02,\
 /* 112 */ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x01,\
 /* 120 */ 0x11, 0x00, 0x00, 0x05, 0x00, 0x11, 0x02, 0x05,\
 /* 128 */ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
 /* 136 */ 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04,\
@@ -8374,9 +8382,9 @@
 ** This header file defines the interface that the sqlite page cache
 ** subsystem.  The page cache subsystem reads and writes a file a page
 ** at a time and provides a journal for rollback.
 **
-** @(#) $Id: pager.h,v 1.87 2008/11/19 10:22:33 danielk1977 Exp $
+** @(#) $Id: pager.h,v 1.88 2008/12/10 16:45:51 drh Exp $
 */
 
 #ifndef _PAGER_H_
 #define _PAGER_H_
@@ -8454,9 +8462,9 @@
 SQLITE_PRIVATE int sqlite3PagerBegin(DbPage*, int exFlag);
 SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, Pgno, int);
 SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager*);
 SQLITE_PRIVATE int sqlite3PagerRollback(Pager*);
-SQLITE_PRIVATE int sqlite3PagerIsreadonly(Pager*);
+SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*);
 SQLITE_PRIVATE int sqlite3PagerStmtBegin(Pager*);
 SQLITE_PRIVATE int sqlite3PagerStmtCommit(Pager*);
 SQLITE_PRIVATE int sqlite3PagerStmtRollback(Pager*);
 SQLITE_PRIVATE void sqlite3PagerDontRollback(DbPage*);
@@ -8688,9 +8696,9 @@
 **
 ** This header file is #include-ed by sqliteInt.h and thus ends up
 ** being included by every source file.
 **
-** $Id: os.h,v 1.105 2008/06/26 10:41:19 danielk1977 Exp $
+** $Id: os.h,v 1.106 2008/12/08 18:19:18 drh Exp $
 */
 #ifndef _SQLITE_OS_H_
 #define _SQLITE_OS_H_
 
@@ -8929,9 +8937,9 @@
 SQLITE_PRIVATE int sqlite3OsFullPathname(sqlite3_vfs *, const char *, int, char *);
 #ifndef SQLITE_OMIT_LOAD_EXTENSION
 SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *, const char *);
 SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *, int, char *);
-SQLITE_PRIVATE void *sqlite3OsDlSym(sqlite3_vfs *, void *, const char *);
+void (*sqlite3OsDlSym(sqlite3_vfs *, void *, const char *))(void);
 SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *, void *);
 #endif /* SQLITE_OMIT_LOAD_EXTENSION */
 SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *, int, char *);
 SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *, int);
@@ -9038,9 +9046,9 @@
 struct Db {
   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 synching data to disk */
+  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) */
 };
@@ -9102,9 +9110,9 @@
 #define SQLITE_N_LIMIT (SQLITE_LIMIT_VARIABLE_NUMBER+1)
 
 /*
 ** Lookaside malloc is a set of fixed-size buffers that can be used
-** to satisify small transient memory allocation requests for objects
+** to satisfy small transient memory allocation requests for objects
 ** associated with a particular database connection.  The use of
 ** lookaside malloc provides a significant performance enhancement
 ** (approx 10%) by avoiding numerous malloc/free requests while parsing
 ** SQL statements.
@@ -9167,9 +9175,9 @@
 struct sqlite3 {
   sqlite3_vfs *pVfs;            /* OS Interface */
   int nDb;                      /* Number of backends currently in use */
   Db *aDb;                      /* All backends */
-  int flags;                    /* Miscellanous flags. See below */
+  int flags;                    /* Miscellaneous flags. See below */
   int openFlags;                /* Flags passed to sqlite3_vfs.xOpen() */
   int errCode;                  /* Most recent error code (SQLITE_*) */
   int errMask;                  /* & result codes with this before returning */
   u8 autoCommit;                /* The auto-commit flag. */
@@ -9193,11 +9201,11 @@
     int newTnum;                /* Rootpage of table being initialized */
     u8 busy;                    /* TRUE if currently initializing */
   } init;
   int nExtension;               /* Number of loaded extensions */
-  void **aExtension;            /* Array of shared libraray handles */
+  void **aExtension;            /* Array of shared library handles */
   struct Vdbe *pVdbe;           /* List of active virtual machines */
-  int activeVdbeCnt;            /* Number of vdbes currently executing */
+  int activeVdbeCnt;            /* Number of VDBEs currently executing */
   int writeVdbeCnt;             /* Number of active VDBEs that are writing */
   void (*xTrace)(void*,const char*);        /* Trace function */
   void *pTraceArg;                          /* Argument to the trace function */
   void (*xProfile)(void*,const char*,u64);  /* Profiling function */
@@ -9306,9 +9314,9 @@
   void *pUserData;     /* User data parameter */
   FuncDef *pNext;      /* Next function with same name */
   void (*xFunc)(sqlite3_context*,int,sqlite3_value**); /* Regular function */
   void (*xStep)(sqlite3_context*,int,sqlite3_value**); /* Aggregate step */
-  void (*xFinalize)(sqlite3_context*);                /* Aggregate finializer */
+  void (*xFinalize)(sqlite3_context*);                /* Aggregate finalizer */
   char *zName;         /* SQL name of the function. */
   FuncDef *pHash;      /* Next with a different name but the same hash */
 };
 
@@ -9316,9 +9324,9 @@
 ** Possible values for FuncDef.flags
 */
 #define SQLITE_FUNC_LIKE     0x01 /* Candidate for the LIKE optimization */
 #define SQLITE_FUNC_CASE     0x02 /* Case-sensitive LIKE-type function */
-#define SQLITE_FUNC_EPHEM    0x04 /* Ephermeral.  Delete with VDBE */
+#define SQLITE_FUNC_EPHEM    0x04 /* Ephemeral.  Delete with VDBE */
 #define SQLITE_FUNC_NEEDCOLL 0x08 /* sqlite3GetFuncCollSeq() might be called */
 
 /*
 ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
@@ -9388,9 +9396,9 @@
 ** A "Collating Sequence" is defined by an instance of the following
 ** structure. Conceptually, a collating sequence consists of a name and
 ** a comparison routine that defines the order of that sequence.
 **
-** There may two seperate implementations of the collation function, one
+** There may two separate implementations of the collation function, one
 ** that processes text in UTF-8 encoding (CollSeq.xCmp) and another that
 ** processes text encoded in UTF-16 (CollSeq.xCmp16), using the machine
 ** native byte order. When a collation sequence is invoked, SQLite selects
 ** the version that will require the least expensive encoding
@@ -9527,9 +9535,9 @@
 /*
 ** Allowed values for Tabe.tabFlags.
 */
 #define TF_Readonly        0x01    /* Read-only system table */
-#define TF_Ephemeral       0x02    /* An emphermal table */
+#define TF_Ephemeral       0x02    /* An ephemeral table */
 #define TF_HasPrimaryKey   0x04    /* Table has a primary key */
 #define TF_Autoincrement   0x08    /* Integer primary key is autoincrement */
 #define TF_Virtual         0x10    /* Is a virtual table */
 #define TF_NeedMetadata    0x20    /* aCol[].zType and aCol[].pColl missing */
@@ -9565,9 +9573,9 @@
 ** For foreign key "fk1", the from-table is "ex1" and the to-table is "ex2".
 **
 ** Each REFERENCES clause generates an instance of the following structure
 ** which is attached to the from-table.  The to-table need not exist when
-** the from-table is created.  The existance of the to-table is not checked
+** the from-table is created.  The existence of the to-table is not checked
 ** until an attempt is made to insert data into the from-table.
 **
 ** The sqlite.aFKey hash table stores pointers to this structure
 ** given the name of a to-table.  For each to-table, all foreign keys
@@ -9574,9 +9582,9 @@
 ** associated with that table are on a linked list using the FKey.pNextTo
 ** field.
 */
 struct FKey {
-  Table *pFrom;     /* The table that constains the REFERENCES clause */
+  Table *pFrom;     /* The table that contains the REFERENCES clause */
   FKey *pNextFrom;  /* Next foreign key in pFrom */
   char *zTo;        /* Name of table that the key points to */
   FKey *pNextTo;    /* Next foreign key that points to zTo */
   int nCol;         /* Number of columns in this key */
@@ -9650,13 +9658,13 @@
 **
 ** A record is an object that contains one or more fields of data.
 ** Records are used to store the content of a table row and to store
 ** the key of an index.  A blob encoding of a record is created by
-** the OP_MakeRecord opcode of the VDBE and is disassemblied by the
+** the OP_MakeRecord opcode of the VDBE and is disassembled by the
 ** OP_Column opcode.
 **
 ** This structure holds a record that has already been disassembled
-** into its constitutent fields.
+** into its constituent fields.
 */
 struct UnpackedRecord {
   KeyInfo *pKeyInfo;  /* Collation and sort-order information */
   u16 nField;         /* Number of entries in apMem[] */
@@ -9719,9 +9727,9 @@
 ** Each token coming out of the lexer is an instance of
 ** this structure.  Tokens are also used as part of an expression.
 **
 ** Note if Token.z==0 then Token.dyn and Token.n are undefined and
-** may contain random values.  Do not make any assuptions about Token.dyn
+** 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! */
@@ -9766,9 +9774,9 @@
   struct AggInfo_func {   /* For each aggregate function */
     Expr *pExpr;             /* Expression encoding the function */
     FuncDef *pFunc;          /* The aggregate function implementation */
     int iMem;                /* Memory location that acts as accumulator */
-    int iDistinct;           /* Ephermeral table used to enforce DISTINCT */
+    int iDistinct;           /* Ephemeral table used to enforce DISTINCT */
   } *aFunc;
   int nFunc;              /* Number of entries in aFunc[] */
   int nFuncAlloc;         /* Number of slots allocated for aFunc[] */
 };
@@ -9994,24 +10002,25 @@
 **
 */
 struct WhereLevel {
   int iFrom;            /* Which entry in the FROM clause */
-  int flags;            /* Flags associated with this level */
+  int wsFlags;          /* "Where-Scan" flags show the choosen scan strategy */
   int iMem;             /* First memory cell used by this level */
   int iLeftJoin;        /* Memory cell used to implement LEFT OUTER JOIN */
   Index *pIdx;          /* Index used.  NULL if no index */
   int iTabCur;          /* The VDBE cursor used to access the table */
-  int iIdxCur;          /* The VDBE cursor used to acesss pIdx */
-  int brk;              /* Jump here to break out of the loop */
-  int nxt;              /* Jump here to start the next IN combination */
-  int cont;             /* Jump here to continue with the next loop cycle */
-  int top;              /* First instruction of interior of the loop */
-  int op, p1, p2, p5;   /* Opcode used to terminate the loop */
+  int iIdxCur;          /* The VDBE cursor used to access pIdx */
+  int addrBrk;          /* Jump here to break out of the loop */
+  int addrNxt;          /* Jump here to start the next IN combination */
+  int addrCont;         /* Jump here to continue with the next loop cycle */
+  int addrFirst;        /* First instruction of interior of the loop */
+  int op, p1, p2;       /* Opcode used to terminate the loop */
+  u8 p5;                /* P5 operand of the opcode that terminates the loop */
   int nEq;              /* Number of == or IN constraints on this loop */
   int nIn;              /* Number of IN operators constraining this loop */
   struct InLoop {
     int iCur;              /* The VDBE cursor used by this IN operator */
-    int topAddr;           /* Top of the IN loop */
+    int addrInTop;         /* Top of the IN loop */
   } *aInLoop;           /* Information about each nested IN operator */
   sqlite3_index_info *pBestIdx;  /* Index information for this level */
 
   /* The following field is really not part of the current level.  But
@@ -10021,9 +10030,9 @@
   sqlite3_index_info *pIdxInfo;  /* Index info for n-th source table */
 };
 
 /*
-** Flags appropriate for the wflags parameter of sqlite3WhereBegin().
+** Flags appropriate for the wctrlFlags parameter of sqlite3WhereBegin().
 */
 #define WHERE_ORDERBY_NORMAL     0   /* No-op */
 #define WHERE_ORDERBY_MIN        1   /* ORDER BY processing for min() func */
 #define WHERE_ORDERBY_MAX        2   /* ORDER BY processing for max() func */
@@ -10153,9 +10162,9 @@
 #define SRT_EphemTab     9  /* Create transient tab and store like SRT_Table */
 #define SRT_Coroutine   10  /* Generate a single row of result */
 
 /*
-** A structure used to customize the behaviour of sqlite3Select(). See
+** A structure used to customize the behavior of sqlite3Select(). See
 ** comments above sqlite3Select() for details.
 */
 typedef struct SelectDest SelectDest;
 struct SelectDest {
@@ -10229,8 +10238,9 @@
   int nVarExpr;        /* Number of used slots in apVarExpr[] */
   int nVarExprAlloc;   /* Number of allocated slots in apVarExpr[] */
   Expr **apVarExpr;    /* Pointers to :aaa and $aaaa wildcard expressions */
   int nAlias;          /* Number of aliased result set columns */
+  int nAliasAlloc;     /* Number of allocated slots for aAlias[] */
   int *aAlias;         /* Register used to hold aliased result */
   u8 explain;          /* True if the EXPLAIN flag is found on the query */
   Token sErrToken;     /* The token at which the error occurred */
   Token sNameToken;    /* Token with unqualified schema object name */
@@ -10293,9 +10303,9 @@
   char *name;             /* The name of the trigger                        */
   char *table;            /* The table or view to which the trigger applies */
   u8 op;                  /* One of TK_DELETE, TK_UPDATE, TK_INSERT         */
   u8 tr_tm;               /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
-  Expr *pWhen;            /* The WHEN clause of the expresion (may be NULL) */
+  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 */
@@ -10431,9 +10441,9 @@
   int  nChar;          /* Length of the string so far */
   int  nAlloc;         /* Amount of space allocated in zText */
   int  mxAlloc;        /* Maximum allowed string length */
   u8   mallocFailed;   /* Becomes true if any memory allocation fails */
-  u8   useMalloc;      /* True if zText is enlargable using realloc */
+  u8   useMalloc;      /* True if zText is enlargeable using realloc */
   u8   tooBig;         /* Becomes true if string size exceeds limits */
 };
 
 /*
@@ -10470,15 +10480,17 @@
   int nScratch;                     /* Number of scratch buffers */
   void *pPage;                      /* Page cache memory */
   int szPage;                       /* Size of each page in pPage[] */
   int nPage;                        /* Number of pages in pPage[] */
+  int mxParserStack;                /* maximum depth of the parser stack */
+  int sharedCacheEnabled;           /* true if shared-cache mode enabled */
+  /* The above might be initialized to non-zero.  The following need to always
+  ** initially be zero, however. */
   int isInit;                       /* True after initialization has finished */
   int inProgress;                   /* True while initialization in progress */
   int isMallocInit;                 /* True after malloc is initialized */
   sqlite3_mutex *pInitMutex;        /* Mutex used by sqlite3_initialize() */
   int nRefInitMutex;                /* Number of users of pInitMutex */
-  int mxParserStack;                /* maximum depth of the parser stack */
-  int sharedCacheEnabled;           /* true if shared-cache mode enabled */
 };
 
 /*
 ** Context pointer passed down through the tree-walk.
@@ -10503,11 +10515,11 @@
 /*
 ** Return code from the parse-tree walking primitives and their
 ** callbacks.
 */
-#define WRC_Continue    0
-#define WRC_Prune       1
-#define WRC_Abort       2
+#define WRC_Continue    0   /* Continue down into children */
+#define WRC_Prune       1   /* Omit children but continue walking siblings */
+#define WRC_Abort       2   /* Abandon the tree walk */
 
 /*
 ** Assuming zIn points to the first byte of a UTF-8 character,
 ** advance zIn to point to the first byte of the next UTF-8 character.
@@ -10537,8 +10549,9 @@
 SQLITE_PRIVATE int sqlite3StrICmp(const char *, const char *);
 SQLITE_PRIVATE int sqlite3StrNICmp(const char *, const char *, int);
 SQLITE_PRIVATE int sqlite3IsNumber(const char*, int*, u8);
 SQLITE_PRIVATE int sqlite3Strlen(sqlite3*, const char*);
+SQLITE_PRIVATE int sqlite3Strlen30(const char*);
 
 SQLITE_PRIVATE int sqlite3MallocInit(void);
 SQLITE_PRIVATE void sqlite3MallocEnd(void);
 SQLITE_PRIVATE void *sqlite3Malloc(int);
@@ -10638,8 +10651,13 @@
 SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec*, u32);
 SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec*, u32);
 SQLITE_PRIVATE void sqlite3BitvecDestroy(Bitvec*);
 SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int,int*);
+
+SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3*, void*, unsigned int);
+SQLITE_PRIVATE void sqlite3RowSetClear(RowSet*);
+SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet*, i64);
+SQLITE_PRIVATE int sqlite3RowSetNext(RowSet*, i64*);
 
 SQLITE_PRIVATE void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int);
 
 #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
@@ -10821,10 +10839,10 @@
 ** the MACRO form does).
 */
 SQLITE_PRIVATE int sqlite3PutVarint(unsigned char*, u64);
 SQLITE_PRIVATE int sqlite3PutVarint32(unsigned char*, u32);
-SQLITE_PRIVATE int sqlite3GetVarint(const unsigned char *, u64 *);
-SQLITE_PRIVATE int sqlite3GetVarint32(const unsigned char *, u32 *);
+SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *, u64 *);
+SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *, u32 *);
 SQLITE_PRIVATE int sqlite3VarintLen(u64 v);
 
 /*
 ** The header of a record consists of a sequence variable-length integers.
@@ -10842,10 +10860,10 @@
 **     x = getVarint32( A, B );
 **     x = putVarint32( A, B );
 **
 */
-#define getVarint32(A,B)  ((*(A)<(unsigned char)0x80) ? ((B) = (u32)*(A)),1 : sqlite3GetVarint32((A), (u32 *)&(B)))
-#define putVarint32(A,B)  (((u32)(B)<(u32)0x80) ? (*(A) = (unsigned char)(B)),1 : sqlite3PutVarint32((A), (B)))
+#define getVarint32(A,B)  (u8)((*(A)<(u8)0x80) ? ((B) = (u32)*(A)),1 : sqlite3GetVarint32((A), (u32 *)&(B)))
+#define putVarint32(A,B)  (u8)(((u32)(B)<(u32)0x80) ? (*(A) = (unsigned char)(B)),1 : sqlite3PutVarint32((A), (B)))
 #define getVarint    sqlite3GetVarint
 #define putVarint    sqlite3PutVarint
 
 
@@ -11070,9 +11088,9 @@
 *************************************************************************
 **
 ** This file contains definitions of global variables and contants.
 **
-** $Id: global.c,v 1.8 2008/09/04 17:17:39 danielk1977 Exp $
+** $Id: global.c,v 1.9 2008/12/08 18:19:18 drh Exp $
 */
 
 
 /* An array to map all upper-case characters into their corresponding
@@ -11130,9 +11148,28 @@
    SQLITE_THREADSAFE==1,      /* bFullMutex */
    0x7ffffffe,                /* mxStrlen */
    100,                       /* szLookaside */
    500,                       /* nLookaside */
-   /* Other fields all default to zero */
+   {0,0,0,0,0,0,0,0},         /* m */
+   {0,0,0,0,0,0,0,0,0},       /* mutex */
+   {0,0,0,0,0,0,0,0,0,0,0},   /* pcache */
+   (void*)0,                  /* pHeap */
+   0,                         /* nHeap */
+   0, 0,                      /* mnHeap, mxHeap */
+   (void*)0,                  /* pScratch */
+   0,                         /* szScratch */
+   0,                         /* nScratch */
+   (void*)0,                  /* pPage */
+   0,                         /* szPage */
+   0,                         /* nPage */
+   0,                         /* mxParserStack */
+   0,                         /* sharedCacheEnabled */
+   /* All the rest need to always be zero */
+   0,                         /* isInit */
+   0,                         /* inProgress */
+   0,                         /* isMallocInit */
+   0,                         /* pInitMutex */
+   0,                         /* nRefInitMutex */
 };
 
 
 /*
@@ -11285,9 +11322,9 @@
 ** There is only one exported symbol in this file - the function
 ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
 ** All other code has file scope.
 **
-** $Id: date.c,v 1.94 2008/11/19 09:05:27 danielk1977 Exp $
+** $Id: date.c,v 1.98 2008/12/10 22:30:25 shane Exp $
 **
 ** SQLite processes all times and dates as Julian Day numbers.  The
 ** dates and times are stored as the number of days since noon
 ** in Greenwich on November 24, 4714 B.C. according to the Gregorian
@@ -11346,12 +11383,12 @@
   int Y, M, D;       /* Year, month, and day */
   int h, m;          /* Hour and minutes */
   int tz;            /* Timezone offset in minutes */
   double s;          /* Seconds */
-  char validYMD;     /* True if Y,M,D are valid */
-  char validHMS;     /* True if h,m,s are valid */
-  char validJD;      /* True if iJD is valid */
-  char validTZ;      /* True if tz is valid */
+  char validYMD;     /* True (1) if Y,M,D are valid */
+  char validHMS;     /* True (1) if h,m,s are valid */
+  char validJD;      /* True (1) if iJD is valid */
+  char validTZ;      /* True (1) if tz is valid */
 };
 
 
 /*
@@ -11491,9 +11528,9 @@
   p->h = h;
   p->m = m;
   p->s = s + ms;
   if( parseTimezone(zDate, p) ) return 1;
-  p->validTZ = p->tz!=0;
+  p->validTZ = (p->tz!=0)?1:0;
   return 0;
 }
 
 /*
@@ -11520,14 +11557,14 @@
     M += 12;
   }
   A = Y/100;
   B = 2 - A + (A/4);
-  X1 = 365.25*(Y+4716);
-  X2 = 30.6001*(M+1);
-  p->iJD = (X1 + X2 + D + B - 1524.5)*86400000;
+  X1 = 36525*(Y+4716)/100;
+  X2 = 306001*(M+1)/10000;
+  p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000);
   p->validJD = 1;
   if( p->validHMS ){
-    p->iJD += p->h*3600000 + p->m*60000 + p->s*1000;
+    p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000);
     if( p->validTZ ){
       p->iJD -= p->tz*60000;
       p->validYMD = 0;
       p->validHMS = 0;
@@ -11639,16 +11676,16 @@
     p->Y = 2000;
     p->M = 1;
     p->D = 1;
   }else{
-    Z = (p->iJD + 43200000)/86400000;
-    A = (Z - 1867216.25)/36524.25;
+    Z = (int)((p->iJD + 43200000)/86400000);
+    A = (int)((Z - 1867216.25)/36524.25);
     A = Z + 1 + A - (A/4);
     B = A + 1524;
-    C = (B - 122.1)/365.25;
-    D = 365.25*C;
-    E = (B-D)/30.6001;
-    X1 = 30.6001*E;
+    C = (int)((B - 122.1)/365.25);
+    D = (36525*C)/100;
+    E = (int)((B-D)/30.6001);
+    X1 = (int)(30.6001*E);
     p->D = B - D - X1;
     p->M = E<14 ? E-1 : E-13;
     p->Y = p->M>2 ? C - 4716 : C - 4715;
   }
@@ -11661,11 +11698,11 @@
 static void computeHMS(DateTime *p){
   int s;
   if( p->validHMS ) return;
   computeJD(p);
-  s = (p->iJD + 43200000) % 86400000;
+  s = (int)((p->iJD + 43200000) % 86400000);
   p->s = s/1000.0;
-  s = p->s;
+  s = (int)p->s;
   p->s -= s;
   p->h = s/3600;
   s -= p->h*3600;
   p->m = s/60;
@@ -11695,9 +11732,9 @@
 ** Compute the difference (in milliseconds)
 ** between localtime and UTC (a.k.a. GMT)
 ** for the time value p where p is in UTC.
 */
-static int localtimeOffset(DateTime *p){
+static sqlite3_int64 localtimeOffset(DateTime *p){
   DateTime x, y;
   time_t t;
   x = *p;
   computeYMD_HMS(&x);
@@ -11708,15 +11745,15 @@
     x.h = 0;
     x.m = 0;
     x.s = 0.0;
   } else {
-    int s = x.s + 0.5;
+    int s = (int)(x.s + 0.5);
     x.s = s;
   }
   x.tz = 0;
   x.validJD = 0;
   computeJD(&x);
-  t = x.iJD/1000 - 2440587.5*86400.0;
+  t = x.iJD/1000 - 210866760000LL;
 #ifdef HAVE_LOCALTIME_R
   {
     struct tm sLocal;
     localtime_r(&t, &sLocal);
@@ -11788,9 +11825,9 @@
   double r;
   char *z, zBuf[30];
   z = zBuf;
   for(n=0; n<ArraySize(zBuf)-1 && zMod[n]; n++){
-    z[n] = tolower(zMod[n]);
+    z[n] = (char)sqlite3UpperToLower[(u8)zMod[n]];
   }
   z[n] = 0;
   switch( z[0] ){
 #ifndef SQLITE_OMIT_LOCALTIME
@@ -11816,15 +11853,15 @@
       ** Treat the current value of p->iJD as the number of
       ** seconds since 1970.  Convert to a real julian day number.
       */
       if( strcmp(z, "unixepoch")==0 && p->validJD ){
-        p->iJD = p->iJD/86400.0 + 2440587.5*86400000.0;
+        p->iJD = p->iJD/86400 + 210866760000000LL;
         clearYMD_HMS_TZ(p);
         rc = 0;
       }
 #ifndef SQLITE_OMIT_LOCALTIME
       else if( strcmp(z, "utc")==0 ){
-        int c1;
+        sqlite3_int64 c1;
         computeJD(p);
         c1 = localtimeOffset(p);
         p->iJD -= c1;
         clearYMD_HMS_TZ(p);
@@ -11842,9 +11879,9 @@
       ** weekday N where 0==Sunday, 1==Monday, and so forth.  If the
       ** date is already on the appropriate weekday, this is a no-op.
       */
       if( strncmp(z, "weekday ", 8)==0 && getValue(&z[8],&r)>0
-                 && (n=r)==r && n>=0 && r<7 ){
+                 && (n=(int)r)==r && n>=0 && r<7 ){
         sqlite3_int64 Z;
         computeYMD_HMS(p);
         p->validTZ = 0;
         p->validJD = 0;
@@ -11923,37 +11960,37 @@
         break;
       }
       z += n;
       while( isspace(*(u8*)z) ) z++;
-      n = strlen(z);
+      n = sqlite3Strlen30(z);
       if( n>10 || n<3 ) break;
       if( z[n-1]=='s' ){ z[n-1] = 0; n--; }
       computeJD(p);
       rc = 0;
       if( n==3 && strcmp(z,"day")==0 ){
-        p->iJD += r*86400000.0 + 0.5;
+        p->iJD += (sqlite3_int64)(r*86400000.0 + 0.5);
       }else if( n==4 && strcmp(z,"hour")==0 ){
-        p->iJD += r*(86400000.0/24.0) + 0.5;
+        p->iJD += (sqlite3_int64)(r*(86400000.0/24.0) + 0.5);
       }else if( n==6 && strcmp(z,"minute")==0 ){
-        p->iJD += r*(86400000.0/(24.0*60.0)) + 0.5;
+        p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0)) + 0.5);
       }else if( n==6 && strcmp(z,"second")==0 ){
-        p->iJD += r*(86400000.0/(24.0*60.0*60.0)) + 0.5;
+        p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0*60.0)) + 0.5);
       }else if( n==5 && strcmp(z,"month")==0 ){
         int x, y;
         computeYMD_HMS(p);
-        p->M += r;
+        p->M += (int)r;
         x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
         p->Y += x;
         p->M -= x*12;
         p->validJD = 0;
         computeJD(p);
-        y = r;
+        y = (int)r;
         if( y!=r ){
-          p->iJD += (r - y)*30.0*86400000.0 + 0.5;
+          p->iJD += (sqlite3_int64)((r - y)*30.0*86400000.0 + 0.5);
         }
       }else if( n==4 && strcmp(z,"year")==0 ){
         computeYMD_HMS(p);
-        p->Y += r;
+        p->Y += (int)r;
         p->validJD = 0;
         computeJD(p);
       }else{
         rc = 1;
@@ -11990,9 +12027,9 @@
   if( argc==0 ){
     setDateTimeToCurrent(context, p);
   }else if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT
                    || eType==SQLITE_INTEGER ){
-    p->iJD = sqlite3_value_double(argv[0])*86400000.0 + 0.5;
+    p->iJD = (sqlite3_int64)(sqlite3_value_double(argv[0])*86400000.0 + 0.5);
     p->validJD = 1;
   }else{
     z = sqlite3_value_text(argv[0]);
     if( !z || parseDateOrTime(context, (char*)z, p) ){
@@ -12113,9 +12150,9 @@
   sqlite3_value **argv
 ){
   DateTime x;
   u64 n;
-  int i, j;
+  size_t i,j;
   char *z;
   sqlite3 *db;
   const char *zFmt = (const char*)sqlite3_value_text(argv[0]);
   char zBuf[100];
@@ -12159,9 +12196,9 @@
   }else if( n>(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ){
     sqlite3_result_error_toobig(context);
     return;
   }else{
-    z = sqlite3DbMallocRaw(db, n);
+    z = sqlite3DbMallocRaw(db, (int)n);
     if( z==0 ){
       sqlite3_result_error_nomem(context);
       return;
     }
@@ -12178,9 +12215,9 @@
         case 'f': {
           double s = x.s;
           if( s>59.999 ) s = 59.999;
           sqlite3_snprintf(7, &z[j],"%06.3f", s);
-          j += strlen(&z[j]);
+          j += sqlite3Strlen30(&z[j]);
           break;
         }
         case 'H':  sqlite3_snprintf(3, &z[j],"%02d",x.h); j+=2; break;
         case 'W': /* Fall thru */
@@ -12190,12 +12227,12 @@
           y.validJD = 0;
           y.M = 1;
           y.D = 1;
           computeJD(&y);
-          nDay = (x.iJD - y.iJD)/86400000.0 + 0.5;
+          nDay = (int)((x.iJD-y.iJD+43200000)/86400000);
           if( zFmt[i]=='W' ){
             int wd;   /* 0=Monday, 1=Tuesday, ... 6=Sunday */
-            wd = ((x.iJD+43200000)/86400000) % 7;
+            wd = (int)(((x.iJD+43200000)/86400000)%7);
             sqlite3_snprintf(3, &z[j],"%02d",(nDay+7-wd)/7);
             j += 2;
           }else{
             sqlite3_snprintf(4, &z[j],"%03d",nDay+1);
@@ -12204,22 +12241,28 @@
           break;
         }
         case 'J': {
           sqlite3_snprintf(20, &z[j],"%.16g",x.iJD/86400000.0);
-          j+=strlen(&z[j]);
+          j+=sqlite3Strlen30(&z[j]);
           break;
         }
         case 'm':  sqlite3_snprintf(3, &z[j],"%02d",x.M); j+=2; break;
         case 'M':  sqlite3_snprintf(3, &z[j],"%02d",x.m); j+=2; break;
         case 's': {
           sqlite3_snprintf(30,&z[j],"%d",
                            (int)(x.iJD/1000.0 - 210866760000.0));
-          j += strlen(&z[j]);
+          j += sqlite3Strlen30(&z[j]);
           break;
         }
         case 'S':  sqlite3_snprintf(3,&z[j],"%02d",(int)x.s); j+=2; break;
-        case 'w':  z[j++] = (((x.iJD+129600000)/86400000) % 7) + '0'; break;
-        case 'Y':  sqlite3_snprintf(5,&z[j],"%04d",x.Y); j+=strlen(&z[j]);break;
+        case 'w': {
+          z[j++] = (char)(((x.iJD+129600000)/86400000) % 7) + '0';
+          break;
+        }
+        case 'Y': {
+          sqlite3_snprintf(5,&z[j],"%04d",x.Y); j+=sqlite3Strlen30(&z[j]);
+          break;
+        }
         default:   z[j++] = '%'; break;
       }
     }
   }
@@ -12364,9 +12407,9 @@
 **
 ** This file contains OS interface code that is common to all
 ** architectures.
 **
-** $Id: os.c,v 1.124 2008/10/07 15:25:48 drh Exp $
+** $Id: os.c,v 1.125 2008/12/08 18:19:18 drh Exp $
 */
 #define _SQLITE_OS_C_ 1
 #undef _SQLITE_OS_C_
 
@@ -12492,10 +12535,10 @@
 }
 SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
   pVfs->xDlError(pVfs, nByte, zBufOut);
 }
-SQLITE_PRIVATE void *sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
-  return pVfs->xDlSym(pVfs, pHandle, zSymbol);
+void (*sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){
+  return pVfs->xDlSym(pVfs, pHdle, zSym);
 }
 SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
   pVfs->xDlClose(pVfs, pHandle);
 }
@@ -12804,9 +12847,9 @@
 **
 ** This file contains implementations of the low-level memory allocation
 ** routines specified in the sqlite3_mem_methods object.
 **
-** $Id: mem1.c,v 1.28 2008/11/19 09:05:27 danielk1977 Exp $
+** $Id: mem1.c,v 1.29 2008/12/10 21:19:57 drh Exp $
 */
 
 /*
 ** This version of the memory allocator is the default.  It is
@@ -12882,9 +12925,9 @@
   sqlite3_int64 *p;
   if( pPrior==0 ) return 0;
   p = (sqlite3_int64*)pPrior;
   p--;
-  return p[0];
+  return (int)p[0];
 }
 
 /*
 ** Round up a request size to the next valid allocation size.
@@ -12953,9 +12996,9 @@
 **
 ** This file contains implementations of the low-level memory allocation
 ** routines specified in the sqlite3_mem_methods object.
 **
-** $Id: mem2.c,v 1.40 2008/10/28 18:58:20 drh Exp $
+** $Id: mem2.c,v 1.42 2008/12/10 19:26:24 drh Exp $
 */
 
 /*
 ** This version of the memory allocator is used only if the
@@ -13090,13 +13133,13 @@
   int nReserve;
 
   p = (struct MemBlockHdr*)pAllocation;
   p--;
-  assert( p->iForeGuard==FOREGUARD );
+  assert( p->iForeGuard==(int)FOREGUARD );
   nReserve = (p->iSize+7)&~7;
   pInt = (int*)pAllocation;
   pU8 = (u8*)pAllocation;
-  assert( pInt[nReserve/sizeof(int)]==REARGUARD );
+  assert( pInt[nReserve/sizeof(int)]==(int)REARGUARD );
   assert( (nReserve-0)<=p->iSize || pU8[nReserve-1]==0x65 );
   assert( (nReserve-1)<=p->iSize || pU8[nReserve-2]==0x65 );
   assert( (nReserve-2)<=p->iSize || pU8[nReserve-3]==0x65 );
   return p;
@@ -13117,8 +13160,9 @@
 /*
 ** Initialize the memory allocation subsystem.
 */
 static int sqlite3MemInit(void *NotUsed){
+  UNUSED_PARAMETER(NotUsed);
   if( !sqlite3GlobalConfig.bMemstat ){
     /* If memory status is enabled, then the malloc.c wrapper will already
     ** hold the STATIC_MEM mutex when the routines here are invoked. */
     mem.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
@@ -13129,8 +13173,9 @@
 /*
 ** Deinitialize the memory allocation subsystem.
 */
 static void sqlite3MemShutdown(void *NotUsed){
+  UNUSED_PARAMETER(NotUsed);
   mem.mutex = 0;
 }
 
 /*
@@ -13293,9 +13338,9 @@
 /*
 ** Set the title string for subsequent allocations.
 */
 SQLITE_PRIVATE void sqlite3MemdebugSettitle(const char *zTitle){
-  int n = strlen(zTitle) + 1;
+  unsigned int n = sqlite3Strlen30(zTitle) + 1;
   sqlite3_mutex_enter(mem.mutex);
   if( n>=sizeof(mem.zTitle) ) n = sizeof(mem.zTitle)-1;
   memcpy(mem.zTitle, zTitle, n);
   mem.zTitle[n] = 0;
@@ -14727,9 +14772,9 @@
 ** If compiled with SQLITE_DEBUG, then additional logic is inserted
 ** that does error checking on mutexes to make sure they are being
 ** called correctly.
 **
-** $Id: mutex_noop.c,v 1.2 2008/10/15 19:03:03 drh Exp $
+** $Id: mutex_noop.c,v 1.3 2008/12/05 17:17:08 drh Exp $
 */
 
 
 #if defined(SQLITE_MUTEX_NOOP) && !defined(SQLITE_DEBUG)
@@ -14817,9 +14862,9 @@
       break;
     }
     default: {
       assert( id-2 >= 0 );
-      assert( id-2 < sizeof(aStatic)/sizeof(aStatic[0]) );
+      assert( id-2 < (int)(sizeof(aStatic)/sizeof(aStatic[0])) );
       pNew = &aStatic[id-2];
       pNew->id = id;
       break;
     }
@@ -14901,9 +14946,9 @@
 **
 *************************************************************************
 ** This file contains the C functions that implement mutexes for OS/2
 **
-** $Id: mutex_os2.c,v 1.10 2008/06/23 22:13:28 pweilbacher Exp $
+** $Id: mutex_os2.c,v 1.11 2008/11/22 19:50:54 pweilbacher Exp $
 */
 
 /*
 ** The code in this file is only used if SQLITE_MUTEX_OS2 is defined.
@@ -15011,9 +15056,9 @@
         while( !isInit ){
           mutex = 0;
           rc = DosCreateMutexSem( name, &mutex, 0, FALSE);
           if( rc == NO_ERROR ){
-            int i;
+            unsigned int i;
             if( !isInit ){
               for( i = 0; i < sizeof(staticMutexes)/sizeof(staticMutexes[0]); i++ ){
                 DosCreateMutexSem( 0, &staticMutexes[i].mutex, 0, FALSE );
               }
@@ -15176,9 +15221,9 @@
 **
 *************************************************************************
 ** This file contains the C functions that implement mutexes for pthreads
 **
-** $Id: mutex_unix.c,v 1.15 2008/11/17 19:18:55 danielk1977 Exp $
+** $Id: mutex_unix.c,v 1.16 2008/12/08 18:19:18 drh Exp $
 */
 
 /*
 ** The code in this file is only used if we are compiling threadsafe
@@ -15480,8 +15525,11 @@
     pthreadMutexLeave,
 #ifdef SQLITE_DEBUG
     pthreadMutexHeld,
     pthreadMutexNotheld
+#else
+    0,
+    0
 #endif
   };
 
   return &sMutex;
@@ -15503,9 +15551,9 @@
 **
 *************************************************************************
 ** This file contains the C functions that implement mutexes for win32
 **
-** $Id: mutex_w32.c,v 1.12 2008/11/10 20:01:41 shane Exp $
+** $Id: mutex_w32.c,v 1.13 2008/12/08 18:19:18 drh Exp $
 */
 
 /*
 ** The code in this file is only used if we are compiling multithreaded
@@ -15734,8 +15782,11 @@
     winMutexLeave,
 #ifdef SQLITE_DEBUG
     winMutexHeld,
     winMutexNotheld
+#else
+    0,
+    0
 #endif
   };
 
   return &sMutex;
@@ -15757,9 +15808,9 @@
 *************************************************************************
 **
 ** Memory allocation functions used throughout sqlite.
 **
-** $Id: malloc.c,v 1.48 2008/11/19 09:05:27 danielk1977 Exp $
+** $Id: malloc.c,v 1.53 2008/12/16 17:20:38 shane Exp $
 */
 
 /*
 ** This routine runs when the memory allocator sees that the
@@ -15792,9 +15843,9 @@
     sqlite3MemoryAlarm(softHeapLimitEnforcer, 0, iLimit);
   }else{
     sqlite3MemoryAlarm(0, 0, 0);
   }
-  overage = sqlite3_memory_used() - n;
+  overage = (int)(sqlite3_memory_used() - (i64)n);
   if( overage>0 ){
     sqlite3_release_memory(overage);
   }
 }
@@ -15864,9 +15915,9 @@
   }
   if( sqlite3GlobalConfig.pScratch && sqlite3GlobalConfig.szScratch>=100
       && sqlite3GlobalConfig.nScratch>=0 ){
     int i;
-    sqlite3GlobalConfig.szScratch -= 4;
+    sqlite3GlobalConfig.szScratch = (sqlite3GlobalConfig.szScratch - 4) & ~7;
     mem0.aScratchFree = (u32*)&((char*)sqlite3GlobalConfig.pScratch)
                   [sqlite3GlobalConfig.szScratch*sqlite3GlobalConfig.nScratch];
     for(i=0; i<sqlite3GlobalConfig.nScratch; i++){ mem0.aScratchFree[i] = i; }
     mem0.nScratchFree = sqlite3GlobalConfig.nScratch;
@@ -15877,9 +15928,9 @@
   if( sqlite3GlobalConfig.pPage && sqlite3GlobalConfig.szPage>=512
       && sqlite3GlobalConfig.nPage>=1 ){
     int i;
     int overhead;
-    int sz = sqlite3GlobalConfig.szPage;
+    int sz = sqlite3GlobalConfig.szPage & ~7;
     int n = sqlite3GlobalConfig.nPage;
     overhead = (4*n + sz - 1)/sz;
     sqlite3GlobalConfig.nPage -= overhead;
     mem0.aPageFree = (u32*)&((char*)sqlite3GlobalConfig.pPage)
@@ -16077,8 +16128,9 @@
       sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, 1);
       sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n);
       sqlite3_mutex_leave(mem0.mutex);
       p = (void*)&((char*)sqlite3GlobalConfig.pScratch)[i];
+      assert(  (((u8*)p - (u8*)0) & 7)==0 );
     }
   }
 #if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
   scratchAllocOut = p!=0;
@@ -16127,9 +16179,9 @@
         sqlite3GlobalConfig.m.xFree(p);
       }
     }else{
       int i;
-      i = (u8 *)p - (u8 *)sqlite3GlobalConfig.pScratch;
+      i = (int)((u8*)p - (u8*)sqlite3GlobalConfig.pScratch);
       i /= sqlite3GlobalConfig.szScratch;
       assert( i>=0 && i<sqlite3GlobalConfig.nScratch );
       sqlite3_mutex_enter(mem0.mutex);
       assert( mem0.nScratchFree<(u32)sqlite3GlobalConfig.nScratch );
@@ -16247,9 +16299,11 @@
 SQLITE_PRIVATE int sqlite3MallocSize(void *p){
   return sqlite3GlobalConfig.m.xSize(p);
 }
 SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
-  if( isLookaside(db, p) ){
+  if( p==0 ){
+    return 0;
+  }else if( isLookaside(db, p) ){
     return db->lookaside.sz;
   }else{
     return sqlite3GlobalConfig.m.xSize(p);
   }
@@ -16464,9 +16518,9 @@
   size_t n;
   if( z==0 ){
     return 0;
   }
-  n = strlen(z)+1;
+  n = (db ? sqlite3Strlen(db, z) : sqlite3Strlen30(z))+1;
   assert( (n&0x7fffffff)==n );
   zNew = sqlite3DbMallocRaw(db, (int)n);
   if( zNew ){
     memcpy(zNew, z, n);
@@ -16539,9 +16593,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.96 2008/11/20 18:20:28 drh Exp $
+** $Id: printf.c,v 1.99 2008/12/10 19:26:24 drh Exp $
 **
 **************************************************************************
 **
 ** The following modules is an enhanced replacement for the "printf" subroutines
@@ -16689,17 +16743,17 @@
 ** The counter *cnt is incremented each time.  After counter exceeds
 ** 16 (the number of significant digits in a 64-bit float) '0' is
 ** always returned.
 */
-static int et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
+static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
   int digit;
   LONGDOUBLE_TYPE d;
   if( (*cnt)++ >= 16 ) return '0';
   digit = (int)*val;
   d = digit;
   digit += '0';
   *val = (*val - d)*10.0;
-  return digit;
+  return (char)digit;
 }
 #endif /* SQLITE_OMIT_FLOATING_POINT */
 
 /*
@@ -16778,9 +16832,9 @@
   LONGDOUBLE_TYPE realvalue; /* Value for real types */
   const et_info *infop;      /* Pointer to the appropriate info structure */
   char buf[etBUFSIZE];       /* Conversion buffer */
   char prefix;               /* Prefix character.  "+" or "-" or " " or '\0'. */
-  etByte xtype;              /* Conversion paradigm */
+  etByte xtype = 0;          /* Conversion paradigm */
   char *zExtra;              /* Extra memory used for etTCLESCAPE conversions */
 #ifndef SQLITE_OMIT_FLOATING_POINT
   int  exp, e2;              /* exponent of real numbers */
   double rounder;            /* Used for rounding floating point values */
@@ -16946,9 +17000,9 @@
         }
         bufpt = &buf[etBUFSIZE-1];
         if( xtype==etORDINAL ){
           static const char zOrd[] = "thstndrd";
-          int x = longvalue % 10;
+          int x = (int)(longvalue % 10);
           if( x>=4 || (longvalue/10)%10==1 ){
             x = 0;
           }
           buf[etBUFSIZE-3] = zOrd[x*2];
@@ -16964,9 +17018,9 @@
             *(--bufpt) = cset[longvalue%base];
             longvalue = longvalue/base;
           }while( longvalue>0 );
         }
-        length = &buf[etBUFSIZE-1]-bufpt;
+        length = (int)(&buf[etBUFSIZE-1]-bufpt);
         for(idx=precision-length; idx>0; idx--){
           *(--bufpt) = '0';                             /* Zero pad */
         }
         if( prefix ) *(--bufpt) = prefix;               /* Add sign */
@@ -16975,9 +17029,9 @@
           char x;
           pre = &aPrefix[infop->prefix];
           for(; (x=(*pre))!=0; pre++) *(--bufpt) = x;
         }
-        length = &buf[etBUFSIZE-1]-bufpt;
+        length = (int)(&buf[etBUFSIZE-1]-bufpt);
         break;
       case etFLOAT:
       case etEXP:
       case etGENERIC:
@@ -17003,9 +17057,9 @@
 #endif
         if( xtype==etFLOAT ) realvalue += rounder;
         /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
         exp = 0;
-        if( sqlite3IsNaN(realvalue) ){
+        if( sqlite3IsNaN((double)realvalue) ){
           bufpt = "NaN";
           length = 3;
           break;
         }
@@ -17022,9 +17076,9 @@
               bufpt = "+Inf";
             }else{
               bufpt = "Inf";
             }
-            length = strlen(bufpt);
+            length = sqlite3Strlen30(bufpt);
             break;
           }
         }
         bufpt = buf;
@@ -17053,9 +17107,9 @@
         }else{
           e2 = exp;
         }
         nsd = 0;
-        flag_dp = (precision>0) | flag_alternateform | flag_altform2;
+        flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
         /* The sign in front of the number */
         if( prefix ){
           *(bufpt++) = prefix;
         }
@@ -17101,20 +17155,20 @@
           }else{
             *(bufpt++) = '+';
           }
           if( exp>=100 ){
-            *(bufpt++) = (exp/100)+'0';                /* 100's digit */
+            *(bufpt++) = (char)((exp/100)+'0');        /* 100's digit */
             exp %= 100;
           }
-          *(bufpt++) = exp/10+'0';                     /* 10's digit */
-          *(bufpt++) = exp%10+'0';                     /* 1's digit */
+          *(bufpt++) = (char)(exp/10+'0');             /* 10's digit */
+          *(bufpt++) = (char)(exp%10+'0');             /* 1's digit */
         }
         *bufpt = 0;
 
         /* The converted number is in buf[] and zero terminated. Output it.
         ** Note that the number is in the usual order, not reversed as with
         ** integer conversions. */
-        length = bufpt-buf;
+        length = (int)(bufpt-buf);
         bufpt = buf;
 
         /* Special case:  Add leading zeros if the flag_zeropad flag is
         ** set and we are not left justified */
@@ -17139,11 +17193,12 @@
         bufpt = buf;
         length = 1;
         break;
       case etCHARX:
-        c = buf[0] = va_arg(ap,int);
+        c = va_arg(ap,int);
+        buf[0] = (char)c;
         if( precision>=0 ){
-          for(idx=1; idx<precision; idx++) buf[idx] = c;
+          for(idx=1; idx<precision; idx++) buf[idx] = (char)c;
           length = precision;
         }else{
           length =1;
         }
@@ -17159,16 +17214,17 @@
         }
         if( precision>=0 ){
           for(length=0; length<precision && bufpt[length]; length++){}
         }else{
-          length = strlen(bufpt);
+          length = sqlite3Strlen30(bufpt);
         }
         break;
       case etSQLESCAPE:
       case etSQLESCAPE2:
       case etSQLESCAPE3: {
-        int i, j, n, ch, isnull;
+        int i, j, n, isnull;
         int needQuote;
+        char ch;
         char q = ((xtype==etSQLESCAPE3)?'"':'\'');   /* Quote character */
         char *escarg = va_arg(ap,char*);
         isnull = escarg==0;
         if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
@@ -17256,11 +17312,11 @@
   if( p->tooBig | p->mallocFailed ){
     return;
   }
   if( N<0 ){
-    N = strlen(z);
-  }
-  if( N==0 ){
+    N = sqlite3Strlen30(z);
+  }
+  if( N==0 || z==0 ){
     return;
   }
   if( p->nChar+N >= p->nAlloc ){
     char *zNew;
@@ -17277,9 +17333,9 @@
         sqlite3StrAccumReset(p);
         p->tooBig = 1;
         return;
       }else{
-        p->nAlloc = szNew;
+        p->nAlloc = (int)szNew;
       }
       zNew = sqlite3DbMallocRaw(p->db, p->nAlloc );
       if( zNew ){
         memcpy(zNew, p->zText, p->nChar);
@@ -17485,9 +17541,9 @@
 **
 ** Random numbers are used by some of the database backends in order
 ** to generate random integer keys for tables or random filenames.
 **
-** $Id: random.c,v 1.27 2008/10/07 15:25:48 drh Exp $
+** $Id: random.c,v 1.29 2008/12/10 19:26:24 drh Exp $
 */
 
 
 /* All threads share a single random number generator.
@@ -17496,9 +17552,9 @@
 static SQLITE_WSD struct sqlite3PrngType {
   unsigned char isInit;          /* True if initialized */
   unsigned char i, j;            /* State variables */
   unsigned char s[256];          /* State variables */
-} sqlite3Prng = { 0, };
+} sqlite3Prng;
 
 /*
 ** Get a single 8-bit random value from the RC4 PRNG.  The Mutex
 ** must be held while executing this routine.
@@ -17514,9 +17570,9 @@
 **
 ** (Later):  Actually, OP_NewRowid does not depend on a good source of
 ** randomness any more.  But we will leave this code in all the same.
 */
-static int randomByte(void){
+static u8 randomByte(void){
   unsigned char t;
 
 
   /* The "wsdPrng" macro will resolve to the pseudo-random number generator
@@ -17548,9 +17604,9 @@
     wsdPrng.j = 0;
     wsdPrng.i = 0;
     sqlite3OsRandomness(sqlite3_vfs_find(0), 256, k);
     for(i=0; i<256; i++){
-      wsdPrng.s[i] = i;
+      wsdPrng.s[i] = (u8)i;
     }
     for(i=0; i<256; i++){
       wsdPrng.j += wsdPrng.s[i] + k[i];
       t = wsdPrng.s[wsdPrng.j];
@@ -17595,9 +17651,9 @@
 **
 ** The sqlite3_test_control() interface calls these routines to
 ** control the PRNG.
 */
-static SQLITE_WSD struct sqlite3PrngType sqlite3SavedPrng = { 0, };
+static SQLITE_WSD struct sqlite3PrngType sqlite3SavedPrng;
 SQLITE_PRIVATE void sqlite3PrngSaveState(void){
   memcpy(
     &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng),
     &GLOBAL(struct sqlite3PrngType, sqlite3Prng),
@@ -17631,9 +17687,9 @@
 *************************************************************************
 ** This file contains routines used to translate between UTF-8,
 ** UTF-16, UTF-16BE, and UTF-16LE.
 **
-** $Id: utf.c,v 1.66 2008/11/07 03:29:34 drh Exp $
+** $Id: utf.c,v 1.70 2008/12/10 22:30:25 shane Exp $
 **
 ** Notes on UTF-8:
 **
 **   Byte-0    Byte-1    Byte-2    Byte-3    Value
@@ -17673,9 +17729,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.158 2008/11/17 15:31:48 danielk1977 Exp $
+** $Id: vdbeInt.h,v 1.160 2008/12/09 02:51:24 drh Exp $
 */
 #ifndef _VDBEINT_H_
 #define _VDBEINT_H_
 
@@ -17771,10 +17827,12 @@
 ** SQLITE_BLOB.
 */
 struct Mem {
   union {
-    i64 i;              /* Integer value. Or FuncDef* when flags==MEM_Agg */
+    i64 i;              /* Integer value. */
+    int nZero;          /* Used when bit MEM_Zero is set in flags */
     FuncDef *pDef;      /* Used only when flags==MEM_Agg */
+    RowSet *pRowSet;    /* Used only when flags==MEM_RowSet */
   } u;
   double r;           /* Real value */
   sqlite3 *db;        /* The associated database connection */
   char *z;            /* String or BLOB value */
@@ -17805,28 +17863,33 @@
 #define MEM_Str       0x0002   /* Value is a string */
 #define MEM_Int       0x0004   /* Value is an integer */
 #define MEM_Real      0x0008   /* Value is a real number */
 #define MEM_Blob      0x0010   /* Value is a BLOB */
-
-#define MemSetTypeFlag(p, f) \
-  ((p)->flags = ((p)->flags&~(MEM_Int|MEM_Real|MEM_Null|MEM_Blob|MEM_Str))|f)
+#define MEM_RowSet    0x0020   /* Value is a RowSet object */
+#define MEM_TypeMask  0x00ff   /* Mask of type bits */
 
 /* Whenever Mem contains a valid string or blob representation, one of
 ** the following flags must be set to determine the memory management
 ** policy for Mem.z.  The MEM_Term flag tells us whether or not the
 ** string is \000 or \u0000 terminated
 */
-#define MEM_Term      0x0020   /* String rep is nul terminated */
-#define MEM_Dyn       0x0040   /* Need to call sqliteFree() on Mem.z */
-#define MEM_Static    0x0080   /* Mem.z points to a static string */
-#define MEM_Ephem     0x0100   /* Mem.z points to an ephemeral string */
-#define MEM_Agg       0x0400   /* Mem.z points to an agg function context */
-#define MEM_Zero      0x0800   /* Mem.i contains count of 0s appended to blob */
+#define MEM_Term      0x0200   /* String rep is nul terminated */
+#define MEM_Dyn       0x0400   /* Need to call sqliteFree() on Mem.z */
+#define MEM_Static    0x0800   /* Mem.z points to a static string */
+#define MEM_Ephem     0x1000   /* Mem.z points to an ephemeral string */
+#define MEM_Agg       0x2000   /* Mem.z points to an agg function context */
+#define MEM_Zero      0x4000   /* Mem.i contains count of 0s appended to blob */
 
 #ifdef SQLITE_OMIT_INCRBLOB
   #undef MEM_Zero
   #define MEM_Zero 0x0000
 #endif
+
+
+/*
+** Clear any existing type flags from a Mem and replace them with f
+*/
+#define MemSetTypeFlag(p, f) ((p)->flags = ((p)->flags&~(MEM_TypeMask))|f)
 
 
 /* A VdbeFunc is just a FuncDef (defined in sqliteInt.h) that contains
 ** additional information about auxiliary information bound to arguments
@@ -17880,35 +17943,8 @@
   HashElem *prev;        /* Previously accessed hash elemen */
 };
 
 /*
-** A FifoPage structure holds a single page of valves.  Pages are arranged
-** in a list.
-*/
-typedef struct FifoPage FifoPage;
-struct FifoPage {
-  int nSlot;         /* Number of entries aSlot[] */
-  int iWrite;        /* Push the next value into this entry in aSlot[] */
-  int iRead;         /* Read the next value from this entry in aSlot[] */
-  FifoPage *pNext;   /* Next page in the fifo */
-  i64 aSlot[1];      /* One or more slots for rowid values */
-};
-
-/*
-** The Fifo structure is typedef-ed in vdbeInt.h.  But the implementation
-** of that structure is private to this file.
-**
-** The Fifo structure describes the entire fifo.
-*/
-typedef struct Fifo Fifo;
-struct Fifo {
-  int nEntry;         /* Total number of entries */
-  sqlite3 *db;        /* The associated database connection */
-  FifoPage *pFirst;   /* First page on the list */
-  FifoPage *pLast;    /* Last page on the list */
-};
-
-/*
 ** A Context stores the last insert rowid, the last statement change count,
 ** and the current statement change count (i.e. changes since last statement).
 ** The current keylist is also stored in the context.
 ** Elements of Context structure type make up the ContextStack, which is
@@ -17919,9 +17955,8 @@
 typedef struct Context Context;
 struct Context {
   i64 lastRowid;    /* Last insert rowid (sqlite3.lastRowid) */
   int nChange;      /* Statement changes (Vdbe.nChanges)     */
-  Fifo sFifo;       /* Records that will participate in a DELETE or UPDATE */
 };
 
 /*
 ** An instance of the virtual machine.  This structure contains the complete
@@ -17959,9 +17994,8 @@
   int nMem;               /* Number of memory locations currently allocated */
   Mem *aMem;              /* The memory locations */
   int nCallback;          /* Number of callbacks invoked so far */
   int cacheCtr;           /* VdbeCursor row cache generation counter */
-  Fifo sFifo;             /* A list of ROWIDs */
   int contextStackTop;    /* Index of top element in the context stack */
   int contextStackDepth;  /* The size of the "context" stack */
   Context *contextStack;  /* Stack used by opcodes ContextPush & ContextPop*/
   int pc;                 /* The program counter */
@@ -18041,8 +18075,9 @@
 SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem*, i64);
 SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem*, double);
 SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*);
 SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int);
+SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem*);
 SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*);
 SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, int);
 SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*);
 SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*);
@@ -18069,12 +18104,8 @@
 SQLITE_PRIVATE   void sqlite3VdbePrintSql(Vdbe*);
 SQLITE_PRIVATE   void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf);
 #endif
 SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem);
-SQLITE_PRIVATE void sqlite3VdbeFifoInit(Fifo*, sqlite3*);
-SQLITE_PRIVATE int sqlite3VdbeFifoPush(Fifo*, i64);
-SQLITE_PRIVATE int sqlite3VdbeFifoPop(Fifo*, i64*);
-SQLITE_PRIVATE void sqlite3VdbeFifoClear(Fifo*);
 
 #ifndef SQLITE_OMIT_INCRBLOB
 SQLITE_PRIVATE   int sqlite3VdbeMemExpandBlob(Mem *);
 #else
@@ -18085,19 +18116,21 @@
 
 /************** End of vdbeInt.h *********************************************/
 /************** Continuing where we left off in utf.c ************************/
 
+#ifndef SQLITE_AMALGAMATION
 /*
 ** The following constant value is used by the SQLITE_BIGENDIAN and
 ** SQLITE_LITTLEENDIAN macros.
 */
 SQLITE_PRIVATE const int sqlite3one = 1;
+#endif /* SQLITE_AMALGAMATION */
 
 /*
 ** This lookup table is used to help decode the first byte of
 ** a multi-byte UTF8 character.
 */
-static const unsigned char sqlite3UtfTrans1[] = {
+static const unsigned char sqlite3Utf8Trans1[] = {
   0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
   0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
   0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
   0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
@@ -18109,48 +18142,48 @@
 
 
 #define WRITE_UTF8(zOut, c) {                          \
   if( c<0x00080 ){                                     \
-    *zOut++ = (c&0xFF);                                \
+    *zOut++ = (u8)(c&0xFF);                            \
   }                                                    \
   else if( c<0x00800 ){                                \
-    *zOut++ = 0xC0 + ((c>>6)&0x1F);                    \
-    *zOut++ = 0x80 + (c & 0x3F);                       \
+    *zOut++ = 0xC0 + (u8)((c>>6)&0x1F);                \
+    *zOut++ = 0x80 + (u8)(c & 0x3F);                   \
   }                                                    \
   else if( c<0x10000 ){                                \
-    *zOut++ = 0xE0 + ((c>>12)&0x0F);                   \
-    *zOut++ = 0x80 + ((c>>6) & 0x3F);                  \
-    *zOut++ = 0x80 + (c & 0x3F);                       \
+    *zOut++ = 0xE0 + (u8)((c>>12)&0x0F);               \
+    *zOut++ = 0x80 + (u8)((c>>6) & 0x3F);              \
+    *zOut++ = 0x80 + (u8)(c & 0x3F);                   \
   }else{                                               \
-    *zOut++ = 0xF0 + ((c>>18) & 0x07);                 \
-    *zOut++ = 0x80 + ((c>>12) & 0x3F);                 \
-    *zOut++ = 0x80 + ((c>>6) & 0x3F);                  \
-    *zOut++ = 0x80 + (c & 0x3F);                       \
+    *zOut++ = 0xF0 + (u8)((c>>18) & 0x07);             \
+    *zOut++ = 0x80 + (u8)((c>>12) & 0x3F);             \
+    *zOut++ = 0x80 + (u8)((c>>6) & 0x3F);              \
+    *zOut++ = 0x80 + (u8)(c & 0x3F);                   \
   }                                                    \
 }
 
-#define WRITE_UTF16LE(zOut, c) {                                \
-  if( c<=0xFFFF ){                                              \
-    *zOut++ = (c&0x00FF);                                       \
-    *zOut++ = ((c>>8)&0x00FF);                                  \
-  }else{                                                        \
-    *zOut++ = (((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0));  \
-    *zOut++ = (0x00D8 + (((c-0x10000)>>18)&0x03));              \
-    *zOut++ = (c&0x00FF);                                       \
-    *zOut++ = (0x00DC + ((c>>8)&0x03));                         \
-  }                                                             \
-}
-
-#define WRITE_UTF16BE(zOut, c) {                                \
-  if( c<=0xFFFF ){                                              \
-    *zOut++ = ((c>>8)&0x00FF);                                  \
-    *zOut++ = (c&0x00FF);                                       \
-  }else{                                                        \
-    *zOut++ = (0x00D8 + (((c-0x10000)>>18)&0x03));              \
-    *zOut++ = (((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0));  \
-    *zOut++ = (0x00DC + ((c>>8)&0x03));                         \
-    *zOut++ = (c&0x00FF);                                       \
-  }                                                             \
+#define WRITE_UTF16LE(zOut, c) {                                    \
+  if( c<=0xFFFF ){                                                  \
+    *zOut++ = (u8)(c&0x00FF);                                       \
+    *zOut++ = (u8)((c>>8)&0x00FF);                                  \
+  }else{                                                            \
+    *zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0));  \
+    *zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03));              \
+    *zOut++ = (u8)(c&0x00FF);                                       \
+    *zOut++ = (u8)(0x00DC + ((c>>8)&0x03));                         \
+  }                                                                 \
+}
+
+#define WRITE_UTF16BE(zOut, c) {                                    \
+  if( c<=0xFFFF ){                                                  \
+    *zOut++ = (u8)((c>>8)&0x00FF);                                  \
+    *zOut++ = (u8)(c&0x00FF);                                       \
+  }else{                                                            \
+    *zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03));              \
+    *zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0));  \
+    *zOut++ = (u8)(0x00DC + ((c>>8)&0x03));                         \
+    *zOut++ = (u8)(c&0x00FF);                                       \
+  }                                                                 \
 }
 
 #define READ_UTF16LE(zIn, c){                                         \
   c = (*zIn++);                                                       \
@@ -18203,9 +18236,9 @@
 */
 #define READ_UTF8(zIn, zTerm, c)                           \
   c = *(zIn++);                                            \
   if( c>=0xc0 ){                                           \
-    c = sqlite3UtfTrans1[c-0xc0];                          \
+    c = sqlite3Utf8Trans1[c-0xc0];                         \
     while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){            \
       c = (c<<6) + (0x3f & *(zIn++));                      \
     }                                                      \
     if( c<0x80                                             \
@@ -18332,9 +18365,9 @@
         READ_UTF8(zIn, zTerm, c);
         WRITE_UTF16BE(z, c);
       }
     }
-    pMem->n = z - zOut;
+    pMem->n = (int)(z - zOut);
     *z++ = 0;
   }else{
     assert( desiredEnc==SQLITE_UTF8 );
     if( pMem->enc==SQLITE_UTF16LE ){
@@ -18349,9 +18382,9 @@
         READ_UTF16BE(zIn, c);
         WRITE_UTF8(z, c);
       }
     }
-    pMem->n = z - zOut;
+    pMem->n = (int)(z - zOut);
   }
   *z = 0;
   assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len );
 
@@ -18451,9 +18484,9 @@
 */
 SQLITE_PRIVATE int sqlite3Utf8To8(unsigned char *zIn){
   unsigned char *zOut = zIn;
   unsigned char *zStart = zIn;
-  unsigned char *zTerm = &zIn[strlen((char *)zIn)];
+  unsigned char *zTerm = &zIn[sqlite3Strlen30((char *)zIn)];
   u32 c;
 
   while( zIn[0] ){
     c = sqlite3Utf8Read(zIn, zTerm, (const u8**)&zIn);
@@ -18519,9 +18552,9 @@
       READ_UTF16LE(z, c);
       n++;
     }
   }
-  return (z-(char const *)zIn)-((c==0)?2:0);
+  return (int)(z-(char const *)zIn)-((c==0)?2:0);
 }
 
 #if defined(SQLITE_TEST)
 /*
@@ -18539,9 +18572,10 @@
 
   for(i=0; i<0x00110000; i++){
     z = zBuf;
     WRITE_UTF8(z, i);
-    n = z-zBuf;
+    n = (int)(z-zBuf);
+    assert( n>0 && n<=4 );
     z[0] = 0;
     zTerm = z;
     z = zBuf;
     c = sqlite3Utf8Read(z, zTerm, (const u8**)&z);
@@ -18554,9 +18588,10 @@
   for(i=0; i<0x00110000; i++){
     if( i>=0xD800 && i<0xE000 ) continue;
     z = zBuf;
     WRITE_UTF16LE(z, i);
-    n = z-zBuf;
+    n = (int)(z-zBuf);
+    assert( n>0 && n<=4 );
     z[0] = 0;
     z = zBuf;
     READ_UTF16LE(z, c);
     assert( c==i );
@@ -18565,9 +18600,10 @@
   for(i=0; i<0x00110000; i++){
     if( i>=0xD800 && i<0xE000 ) continue;
     z = zBuf;
     WRITE_UTF16BE(z, i);
-    n = z-zBuf;
+    n = (int)(z-zBuf);
+    assert( n>0 && n<=4 );
     z[0] = 0;
     z = zBuf;
     READ_UTF16BE(z, c);
     assert( c==i );
@@ -18594,9 +18630,9 @@
 **
 ** This file contains functions for allocating memory, comparing
 ** strings, and stuff like that.
 **
-** $Id: util.c,v 1.242 2008/11/17 19:18:55 danielk1977 Exp $
+** $Id: util.c,v 1.245 2008/12/10 22:15:00 drh Exp $
 */
 
 
 /*
@@ -18628,8 +18664,18 @@
   return y!=z;
 }
 
 /*
+** Compute a string length that is limited to what can be stored in
+** lower 30 bits of a 32-bit signed integer.
+*/
+SQLITE_PRIVATE int sqlite3Strlen30(const char *z){
+  const char *z2 = z;
+  while( *z2 ){ z2++; }
+  return 0x3fffffff & (int)(z2 - z);
+}
+
+/*
 ** Return the length of a string, except do not allow the string length
 ** to exceed the SQLITE_LIMIT_LENGTH setting.
 */
 SQLITE_PRIVATE int sqlite3Strlen(sqlite3 *db, const char *z){
@@ -18636,9 +18682,9 @@
   const char *z2 = z;
   int len;
   int x;
   while( *z2 ){ z2++; }
-  x = z2 - z;
+  x = (int)(z2 - z);
   len = 0x7fffffff & x;
   if( len!=x || len > db->aLimit[SQLITE_LIMIT_LENGTH] ){
     return db->aLimit[SQLITE_LIMIT_LENGTH];
   }else{
@@ -18732,9 +18778,9 @@
 ** brackets from around identifers.  For example:  "[a-b-c]" becomes
 ** "a-b-c".
 */
 SQLITE_PRIVATE void sqlite3Dequote(char *z){
-  int quote;
+  char quote;
   int i, j;
   if( z==0 ) return;
   quote = z[0];
   switch( quote ){
@@ -18891,10 +18937,10 @@
     }else{
       v1 *= scale;
     }
   }
-  *pResult = sign<0 ? -v1 : v1;
-  return z - zBegin;
+  *pResult = (double)(sign<0 ? -v1 : v1);
+  return (int)(z - zBegin);
 #else
   return sqlite3Atoi64(z, pResult);
 #endif /* SQLITE_OMIT_FLOATING_POINT */
 }
@@ -19078,19 +19124,19 @@
 SQLITE_PRIVATE int sqlite3PutVarint(unsigned char *p, u64 v){
   int i, j, n;
   u8 buf[10];
   if( v & (((u64)0xff000000)<<32) ){
-    p[8] = v;
+    p[8] = (u8)v;
     v >>= 8;
     for(i=7; i>=0; i--){
-      p[i] = (v & 0x7f) | 0x80;
+      p[i] = (u8)((v & 0x7f) | 0x80);
       v >>= 7;
     }
     return 9;
   }
   n = 0;
   do{
-    buf[n++] = (v & 0x7f) | 0x80;
+    buf[n++] = (u8)((v & 0x7f) | 0x80);
     v >>= 7;
   }while( v!=0 );
   buf[0] &= 0x7f;
   assert( n<=9 );
@@ -19115,10 +19161,10 @@
     return 1;
   }
 #endif
   if( (v & ~0x3fff)==0 ){
-    p[0] = (v>>7) | 0x80;
-    p[1] = v & 0x7f;
+    p[0] = (u8)((v>>7) | 0x80);
+    p[1] = (u8)(v & 0x7f);
     return 2;
   }
   return sqlite3PutVarint(p, v);
 }
@@ -19126,9 +19172,9 @@
 /*
 ** Read a 64-bit variable-length integer from memory starting at p[0].
 ** Return the number of bytes read.  The value is stored in *v.
 */
-SQLITE_PRIVATE int sqlite3GetVarint(const unsigned char *p, u64 *v){
+SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *p, u64 *v){
   u32 a,b,s;
 
   a = *p;
   /* a: p0 (unmasked) */
@@ -19288,9 +19334,9 @@
 ** A MACRO version, getVarint32, is provided which inlines the
 ** single-byte case.  All code should use the MACRO version as
 ** this function assumes the single-byte case has already been handled.
 */
-SQLITE_PRIVATE int sqlite3GetVarint32(const unsigned char *p, u32 *v){
+SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){
   u32 a,b;
 
   a = *p;
   /* a: p0 (unmasked) */
@@ -19357,9 +19403,9 @@
   ** slow) general-purpose sqlite3GetVarint() routine to extract the
   ** value. */
   {
     u64 v64;
-    int n;
+    u8 n;
 
     p -= 4;
     n = sqlite3GetVarint(p, &v64);
     assert( n>5 && n<=9 );
@@ -19388,12 +19434,12 @@
 SQLITE_PRIVATE u32 sqlite3Get4byte(const u8 *p){
   return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
 }
 SQLITE_PRIVATE void sqlite3Put4byte(unsigned char *p, u32 v){
-  p[0] = v>>24;
-  p[1] = v>>16;
-  p[2] = v>>8;
-  p[3] = v;
+  p[0] = (u8)(v>>24);
+  p[1] = (u8)(v>>16);
+  p[2] = (u8)(v>>8);
+  p[3] = (u8)v;
 }
 
 
 
@@ -19402,17 +19448,17 @@
 ** Translate a single byte of Hex into an integer.
 ** This routinen only works if h really is a valid hexadecimal
 ** character:  0..9a..fA..F
 */
-static int hexToInt(int h){
+static u8 hexToInt(int h){
   assert( (h>='0' && h<='9') ||  (h>='a' && h<='f') ||  (h>='A' && h<='F') );
 #ifdef SQLITE_ASCII
   h += 9*(1&(h>>6));
 #endif
 #ifdef SQLITE_EBCDIC
   h += 9*(1&~(h>>4));
 #endif
-  return h & 0xf;
+  return (u8)(h & 0xf);
 }
 #endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC */
 
 #if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC)
@@ -19544,9 +19590,9 @@
 *************************************************************************
 ** This is the implementation of generic hash-tables
 ** used in SQLite.
 **
-** $Id: hash.c,v 1.31 2008/10/10 17:41:29 drh Exp $
+** $Id: hash.c,v 1.32 2008/12/10 19:26:24 drh Exp $
 */
 
 /* Turn bulk memory into a hash table object by initializing the
 ** fields of the Hash structure.
@@ -19593,9 +19639,9 @@
 */
 static int strHash(const void *pKey, int nKey){
   const char *z = (const char *)pKey;
   int h = 0;
-  if( nKey<=0 ) nKey = strlen(z);
+  if( nKey<=0 ) nKey = sqlite3Strlen30(z);
   while( nKey > 0  ){
     h = (h<<3) ^ h ^ sqlite3UpperToLower[(unsigned char)*z++];
     nKey--;
   }
@@ -19843,10 +19889,10 @@
      /*   1 */ "VNext",
      /*   2 */ "Affinity",
      /*   3 */ "Column",
      /*   4 */ "SetCookie",
-     /*   5 */ "Sequence",
-     /*   6 */ "MoveGt",
+     /*   5 */ "Seek",
+     /*   6 */ "Sequence",
      /*   7 */ "RowKey",
      /*   8 */ "SCopy",
      /*   9 */ "OpenWrite",
      /*  10 */ "If",
@@ -19888,23 +19934,23 @@
      /*  46 */ "NotExists",
      /*  47 */ "Gosub",
      /*  48 */ "Integer",
      /*  49 */ "Prev",
-     /*  50 */ "VColumn",
-     /*  51 */ "CreateTable",
-     /*  52 */ "Last",
-     /*  53 */ "IncrVacuum",
-     /*  54 */ "IdxRowid",
-     /*  55 */ "ResetCount",
-     /*  56 */ "FifoWrite",
-     /*  57 */ "ContextPush",
-     /*  58 */ "Yield",
-     /*  59 */ "DropTrigger",
+     /*  50 */ "RowSetRead",
+     /*  51 */ "RowSetAdd",
+     /*  52 */ "VColumn",
+     /*  53 */ "CreateTable",
+     /*  54 */ "Last",
+     /*  55 */ "SeekLe",
+     /*  56 */ "IncrVacuum",
+     /*  57 */ "IdxRowid",
+     /*  58 */ "ResetCount",
+     /*  59 */ "ContextPush",
      /*  60 */ "Or",
      /*  61 */ "And",
-     /*  62 */ "DropIndex",
-     /*  63 */ "IdxGE",
-     /*  64 */ "IdxDelete",
+     /*  62 */ "Yield",
+     /*  63 */ "DropTrigger",
+     /*  64 */ "DropIndex",
      /*  65 */ "IsNull",
      /*  66 */ "NotNull",
      /*  67 */ "Ne",
      /*  68 */ "Eq",
@@ -19911,9 +19957,9 @@
      /*  69 */ "Gt",
      /*  70 */ "Le",
      /*  71 */ "Lt",
      /*  72 */ "Ge",
-     /*  73 */ "Vacuum",
+     /*  73 */ "IdxGE",
      /*  74 */ "BitAnd",
      /*  75 */ "BitOr",
      /*  76 */ "ShiftLeft",
      /*  77 */ "ShiftRight",
@@ -19922,23 +19968,23 @@
      /*  80 */ "Multiply",
      /*  81 */ "Divide",
      /*  82 */ "Remainder",
      /*  83 */ "Concat",
-     /*  84 */ "MoveLe",
-     /*  85 */ "IfNot",
-     /*  86 */ "DropTable",
+     /*  84 */ "IdxDelete",
+     /*  85 */ "Vacuum",
+     /*  86 */ "IfNot",
      /*  87 */ "BitNot",
      /*  88 */ "String8",
-     /*  89 */ "MakeRecord",
-     /*  90 */ "ResultRow",
-     /*  91 */ "Delete",
-     /*  92 */ "AggFinal",
-     /*  93 */ "Compare",
-     /*  94 */ "Goto",
-     /*  95 */ "TableLock",
-     /*  96 */ "FifoRead",
-     /*  97 */ "Clear",
-     /*  98 */ "MoveLt",
+     /*  89 */ "DropTable",
+     /*  90 */ "SeekLt",
+     /*  91 */ "MakeRecord",
+     /*  92 */ "ResultRow",
+     /*  93 */ "Delete",
+     /*  94 */ "AggFinal",
+     /*  95 */ "Compare",
+     /*  96 */ "Goto",
+     /*  97 */ "TableLock",
+     /*  98 */ "Clear",
      /*  99 */ "VerifyCookie",
      /* 100 */ "AggStep",
      /* 101 */ "SetNumColumns",
      /* 102 */ "Transaction",
@@ -19946,12 +19992,12 @@
      /* 104 */ "VDestroy",
      /* 105 */ "ContextPop",
      /* 106 */ "Next",
      /* 107 */ "IdxInsert",
-     /* 108 */ "Insert",
-     /* 109 */ "Destroy",
-     /* 110 */ "ReadCookie",
-     /* 111 */ "ForceInt",
+     /* 108 */ "SeekGe",
+     /* 109 */ "Insert",
+     /* 110 */ "Destroy",
+     /* 111 */ "ReadCookie",
      /* 112 */ "LoadAnalysis",
      /* 113 */ "Explain",
      /* 114 */ "OpenPseudo",
      /* 115 */ "OpenEphemeral",
@@ -19958,9 +20004,9 @@
      /* 116 */ "Null",
      /* 117 */ "Move",
      /* 118 */ "Blob",
      /* 119 */ "Rewind",
-     /* 120 */ "MoveGe",
+     /* 120 */ "SeekGt",
      /* 121 */ "VBegin",
      /* 122 */ "VUpdate",
      /* 123 */ "IfZero",
      /* 124 */ "VCreate",
@@ -20003,9 +20049,9 @@
 ******************************************************************************
 **
 ** This file contains code that is specific to OS/2.
 **
-** $Id: os_os2.c,v 1.59 2008/11/18 23:03:40 pweilbacher Exp $
+** $Id: os_os2.c,v 1.63 2008/12/10 19:26:24 drh Exp $
 */
 
 
 #if SQLITE_OS_OS2
@@ -20422,8 +20468,9 @@
   /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
   ** no-op
   */
 #ifdef SQLITE_NO_SYNC
+  UNUSED_PARAMETER(pFile);
   return SQLITE_OK;
 #else
   return DosResetBuffer( pFile->h ) == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
 #endif
@@ -20915,9 +20962,9 @@
   }
   /* Strip off a trailing slashes or backslashes, otherwise we would get *
    * multiple (back)slashes which causes DosOpen() to fail.              *
    * Trailing spaces are not allowed, either.                            */
-  j = strlen(zTempPath);
+  j = sqlite3Strlen30(zTempPath);
   while( j > 0 && ( zTempPath[j-1] == '\\' || zTempPath[j-1] == '/'
                     || zTempPath[j-1] == ' ' ) ){
     j--;
   }
@@ -20930,9 +20977,9 @@
   }else{
     sqlite3_snprintf( nBuf-30, zBuf,
                       "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath );
   }
-  j = strlen( zBuf );
+  j = sqlite3Strlen30( zBuf );
   sqlite3_randomness( 20, &zBuf[j] );
   for( i = 0; i < 20; i++, j++ ){
     zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
   }
@@ -21188,11 +21235,15 @@
 /*
 ** Write up to nBuf bytes of randomness into zBuf.
 */
 static int os2Randomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf ){
-  ULONG sizeofULong = sizeof(ULONG);
   int n = 0;
-  if( sizeof(DATETIME) <= nBuf - n ){
+#if defined(SQLITE_TEST)
+  n = nBuf;
+  memset(zBuf, 0, nBuf);
+#else
+  int sizeofULong = sizeof(ULONG);
+  if( (int)sizeof(DATETIME) <= nBuf - n ){
     DATETIME x;
     DosGetDateTime(&x);
     memcpy(&zBuf[n], &x, sizeof(x));
     n += sizeof(x);
@@ -21237,8 +21288,9 @@
       memcpy(&zBuf[n], &ulSysInfo[QSV_TOTAVAILMEM - 1], sizeofULong);
       n += sizeofULong;
     }
   }
+#endif
 
   return n;
 }
 
@@ -21356,27 +21408,61 @@
 **    May you share freely, never taking more than you give.
 **
 ******************************************************************************
 **
-** This file contains code that is specific to Unix systems.
-**
-** $Id: os_unix.c,v 1.216 2008/11/19 16:52:44 danielk1977 Exp $
+** This file contains the VFS implementation for unix-like operating systems
+** include Linux, MacOSX, *BSD, QNX, VxWorks, AIX, HPUX, and others.
+**
+** There are actually several different VFS implementations in this file.
+** The differences are in the way that file locking is done.  The default
+** implementation uses Posix Advisory Locks.  Alternative implementations
+** use flock(), dot-files, various proprietary locking schemas, or simply
+** skip locking all together.
+**
+** This source file is organized into divisions where the logic for various
+** subfunctions is contained within the appropriate division.  PLEASE
+** KEEP THE STRUCTURE OF THIS FILE INTACT.  New code should be placed
+** in the correct division and should be clearly labeled.
+**
+** The layout of divisions is as follows:
+**
+**   *  General-purpose declarations and utility functions.
+**   *  Unique file ID logic used by VxWorks.
+**   *  Various locking primitive implementations (all except proxy locking):
+**      + for Posix Advisory Locks
+**      + for no-op locks
+**      + for dot-file locks
+**      + for flock() locking
+**      + for named semaphore locks (VxWorks only)
+**      + for AFP filesystem locks (MacOSX only)
+**   *  sqlite3_file methods not associated with locking.
+**   *  Definitions of sqlite3_io_methods objects for all locking
+**      methods plus "finder" functions for each locking method.
+**   *  sqlite3_vfs method implementations.
+**   *  Locking primitives for the proxy uber-locking-method. (MacOSX only)
+**   *  Definitions of sqlite3_vfs objects for all locking methods
+**      plus implementations of sqlite3_os_init() and sqlite3_os_end().
+**
+** $Id: os_unix.c,v 1.232 2008/12/11 02:56:07 drh Exp $
 */
 #if SQLITE_OS_UNIX              /* This file is used on unix only */
 
 /*
-** If SQLITE_ENABLE_LOCKING_STYLE is defined and is non-zero, then several
-** alternative locking implementations are provided:
-**
-**   * POSIX locking (the default),
-**   * No locking,
-**   * Dot-file locking,
-**   * flock() locking,
-**   * AFP locking (OSX only),
-**   * Named POSIX semaphores (VXWorks only).
-**
-** SQLITE_ENABLE_LOCKING_STYLE only works on a Mac. It is turned on by
-** default on a Mac and disabled on all other posix platforms.
+** There are various methods for file locking used for concurrency
+** control:
+**
+**   1. POSIX locking (the default),
+**   2. No locking,
+**   3. Dot-file locking,
+**   4. flock() locking,
+**   5. AFP locking (OSX only),
+**   6. Named POSIX semaphores (VXWorks only),
+**   7. proxy locking. (OSX only)
+**
+** Styles 4, 5, and 7 are only available of SQLITE_ENABLE_LOCKING_STYLE
+** is defined to 1.  The SQLITE_ENABLE_LOCKING_STYLE also enables automatic
+** selection of the appropriate locking style based on the filesystem
+** where the database is located.
 */
 #if !defined(SQLITE_ENABLE_LOCKING_STYLE)
 #  if defined(__DARWIN__)
 #    define SQLITE_ENABLE_LOCKING_STYLE 1
@@ -21385,15 +21471,17 @@
 #  endif
 #endif
 
 /*
-** Define the IS_VXWORKS pre-processor macro to 1 if building on
+** Define the OS_VXWORKS pre-processor macro to 1 if building on
 ** vxworks, or 0 otherwise.
 */
-#if defined(__RTP__) || defined(_WRS_KERNEL)
-#  define IS_VXWORKS 1
-#else
-#  define IS_VXWORKS 0
+#ifndef OS_VXWORKS
+#  if defined(__RTP__) || defined(_WRS_KERNEL)
+#    define OS_VXWORKS 1
+#  else
+#    define OS_VXWORKS 0
+#  endif
 #endif
 
 /*
 ** These #defines should enable >2GB file support on Posix if the
@@ -21406,8 +21494,13 @@
 ** on an older machine (ex: RedHat 6.0).  If you compile on RedHat 7.2
 ** without this option, LFS is enable.  But LFS does not exist in the kernel
 ** in RedHat 6.0, so the code won't work.  Hence, for maximum binary
 ** portability you should omit LFS.
+**
+** The previous paragraph was written in 2005.  (This paragraph is written
+** on 2008-11-28.) These days, all Linux kernels support large files, so
+** you should probably leave LFS enabled.  But some embedded platforms might
+** lack LFS in which case the SQLITE_DISABLE_LFS macro might still be useful.
 */
 #ifndef SQLITE_DISABLE_LFS
 # define _LARGE_FILE       1
 # ifndef _FILE_OFFSET_BITS
@@ -21427,13 +21520,13 @@
 #include <errno.h>
 
 #if SQLITE_ENABLE_LOCKING_STYLE
 # include <sys/ioctl.h>
-# if IS_VXWORKS
-#  define lstat stat
+# if OS_VXWORKS
 #  include <semaphore.h>
 #  include <limits.h>
 # else
+#  include <sys/file.h>
 #  include <sys/param.h>
 #  include <sys/mount.h>
 # endif
 #endif /* SQLITE_ENABLE_LOCKING_STYLE */
@@ -21453,41 +21546,53 @@
 # define SQLITE_DEFAULT_FILE_PERMISSIONS 0644
 #endif
 
 /*
+ ** Default permissions when creating auto proxy dir
+ */
+#ifndef SQLITE_DEFAULT_PROXYDIR_PERMISSIONS
+# define SQLITE_DEFAULT_PROXYDIR_PERMISSIONS 0755
+#endif
+
+/*
 ** Maximum supported path-length.
 */
 #define MAX_PATHNAME 512
 
-
-/*
-** The unixFile structure is subclass of sqlite3_file specific for the unix
-** protability layer.
+/*
+** Only set the lastErrno if the error code is a real error and not
+** a normal expected return code of SQLITE_BUSY or SQLITE_OK
+*/
+#define IS_LOCK_ERROR(x)  ((x != SQLITE_OK) && (x != SQLITE_BUSY))
+
+
+/*
+** The unixFile structure is subclass of sqlite3_file specific to the unix
+** VFS implementations.
 */
 typedef struct unixFile unixFile;
 struct unixFile {
   sqlite3_io_methods const *pMethod;  /* Always the first entry */
+  struct unixOpenCnt *pOpen;       /* Info about all open fd's on this inode */
+  struct unixLockInfo *pLock;      /* Info about locks on this inode */
+  int h;                           /* The file descriptor */
+  int dirfd;                       /* File descriptor for the directory */
+  unsigned char locktype;          /* The type of lock held on this fd */
+  int lastErrno;                   /* The unix errno from the last I/O error */
+  void *lockingContext;            /* Locking style specific state */
+  int openFlags;                   /* The flags specified at open */
+#if SQLITE_THREADSAFE && defined(__linux__)
+  pthread_t tid;                   /* The thread that "owns" this unixFile */
+#endif
+#if OS_VXWORKS
+  int isDelete;                    /* Delete on close if true */
+  struct vxworksFileId *pId;       /* Unique file ID */
+#endif
 #ifdef SQLITE_TEST
   /* In test mode, increase the size of this structure a bit so that
   ** it is larger than the struct CrashFile defined in test6.c.
   */
   char aPadding[32];
-#endif
-  struct openCnt *pOpen;    /* Info about all open fd's on this inode */
-  struct lockInfo *pLock;   /* Info about locks on this inode */
-#if SQLITE_ENABLE_LOCKING_STYLE
-  void *lockingContext;     /* Locking style specific state */
-#endif
-  int h;                    /* The file descriptor */
-  unsigned char locktype;   /* The type of lock held on this fd */
-  int dirfd;                /* File descriptor for the directory */
-#if SQLITE_THREADSAFE
-  pthread_t tid;            /* The thread that "owns" this unixFile */
-#endif
-  int lastErrno;            /* The unix errno from the last I/O error */
-#if IS_VXWORKS
-  int isDelete;             /* Delete on close if true */
-  char *zRealpath;
 #endif
 };
 
 /*
@@ -21763,301 +21868,37 @@
 #else
 #define threadid 0
 #endif
 
-/*
-** Set or check the unixFile.tid field.  This field is set when an unixFile
-** is first opened.  All subsequent uses of the unixFile verify that the
-** same thread is operating on the unixFile.  Some operating systems do
-** not allow locks to be overridden by other threads and that restriction
-** means that sqlite3* database handles cannot be moved from one thread
-** to another.  This logic makes sure a user does not try to do that
-** by mistake.
-**
-** Version 3.3.1 (2006-01-15):  unixFile can be moved from one thread to
-** another as long as we are running on a system that supports threads
-** overriding each others locks (which now the most common behavior)
-** or if no locks are held.  But the unixFile.pLock field needs to be
-** recomputed because its key includes the thread-id.  See the
-** transferOwnership() function below for additional information
-*/
-#if SQLITE_THREADSAFE
-# define SET_THREADID(X)   (X)->tid = pthread_self()
-# define CHECK_THREADID(X) (threadsOverrideEachOthersLocks==0 && \
-                            !pthread_equal((X)->tid, pthread_self()))
-#else
-# define SET_THREADID(X)
-# define CHECK_THREADID(X) 0
-#endif
-
-/*
-** Here is the dirt on POSIX advisory locks:  ANSI STD 1003.1 (1996)
-** section 6.5.2.2 lines 483 through 490 specify that when a process
-** sets or clears a lock, that operation overrides any prior locks set
-** by the same process.  It does not explicitly say so, but this implies
-** that it overrides locks set by the same process using a different
-** file descriptor.  Consider this test case:
-**       int fd2 = open("./file2", O_RDWR|O_CREAT, 0644);
-**
-** Suppose ./file1 and ./file2 are really the same file (because
-** one is a hard or symbolic link to the other) then if you set
-** an exclusive lock on fd1, then try to get an exclusive lock
-** on fd2, it works.  I would have expected the second lock to
-** fail since there was already a lock on the file due to fd1.
-** But not so.  Since both locks came from the same process, the
-** second overrides the first, even though they were on different
-** file descriptors opened on different file names.
-**
-** Bummer.  If you ask me, this is broken.  Badly broken.  It means
-** that we cannot use POSIX locks to synchronize file access among
-** competing threads of the same process.  POSIX locks will work fine
-** to synchronize access for threads in separate processes, but not
-** threads within the same process.
-**
-** To work around the problem, SQLite has to manage file locks internally
-** on its own.  Whenever a new database is opened, we have to find the
-** specific inode of the database file (the inode is determined by the
-** st_dev and st_ino fields of the stat structure that fstat() fills in)
-** and check for locks already existing on that inode.  When locks are
-** created or removed, we have to look at our own internal record of the
-** locks to see if another thread has previously set a lock on that same
-** inode.
-**
-** The sqlite3_file structure for POSIX is no longer just an integer file
-** descriptor.  It is now a structure that holds the integer file
-** descriptor and a pointer to a structure that describes the internal
-** locks on the corresponding inode.  There is one locking structure
-** per inode, so if the same inode is opened twice, both unixFile structures
-** point to the same locking structure.  The locking structure keeps
-** a reference count (so we will know when to delete it) and a "cnt"
-** field that tells us its internal lock status.  cnt==0 means the
-** file is unlocked.  cnt==-1 means the file has an exclusive lock.
-** cnt>0 means there are cnt shared locks on the file.
-**
-** Any attempt to lock or unlock a file first checks the locking
-** structure.  The fcntl() system call is only invoked to set a
-** POSIX lock if the internal lock structure transitions between
-** a locked and an unlocked state.
-**
-** 2004-Jan-11:
-** More recent discoveries about POSIX advisory locks.  (The more
-** I discover, the more I realize the a POSIX advisory locks are
-** an abomination.)
-**
-** If you close a file descriptor that points to a file that has locks,
-** all locks on that file that are owned by the current process are
-** released.  To work around this problem, each unixFile structure contains
-** a pointer to an openCnt structure.  There is one openCnt structure
-** per open inode, which means that multiple unixFile can point to a single
-** openCnt.  When an attempt is made to close an unixFile, if there are
-** other unixFile open on the same inode that are holding locks, the call
-** to close() the file descriptor is deferred until all of the locks clear.
-** The openCnt structure keeps a list of file descriptors that need to
-** be closed and that list is walked (and cleared) when the last lock
-** clears.
-**
-** First, under Linux threads, because each thread has a separate
-** process ID, lock operations in one thread do not override locks
-** to the same file in other threads.  Linux threads behave like
-** separate processes in this respect.  But, if you close a file
-** descriptor in linux threads, all locks are cleared, even locks
-** on other threads and even though the other threads have different
-** process IDs.  Linux threads is inconsistent in this respect.
-** (I'm beginning to think that linux threads is an abomination too.)
-** The consequence of this all is that the hash table for the lockInfo
-** structure has to include the process id as part of its key because
-** locks in different threads are treated as distinct.  But the
-** openCnt structure should not include the process id in its
-** key because close() clears lock on all threads, not just the current
-** thread.  Were it not for this goofiness in linux threads, we could
-** combine the lockInfo and openCnt structures into a single structure.
-**
-** 2004-Jun-28:
-** On some versions of linux, threads can override each others locks.
-** On others not.  Sometimes you can change the behavior on the same
-** system by setting the LD_ASSUME_KERNEL environment variable.  The
-** POSIX standard is silent as to which behavior is correct, as far
-** as I can tell, so other versions of unix might show the same
-** inconsistency.  There is no little doubt in my mind that posix
-** advisory locks and linux threads are profoundly broken.
-**
-** To work around the inconsistencies, we have to test at runtime
-** whether or not threads can override each others locks.  This test
-** is run once, the first time any lock is attempted.  A static
-** variable is set to record the results of this test for future
-** use.
-*/
-
-/*
-** An instance of the following structure serves as the key used
-** to locate a particular lockInfo structure given its inode.
-**
-** If threads cannot override each others locks, then we set the
-** lockKey.tid field to the thread ID.  If threads can override
-** each others locks then tid is always set to zero.  tid is omitted
-** if we compile without threading support.
-*/
-struct lockKey {
-  dev_t dev;       /* Device number */
-#if IS_VXWORKS
-  void *rnam;      /* Realname since inode unusable */
-#else
-  ino_t ino;       /* Inode number */
-#endif
-#if SQLITE_THREADSAFE
-  pthread_t tid;   /* Thread ID or zero if threads can override each other */
-#endif
-};
-
-/*
-** An instance of the following structure is allocated for each open
-** inode on each thread with a different process ID.  (Threads have
-** different process IDs on linux, but not on most other unixes.)
-**
-** A single inode can have multiple file descriptors, so each unixFile
-** structure contains a pointer to an instance of this object and this
-** object keeps a count of the number of unixFile pointing to it.
-*/
-struct lockInfo {
-  struct lockKey key;  /* The lookup key */
-  int cnt;             /* Number of SHARED locks held */
-  int locktype;        /* One of SHARED_LOCK, RESERVED_LOCK etc. */
-  int nRef;            /* Number of pointers to this structure */
-  struct lockInfo *pNext, *pPrev;   /* List of all lockInfo objects */
-};
-
-/*
-** An instance of the following structure serves as the key used
-** to locate a particular openCnt structure given its inode.  This
-** is the same as the lockKey except that the thread ID is omitted.
-*/
-struct openKey {
-  dev_t dev;   /* Device number */
-#if IS_VXWORKS
-  void *rnam;  /* Realname since inode unusable */
-#else
-  ino_t ino;   /* Inode number */
-#endif
-};
-
-/*
-** An instance of the following structure is allocated for each open
-** inode.  This structure keeps track of the number of locks on that
-** inode.  If a close is attempted against an inode that is holding
-** locks, the close is deferred until all locks clear by adding the
-** file descriptor to be closed to the pending list.
-*/
-struct openCnt {
-  struct openKey key;   /* The lookup key */
-  int nRef;             /* Number of pointers to this structure */
-  int nLock;            /* Number of outstanding locks */
-  int nPending;         /* Number of pending close() operations */
-  int *aPending;        /* Malloced space holding fd's awaiting a close() */
-#if IS_VXWORKS
-  sem_t *pSem;          /* Named POSIX semaphore */
-  char aSemName[MAX_PATHNAME+1];   /* Name of that semaphore */
-#endif
-  struct openCnt *pNext, *pPrev;   /* List of all openCnt objects */
-};
-
-/*
-** List of all lockInfo and openCnt objects.  This used to be a hash
-** table.  But the number of objects is rarely more than a dozen and
-** never exceeds a few thousand.  And lookup is not on a critical
-** path oo a simple linked list will suffice.
-*/
-static struct lockInfo *lockList = 0;
-static struct openCnt *openList = 0;
-
-#if IS_VXWORKS
-/*
-** This hash table is used to bind the canonical file name to a
-** unixFile structure and use the hash key (= canonical name)
-** instead of the Inode number of the file to find the matching
-** lockInfo and openCnt structures. It also helps to make the
-** name of the semaphore when LOCKING_STYLE_NAMEDSEM is used
-** for the file.
-*/
-static Hash nameHash;
-#endif
-
-/*
-** The locking styles are associated with the different file locking
-** capabilities supported by different file systems.
-**
-** POSIX locking style fully supports shared and exclusive byte-range locks
-** AFP locking only supports exclusive byte-range locks
-** FLOCK only supports a single file-global exclusive lock
-** DOTLOCK isn't a true locking style, it refers to the use of a special
-**   file named the same as the database file with a '.lock' extension, this
-**   can be used on file systems that do not offer any reliable file locking
-** NO locking means that no locking will be attempted, this is only used for
-**   read-only file systems currently
-** NAMEDSEM is similar to DOTLOCK but uses a named semaphore instead of an
-**   indicator file.
-** UNSUPPORTED means that no locking will be attempted, this is only used for
-**   file systems that are known to be unsupported
-*/
-#define LOCKING_STYLE_POSIX        1
-#define LOCKING_STYLE_NONE         2
-#define LOCKING_STYLE_DOTFILE      3
-#define LOCKING_STYLE_FLOCK        4
-#define LOCKING_STYLE_AFP          5
-#define LOCKING_STYLE_NAMEDSEM     6
-
-/*
-** Only set the lastErrno if the error code is a real error and not
-** a normal expected return code of SQLITE_BUSY or SQLITE_OK
-*/
-#define IS_LOCK_ERROR(x)  ((x != SQLITE_OK) && (x != SQLITE_BUSY))
 
 /*
 ** Helper functions to obtain and relinquish the global mutex.
 */
-static void enterMutex(void){
+static void unixEnterMutex(void){
   sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
 }
-static void leaveMutex(void){
+static void unixLeaveMutex(void){
   sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
 }
 
-#if SQLITE_THREADSAFE
-/*
-** This variable records whether or not threads can override each others
-** locks.
-**
-**    0:  No.  Threads cannot override each others locks.
-**    1:  Yes.  Threads can override each others locks.
-**   -1:  We don't know yet.
-**
-** On some systems, we know at compile-time if threads can override each
-** others locks.  On those systems, the SQLITE_THREAD_OVERRIDE_LOCK macro
-** will be set appropriately.  On other systems, we have to check at
-** runtime.  On these latter systems, SQLTIE_THREAD_OVERRIDE_LOCK is
-** undefined.
-**
-** This variable normally has file scope only.  But during testing, we make
-** it a global so that the test code can change its value in order to verify
-** that the right stuff happens in either case.
-*/
-#ifndef SQLITE_THREAD_OVERRIDE_LOCK
-# define SQLITE_THREAD_OVERRIDE_LOCK -1
-#endif
-#ifdef SQLITE_TEST
-int threadsOverrideEachOthersLocks = SQLITE_THREAD_OVERRIDE_LOCK;
-#else
-static int threadsOverrideEachOthersLocks = SQLITE_THREAD_OVERRIDE_LOCK;
-#endif
-
-/*
-** This structure holds information passed into individual test
-** threads by the testThreadLockingBehavior() routine.
-*/
-struct threadTestData {
-  int fd;                /* File to be locked */
-  struct flock lock;     /* The locking operation */
-  int result;            /* Result of the locking operation */
-};
+
+#ifdef SQLITE_DEBUG
+/*
+** Helper function for printing out trace information from debugging
+** binaries. This returns the string represetation of the supplied
+** integer lock-type.
+*/
+static const char *locktypeName(int locktype){
+  switch( locktype ){
+  case NO_LOCK: return "NONE";
+  case SHARED_LOCK: return "SHARED";
+  case RESERVED_LOCK: return "RESERVED";
+  case PENDING_LOCK: return "PENDING";
+  case EXCLUSIVE_LOCK: return "EXCLUSIVE";
+  }
+  return "ERROR";
+}
+#endif
 
 #ifdef SQLITE_LOCK_TRACE
 /*
 ** Print out information about all locking operations.
@@ -22116,9 +21957,455 @@
 }
 #define fcntl lockTrace
 #endif /* SQLITE_LOCK_TRACE */
 
-#ifdef __linux__
+
+
+/*
+** This routine translates a standard POSIX errno code into something
+** useful to the clients of the sqlite3 functions.  Specifically, it is
+** intended to translate a variety of "try again" errors into SQLITE_BUSY
+** and a variety of "please close the file descriptor NOW" errors into
+** SQLITE_IOERR
+**
+** Errors during initialization of locks, or file system support for locks,
+** should handle ENOLCK, ENOTSUP, EOPNOTSUPP separately.
+*/
+static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) {
+  switch (posixError) {
+  case 0:
+    return SQLITE_OK;
+
+  case EAGAIN:
+  case ETIMEDOUT:
+  case EBUSY:
+  case EINTR:
+  case ENOLCK:
+    /* random NFS retry error, unless during file system support
+     * introspection, in which it actually means what it says */
+    return SQLITE_BUSY;
+
+  case EACCES:
+    /* EACCES is like EAGAIN during locking operations, but not any other time*/
+    if( (sqliteIOErr == SQLITE_IOERR_LOCK) ||
+	(sqliteIOErr == SQLITE_IOERR_UNLOCK) ||
+	(sqliteIOErr == SQLITE_IOERR_RDLOCK) ||
+	(sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ){
+      return SQLITE_BUSY;
+    }
+    /* else fall through */
+  case EPERM:
+    return SQLITE_PERM;
+
+  case EDEADLK:
+    return SQLITE_IOERR_BLOCKED;
+
+#if EOPNOTSUPP!=ENOTSUP
+  case EOPNOTSUPP:
+    /* something went terribly awry, unless during file system support
+     * introspection, in which it actually means what it says */
+#endif
+#ifdef ENOTSUP
+  case ENOTSUP:
+    /* invalid fd, unless during file system support introspection, in which
+     * it actually means what it says */
+#endif
+  case EIO:
+  case EBADF:
+  case EINVAL:
+  case ENOTCONN:
+  case ENODEV:
+  case ENXIO:
+  case ENOENT:
+  case ESTALE:
+  case ENOSYS:
+    /* these should force the client to close the file and reconnect */
+
+  default:
+    return sqliteIOErr;
+  }
+}
+
+
+
+/******************************************************************************
+****************** Begin Unique File ID Utility Used By VxWorks ***************
+**
+** On most versions of unix, we can get a unique ID for a file by concatenating
+** the device number and the inode number.  But this does not work on VxWorks.
+** On VxWorks, a unique file id must be based on the canonical filename.
+**
+** A pointer to an instance of the following structure can be used as a
+** unique file ID in VxWorks.  Each instance of this structure contains
+** a copy of the canonical filename.  There is also a reference count.
+** The structure is reclaimed when the number of pointers to it drops to
+** zero.
+**
+** There are never very many files open at one time and lookups are not
+** a performance-critical path, so it is sufficient to put these
+** structures on a linked list.
+*/
+struct vxworksFileId {
+  struct vxworksFileId *pNext;  /* Next in a list of them all */
+  int nRef;                     /* Number of references to this one */
+  int nName;                    /* Length of the zCanonicalName[] string */
+  char *zCanonicalName;         /* Canonical filename */
+};
+
+#if OS_VXWORKS
+/*
+** All unique filenames are held on a linked list headed by this
+** variable:
+*/
+static struct vxworksFileId *vxworksFileList = 0;
+
+/*
+** Simplify a filename into its canonical form
+** by making the following changes:
+**
+**  * removing any trailing and duplicate /
+**  * convert /./ into just /
+**  * convert /A/../ where A is any simple name into just /
+**
+** Changes are made in-place.  Return the new name length.
+**
+** The original filename is in z[0..n-1].  Return the number of
+** characters in the simplified name.
+*/
+static int vxworksSimplifyName(char *z, int n){
+  int i, j;
+  while( n>1 && z[n-1]=='/' ){ n--; }
+  for(i=j=0; i<n; i++){
+    if( z[i]=='/' ){
+      if( z[i+1]=='/' ) continue;
+      if( z[i+1]=='.' && i+2<n && z[i+2]=='/' ){
+        i += 1;
+        continue;
+      }
+      if( z[i+1]=='.' && i+3<n && z[i+2]=='.' && z[i+3]=='/' ){
+        while( j>0 && z[j-1]!='/' ){ j--; }
+        if( j>0 ){ j--; }
+        i += 2;
+        continue;
+      }
+    }
+    z[j++] = z[i];
+  }
+  z[j] = 0;
+  return j;
+}
+
+/*
+** Find a unique file ID for the given absolute pathname.  Return
+** a pointer to the vxworksFileId object.  This pointer is the unique
+** file ID.
+**
+** The nRef field of the vxworksFileId object is incremented before
+** the object is returned.  A new vxworksFileId object is created
+** and added to the global list if necessary.
+**
+** If a memory allocation error occurs, return NULL.
+*/
+static struct vxworksFileId *vxworksFindFileId(const char *zAbsoluteName){
+  struct vxworksFileId *pNew;         /* search key and new file ID */
+  struct vxworksFileId *pCandidate;   /* For looping over existing file IDs */
+  int n;                              /* Length of zAbsoluteName string */
+
+  assert( zAbsoluteName[0]=='/' );
+  n = (int)strlen(zAbsoluteName);
+  pNew = sqlite3_malloc( sizeof(*pNew) + (n+1) );
+  if( pNew==0 ) return 0;
+  pNew->zCanonicalName = (char*)&pNew[1];
+  memcpy(pNew->zCanonicalName, zAbsoluteName, n+1);
+  n = vxworksSimplifyName(pNew->zCanonicalName, n);
+
+  /* Search for an existing entry that matching the canonical name.
+  ** If found, increment the reference count and return a pointer to
+  ** the existing file ID.
+  */
+  unixEnterMutex();
+  for(pCandidate=vxworksFileList; pCandidate; pCandidate=pCandidate->pNext){
+    if( pCandidate->nName==n
+     && memcmp(pCandidate->zCanonicalName, pNew->zCanonicalName, n)==0
+    ){
+       sqlite3_free(pNew);
+       pCandidate->nRef++;
+       unixLeaveMutex();
+       return pCandidate;
+    }
+  }
+
+  /* No match was found.  We will make a new file ID */
+  pNew->nRef = 1;
+  pNew->nName = n;
+  pNew->pNext = vxworksFileList;
+  vxworksFileList = pNew;
+  unixLeaveMutex();
+  return pNew;
+}
+
+/*
+** Decrement the reference count on a vxworksFileId object.  Free
+** the object when the reference count reaches zero.
+*/
+static void vxworksReleaseFileId(struct vxworksFileId *pId){
+  unixEnterMutex();
+  assert( pId->nRef>0 );
+  pId->nRef--;
+  if( pId->nRef==0 ){
+    struct vxworksFileId **pp;
+    for(pp=&vxworksFileList; *pp && *pp!=pId; pp = &((*pp)->pNext)){}
+    assert( *pp==pId );
+    *pp = pId->pNext;
+    sqlite3_free(pId);
+  }
+  unixLeaveMutex();
+}
+#endif /* OS_VXWORKS */
+/*************** End of Unique File ID Utility Used By VxWorks ****************
+******************************************************************************/
+
+
+/******************************************************************************
+*************************** Posix Advisory Locking ****************************
+**
+** POSIX advisory locks are broken by design.  ANSI STD 1003.1 (1996)
+** section 6.5.2.2 lines 483 through 490 specify that when a process
+** sets or clears a lock, that operation overrides any prior locks set
+** by the same process.  It does not explicitly say so, but this implies
+** that it overrides locks set by the same process using a different
+** file descriptor.  Consider this test case:
+**
+**       int fd1 = open("./file1", O_RDWR|O_CREAT, 0644);
+**       int fd2 = open("./file2", O_RDWR|O_CREAT, 0644);
+**
+** Suppose ./file1 and ./file2 are really the same file (because
+** one is a hard or symbolic link to the other) then if you set
+** an exclusive lock on fd1, then try to get an exclusive lock
+** on fd2, it works.  I would have expected the second lock to
+** fail since there was already a lock on the file due to fd1.
+** But not so.  Since both locks came from the same process, the
+** second overrides the first, even though they were on different
+** file descriptors opened on different file names.
+**
+** This means that we cannot use POSIX locks to synchronize file access
+** among competing threads of the same process.  POSIX locks will work fine
+** to synchronize access for threads in separate processes, but not
+** threads within the same process.
+**
+** To work around the problem, SQLite has to manage file locks internally
+** on its own.  Whenever a new database is opened, we have to find the
+** specific inode of the database file (the inode is determined by the
+** st_dev and st_ino fields of the stat structure that fstat() fills in)
+** and check for locks already existing on that inode.  When locks are
+** created or removed, we have to look at our own internal record of the
+** locks to see if another thread has previously set a lock on that same
+** inode.
+**
+** (Aside: The use of inode numbers as unique IDs does not work on VxWorks.
+** For VxWorks, we have to use the alternative unique ID system based on
+** canonical filename and implemented in the previous division.)
+**
+** The sqlite3_file structure for POSIX is no longer just an integer file
+** descriptor.  It is now a structure that holds the integer file
+** descriptor and a pointer to a structure that describes the internal
+** locks on the corresponding inode.  There is one locking structure
+** per inode, so if the same inode is opened twice, both unixFile structures
+** point to the same locking structure.  The locking structure keeps
+** a reference count (so we will know when to delete it) and a "cnt"
+** field that tells us its internal lock status.  cnt==0 means the
+** file is unlocked.  cnt==-1 means the file has an exclusive lock.
+** cnt>0 means there are cnt shared locks on the file.
+**
+** Any attempt to lock or unlock a file first checks the locking
+** structure.  The fcntl() system call is only invoked to set a
+** POSIX lock if the internal lock structure transitions between
+** a locked and an unlocked state.
+**
+** But wait:  there are yet more problems with POSIX advisory locks.
+**
+** If you close a file descriptor that points to a file that has locks,
+** all locks on that file that are owned by the current process are
+** released.  To work around this problem, each unixFile structure contains
+** a pointer to an unixOpenCnt structure.  There is one unixOpenCnt structure
+** per open inode, which means that multiple unixFile can point to a single
+** unixOpenCnt.  When an attempt is made to close an unixFile, if there are
+** other unixFile open on the same inode that are holding locks, the call
+** to close() the file descriptor is deferred until all of the locks clear.
+** The unixOpenCnt structure keeps a list of file descriptors that need to
+** be closed and that list is walked (and cleared) when the last lock
+** clears.
+**
+** Yet another problem:  LinuxThreads do not play well with posix locks.
+**
+** Many older versions of linux use the LinuxThreads library which is
+** not posix compliant.  Under LinuxThreads, a lock created by thread
+** A cannot be modified or overridden by a different thread B.
+** Only thread A can modify the lock.  Locking behavior is correct
+** if the appliation uses the newer Native Posix Thread Library (NPTL)
+** on linux - with NPTL a lock created by thread A can override locks
+** in thread B.  But there is no way to know at compile-time which
+** threading library is being used.  So there is no way to know at
+** compile-time whether or not thread A can override locks on thread B.
+** We have to do a run-time check to discover the behavior of the
+** current process.
+**
+** On systems where thread A is unable to modify locks created by
+** thread B, we have to keep track of which thread created each
+** lock.  Hence there is an extra field in the key to the unixLockInfo
+** structure to record this information.  And on those systems it
+** is illegal to begin a transaction in one thread and finish it
+** in another.  For this latter restriction, there is no work-around.
+** It is a limitation of LinuxThreads.
+*/
+
+/*
+** Set or check the unixFile.tid field.  This field is set when an unixFile
+** is first opened.  All subsequent uses of the unixFile verify that the
+** same thread is operating on the unixFile.  Some operating systems do
+** not allow locks to be overridden by other threads and that restriction
+** means that sqlite3* database handles cannot be moved from one thread
+** to another while locks are held.
+**
+** Version 3.3.1 (2006-01-15):  unixFile can be moved from one thread to
+** another as long as we are running on a system that supports threads
+** overriding each others locks (which is now the most common behavior)
+** or if no locks are held.  But the unixFile.pLock field needs to be
+** recomputed because its key includes the thread-id.  See the
+** transferOwnership() function below for additional information
+*/
+#if SQLITE_THREADSAFE && defined(__linux__)
+# define SET_THREADID(X)   (X)->tid = pthread_self()
+# define CHECK_THREADID(X) (threadsOverrideEachOthersLocks==0 && \
+                            !pthread_equal((X)->tid, pthread_self()))
+#else
+# define SET_THREADID(X)
+# define CHECK_THREADID(X) 0
+#endif
+
+/*
+** An instance of the following structure serves as the key used
+** to locate a particular unixOpenCnt structure given its inode.  This
+** is the same as the unixLockKey except that the thread ID is omitted.
+*/
+struct unixFileId {
+  dev_t dev;                  /* Device number */
+#if OS_VXWORKS
+  struct vxworksFileId *pId;  /* Unique file ID for vxworks. */
+#else
+  ino_t ino;                  /* Inode number */
+#endif
+};
+
+/*
+** An instance of the following structure serves as the key used
+** to locate a particular unixLockInfo structure given its inode.
+**
+** If threads cannot override each others locks (LinuxThreads), then we
+** set the unixLockKey.tid field to the thread ID.  If threads can override
+** each others locks (Posix and NPTL) then tid is always set to zero.
+** tid is omitted if we compile without threading support or on an OS
+** other than linux.
+*/
+struct unixLockKey {
+  struct unixFileId fid;  /* Unique identifier for the file */
+#if SQLITE_THREADSAFE && defined(__linux__)
+  pthread_t tid;  /* Thread ID of lock owner. Zero if not using LinuxThreads */
+#endif
+};
+
+/*
+** An instance of the following structure is allocated for each open
+** inode.  Or, on LinuxThreads, there is one of these structures for
+** each inode opened by each thread.
+**
+** A single inode can have multiple file descriptors, so each unixFile
+** structure contains a pointer to an instance of this object and this
+** object keeps a count of the number of unixFile pointing to it.
+*/
+struct unixLockInfo {
+  struct unixLockKey lockKey;     /* The lookup key */
+  int cnt;                        /* Number of SHARED locks held */
+  int locktype;                   /* One of SHARED_LOCK, RESERVED_LOCK etc. */
+  int nRef;                       /* Number of pointers to this structure */
+  struct unixLockInfo *pNext;     /* List of all unixLockInfo objects */
+  struct unixLockInfo *pPrev;     /*    .... doubly linked */
+};
+
+/*
+** An instance of the following structure is allocated for each open
+** inode.  This structure keeps track of the number of locks on that
+** inode.  If a close is attempted against an inode that is holding
+** locks, the close is deferred until all locks clear by adding the
+** file descriptor to be closed to the pending list.
+**
+** TODO:  Consider changing this so that there is only a single file
+** descriptor for each open file, even when it is opened multiple times.
+** The close() system call would only occur when the last database
+** using the file closes.
+*/
+struct unixOpenCnt {
+  struct unixFileId fileId;   /* The lookup key */
+  int nRef;                   /* Number of pointers to this structure */
+  int nLock;                  /* Number of outstanding locks */
+  int nPending;               /* Number of pending close() operations */
+  int *aPending;            /* Malloced space holding fd's awaiting a close() */
+#if OS_VXWORKS
+  sem_t *pSem;                     /* Named POSIX semaphore */
+  char aSemName[MAX_PATHNAME+1];   /* Name of that semaphore */
+#endif
+  struct unixOpenCnt *pNext, *pPrev;   /* List of all unixOpenCnt objects */
+};
+
+/*
+** Lists of all unixLockInfo and unixOpenCnt objects.  These used to be hash
+** tables.  But the number of objects is rarely more than a dozen and
+** never exceeds a few thousand.  And lookup is not on a critical
+** path so a simple linked list will suffice.
+*/
+static struct unixLockInfo *lockList = 0;
+static struct unixOpenCnt *openList = 0;
+
+/*
+** This variable remembers whether or not threads can override each others
+** locks.
+**
+**    0:  No.  Threads cannot override each others locks.  (LinuxThreads)
+**    1:  Yes.  Threads can override each others locks.  (Posix & NLPT)
+**   -1:  We don't know yet.
+**
+** On some systems, we know at compile-time if threads can override each
+** others locks.  On those systems, the SQLITE_THREAD_OVERRIDE_LOCK macro
+** will be set appropriately.  On other systems, we have to check at
+** runtime.  On these latter systems, SQLTIE_THREAD_OVERRIDE_LOCK is
+** undefined.
+**
+** This variable normally has file scope only.  But during testing, we make
+** it a global so that the test code can change its value in order to verify
+** that the right stuff happens in either case.
+*/
+#if SQLITE_THREADSAFE && defined(__linux__)
+#  ifndef SQLITE_THREAD_OVERRIDE_LOCK
+#    define SQLITE_THREAD_OVERRIDE_LOCK -1
+#  endif
+#  ifdef SQLITE_TEST
+int threadsOverrideEachOthersLocks = SQLITE_THREAD_OVERRIDE_LOCK;
+#  else
+static int threadsOverrideEachOthersLocks = SQLITE_THREAD_OVERRIDE_LOCK;
+#  endif
+#endif
+
+/*
+** This structure holds information passed into individual test
+** threads by the testThreadLockingBehavior() routine.
+*/
+struct threadTestData {
+  int fd;                /* File to be locked */
+  struct flock lock;     /* The locking operation */
+  int result;            /* Result of the locking operation */
+};
+
+#if SQLITE_THREADSAFE && defined(__linux__)
 /*
 ** This function is used as the main routine for a thread launched by
 ** testThreadLockingBehavior(). It tests whether the shared-lock obtained
 ** by the main thread in testThreadLockingBehavior() conflicts with a
@@ -22131,9 +22418,12 @@
   struct threadTestData *pData = (struct threadTestData*)pArg;
   pData->result = fcntl(pData->fd, F_GETLK, &pData->lock);
   return pArg;
 }
-
+#endif /* SQLITE_THREADSAFE && defined(__linux__) */
+
+
+#if SQLITE_THREADSAFE && defined(__linux__)
 /*
 ** This procedure attempts to determine whether or not threads
 ** can override each others locks then sets the
 ** threadsOverrideEachOthersLocks variable appropriately.
@@ -22163,23 +22453,14 @@
   close(fd);
   if( d.result!=0 ) return;
   threadsOverrideEachOthersLocks = (d.lock.l_type==F_UNLCK);
 }
-#else
-/*
-** On anything other than linux, assume threads override each others locks.
-*/
-static void testThreadLockingBehavior(int fd_orig){
-  threadsOverrideEachOthersLocks = 1;
-}
-#endif /* __linux__ */
-
-#endif /* SQLITE_THREADSAFE */
-
-/*
-** Release a lockInfo structure previously allocated by findLockInfo().
-*/
-static void releaseLockInfo(struct lockInfo *pLock){
+#endif /* SQLITE_THERADSAFE && defined(__linux__) */
+
+/*
+** Release a unixLockInfo structure previously allocated by findLockInfo().
+*/
+static void releaseLockInfo(struct unixLockInfo *pLock){
   if( pLock ){
     pLock->nRef--;
     if( pLock->nRef==0 ){
       if( pLock->pPrev ){
@@ -22198,11 +22479,11 @@
   }
 }
 
 /*
-** Release a openCnt structure previously allocated by findLockInfo().
-*/
-static void releaseOpenCnt(struct openCnt *pOpen){
+** Release a unixOpenCnt structure previously allocated by findLockInfo().
+*/
+static void releaseOpenCnt(struct unixOpenCnt *pOpen){
   if( pOpen ){
     pOpen->nRef--;
     if( pOpen->nRef==0 ){
       if( pOpen->pPrev ){
@@ -22221,227 +22502,37 @@
     }
   }
 }
 
-#if IS_VXWORKS
-/*
-** Implementation of a realpath() like function for vxWorks
-** to determine canonical path name from given name. It does
-** not support symlinks. Neither does it handle volume prefixes.
-*/
-char *
-vxrealpath(const char *pathname, int dostat)
-{
-  struct stat sbuf;
-  int len;
-  char *where, *ptr, *last;
-  char *result, *curpath, *workpath, *namebuf;
-
-  len = pathconf(pathname, _PC_PATH_MAX);
-  if( len<0 ){
-    len = PATH_MAX;
-  }
-  result = sqlite3_malloc(len * 4);
-  if( !result ){
-    return 0;
-  }
-  curpath = result + len;
-  workpath = curpath + len;
-  namebuf = workpath + len;
-  strcpy(curpath, pathname);
-  if( *pathname!='/' ){
-    if( !getcwd(workpath, len) ){
-      sqlite3_free(result);
-      return 0;
-    }
-  }else{
-    *workpath = '\0';
-  }
-  where = curpath;
-  while( *where ){
-    if( !strcmp(where, ".") ){
-      where++;
-      continue;
-    }
-    if( !strncmp(where, "./", 2) ){
-      where += 2;
-      continue;
-    }
-    if( !strncmp(where, "../", 3) ){
-      where += 3;
-      ptr = last = workpath;
-      while( *ptr ){
-        if( *ptr=='/' ){
-          last = ptr;
-        }
-        ptr++;
-      }
-      *last = '\0';
-      continue;
-    }
-    ptr = strchr(where, '/');
-    if( !ptr ){
-      ptr = where + strlen(where) - 1;
-    }else{
-      *ptr = '\0';
-    }
-    strcpy(namebuf, workpath);
-    for( last = namebuf; *last; last++ ){
-      continue;
-    }
-    if( *--last!='/' ){
-      strcat(namebuf, "/");
-    }
-    strcat(namebuf, where);
-    where = ++ptr;
-    if( dostat ){
-      if( stat(namebuf, &sbuf)==-1 ){
-        sqlite3_free(result);
-        return 0;
-      }
-      if( (sbuf.st_mode & S_IFDIR)==S_IFDIR ){
-        strcpy(workpath, namebuf);
-        continue;
-      }
-      if( *where ){
-        sqlite3_free(result);
-        return 0;
-      }
-    }
-    strcpy(workpath, namebuf);
-  }
-  strcpy(result, workpath);
-  return result;
-}
-#endif
-
-#if SQLITE_ENABLE_LOCKING_STYLE
-/*
-** Tests a byte-range locking query to see if byte range locks are
-** supported, if not we fall back to dotlockLockingStyle.
-** On vxWorks we fall back to namedsemLockingStyle.
-*/
-static int testLockingStyle(int fd){
-  struct flock lockInfo;
-
-  /* Test byte-range lock using fcntl(). If the call succeeds,
-  ** assume that the file-system supports POSIX style locks.
-  */
-  lockInfo.l_len = 1;
-  lockInfo.l_start = 0;
-  lockInfo.l_whence = SEEK_SET;
-  lockInfo.l_type = F_RDLCK;
-  if( fcntl(fd, F_GETLK, &lockInfo)!=-1 ) {
-    return LOCKING_STYLE_POSIX;
-  }
-
-  /* Testing for flock() can give false positives.  So if if the above
-  ** test fails, then we fall back to using dot-file style locking (or
-  ** named-semaphore locking on vxworks).
-  */
-  return (IS_VXWORKS ? LOCKING_STYLE_NAMEDSEM : LOCKING_STYLE_DOTFILE);
-}
-#endif
-
-/*
-** If SQLITE_ENABLE_LOCKING_STYLE is defined, this function Examines the
-** f_fstypename entry in the statfs structure as returned by stat() for
-** the file system hosting the database file and selects  the appropriate
-** locking style based on its value.  These values and assignments are
-** based on Darwin/OSX behavior and have not been thoroughly tested on
-** other systems.
-**
-** If SQLITE_ENABLE_LOCKING_STYLE is not defined, this function always
-** returns LOCKING_STYLE_POSIX.
-*/
-#if SQLITE_ENABLE_LOCKING_STYLE
-static int detectLockingStyle(
-  sqlite3_vfs *pVfs,
-  const char *filePath,
-  int fd
-){
-#if IS_VXWORKS
-  if( !filePath ){
-    return LOCKING_STYLE_NONE;
-  }
-  if( pVfs->pAppData ){
-    return SQLITE_PTR_TO_INT(pVfs->pAppData);
-  }
-  if (access(filePath, 0) != -1){
-    return testLockingStyle(fd);
-  }
-#else
-  struct Mapping {
-    const char *zFilesystem;
-    int eLockingStyle;
-  } aMap[] = {
-    { "hfs",    LOCKING_STYLE_POSIX },
-    { "ufs",    LOCKING_STYLE_POSIX },
-    { "afpfs",  LOCKING_STYLE_AFP },
-#ifdef SQLITE_ENABLE_AFP_LOCKING_SMB
-    { "smbfs",  LOCKING_STYLE_AFP },
-#else
-    { "smbfs",  LOCKING_STYLE_FLOCK },
-#endif
-    { "msdos",  LOCKING_STYLE_DOTFILE },
-    { "webdav", LOCKING_STYLE_NONE },
-    { 0, 0 }
-  };
-  int i;
-  struct statfs fsInfo;
-
-  if( !filePath ){
-    return LOCKING_STYLE_NONE;
-  }
-  if( pVfs->pAppData ){
-    return SQLITE_PTR_TO_INT(pVfs->pAppData);
-  }
-
-  if( statfs(filePath, &fsInfo) != -1 ){
-    if( fsInfo.f_flags & MNT_RDONLY ){
-      return LOCKING_STYLE_NONE;
-    }
-    for(i=0; aMap[i].zFilesystem; i++){
-      if( strcmp(fsInfo.f_fstypename, aMap[i].zFilesystem)==0 ){
-        return aMap[i].eLockingStyle;
-      }
-    }
-  }
-
-  /* Default case. Handles, amongst others, "nfs". */
-  return testLockingStyle(fd);
-#endif /* if IS_VXWORKS */
-  return LOCKING_STYLE_POSIX;
-}
-#else
-  #define detectLockingStyle(x,y,z) LOCKING_STYLE_POSIX
-#endif /* ifdef SQLITE_ENABLE_LOCKING_STYLE */
-
-/*
-** Given a file descriptor, locate lockInfo and openCnt structures that
+/*
+** Given a file descriptor, locate unixLockInfo and unixOpenCnt structures that
 ** describes that file descriptor.  Create new ones if necessary.  The
 ** return values might be uninitialized if an error occurs.
 **
 ** Return an appropriate error code.
 */
 static int findLockInfo(
-  int fd,                      /* The file descriptor used in the key */
-#if IS_VXWORKS
-  void *rnam,                  /* vxWorks realname */
-#endif
-  struct lockInfo **ppLock,    /* Return the lockInfo structure here */
-  struct openCnt **ppOpen      /* Return the openCnt structure here */
-){
-  int rc;
-  struct lockKey key1;
-  struct openKey key2;
-  struct stat statbuf;
-  struct lockInfo *pLock;
-  struct openCnt *pOpen;
+  unixFile *pFile,               /* Unix file with file desc used in the key */
+  struct unixLockInfo **ppLock,  /* Return the unixLockInfo structure here */
+  struct unixOpenCnt **ppOpen    /* Return the unixOpenCnt structure here */
+){
+  int rc;                        /* System call return code */
+  int fd;                        /* The file descriptor for pFile */
+  struct unixLockKey lockKey;    /* Lookup key for the unixLockInfo structure */
+  struct unixFileId fileId;      /* Lookup key for the unixOpenCnt struct */
+  struct stat statbuf;           /* Low-level file information */
+  struct unixLockInfo *pLock;    /* Candidate unixLockInfo object */
+  struct unixOpenCnt *pOpen;     /* Candidate unixOpenCnt object */
+
+  /* Get low-level information about the file that we can used to
+  ** create a unique name for the file.
+  */
+  fd = pFile->h;
   rc = fstat(fd, &statbuf);
   if( rc!=0 ){
+    pFile->lastErrno = errno;
 #ifdef EOVERFLOW
-    if( errno==EOVERFLOW ) return SQLITE_NOLFS;
+    if( pFile->lastErrno==EOVERFLOW ) return SQLITE_NOLFS;
 #endif
     return SQLITE_IOERR;
   }
 
@@ -22458,57 +22549,54 @@
   if( statbuf.st_size==0 ){
     write(fd, "S", 1);
     rc = fstat(fd, &statbuf);
     if( rc!=0 ){
+      pFile->lastErrno = errno;
       return SQLITE_IOERR;
     }
   }
 
-  memset(&key1, 0, sizeof(key1));
-  key1.dev = statbuf.st_dev;
-#if IS_VXWORKS
-  key1.rnam = rnam;
-#else
-  key1.ino = statbuf.st_ino;
-#endif
-#if SQLITE_THREADSAFE
+  memset(&lockKey, 0, sizeof(lockKey));
+  lockKey.fid.dev = statbuf.st_dev;
+#if OS_VXWORKS
+  lockKey.fid.pId = pFile->pId;
+#else
+  lockKey.fid.ino = statbuf.st_ino;
+#endif
+#if SQLITE_THREADSAFE && defined(__linux__)
   if( threadsOverrideEachOthersLocks<0 ){
     testThreadLockingBehavior(fd);
   }
-  key1.tid = threadsOverrideEachOthersLocks ? 0 : pthread_self();
-#endif
-  memset(&key2, 0, sizeof(key2));
-  key2.dev = statbuf.st_dev;
-#if IS_VXWORKS
-  key2.rnam = rnam;
-#else
-  key2.ino = statbuf.st_ino;
-#endif
-  pLock = lockList;
-  while( pLock && memcmp(&key1, &pLock->key, sizeof(key1)) ){
-    pLock = pLock->pNext;
-  }
-  if( pLock==0 ){
-    pLock = sqlite3_malloc( sizeof(*pLock) );
+  lockKey.tid = threadsOverrideEachOthersLocks ? 0 : pthread_self();
+#endif
+  fileId = lockKey.fid;
+  if( ppLock!=0 ){
+    pLock = lockList;
+    while( pLock && memcmp(&lockKey, &pLock->lockKey, sizeof(lockKey)) ){
+      pLock = pLock->pNext;
+    }
     if( pLock==0 ){
-      rc = SQLITE_NOMEM;
-      goto exit_findlockinfo;
-    }
-    pLock->key = key1;
-    pLock->nRef = 1;
-    pLock->cnt = 0;
-    pLock->locktype = 0;
-    pLock->pNext = lockList;
-    pLock->pPrev = 0;
-    if( lockList ) lockList->pPrev = pLock;
-    lockList = pLock;
-  }else{
-    pLock->nRef++;
-  }
-  *ppLock = pLock;
+      pLock = sqlite3_malloc( sizeof(*pLock) );
+      if( pLock==0 ){
+        rc = SQLITE_NOMEM;
+        goto exit_findlockinfo;
+      }
+      pLock->lockKey = lockKey;
+      pLock->nRef = 1;
+      pLock->cnt = 0;
+      pLock->locktype = 0;
+      pLock->pNext = lockList;
+      pLock->pPrev = 0;
+      if( lockList ) lockList->pPrev = pLock;
+      lockList = pLock;
+    }else{
+      pLock->nRef++;
+    }
+    *ppLock = pLock;
+  }
   if( ppOpen!=0 ){
     pOpen = openList;
-    while( pOpen && memcmp(&key2, &pOpen->key, sizeof(key2)) ){
+    while( pOpen && memcmp(&fileId, &pOpen->fileId, sizeof(fileId)) ){
       pOpen = pOpen->pNext;
     }
     if( pOpen==0 ){
       pOpen = sqlite3_malloc( sizeof(*pOpen) );
@@ -22516,9 +22604,9 @@
         releaseLockInfo(pLock);
         rc = SQLITE_NOMEM;
         goto exit_findlockinfo;
       }
-      pOpen->key = key2;
+      pOpen->fileId = fileId;
       pOpen->nRef = 1;
       pOpen->nLock = 0;
       pOpen->nPending = 0;
       pOpen->aPending = 0;
@@ -22525,9 +22613,9 @@
       pOpen->pNext = openList;
       pOpen->pPrev = 0;
       if( openList ) openList->pPrev = pOpen;
       openList = pOpen;
-#if IS_VXWORKS
+#if OS_VXWORKS
       pOpen->pSem = NULL;
       pOpen->aSemName[0] = '\0';
 #endif
     }else{
@@ -22539,40 +22627,20 @@
 exit_findlockinfo:
   return rc;
 }
 
-#ifdef SQLITE_DEBUG
-/*
-** Helper function for printing out trace information from debugging
-** binaries. This returns the string represetation of the supplied
-** integer lock-type.
-*/
-static const char *locktypeName(int locktype){
-  switch( locktype ){
-  case NO_LOCK: return "NONE";
-  case SHARED_LOCK: return "SHARED";
-  case RESERVED_LOCK: return "RESERVED";
-  case PENDING_LOCK: return "PENDING";
-  case EXCLUSIVE_LOCK: return "EXCLUSIVE";
-  }
-  return "ERROR";
-}
-#endif
-
 /*
 ** If we are currently in a different thread than the thread that the
 ** unixFile argument belongs to, then transfer ownership of the unixFile
 ** over to the current thread.
 **
-** A unixFile is only owned by a thread on systems where one thread is
-** unable to override locks created by a different thread.  RedHat9 is
-** an example of such a system.
+** A unixFile is only owned by a thread on systems that use LinuxThreads.
 **
 ** Ownership transfer is only allowed if the unixFile is currently unlocked.
 ** If the unixFile is locked and an ownership is wrong, then return
 ** SQLITE_MISUSE.  SQLITE_OK is returned if everything works.
 */
-#if SQLITE_THREADSAFE
+#if SQLITE_THREADSAFE && defined(__linux__)
 static int transferOwnership(unixFile *pFile){
   int rc;
   pthread_t hSelf;
   if( threadsOverrideEachOthersLocks ){
@@ -22593,13 +22661,9 @@
             pFile->h, pFile->tid, hSelf);
   pFile->tid = hSelf;
   if (pFile->pLock != NULL) {
     releaseLockInfo(pFile->pLock);
-#if IS_VXWORKS
-    rc = findLockInfo(pFile->h, pFile->zRealpath, &pFile->pLock, 0);
-#else
-    rc = findLockInfo(pFile->h, &pFile->pLock, 0);
-#endif
+    rc = findLockInfo(pFile, &pFile->pLock, 0);
     OSTRACE5("LOCK    %d is now %s(%s,%d)\n", pFile->h,
            locktypeName(pFile->locktype),
            locktypeName(pFile->pLock->locktype), pFile->pLock->cnt);
     return rc;
@@ -22606,398 +22670,13 @@
   } else {
     return SQLITE_OK;
   }
 }
-#else
+#else  /* if not SQLITE_THREADSAFE */
   /* On single-threaded builds, ownership transfer is a no-op */
 # define transferOwnership(X) SQLITE_OK
-#endif
-
-/*
-** Seek to the offset passed as the second argument, then read cnt
-** bytes into pBuf. Return the number of bytes actually read.
-**
-** NB:  If you define USE_PREAD or USE_PREAD64, then it might also
-** be necessary to define _XOPEN_SOURCE to be 500.  This varies from
-** one system to another.  Since SQLite does not define USE_PREAD
-** any any form by default, we will not attempt to define _XOPEN_SOURCE.
-** See tickets #2741 and #2681.
-*/
-static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
-  int got;
-  i64 newOffset;
-  TIMER_START;
-#if defined(USE_PREAD)
-  got = pread(id->h, pBuf, cnt, offset);
-  SimulateIOError( got = -1 );
-#elif defined(USE_PREAD64)
-  got = pread64(id->h, pBuf, cnt, offset);
-  SimulateIOError( got = -1 );
-#else
-  newOffset = lseek(id->h, offset, SEEK_SET);
-  SimulateIOError( newOffset-- );
-  if( newOffset!=offset ){
-    return -1;
-  }
-  got = read(id->h, pBuf, cnt);
-#endif
-  TIMER_END;
-  OSTRACE5("READ    %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED);
-  return got;
-}
-
-/*
-** Read data from a file into a buffer.  Return SQLITE_OK if all
-** bytes were read successfully and SQLITE_IOERR if anything goes
-** wrong.
-*/
-static int unixRead(
-  sqlite3_file *id,
-  void *pBuf,
-  int amt,
-  sqlite3_int64 offset
-){
-  int got;
-  assert( id );
-  got = seekAndRead((unixFile*)id, offset, pBuf, amt);
-  if( got==amt ){
-    return SQLITE_OK;
-  }else if( got<0 ){
-    return SQLITE_IOERR_READ;
-  }else{
-    /* Unread parts of the buffer must be zero-filled */
-    memset(&((char*)pBuf)[got], 0, amt-got);
-    return SQLITE_IOERR_SHORT_READ;
-  }
-}
-
-/*
-** Seek to the offset in id->offset then read cnt bytes into pBuf.
-** Return the number of bytes actually read.  Update the offset.
-*/
-static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){
-  int got;
-  i64 newOffset;
-  TIMER_START;
-#if defined(USE_PREAD)
-  got = pwrite(id->h, pBuf, cnt, offset);
-#elif defined(USE_PREAD64)
-  got = pwrite64(id->h, pBuf, cnt, offset);
-#else
-  newOffset = lseek(id->h, offset, SEEK_SET);
-  if( newOffset!=offset ){
-    return -1;
-  }
-  got = write(id->h, pBuf, cnt);
-#endif
-  TIMER_END;
-  OSTRACE5("WRITE   %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED);
-  return got;
-}
-
-
-/*
-** Write data from a buffer into a file.  Return SQLITE_OK on success
-** or some other error code on failure.
-*/
-static int unixWrite(
-  sqlite3_file *id,
-  const void *pBuf,
-  int amt,
-  sqlite3_int64 offset
-){
-  int wrote = 0;
-  assert( id );
-  assert( amt>0 );
-  while( amt>0 && (wrote = seekAndWrite((unixFile*)id, offset, pBuf, amt))>0 ){
-    amt -= wrote;
-    offset += wrote;
-    pBuf = &((char*)pBuf)[wrote];
-  }
-  SimulateIOError(( wrote=(-1), amt=1 ));
-  SimulateDiskfullError(( wrote=0, amt=1 ));
-  if( amt>0 ){
-    if( wrote<0 ){
-      return SQLITE_IOERR_WRITE;
-    }else{
-      return SQLITE_FULL;
-    }
-  }
-  return SQLITE_OK;
-}
-
-#ifdef SQLITE_TEST
-/*
-** Count the number of fullsyncs and normal syncs.  This is used to test
-** that syncs and fullsyncs are occuring at the right times.
-*/
-SQLITE_API int sqlite3_sync_count = 0;
-SQLITE_API int sqlite3_fullsync_count = 0;
-#endif
-
-/*
-** Use the fdatasync() API only if the HAVE_FDATASYNC macro is defined.
-** Otherwise use fsync() in its place.
-*/
-#ifndef HAVE_FDATASYNC
-# define fdatasync fsync
-#endif
-
-/*
-** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not
-** the F_FULLFSYNC macro is defined.  F_FULLFSYNC is currently
-** only available on Mac OS X.  But that could change.
-*/
-#ifdef F_FULLFSYNC
-# define HAVE_FULLFSYNC 1
-#else
-# define HAVE_FULLFSYNC 0
-#endif
-
-
-/*
-** The fsync() system call does not work as advertised on many
-** unix systems.  The following procedure is an attempt to make
-** it work better.
-**
-** The SQLITE_NO_SYNC macro disables all fsync()s.  This is useful
-** for testing when we want to run through the test suite quickly.
-** You are strongly advised *not* to deploy with SQLITE_NO_SYNC
-** enabled, however, since with SQLITE_NO_SYNC enabled, an OS crash
-** or power failure will likely corrupt the database file.
-*/
-static int full_fsync(int fd, int fullSync, int dataOnly){
-  int rc;
-
-  /* The following "ifdef/elif/else/" block has the same structure as
-  ** the one below. It is replicated here solely to avoid cluttering
-  ** up the real code with the UNUSED_PARAMETER() macros.
-  */
-#ifdef SQLITE_NO_SYNC
-  UNUSED_PARAMETER(fd);
-  UNUSED_PARAMETER(fullSync);
-  UNUSED_PARAMETER(dataOnly);
-#elif HAVE_FULLFSYNC
-  UNUSED_PARAMETER(dataOnly);
-#else
-  UNUSED_PARAMETER(fullSync);
-#endif
-
-  /* Record the number of times that we do a normal fsync() and
-  ** FULLSYNC.  This is used during testing to verify that this procedure
-  ** gets called with the correct arguments.
-  */
-#ifdef SQLITE_TEST
-  if( fullSync ) sqlite3_fullsync_count++;
-  sqlite3_sync_count++;
-#endif
-
-  /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
-  ** no-op
-  */
-#ifdef SQLITE_NO_SYNC
-  rc = SQLITE_OK;
-#elif HAVE_FULLFSYNC
-  if( fullSync ){
-    rc = fcntl(fd, F_FULLFSYNC, 0);
-  }else{
-    rc = 1;
-  }
-  /* If the FULLFSYNC failed, fall back to attempting an fsync().
-   * It shouldn't be possible for fullfsync to fail on the local
-   * file system (on OSX), so failure indicates that FULLFSYNC
-   * isn't supported for this file system. So, attempt an fsync
-   * and (for now) ignore the overhead of a superfluous fcntl call.
-   * It'd be better to detect fullfsync support once and avoid
-   * the fcntl call every time sync is called.
-   */
-  if( rc ) rc = fsync(fd);
-
-#else
-  if( dataOnly ){
-    rc = fdatasync(fd);
-    if( IS_VXWORKS && rc==-1 && errno==ENOTSUP ){
-      rc = fsync(fd);
-    }
-  }else{
-    rc = fsync(fd);
-  }
-#endif /* ifdef SQLITE_NO_SYNC elif HAVE_FULLFSYNC */
-
-  if( IS_VXWORKS && rc!= -1 ){
-    rc = 0;
-  }
-  return rc;
-}
-
-/*
-** Make sure all writes to a particular file are committed to disk.
-**
-** If dataOnly==0 then both the file itself and its metadata (file
-** size, access time, etc) are synced.  If dataOnly!=0 then only the
-** file data is synced.
-**
-** Under Unix, also make sure that the directory entry for the file
-** has been created by fsync-ing the directory that contains the file.
-** If we do not do this and we encounter a power failure, the directory
-** entry for the journal might not exist after we reboot.  The next
-** SQLite to access the file will not know that the journal exists (because
-** the directory entry for the journal was never created) and the transaction
-** will not roll back - possibly leading to database corruption.
-*/
-static int unixSync(sqlite3_file *id, int flags){
-  int rc;
-  unixFile *pFile = (unixFile*)id;
-
-  int isDataOnly = (flags&SQLITE_SYNC_DATAONLY);
-  int isFullsync = (flags&0x0F)==SQLITE_SYNC_FULL;
-
-  /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */
-  assert((flags&0x0F)==SQLITE_SYNC_NORMAL
-      || (flags&0x0F)==SQLITE_SYNC_FULL
-  );
-
-  /* Unix cannot, but some systems may return SQLITE_FULL from here. This
-  ** line is to test that doing so does not cause any problems.
-  */
-  SimulateDiskfullError( return SQLITE_FULL );
-
-  assert( pFile );
-  OSTRACE2("SYNC    %-3d\n", pFile->h);
-  rc = full_fsync(pFile->h, isFullsync, isDataOnly);
-  SimulateIOError( rc=1 );
-  if( rc ){
-    return SQLITE_IOERR_FSYNC;
-  }
-  if( pFile->dirfd>=0 ){
-    OSTRACE4("DIRSYNC %-3d (have_fullfsync=%d fullsync=%d)\n", pFile->dirfd,
-            HAVE_FULLFSYNC, isFullsync);
-#ifndef SQLITE_DISABLE_DIRSYNC
-    /* The directory sync is only attempted if full_fsync is
-    ** turned off or unavailable.  If a full_fsync occurred above,
-    ** then the directory sync is superfluous.
-    */
-    if( (!HAVE_FULLFSYNC || !isFullsync) && full_fsync(pFile->dirfd,0,0) ){
-       /*
-       ** We have received multiple reports of fsync() returning
-       ** errors when applied to directories on certain file systems.
-       ** A failed directory sync is not a big deal.  So it seems
-       ** better to ignore the error.  Ticket #1657
-       */
-       /* return SQLITE_IOERR; */
-    }
-#endif
-    close(pFile->dirfd);  /* Only need to sync once, so close the directory */
-    pFile->dirfd = -1;    /* when we are done. */
-  }
-  return SQLITE_OK;
-}
-
-/*
-** Truncate an open file to a specified size
-*/
-static int unixTruncate(sqlite3_file *id, i64 nByte){
-  int rc;
-  assert( id );
-  SimulateIOError( return SQLITE_IOERR_TRUNCATE );
-  rc = ftruncate(((unixFile*)id)->h, (off_t)nByte);
-  if( rc ){
-    return SQLITE_IOERR_TRUNCATE;
-  }else{
-    return SQLITE_OK;
-  }
-}
-
-/*
-** Determine the current size of a file in bytes
-*/
-static int unixFileSize(sqlite3_file *id, i64 *pSize){
-  int rc;
-  struct stat buf;
-  assert( id );
-  rc = fstat(((unixFile*)id)->h, &buf);
-  SimulateIOError( rc=1 );
-  if( rc!=0 ){
-    return SQLITE_IOERR_FSTAT;
-  }
-  *pSize = buf.st_size;
-
-  /* When opening a zero-size database, the findLockInfo() procedure
-  ** writes a single byte into that file in order to work around a bug
-  ** in the OS-X msdos filesystem.  In order to avoid problems with upper
-  ** layers, we need to report this file size as zero even though it is
-  ** really 1.   Ticket #3260.
-  */
-  if( *pSize==1 ) *pSize = 0;
-
-
-  return SQLITE_OK;
-}
-
-/*
-** This routine translates a standard POSIX errno code into something
-** useful to the clients of the sqlite3 functions.  Specifically, it is
-** intended to translate a variety of "try again" errors into SQLITE_BUSY
-** and a variety of "please close the file descriptor NOW" errors into
-** SQLITE_IOERR
-**
-** Errors during initialization of locks, or file system support for locks,
-** should handle ENOLCK, ENOTSUP, EOPNOTSUPP separately.
-*/
-static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) {
-  switch (posixError) {
-  case 0:
-    return SQLITE_OK;
-
-  case EAGAIN:
-  case ETIMEDOUT:
-  case EBUSY:
-  case EINTR:
-  case ENOLCK:
-    /* random NFS retry error, unless during file system support
-     * introspection, in which it actually means what it says */
-    return SQLITE_BUSY;
-
-  case EACCES:
-    /* EACCES is like EAGAIN during locking operations, but not any other time*/
-    if( (sqliteIOErr == SQLITE_IOERR_LOCK) ||
-	(sqliteIOErr == SQLITE_IOERR_UNLOCK) ||
-	(sqliteIOErr == SQLITE_IOERR_RDLOCK) ||
-	(sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ){
-      return SQLITE_BUSY;
-    }
-    /* else fall through */
-  case EPERM:
-    return SQLITE_PERM;
-
-  case EDEADLK:
-    return SQLITE_IOERR_BLOCKED;
-
-#if EOPNOTSUPP!=ENOTSUP
-  case EOPNOTSUPP:
-    /* something went terribly awry, unless during file system support
-     * introspection, in which it actually means what it says */
-#endif
-#ifdef ENOTSUP
-  case ENOTSUP:
-    /* invalid fd, unless during file system support introspection, in which
-     * it actually means what it says */
-#endif
-  case EIO:
-  case EBADF:
-  case EINVAL:
-  case ENOTCONN:
-  case ENODEV:
-  case ENXIO:
-  case ENOENT:
-  case ESTALE:
-  case ENOSYS:
-    /* these should force the client to close the file and reconnect */
-
-  default:
-    return sqliteIOErr;
-  }
-}
+#endif /* SQLITE_THREADSAFE */
+
 
 /*
 ** This routine checks if there is a RESERVED lock held on the specified
 ** file by this or any other process. If such a lock is held, set *pResOut
@@ -23011,9 +22690,9 @@
 
   SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
 
   assert( pFile );
-  enterMutex(); /* Because pFile->pLock is shared across threads */
+  unixEnterMutex(); /* Because pFile->pLock is shared across threads */
 
   /* Check if a thread in this process holds such a lock */
   if( pFile->pLock->locktype>SHARED_LOCK ){
     reserved = 1;
@@ -23035,9 +22714,9 @@
       reserved = 1;
     }
   }
 
-  leaveMutex();
+  unixLeaveMutex();
   OSTRACE4("TEST WR-LOCK %d %d %d\n", pFile->h, rc, reserved);
 
   *pResOut = reserved;
   return rc;
@@ -23107,9 +22786,9 @@
   ** even if the locking primitive used is always a write-lock.
   */
   int rc = SQLITE_OK;
   unixFile *pFile = (unixFile*)id;
-  struct lockInfo *pLock = pFile->pLock;
+  struct unixLockInfo *pLock = pFile->pLock;
   struct flock lock;
   int s;
 
   assert( pFile );
@@ -23118,9 +22797,9 @@
       locktypeName(pLock->locktype), pLock->cnt , getpid());
 
   /* If there is already a lock of this type or more restrictive on the
   ** unixFile, do nothing. Don't use the end_lock: exit path, as
-  ** enterMutex() hasn't been called yet.
+  ** unixEnterMutex() hasn't been called yet.
   */
   if( pFile->locktype>=locktype ){
     OSTRACE3("LOCK    %d %s ok (already held)\n", pFile->h,
             locktypeName(locktype));
@@ -23134,15 +22813,15 @@
   assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
 
   /* This mutex is needed because pFile->pLock is shared across threads
   */
-  enterMutex();
+  unixEnterMutex();
 
   /* Make sure the current thread owns the pFile.
   */
   rc = transferOwnership(pFile);
   if( rc!=SQLITE_OK ){
-    leaveMutex();
+    unixLeaveMutex();
     return rc;
   }
   pLock = pFile->pLock;
 
@@ -23275,9 +22954,9 @@
     pLock->locktype = PENDING_LOCK;
   }
 
 end_lock:
-  leaveMutex();
+  unixLeaveMutex();
   OSTRACE4("LOCK    %d %s %s\n", pFile->h, locktypeName(locktype),
       rc==SQLITE_OK ? "ok" : "failed");
   return rc;
 }
@@ -23289,9 +22968,9 @@
 ** If the locking level of the file descriptor is already at or below
 ** the requested locking level, this routine is a no-op.
 */
 static int unixUnlock(sqlite3_file *id, int locktype){
-  struct lockInfo *pLock;
+  struct unixLockInfo *pLock;
   struct flock lock;
   int rc = SQLITE_OK;
   unixFile *pFile = (unixFile*)id;
   int h;
@@ -23306,9 +22985,9 @@
   }
   if( CHECK_THREADID(pFile) ){
     return SQLITE_MISUSE;
   }
-  enterMutex();
+  unixEnterMutex();
   h = pFile->h;
   pLock = pFile->pLock;
   assert( pLock->cnt!=0 );
   if( pFile->locktype>SHARED_LOCK ){
@@ -23345,9 +23024,9 @@
 			goto end_unlock;
     }
   }
   if( locktype==NO_LOCK ){
-    struct openCnt *pOpen;
+    struct unixOpenCnt *pOpen;
 
     /* Decrement the shared lock counter.  Release the lock using an
     ** OS call only when all threads in this same process have released
     ** the lock.
@@ -23383,19 +23062,30 @@
       assert( pOpen->nLock>=0 );
       if( pOpen->nLock==0 && pOpen->nPending>0 ){
         int i;
         for(i=0; i<pOpen->nPending; i++){
-          close(pOpen->aPending[i]);
-        }
-        sqlite3_free(pOpen->aPending);
-        pOpen->nPending = 0;
-        pOpen->aPending = 0;
+          /* close pending fds, but if closing fails don't free the array
+          ** assign -1 to the successfully closed descriptors and record the
+          ** error.  The next attempt to unlock will try again. */
+          if( pOpen->aPending[i] < 0 ) continue;
+          if( close(pOpen->aPending[i]) ){
+            pFile->lastErrno = errno;
+            rc = SQLITE_IOERR_CLOSE;
+          }else{
+            pOpen->aPending[i] = -1;
+          }
+        }
+        if( rc==SQLITE_OK ){
+          sqlite3_free(pOpen->aPending);
+          pOpen->nPending = 0;
+          pOpen->aPending = 0;
+        }
       }
     }
   }
 
 end_unlock:
-  leaveMutex();
+  unixLeaveMutex();
   if( rc==SQLITE_OK ) pFile->locktype = locktype;
   return rc;
 }
 
@@ -23403,35 +23093,39 @@
 ** This function performs the parts of the "close file" operation
 ** common to all locking schemes. It closes the directory and file
 ** handles, if they are valid, and sets all fields of the unixFile
 ** structure to 0.
+**
+** It is *not* necessary to hold the mutex when this routine is called,
+** even on VxWorks.  A mutex will be acquired on VxWorks by the
+** vxworksReleaseFileId() routine.
 */
 static int closeUnixFile(sqlite3_file *id){
   unixFile *pFile = (unixFile*)id;
   if( pFile ){
     if( pFile->dirfd>=0 ){
-      close(pFile->dirfd);
+      int err = close(pFile->dirfd);
+      if( err ){
+        pFile->lastErrno = errno;
+        return SQLITE_IOERR_DIR_CLOSE;
+      }else{
+        pFile->dirfd=-1;
+      }
     }
     if( pFile->h>=0 ){
-      close(pFile->h);
-    }
-#if IS_VXWORKS
-    if( pFile->isDelete && pFile->zRealpath ){
-      unlink(pFile->zRealpath);
-    }
-    if( pFile->zRealpath ){
-      HashElem *pElem;
-      int n = strlen(pFile->zRealpath) + 1;
-      pElem = sqlite3HashFindElem(&nameHash, pFile->zRealpath, n);
-      if( pElem ){
-        long cnt = (long)pElem->data;
-        cnt--;
-        if( cnt==0 ){
-          sqlite3HashInsert(&nameHash, pFile->zRealpath, n, 0);
-        }else{
-          pElem->data = (void*)cnt;
-        }
-      }
+      int err = close(pFile->h);
+      if( err ){
+        pFile->lastErrno = errno;
+        return SQLITE_IOERR_CLOSE;
+      }
+    }
+#if OS_VXWORKS
+    if( pFile->pId ){
+      if( pFile->isDelete ){
+        unlink(pFile->pId->zCanonicalName);
+      }
+      vxworksReleaseFileId(pFile->pId);
+      pFile->pId = 0;
     }
 #endif
     OSTRACE2("CLOSE   %-3d\n", pFile->h);
     OpenCounter(-1);
@@ -23443,20 +23137,21 @@
 /*
 ** Close a file.
 */
 static int unixClose(sqlite3_file *id){
+  int rc = SQLITE_OK;
   if( id ){
     unixFile *pFile = (unixFile *)id;
     unixUnlock(id, NO_LOCK);
-    enterMutex();
+    unixEnterMutex();
     if( pFile->pOpen && pFile->pOpen->nLock ){
       /* If there are outstanding locks, do not actually close the file just
       ** yet because that would clear those locks.  Instead, add the file
       ** descriptor to pOpen->aPending.  It will be automatically closed when
       ** the last lock is cleared.
       */
       int *aNew;
-      struct openCnt *pOpen = pFile->pOpen;
+      struct unixOpenCnt *pOpen = pFile->pOpen;
       aNew = sqlite3_realloc(pOpen->aPending, (pOpen->nPending+1)*sizeof(int) );
       if( aNew==0 ){
         /* If a malloc fails, just leak the file descriptor */
       }else{
@@ -23467,246 +23162,188 @@
       }
     }
     releaseLockInfo(pFile->pLock);
     releaseOpenCnt(pFile->pOpen);
-    closeUnixFile(id);
-    leaveMutex();
-  }
-  return SQLITE_OK;
-}
-
-
-#if SQLITE_ENABLE_LOCKING_STYLE
-
-#if !IS_VXWORKS
-#pragma mark AFP Support
-
-/*
- ** The afpLockingContext structure contains all afp lock specific state
- */
-typedef struct afpLockingContext afpLockingContext;
-struct afpLockingContext {
-  unsigned long long sharedLockByte;
-  const char *filePath;
-};
-
-struct ByteRangeLockPB2
-{
-  unsigned long long offset;        /* offset to first byte to lock */
-  unsigned long long length;        /* nbr of bytes to lock */
-  unsigned long long retRangeStart; /* nbr of 1st byte locked if successful */
-  unsigned char unLockFlag;         /* 1 = unlock, 0 = lock */
-  unsigned char startEndFlag;       /* 1=rel to end of fork, 0=rel to start */
-  int fd;                           /* file desc to assoc this lock with */
-};
-
-#define afpfsByteRangeLock2FSCTL        _IOWR('z', 23, struct ByteRangeLockPB2)
-
-/*
- ** Return SQLITE_OK on success, SQLITE_BUSY on failure.
- */
-static int _AFPFSSetLock(
-  const char *path,
-  unixFile *pFile,
-  unsigned long long offset,
-  unsigned long long length,
-  int setLockFlag
-){
-  struct ByteRangeLockPB2       pb;
-  int                     err;
-
-  pb.unLockFlag = setLockFlag ? 0 : 1;
-  pb.startEndFlag = 0;
-  pb.offset = offset;
-  pb.length = length;
-  pb.fd = pFile->h;
-  OSTRACE5("AFPLOCK setting lock %s for %d in range %llx:%llx\n",
-    (setLockFlag?"ON":"OFF"), pFile->h, offset, length);
-  err = fsctl(path, afpfsByteRangeLock2FSCTL, &pb, 0);
-  if ( err==-1 ) {
-    int rc;
-    int tErrno = errno;
-    OSTRACE4("AFPLOCK failed to fsctl() '%s' %d %s\n", path, tErrno, strerror(tErrno));
-    rc = sqliteErrorFromPosixError(tErrno, setLockFlag ? SQLITE_IOERR_LOCK : SQLITE_IOERR_UNLOCK); /* error */
-    if( IS_LOCK_ERROR(rc) ){
-      pFile->lastErrno = tErrno;
-    }
-    return rc;
-  } else {
-    return SQLITE_OK;
-  }
-}
-
-/* AFP-style reserved lock checking following the behavior of
-** unixCheckReservedLock, see the unixCheckReservedLock function comments */
-static int afpCheckReservedLock(sqlite3_file *id, int *pResOut){
+    rc = closeUnixFile(id);
+    unixLeaveMutex();
+  }
+  return rc;
+}
+
+/************** End of the posix advisory lock implementation *****************
+******************************************************************************/
+
+/******************************************************************************
+****************************** No-op Locking **********************************
+**
+** Of the various locking implementations available, this is by far the
+** simplest:  locking is ignored.  No attempt is made to lock the database
+** file for reading or writing.
+**
+** This locking mode is appropriate for use on read-only databases
+** (ex: databases that are burned into CD-ROM, for example.)  It can
+** also be used if the application employs some external mechanism to
+** prevent simultaneous access of the same database by two or more
+** database connections.  But there is a serious risk of database
+** corruption if this locking mode is used in situations where multiple
+** database connections are accessing the same database file at the same
+** time and one or more of those connections are writing.
+*/
+
+static int nolockCheckReservedLock(sqlite3_file *NotUsed, int *pResOut){
+  UNUSED_PARAMETER(NotUsed);
+  *pResOut = 0;
+  return SQLITE_OK;
+}
+static int nolockLock(sqlite3_file *NotUsed, int NotUsed2){
+  UNUSED_PARAMETER2(NotUsed, NotUsed2);
+  return SQLITE_OK;
+}
+static int nolockUnlock(sqlite3_file *NotUsed, int NotUsed2){
+  UNUSED_PARAMETER2(NotUsed, NotUsed2);
+  return SQLITE_OK;
+}
+
+/*
+** Close the file.
+*/
+static int nolockClose(sqlite3_file *id) {
+  return closeUnixFile(id);
+}
+
+/******************* End of the no-op lock implementation *********************
+******************************************************************************/
+
+/******************************************************************************
+************************* Begin dot-file Locking ******************************
+**
+** The dotfile locking implementation uses the existing of separate lock
+** files in order to control access to the database.  This works on just
+** about every filesystem imaginable.  But there are serious downsides:
+**
+**    (1)  There is zero concurrency.  A single reader blocks all other
+**         connections from reading or writing the database.
+**
+**    (2)  An application crash or power loss can leave stale lock files
+**         sitting around that need to be cleared manually.
+**
+** Nevertheless, a dotlock is an appropriate locking mode for use if no
+** other locking strategy is available.
+**
+** Dotfile locking works by creating a file in the same directory as the
+** database and with the same name but with a ".lock" extension added.
+** The existance of a lock file implies an EXCLUSIVE lock.  All other lock
+** types (SHARED, RESERVED, PENDING) are mapped into EXCLUSIVE.
+*/
+
+/*
+** The file suffix added to the data base filename in order to create the
+** lock file.
+*/
+#define DOTLOCK_SUFFIX ".lock"
+
+/*
+** This routine checks if there is a RESERVED lock held on the specified
+** file by this or any other process. If such a lock is held, set *pResOut
+** to a non-zero value otherwise *pResOut is set to zero.  The return value
+** is set to SQLITE_OK unless an I/O error occurs during lock checking.
+**
+** In dotfile locking, either a lock exists or it does not.  So in this
+** variation of CheckReservedLock(), *pResOut is set to true if any lock
+** is held on the file and false if the file is unlocked.
+*/
+static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) {
   int rc = SQLITE_OK;
   int reserved = 0;
   unixFile *pFile = (unixFile*)id;
 
   SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
 
   assert( pFile );
-  afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
 
   /* Check if a thread in this process holds such a lock */
   if( pFile->locktype>SHARED_LOCK ){
+    /* Either this connection or some other connection in the same process
+    ** holds a lock on the file.  No need to check further. */
     reserved = 1;
-  }
-
-  /* Otherwise see if some other process holds it.
-   */
-  if( !reserved ){
-    /* lock the RESERVED byte */
-    int lrc = _AFPFSSetLock(context->filePath, pFile, RESERVED_BYTE, 1,1);
-    if( SQLITE_OK==lrc ){
-      /* if we succeeded in taking the reserved lock, unlock it to restore
-      ** the original state */
-      lrc = _AFPFSSetLock(context->filePath, pFile, RESERVED_BYTE, 1, 0);
-    } else {
-      /* if we failed to get the lock then someone else must have it */
-      reserved = 1;
-    }
-    if( IS_LOCK_ERROR(lrc) ){
-      rc=lrc;
-    }
-  }
-
-  OSTRACE4("TEST WR-LOCK %d %d %d\n", pFile->h, rc, reserved);
-
+  }else{
+    /* The lock is held if and only if the lockfile exists */
+    const char *zLockFile = (const char*)pFile->lockingContext;
+    reserved = access(zLockFile, 0)==0;
+  }
+  OSTRACE4("TEST WR-LOCK %d %d %d\n", pFile->h, rc, reserved);
   *pResOut = reserved;
   return rc;
 }
 
-/* AFP-style locking following the behavior of unixLock, see the unixLock
-** function comments for details of lock management. */
-static int afpLock(sqlite3_file *id, int locktype){
-  int rc = SQLITE_OK;
-  unixFile *pFile = (unixFile*)id;
-  afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
-
-  assert( pFile );
-  OSTRACE5("LOCK    %d %s was %s pid=%d\n", pFile->h,
-         locktypeName(locktype), locktypeName(pFile->locktype), getpid());
-
-  /* If there is already a lock of this type or more restrictive on the
-  ** unixFile, do nothing. Don't use the afp_end_lock: exit path, as
-  ** enterMutex() hasn't been called yet.
-  */
-  if( pFile->locktype>=locktype ){
-    OSTRACE3("LOCK    %d %s ok (already held)\n", pFile->h,
-           locktypeName(locktype));
-    return SQLITE_OK;
-  }
-
-  /* Make sure the locking sequence is correct
-  */
-  assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
-  assert( locktype!=PENDING_LOCK );
-  assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
-
-  /* This mutex is needed because pFile->pLock is shared across threads
-  */
-  enterMutex();
-
-  /* Make sure the current thread owns the pFile.
-  */
-  rc = transferOwnership(pFile);
-  if( rc!=SQLITE_OK ){
-    leaveMutex();
-    return rc;
-  }
-
-  /* A PENDING lock is needed before acquiring a SHARED lock and before
-  ** acquiring an EXCLUSIVE lock.  For the SHARED lock, the PENDING will
-  ** be released.
-  */
-  if( locktype==SHARED_LOCK
-      || (locktype==EXCLUSIVE_LOCK && pFile->locktype<PENDING_LOCK)
-  ){
-    int failed;
-    failed = _AFPFSSetLock(context->filePath, pFile, PENDING_BYTE, 1, 1);
-    if (failed) {
-      rc = failed;
-      goto afp_end_lock;
-    }
-  }
-
-  /* If control gets to this point, then actually go ahead and make
-  ** operating system calls for the specified lock.
-  */
-  if( locktype==SHARED_LOCK ){
-    int lk, lrc1, lrc2, lrc1Errno;
-
-    /* Now get the read-lock SHARED_LOCK */
-    /* note that the quality of the randomness doesn't matter that much */
-    lk = random();
-    context->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);
-    lrc1 = _AFPFSSetLock(context->filePath, pFile,
-          SHARED_FIRST+context->sharedLockByte, 1, 1);
-    if( IS_LOCK_ERROR(lrc1) ){
-      lrc1Errno = pFile->lastErrno;
-    }
-    /* Drop the temporary PENDING lock */
-    lrc2 = _AFPFSSetLock(context->filePath, pFile, PENDING_BYTE, 1, 0);
-
-    if( IS_LOCK_ERROR(lrc1) ) {
-      pFile->lastErrno = lrc1Errno;
-      rc = lrc1;
-      goto afp_end_lock;
-    } else if( IS_LOCK_ERROR(lrc2) ){
-      rc = lrc2;
-      goto afp_end_lock;
-    } else if( lrc1 != SQLITE_OK ) {
-      rc = lrc1;
+/*
+** Lock the file with the lock specified by parameter locktype - one
+** of the following:
+**
+**     (1) SHARED_LOCK
+**     (2) RESERVED_LOCK
+**     (3) PENDING_LOCK
+**     (4) EXCLUSIVE_LOCK
+**
+** Sometimes when requesting one lock state, additional lock states
+** are inserted in between.  The locking might fail on one of the later
+** transitions leaving the lock state different from what it started but
+** still short of its goal.  The following chart shows the allowed
+** transitions and the inserted intermediate states:
+**
+**    UNLOCKED -> SHARED
+**    SHARED -> RESERVED
+**    SHARED -> (PENDING) -> EXCLUSIVE
+**    RESERVED -> (PENDING) -> EXCLUSIVE
+**    PENDING -> EXCLUSIVE
+**
+** This routine will only increase a lock.  Use the sqlite3OsUnlock()
+** routine to lower a locking level.
+**
+** With dotfile locking, we really only support state (4): EXCLUSIVE.
+** But we track the other locking levels internally.
+*/
+static int dotlockLock(sqlite3_file *id, int locktype) {
+  unixFile *pFile = (unixFile*)id;
+  int fd;
+  char *zLockFile = (char *)pFile->lockingContext;
+  int rc = SQLITE_OK;
+
+
+  /* If we have any lock, then the lock file already exists.  All we have
+  ** to do is adjust our internal record of the lock level.
+  */
+  if( pFile->locktype > NO_LOCK ){
+    pFile->locktype = locktype;
+#if !OS_VXWORKS
+    /* Always update the timestamp on the old file */
+    utimes(zLockFile, NULL);
+#endif
+    return SQLITE_OK;
+  }
+
+  /* grab an exclusive lock */
+  fd = open(zLockFile,O_RDONLY|O_CREAT|O_EXCL,0600);
+  if( fd<0 ){
+    /* failed to open/create the file, someone else may have stolen the lock */
+    int tErrno = errno;
+    if( EEXIST == tErrno ){
+      rc = SQLITE_BUSY;
     } else {
-      pFile->locktype = SHARED_LOCK;
-    }
-  }else{
-    /* The request was for a RESERVED or EXCLUSIVE lock.  It is
-    ** assumed that there is a SHARED or greater lock on the file
-    ** already.
-    */
-    int failed = 0;
-    assert( 0!=pFile->locktype );
-    if (locktype >= RESERVED_LOCK && pFile->locktype < RESERVED_LOCK) {
-        /* Acquire a RESERVED lock */
-        failed = _AFPFSSetLock(context->filePath, pFile, RESERVED_BYTE, 1,1);
-    }
-    if (!failed && locktype == EXCLUSIVE_LOCK) {
-      /* Acquire an EXCLUSIVE lock */
-
-      /* Remove the shared lock before trying the range.  we'll need to
-      ** reestablish the shared lock if we can't get the  afpUnlock
-      */
-      if (!(failed = _AFPFSSetLock(context->filePath, pFile, SHARED_FIRST +
-                         context->sharedLockByte, 1, 0))) {
-        /* now attemmpt to get the exclusive lock range */
-        failed = _AFPFSSetLock(context->filePath, pFile, SHARED_FIRST,
-                               SHARED_SIZE, 1);
-        if (failed && (failed = _AFPFSSetLock(context->filePath, pFile,
-                       SHARED_FIRST + context->sharedLockByte, 1, 1))) {
-          rc = failed;
-        }
-      } else {
-        rc = failed;
-      }
-    }
-    if( failed ){
-      rc = failed;
-    }
-  }
-
-  if( rc==SQLITE_OK ){
-    pFile->locktype = locktype;
-  }else if( locktype==EXCLUSIVE_LOCK ){
-    pFile->locktype = PENDING_LOCK;
-  }
-
-afp_end_lock:
-  leaveMutex();
-  OSTRACE4("LOCK    %d %s %s\n", pFile->h, locktypeName(locktype),
-         rc==SQLITE_OK ? "ok" : "failed");
+      rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
+      if( IS_LOCK_ERROR(rc) ){
+        pFile->lastErrno = tErrno;
+      }
+    }
+    return rc;
+  }
+  if( close(fd) ){
+    pFile->lastErrno = errno;
+    rc = SQLITE_IOERR_CLOSE;
+  }
+
+  /* got it, set the type and return ok */
+  pFile->locktype = locktype;
   return rc;
 }
 
 /*
@@ -23714,96 +23351,88 @@
 ** must be either NO_LOCK or SHARED_LOCK.
 **
 ** If the locking level of the file descriptor is already at or below
 ** the requested locking level, this routine is a no-op.
-*/
-static int afpUnlock(sqlite3_file *id, int locktype) {
-  int rc = SQLITE_OK;
-  unixFile *pFile = (unixFile*)id;
-  afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
+**
+** When the locking level reaches NO_LOCK, delete the lock file.
+*/
+static int dotlockUnlock(sqlite3_file *id, int locktype) {
+  unixFile *pFile = (unixFile*)id;
+  char *zLockFile = (char *)pFile->lockingContext;
 
   assert( pFile );
   OSTRACE5("UNLOCK  %d %d was %d pid=%d\n", pFile->h, locktype,
-         pFile->locktype, getpid());
-
+	   pFile->locktype, getpid());
   assert( locktype<=SHARED_LOCK );
-  if( pFile->locktype<=locktype ){
-    return SQLITE_OK;
-  }
-  if( CHECK_THREADID(pFile) ){
-    return SQLITE_MISUSE;
-  }
-  enterMutex();
-  int failed = SQLITE_OK;
-  if( pFile->locktype>SHARED_LOCK ){
-    if( locktype==SHARED_LOCK ){
-
-      /* unlock the exclusive range - then re-establish the shared lock */
-      if (pFile->locktype==EXCLUSIVE_LOCK) {
-        failed = _AFPFSSetLock(context->filePath, pFile, SHARED_FIRST,
-                                 SHARED_SIZE, 0);
-        if (!failed) {
-          /* successfully removed the exclusive lock */
-          if ((failed = _AFPFSSetLock(context->filePath, pFile, SHARED_FIRST+
-                            context->sharedLockByte, 1, 1))) {
-            /* failed to re-establish our shared lock */
-            rc = failed;
-          }
-        } else {
-          rc = failed;
-        }
-      }
-    }
-    if (rc == SQLITE_OK && pFile->locktype>=PENDING_LOCK) {
-      if ((failed = _AFPFSSetLock(context->filePath, pFile,
-                                  PENDING_BYTE, 1, 0))){
-        /* failed to release the pending lock */
-        rc = failed;
-      }
-    }
-    if (rc == SQLITE_OK && pFile->locktype>=RESERVED_LOCK) {
-      if ((failed = _AFPFSSetLock(context->filePath, pFile,
-                                  RESERVED_BYTE, 1, 0))) {
-        /* failed to release the reserved lock */
-        rc = failed;
-      }
-    }
-  }
-  if( locktype==NO_LOCK ){
-    int failed = _AFPFSSetLock(context->filePath, pFile,
-                               SHARED_FIRST + context->sharedLockByte, 1, 0);
-    if (failed) {
-      rc = failed;
-    }
-  }
-  if (rc == SQLITE_OK)
-    pFile->locktype = locktype;
-  leaveMutex();
-  return rc;
-}
-
-/*
-** Close a file & cleanup AFP specific locking context
-*/
-static int afpClose(sqlite3_file *id) {
+
+  /* no-op if possible */
+  if( pFile->locktype==locktype ){
+    return SQLITE_OK;
+  }
+
+  /* To downgrade to shared, simply update our internal notion of the
+  ** lock state.  No need to mess with the file on disk.
+  */
+  if( locktype==SHARED_LOCK ){
+    pFile->locktype = SHARED_LOCK;
+    return SQLITE_OK;
+  }
+
+  /* To fully unlock the database, delete the lock file */
+  assert( locktype==NO_LOCK );
+  if( unlink(zLockFile) ){
+    int rc, tErrno = errno;
+    if( ENOENT != tErrno ){
+      rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
+    }
+    if( IS_LOCK_ERROR(rc) ){
+      pFile->lastErrno = tErrno;
+    }
+    return rc;
+  }
+  pFile->locktype = NO_LOCK;
+  return SQLITE_OK;
+}
+
+/*
+** Close a file.  Make sure the lock has been released before closing.
+*/
+static int dotlockClose(sqlite3_file *id) {
+  int rc;
   if( id ){
     unixFile *pFile = (unixFile*)id;
-    afpUnlock(id, NO_LOCK);
+    dotlockUnlock(id, NO_LOCK);
     sqlite3_free(pFile->lockingContext);
   }
-  return closeUnixFile(id);
-}
-
-
-#pragma mark flock() style locking
-
-/*
-** The flockLockingContext is not used
-*/
-typedef void flockLockingContext;
-
-/* flock-style reserved lock checking following the behavior of
- ** unixCheckReservedLock, see the unixCheckReservedLock function comments */
+  rc = closeUnixFile(id);
+  return rc;
+}
+/****************** End of the dot-file lock implementation *******************
+******************************************************************************/
+
+/******************************************************************************
+************************** Begin flock Locking ********************************
+**
+** Use the flock() system call to do file locking.
+**
+** flock() locking is like dot-file locking in that the various
+** fine-grain locking levels supported by SQLite are collapsed into
+** a single exclusive lock.  In other words, SHARED, RESERVED, and
+** PENDING locks are the same thing as an EXCLUSIVE lock.  SQLite
+** still works when you do this, but concurrency is reduced since
+** only a single process can be reading the database at a time.
+**
+** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off or if
+** compiling for VXWORKS.
+*/
+#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
+
+/*
+** This routine checks if there is a RESERVED lock held on the specified
+** file by this or any other process. If such a lock is held, set *pResOut
+** to a non-zero value otherwise *pResOut is set to zero.  The return value
+** is set to SQLITE_OK unless an I/O error occurs during lock checking.
+*/
 static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){
   int rc = SQLITE_OK;
   int reserved = 0;
   unixFile *pFile = (unixFile*)id;
@@ -23845,12 +23474,47 @@
     }
   }
   OSTRACE4("TEST WR-LOCK %d %d %d\n", pFile->h, rc, reserved);
 
+#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
+  if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){
+    rc = SQLITE_OK;
+    reserved=1;
+  }
+#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
   *pResOut = reserved;
   return rc;
 }
 
+/*
+** Lock the file with the lock specified by parameter locktype - one
+** of the following:
+**
+**     (1) SHARED_LOCK
+**     (2) RESERVED_LOCK
+**     (3) PENDING_LOCK
+**     (4) EXCLUSIVE_LOCK
+**
+** Sometimes when requesting one lock state, additional lock states
+** are inserted in between.  The locking might fail on one of the later
+** transitions leaving the lock state different from what it started but
+** still short of its goal.  The following chart shows the allowed
+** transitions and the inserted intermediate states:
+**
+**    UNLOCKED -> SHARED
+**    SHARED -> RESERVED
+**    SHARED -> (PENDING) -> EXCLUSIVE
+**    RESERVED -> (PENDING) -> EXCLUSIVE
+**    PENDING -> EXCLUSIVE
+**
+** flock() only really support EXCLUSIVE locks.  We track intermediate
+** lock states in the sqlite3_file structure, but all locks SHARED or
+** above are really EXCLUSIVE locks and exclude all other processes from
+** access the file.
+**
+** This routine will only increase a lock.  Use the sqlite3OsUnlock()
+** routine to lower a locking level.
+*/
 static int flockLock(sqlite3_file *id, int locktype) {
   int rc = SQLITE_OK;
   unixFile *pFile = (unixFile*)id;
 
@@ -23877,11 +23541,24 @@
     pFile->locktype = locktype;
   }
   OSTRACE4("LOCK    %d %s %s\n", pFile->h, locktypeName(locktype),
            rc==SQLITE_OK ? "ok" : "failed");
-  return rc;
-}
-
+#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
+  if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){
+    rc = SQLITE_BUSY;
+  }
+#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
+  return rc;
+}
+
+
+/*
+** Lower the locking level on file descriptor pFile to locktype.  locktype
+** must be either NO_LOCK or SHARED_LOCK.
+**
+** If the locking level of the file descriptor is already at or below
+** the requested locking level, this routine is a no-op.
+*/
 static int flockUnlock(sqlite3_file *id, int locktype) {
   unixFile *pFile = (unixFile*)id;
 
   assert( pFile );
@@ -23907,8 +23584,14 @@
     r = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
     if( IS_LOCK_ERROR(r) ){
       pFile->lastErrno = tErrno;
     }
+#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
+    if( (r & SQLITE_IOERR) == SQLITE_IOERR ){
+      r = SQLITE_BUSY;
+    }
+#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
+
     return r;
   } else {
     pFile->locktype = NO_LOCK;
     return SQLITE_OK;
@@ -23924,158 +23607,32 @@
   }
   return closeUnixFile(id);
 }
 
-#endif /* !IS_VXWORKS */
-
-#pragma mark Old-School .lock file based locking
-
-/* Dotlock-style reserved lock checking following the behavior of
-** unixCheckReservedLock, see the unixCheckReservedLock function comments */
-static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) {
-  int rc = SQLITE_OK;
-  int reserved = 0;
-  unixFile *pFile = (unixFile*)id;
-
-  SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
-
-  assert( pFile );
-
-  /* Check if a thread in this process holds such a lock */
-  if( pFile->locktype>SHARED_LOCK ){
-    reserved = 1;
-  }
-
-  /* Otherwise see if some other process holds it. */
-  if( !reserved ){
-    char *zLockFile = (char *)pFile->lockingContext;
-    struct stat statBuf;
-
-    if( lstat(zLockFile, &statBuf)==0 ){
-      /* file exists, someone else has the lock */
-      reserved = 1;
-    }else{
-      /* file does not exist, we could have it if we want it */
-      int tErrno = errno;
-      if( ENOENT != tErrno ){
-        rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK);
-        pFile->lastErrno = tErrno;
-      }
-    }
-  }
-  OSTRACE4("TEST WR-LOCK %d %d %d\n", pFile->h, rc, reserved);
-
-  *pResOut = reserved;
-  return rc;
-}
-
-static int dotlockLock(sqlite3_file *id, int locktype) {
-  unixFile *pFile = (unixFile*)id;
-  int fd;
-  char *zLockFile = (char *)pFile->lockingContext;
-  int rc=SQLITE_OK;
-
-  /* if we already have a lock, it is exclusive.
-  ** Just adjust level and punt on outta here. */
-  if (pFile->locktype > NO_LOCK) {
-    pFile->locktype = locktype;
-#if !IS_VXWORKS
-    /* Always update the timestamp on the old file */
-    utimes(zLockFile, NULL);
-#endif
-    rc = SQLITE_OK;
-    goto dotlock_end_lock;
-  }
-
-  /* check to see if lock file already exists */
-  struct stat statBuf;
-  if (lstat(zLockFile,&statBuf) == 0){
-    rc = SQLITE_BUSY; /* it does, busy */
-    goto dotlock_end_lock;
-  }
-
-  /* grab an exclusive lock */
-  fd = open(zLockFile,O_RDONLY|O_CREAT|O_EXCL,0600);
-  if( fd<0 ){
-    /* failed to open/create the file, someone else may have stolen the lock */
-    int tErrno = errno;
-    if( EEXIST == tErrno ){
-      rc = SQLITE_BUSY;
-    } else {
-      rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
-      if( IS_LOCK_ERROR(rc) ){
-	pFile->lastErrno = tErrno;
-      }
-    }
-    goto dotlock_end_lock;
-  }
-  close(fd);
-
-  /* got it, set the type and return ok */
-  pFile->locktype = locktype;
-
- dotlock_end_lock:
-  return rc;
-}
-
-static int dotlockUnlock(sqlite3_file *id, int locktype) {
-  unixFile *pFile = (unixFile*)id;
-  char *zLockFile = (char *)pFile->lockingContext;
-
-  assert( pFile );
-  OSTRACE5("UNLOCK  %d %d was %d pid=%d\n", pFile->h, locktype,
-	   pFile->locktype, getpid());
-  assert( locktype<=SHARED_LOCK );
-
-  /* no-op if possible */
-  if( pFile->locktype==locktype ){
-    return SQLITE_OK;
-  }
-
-  /* shared can just be set because we always have an exclusive */
-  if (locktype==SHARED_LOCK) {
-    pFile->locktype = locktype;
-    return SQLITE_OK;
-  }
-
-  /* no, really, unlock. */
-  if (unlink(zLockFile) ) {
-    int rc, tErrno = errno;
-    if( ENOENT != tErrno ){
-      rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
-    }
-    if( IS_LOCK_ERROR(rc) ){
-      pFile->lastErrno = tErrno;
-    }
-    return rc;
-  }
-  pFile->locktype = NO_LOCK;
-  return SQLITE_OK;
-}
-
-/*
- ** Close a file.
- */
-static int dotlockClose(sqlite3_file *id) {
-  int rc;
-  if( id ){
-    unixFile *pFile = (unixFile*)id;
-    dotlockUnlock(id, NO_LOCK);
-    sqlite3_free(pFile->lockingContext);
-  }
-  if( IS_VXWORKS ) enterMutex();
-  rc = closeUnixFile(id);
-  if( IS_VXWORKS ) leaveMutex();
-  return rc;
-}
-
-#if IS_VXWORKS
-
-#pragma mark POSIX/vxWorks named semaphore based locking
-
-/* Namedsem-style reserved lock checking following the behavior of
-** unixCheckReservedLock, see the unixCheckReservedLock function comments */
-static int namedsemCheckReservedLock(sqlite3_file *id, int *pResOut) {
+#endif /* SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORK */
+
+/******************* End of the flock lock implementation *********************
+******************************************************************************/
+
+/******************************************************************************
+************************ Begin Named Semaphore Locking ************************
+**
+** Named semaphore locking is only supported on VxWorks.
+**
+** Semaphore locking is like dot-lock and flock in that it really only
+** supports EXCLUSIVE locking.  Only a single process can read or write
+** the database file at a time.  This reduces potential concurrency, but
+** makes the lock implementation much easier.
+*/
+#if OS_VXWORKS
+
+/*
+** This routine checks if there is a RESERVED lock held on the specified
+** file by this or any other process. If such a lock is held, set *pResOut
+** to a non-zero value otherwise *pResOut is set to zero.  The return value
+** is set to SQLITE_OK unless an I/O error occurs during lock checking.
+*/
+static int semCheckReservedLock(sqlite3_file *id, int *pResOut) {
   int rc = SQLITE_OK;
   int reserved = 0;
   unixFile *pFile = (unixFile*)id;
 
@@ -24098,10 +23655,10 @@
       if( EAGAIN != tErrno ){
         rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK);
         pFile->lastErrno = tErrno;
       } else {
-	/* someone else has the lock when we are in NO_LOCK */
-	reserved = (pFile->locktype < SHARED_LOCK);
+        /* someone else has the lock when we are in NO_LOCK */
+        reserved = (pFile->locktype < SHARED_LOCK);
       }
     }else{
       /* we could have it if we want it */
       sem_post(pSem);
@@ -24112,9 +23669,38 @@
   *pResOut = reserved;
   return rc;
 }
 
-static int namedsemLock(sqlite3_file *id, int locktype) {
+/*
+** Lock the file with the lock specified by parameter locktype - one
+** of the following:
+**
+**     (1) SHARED_LOCK
+**     (2) RESERVED_LOCK
+**     (3) PENDING_LOCK
+**     (4) EXCLUSIVE_LOCK
+**
+** Sometimes when requesting one lock state, additional lock states
+** are inserted in between.  The locking might fail on one of the later
+** transitions leaving the lock state different from what it started but
+** still short of its goal.  The following chart shows the allowed
+** transitions and the inserted intermediate states:
+**
+**    UNLOCKED -> SHARED
+**    SHARED -> RESERVED
+**    SHARED -> (PENDING) -> EXCLUSIVE
+**    RESERVED -> (PENDING) -> EXCLUSIVE
+**    PENDING -> EXCLUSIVE
+**
+** Semaphore locks only really support EXCLUSIVE locks.  We track intermediate
+** lock states in the sqlite3_file structure, but all locks SHARED or
+** above are really EXCLUSIVE locks and exclude all other processes from
+** access the file.
+**
+** This routine will only increase a lock.  Use the sqlite3OsUnlock()
+** routine to lower a locking level.
+*/
+static int semLock(sqlite3_file *id, int locktype) {
   unixFile *pFile = (unixFile*)id;
   int fd;
   sem_t *pSem = pFile->pOpen->pSem;
   int rc = SQLITE_OK;
@@ -24123,25 +23709,32 @@
   ** Just adjust level and punt on outta here. */
   if (pFile->locktype > NO_LOCK) {
     pFile->locktype = locktype;
     rc = SQLITE_OK;
-    goto namedsem_end_lock;
+    goto sem_end_lock;
   }
 
   /* lock semaphore now but bail out when already locked. */
   if( sem_trywait(pSem)==-1 ){
     rc = SQLITE_BUSY;
-    goto namedsem_end_lock;
+    goto sem_end_lock;
   }
 
   /* got it, set the type and return ok */
   pFile->locktype = locktype;
 
- namedsem_end_lock:
-  return rc;
-}
-
-static int namedsemUnlock(sqlite3_file *id, int locktype) {
+ sem_end_lock:
+  return rc;
+}
+
+/*
+** Lower the locking level on file descriptor pFile to locktype.  locktype
+** must be either NO_LOCK or SHARED_LOCK.
+**
+** If the locking level of the file descriptor is already at or below
+** the requested locking level, this routine is a no-op.
+*/
+static int semUnlock(sqlite3_file *id, int locktype) {
   unixFile *pFile = (unixFile*)id;
   sem_t *pSem = pFile->pOpen->pSem;
 
   assert( pFile );
@@ -24176,57 +23769,809 @@
 
 /*
  ** Close a file.
  */
-static int namedsemClose(sqlite3_file *id) {
+static int semClose(sqlite3_file *id) {
   if( id ){
     unixFile *pFile = (unixFile*)id;
-    namedsemUnlock(id, NO_LOCK);
+    semUnlock(id, NO_LOCK);
     assert( pFile );
-    enterMutex();
+    unixEnterMutex();
     releaseLockInfo(pFile->pLock);
     releaseOpenCnt(pFile->pOpen);
     closeUnixFile(id);
-    leaveMutex();
-  }
-  return SQLITE_OK;
-}
-
-#endif /* IS_VXWORKS */
-
-#endif /* SQLITE_ENABLE_LOCKING_STYLE */
-
-/*
-** The nolockLockingContext is void
-*/
-typedef void nolockLockingContext;
-
-static int nolockCheckReservedLock(sqlite3_file *NotUsed, int *pResOut){
-  UNUSED_PARAMETER(NotUsed);
-  *pResOut = 0;
-  return SQLITE_OK;
-}
-
-static int nolockLock(sqlite3_file *NotUsed, int NotUsed2){
-  UNUSED_PARAMETER2(NotUsed, NotUsed2);
-  return SQLITE_OK;
-}
-
-static int nolockUnlock(sqlite3_file *NotUsed, int NotUsed2){
-  UNUSED_PARAMETER2(NotUsed, NotUsed2);
-  return SQLITE_OK;
-}
-
-/*
-** Close a file.
-*/
-static int nolockClose(sqlite3_file *id) {
-  int rc;
-  if( IS_VXWORKS ) enterMutex();
-  rc = closeUnixFile(id);
-  if( IS_VXWORKS ) leaveMutex();
-  return rc;
-}
+    unixLeaveMutex();
+  }
+  return SQLITE_OK;
+}
+
+#endif /* OS_VXWORKS */
+/*
+** Named semaphore locking is only available on VxWorks.
+**
+*************** End of the named semaphore lock implementation ****************
+******************************************************************************/
+
+
+/******************************************************************************
+*************************** Begin AFP Locking *********************************
+**
+** AFP is the Apple Filing Protocol.  AFP is a network filesystem found
+** on Apple Macintosh computers - both OS9 and OSX.
+**
+** Third-party implementations of AFP are available.  But this code here
+** only works on OSX.
+*/
+
+#if defined(__DARWIN__) && SQLITE_ENABLE_LOCKING_STYLE
+/*
+** The afpLockingContext structure contains all afp lock specific state
+*/
+typedef struct afpLockingContext afpLockingContext;
+struct afpLockingContext {
+  unsigned long long sharedByte;
+  const char *dbPath;             /* Name of the open file */
+};
+
+struct ByteRangeLockPB2
+{
+  unsigned long long offset;        /* offset to first byte to lock */
+  unsigned long long length;        /* nbr of bytes to lock */
+  unsigned long long retRangeStart; /* nbr of 1st byte locked if successful */
+  unsigned char unLockFlag;         /* 1 = unlock, 0 = lock */
+  unsigned char startEndFlag;       /* 1=rel to end of fork, 0=rel to start */
+  int fd;                           /* file desc to assoc this lock with */
+};
+
+#define afpfsByteRangeLock2FSCTL        _IOWR('z', 23, struct ByteRangeLockPB2)
+
+/*
+** This is a utility for setting or clearing a bit-range lock on an
+** AFP filesystem.
+**
+** Return SQLITE_OK on success, SQLITE_BUSY on failure.
+*/
+static int afpSetLock(
+  const char *path,              /* Name of the file to be locked or unlocked */
+  unixFile *pFile,               /* Open file descriptor on path */
+  unsigned long long offset,     /* First byte to be locked */
+  unsigned long long length,     /* Number of bytes to lock */
+  int setLockFlag                /* True to set lock.  False to clear lock */
+){
+  struct ByteRangeLockPB2 pb;
+  int err;
+
+  pb.unLockFlag = setLockFlag ? 0 : 1;
+  pb.startEndFlag = 0;
+  pb.offset = offset;
+  pb.length = length;
+  pb.fd = pFile->h;
+
+  OSTRACE6("AFPSETLOCK [%s] for %d%s in range %llx:%llx\n",
+    (setLockFlag?"ON":"OFF"), pFile->h, (pb.fd==-1?"[testval-1]":""),
+    offset, length);
+  err = fsctl(path, afpfsByteRangeLock2FSCTL, &pb, 0);
+  if ( err==-1 ) {
+    int rc;
+    int tErrno = errno;
+    OSTRACE4("AFPSETLOCK failed to fsctl() '%s' %d %s\n",
+             path, tErrno, strerror(tErrno));
+#ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS
+    rc = SQLITE_BUSY;
+#else
+    rc = sqliteErrorFromPosixError(tErrno,
+                    setLockFlag ? SQLITE_IOERR_LOCK : SQLITE_IOERR_UNLOCK);
+#endif /* SQLITE_IGNORE_AFP_LOCK_ERRORS */
+    if( IS_LOCK_ERROR(rc) ){
+      pFile->lastErrno = tErrno;
+    }
+    return rc;
+  } else {
+    return SQLITE_OK;
+  }
+}
+
+/*
+** This routine checks if there is a RESERVED lock held on the specified
+** file by this or any other process. If such a lock is held, set *pResOut
+** to a non-zero value otherwise *pResOut is set to zero.  The return value
+** is set to SQLITE_OK unless an I/O error occurs during lock checking.
+*/
+static int afpCheckReservedLock(sqlite3_file *id, int *pResOut){
+  int rc = SQLITE_OK;
+  int reserved = 0;
+  unixFile *pFile = (unixFile*)id;
+
+  SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
+
+  assert( pFile );
+  afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
+
+  /* Check if a thread in this process holds such a lock */
+  if( pFile->locktype>SHARED_LOCK ){
+    reserved = 1;
+  }
+
+  /* Otherwise see if some other process holds it.
+   */
+  if( !reserved ){
+    /* lock the RESERVED byte */
+    int lrc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1);
+    if( SQLITE_OK==lrc ){
+      /* if we succeeded in taking the reserved lock, unlock it to restore
+      ** the original state */
+      lrc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1, 0);
+    } else {
+      /* if we failed to get the lock then someone else must have it */
+      reserved = 1;
+    }
+    if( IS_LOCK_ERROR(lrc) ){
+      rc=lrc;
+    }
+  }
+
+  OSTRACE4("TEST WR-LOCK %d %d %d\n", pFile->h, rc, reserved);
+
+  *pResOut = reserved;
+  return rc;
+}
+
+/*
+** Lock the file with the lock specified by parameter locktype - one
+** of the following:
+**
+**     (1) SHARED_LOCK
+**     (2) RESERVED_LOCK
+**     (3) PENDING_LOCK
+**     (4) EXCLUSIVE_LOCK
+**
+** Sometimes when requesting one lock state, additional lock states
+** are inserted in between.  The locking might fail on one of the later
+** transitions leaving the lock state different from what it started but
+** still short of its goal.  The following chart shows the allowed
+** transitions and the inserted intermediate states:
+**
+**    UNLOCKED -> SHARED
+**    SHARED -> RESERVED
+**    SHARED -> (PENDING) -> EXCLUSIVE
+**    RESERVED -> (PENDING) -> EXCLUSIVE
+**    PENDING -> EXCLUSIVE
+**
+** This routine will only increase a lock.  Use the sqlite3OsUnlock()
+** routine to lower a locking level.
+*/
+static int afpLock(sqlite3_file *id, int locktype){
+  int rc = SQLITE_OK;
+  unixFile *pFile = (unixFile*)id;
+  afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
+
+  assert( pFile );
+  OSTRACE5("LOCK    %d %s was %s pid=%d\n", pFile->h,
+         locktypeName(locktype), locktypeName(pFile->locktype), getpid());
+
+  /* If there is already a lock of this type or more restrictive on the
+  ** unixFile, do nothing. Don't use the afp_end_lock: exit path, as
+  ** unixEnterMutex() hasn't been called yet.
+  */
+  if( pFile->locktype>=locktype ){
+    OSTRACE3("LOCK    %d %s ok (already held)\n", pFile->h,
+           locktypeName(locktype));
+    return SQLITE_OK;
+  }
+
+  /* Make sure the locking sequence is correct
+  */
+  assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
+  assert( locktype!=PENDING_LOCK );
+  assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
+
+  /* This mutex is needed because pFile->pLock is shared across threads
+  */
+  unixEnterMutex();
+
+  /* Make sure the current thread owns the pFile.
+  */
+  rc = transferOwnership(pFile);
+  if( rc!=SQLITE_OK ){
+    unixLeaveMutex();
+    return rc;
+  }
+
+  /* A PENDING lock is needed before acquiring a SHARED lock and before
+  ** acquiring an EXCLUSIVE lock.  For the SHARED lock, the PENDING will
+  ** be released.
+  */
+  if( locktype==SHARED_LOCK
+      || (locktype==EXCLUSIVE_LOCK && pFile->locktype<PENDING_LOCK)
+  ){
+    int failed;
+    failed = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 1);
+    if (failed) {
+      rc = failed;
+      goto afp_end_lock;
+    }
+  }
+
+  /* If control gets to this point, then actually go ahead and make
+  ** operating system calls for the specified lock.
+  */
+  if( locktype==SHARED_LOCK ){
+    int lk, lrc1, lrc2, lrc1Errno;
+
+    /* Now get the read-lock SHARED_LOCK */
+    /* note that the quality of the randomness doesn't matter that much */
+    lk = random();
+    context->sharedByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);
+    lrc1 = afpSetLock(context->dbPath, pFile,
+          SHARED_FIRST+context->sharedByte, 1, 1);
+    if( IS_LOCK_ERROR(lrc1) ){
+      lrc1Errno = pFile->lastErrno;
+    }
+    /* Drop the temporary PENDING lock */
+    lrc2 = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0);
+
+    if( IS_LOCK_ERROR(lrc1) ) {
+      pFile->lastErrno = lrc1Errno;
+      rc = lrc1;
+      goto afp_end_lock;
+    } else if( IS_LOCK_ERROR(lrc2) ){
+      rc = lrc2;
+      goto afp_end_lock;
+    } else if( lrc1 != SQLITE_OK ) {
+      rc = lrc1;
+    } else {
+      pFile->locktype = SHARED_LOCK;
+      pFile->pOpen->nLock++;
+    }
+  }else{
+    /* The request was for a RESERVED or EXCLUSIVE lock.  It is
+    ** assumed that there is a SHARED or greater lock on the file
+    ** already.
+    */
+    int failed = 0;
+    assert( 0!=pFile->locktype );
+    if (locktype >= RESERVED_LOCK && pFile->locktype < RESERVED_LOCK) {
+        /* Acquire a RESERVED lock */
+        failed = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1);
+    }
+    if (!failed && locktype == EXCLUSIVE_LOCK) {
+      /* Acquire an EXCLUSIVE lock */
+
+      /* Remove the shared lock before trying the range.  we'll need to
+      ** reestablish the shared lock if we can't get the  afpUnlock
+      */
+      if( !(failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST +
+                         context->sharedByte, 1, 0)) ){
+        int failed2 = SQLITE_OK;
+        /* now attemmpt to get the exclusive lock range */
+        failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST,
+                               SHARED_SIZE, 1);
+        if( failed && (failed2 = afpSetLock(context->dbPath, pFile,
+                       SHARED_FIRST + context->sharedByte, 1, 1)) ){
+          /* Can't reestablish the shared lock.  Sqlite can't deal, this is
+          ** a critical I/O error
+          */
+          rc = ((failed & SQLITE_IOERR) == SQLITE_IOERR) ? failed2 :
+               SQLITE_IOERR_LOCK;
+          goto afp_end_lock;
+        }
+      }else{
+        rc = failed;
+      }
+    }
+    if( failed ){
+      rc = failed;
+    }
+  }
+
+  if( rc==SQLITE_OK ){
+    pFile->locktype = locktype;
+  }else if( locktype==EXCLUSIVE_LOCK ){
+    pFile->locktype = PENDING_LOCK;
+  }
+
+afp_end_lock:
+  unixLeaveMutex();
+  OSTRACE4("LOCK    %d %s %s\n", pFile->h, locktypeName(locktype),
+         rc==SQLITE_OK ? "ok" : "failed");
+  return rc;
+}
+
+/*
+** Lower the locking level on file descriptor pFile to locktype.  locktype
+** must be either NO_LOCK or SHARED_LOCK.
+**
+** If the locking level of the file descriptor is already at or below
+** the requested locking level, this routine is a no-op.
+*/
+static int afpUnlock(sqlite3_file *id, int locktype) {
+  int rc = SQLITE_OK;
+  unixFile *pFile = (unixFile*)id;
+  afpLockingContext *pCtx = (afpLockingContext *) pFile->lockingContext;
+
+  assert( pFile );
+  OSTRACE5("UNLOCK  %d %d was %d pid=%d\n", pFile->h, locktype,
+         pFile->locktype, getpid());
+
+  assert( locktype<=SHARED_LOCK );
+  if( pFile->locktype<=locktype ){
+    return SQLITE_OK;
+  }
+  if( CHECK_THREADID(pFile) ){
+    return SQLITE_MISUSE;
+  }
+  unixEnterMutex();
+  if( pFile->locktype>SHARED_LOCK ){
+
+    if( pFile->locktype==EXCLUSIVE_LOCK ){
+      rc = afpSetLock(pCtx->dbPath, pFile, SHARED_FIRST, SHARED_SIZE, 0);
+      if( rc==SQLITE_OK && locktype==SHARED_LOCK ){
+        /* only re-establish the shared lock if necessary */
+        int sharedLockByte = SHARED_FIRST+pCtx->sharedByte;
+        rc = afpSetLock(pCtx->dbPath, pFile, sharedLockByte, 1, 1);
+      }
+    }
+    if( rc==SQLITE_OK && pFile->locktype>=PENDING_LOCK ){
+      rc = afpSetLock(pCtx->dbPath, pFile, PENDING_BYTE, 1, 0);
+    }
+    if( rc==SQLITE_OK && pFile->locktype>=RESERVED_LOCK ){
+      rc = afpSetLock(pCtx->dbPath, pFile, RESERVED_BYTE, 1, 0);
+    }
+  }else if( locktype==NO_LOCK ){
+    /* clear the shared lock */
+    int sharedLockByte = SHARED_FIRST+pCtx->sharedByte;
+    rc = afpSetLock(pCtx->dbPath, pFile, sharedLockByte, 1, 0);
+  }
+
+  if( rc==SQLITE_OK ){
+    if( locktype==NO_LOCK ){
+      struct unixOpenCnt *pOpen = pFile->pOpen;
+      pOpen->nLock--;
+      assert( pOpen->nLock>=0 );
+      if( pOpen->nLock==0 && pOpen->nPending>0 ){
+        int i;
+        for(i=0; i<pOpen->nPending; i++){
+          if( pOpen->aPending[i] < 0 ) continue;
+          if( close(pOpen->aPending[i]) ){
+            pFile->lastErrno = errno;
+            rc = SQLITE_IOERR_CLOSE;
+          }else{
+            pOpen->aPending[i] = -1;
+          }
+        }
+        if( rc==SQLITE_OK ){
+          sqlite3_free(pOpen->aPending);
+          pOpen->nPending = 0;
+          pOpen->aPending = 0;
+        }
+      }
+    }
+  }
+  unixLeaveMutex();
+  if( rc==SQLITE_OK ) pFile->locktype = locktype;
+  return rc;
+}
+
+/*
+** Close a file & cleanup AFP specific locking context
+*/
+static int afpClose(sqlite3_file *id) {
+  if( id ){
+    unixFile *pFile = (unixFile*)id;
+    afpUnlock(id, NO_LOCK);
+    unixEnterMutex();
+    if( pFile->pOpen && pFile->pOpen->nLock ){
+      /* If there are outstanding locks, do not actually close the file just
+      ** yet because that would clear those locks.  Instead, add the file
+      ** descriptor to pOpen->aPending.  It will be automatically closed when
+      ** the last lock is cleared.
+      */
+      int *aNew;
+      struct unixOpenCnt *pOpen = pFile->pOpen;
+      aNew = sqlite3_realloc(pOpen->aPending, (pOpen->nPending+1)*sizeof(int) );
+      if( aNew==0 ){
+        /* If a malloc fails, just leak the file descriptor */
+      }else{
+        pOpen->aPending = aNew;
+        pOpen->aPending[pOpen->nPending] = pFile->h;
+        pOpen->nPending++;
+        pFile->h = -1;
+      }
+    }
+    releaseOpenCnt(pFile->pOpen);
+    sqlite3_free(pFile->lockingContext);
+    closeUnixFile(id);
+    unixLeaveMutex();
+  }
+  return SQLITE_OK;
+}
+
+#endif /* defined(__DARWIN__) && SQLITE_ENABLE_LOCKING_STYLE */
+/*
+** The code above is the AFP lock implementation.  The code is specific
+** to MacOSX and does not work on other unix platforms.  No alternative
+** is available.  If you don't compile for a mac, then the "unix-afp"
+** VFS is not available.
+**
+********************* End of the AFP lock implementation **********************
+******************************************************************************/
+
+
+/******************************************************************************
+**************** Non-locking sqlite3_file methods *****************************
+**
+** The next division contains implementations for all methods of the
+** sqlite3_file object other than the locking methods.  The locking
+** methods were defined in divisions above (one locking method per
+** division).  Those methods that are common to all locking modes
+** are gather together into this division.
+*/
+
+/*
+** Seek to the offset passed as the second argument, then read cnt
+** bytes into pBuf. Return the number of bytes actually read.
+**
+** NB:  If you define USE_PREAD or USE_PREAD64, then it might also
+** be necessary to define _XOPEN_SOURCE to be 500.  This varies from
+** one system to another.  Since SQLite does not define USE_PREAD
+** any any form by default, we will not attempt to define _XOPEN_SOURCE.
+** See tickets #2741 and #2681.
+**
+** To avoid stomping the errno value on a failed read the lastErrno value
+** is set before returning.
+*/
+static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
+  int got;
+  i64 newOffset;
+  TIMER_START;
+#if defined(USE_PREAD)
+  got = pread(id->h, pBuf, cnt, offset);
+  SimulateIOError( got = -1 );
+#elif defined(USE_PREAD64)
+  got = pread64(id->h, pBuf, cnt, offset);
+  SimulateIOError( got = -1 );
+#else
+  newOffset = lseek(id->h, offset, SEEK_SET);
+  SimulateIOError( newOffset-- );
+  if( newOffset!=offset ){
+    if( newOffset == -1 ){
+      ((unixFile*)id)->lastErrno = errno;
+    }else{
+      ((unixFile*)id)->lastErrno = 0;
+    }
+    return -1;
+  }
+  got = read(id->h, pBuf, cnt);
+#endif
+  TIMER_END;
+  if( got<0 ){
+    ((unixFile*)id)->lastErrno = errno;
+  }
+  OSTRACE5("READ    %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED);
+  return got;
+}
+
+/*
+** Read data from a file into a buffer.  Return SQLITE_OK if all
+** bytes were read successfully and SQLITE_IOERR if anything goes
+** wrong.
+*/
+static int unixRead(
+  sqlite3_file *id,
+  void *pBuf,
+  int amt,
+  sqlite3_int64 offset
+){
+  int got;
+  assert( id );
+  got = seekAndRead((unixFile*)id, offset, pBuf, amt);
+  if( got==amt ){
+    return SQLITE_OK;
+  }else if( got<0 ){
+    /* lastErrno set by seekAndRead */
+    return SQLITE_IOERR_READ;
+  }else{
+    ((unixFile*)id)->lastErrno = 0; /* not a system error */
+    /* Unread parts of the buffer must be zero-filled */
+    memset(&((char*)pBuf)[got], 0, amt-got);
+    return SQLITE_IOERR_SHORT_READ;
+  }
+}
+
+/*
+** Seek to the offset in id->offset then read cnt bytes into pBuf.
+** Return the number of bytes actually read.  Update the offset.
+**
+** To avoid stomping the errno value on a failed write the lastErrno value
+** is set before returning.
+*/
+static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){
+  int got;
+  i64 newOffset;
+  TIMER_START;
+#if defined(USE_PREAD)
+  got = pwrite(id->h, pBuf, cnt, offset);
+#elif defined(USE_PREAD64)
+  got = pwrite64(id->h, pBuf, cnt, offset);
+#else
+  newOffset = lseek(id->h, offset, SEEK_SET);
+  if( newOffset!=offset ){
+    if( newOffset == -1 ){
+      ((unixFile*)id)->lastErrno = errno;
+    }else{
+      ((unixFile*)id)->lastErrno = 0;
+    }
+    return -1;
+  }
+  got = write(id->h, pBuf, cnt);
+#endif
+  TIMER_END;
+  if( got<0 ){
+    ((unixFile*)id)->lastErrno = errno;
+  }
+
+  OSTRACE5("WRITE   %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED);
+  return got;
+}
+
+
+/*
+** Write data from a buffer into a file.  Return SQLITE_OK on success
+** or some other error code on failure.
+*/
+static int unixWrite(
+  sqlite3_file *id,
+  const void *pBuf,
+  int amt,
+  sqlite3_int64 offset
+){
+  int wrote = 0;
+  assert( id );
+  assert( amt>0 );
+  while( amt>0 && (wrote = seekAndWrite((unixFile*)id, offset, pBuf, amt))>0 ){
+    amt -= wrote;
+    offset += wrote;
+    pBuf = &((char*)pBuf)[wrote];
+  }
+  SimulateIOError(( wrote=(-1), amt=1 ));
+  SimulateDiskfullError(( wrote=0, amt=1 ));
+  if( amt>0 ){
+    if( wrote<0 ){
+      /* lastErrno set by seekAndWrite */
+      return SQLITE_IOERR_WRITE;
+    }else{
+      ((unixFile*)id)->lastErrno = 0; /* not a system error */
+      return SQLITE_FULL;
+    }
+  }
+  return SQLITE_OK;
+}
+
+#ifdef SQLITE_TEST
+/*
+** Count the number of fullsyncs and normal syncs.  This is used to test
+** that syncs and fullsyncs are occurring at the right times.
+*/
+SQLITE_API int sqlite3_sync_count = 0;
+SQLITE_API int sqlite3_fullsync_count = 0;
+#endif
+
+/*
+** Use the fdatasync() API only if the HAVE_FDATASYNC macro is defined.
+** Otherwise use fsync() in its place.
+*/
+#ifndef HAVE_FDATASYNC
+# define fdatasync fsync
+#endif
+
+/*
+** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not
+** the F_FULLFSYNC macro is defined.  F_FULLFSYNC is currently
+** only available on Mac OS X.  But that could change.
+*/
+#ifdef F_FULLFSYNC
+# define HAVE_FULLFSYNC 1
+#else
+# define HAVE_FULLFSYNC 0
+#endif
+
+
+/*
+** The fsync() system call does not work as advertised on many
+** unix systems.  The following procedure is an attempt to make
+** it work better.
+**
+** The SQLITE_NO_SYNC macro disables all fsync()s.  This is useful
+** for testing when we want to run through the test suite quickly.
+** You are strongly advised *not* to deploy with SQLITE_NO_SYNC
+** enabled, however, since with SQLITE_NO_SYNC enabled, an OS crash
+** or power failure will likely corrupt the database file.
+*/
+static int full_fsync(int fd, int fullSync, int dataOnly){
+  int rc;
+
+  /* The following "ifdef/elif/else/" block has the same structure as
+  ** the one below. It is replicated here solely to avoid cluttering
+  ** up the real code with the UNUSED_PARAMETER() macros.
+  */
+#ifdef SQLITE_NO_SYNC
+  UNUSED_PARAMETER(fd);
+  UNUSED_PARAMETER(fullSync);
+  UNUSED_PARAMETER(dataOnly);
+#elif HAVE_FULLFSYNC
+  UNUSED_PARAMETER(dataOnly);
+#else
+  UNUSED_PARAMETER(fullSync);
+#endif
+
+  /* Record the number of times that we do a normal fsync() and
+  ** FULLSYNC.  This is used during testing to verify that this procedure
+  ** gets called with the correct arguments.
+  */
+#ifdef SQLITE_TEST
+  if( fullSync ) sqlite3_fullsync_count++;
+  sqlite3_sync_count++;
+#endif
+
+  /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
+  ** no-op
+  */
+#ifdef SQLITE_NO_SYNC
+  rc = SQLITE_OK;
+#elif HAVE_FULLFSYNC
+  if( fullSync ){
+    rc = fcntl(fd, F_FULLFSYNC, 0);
+  }else{
+    rc = 1;
+  }
+  /* If the FULLFSYNC failed, fall back to attempting an fsync().
+  ** It shouldn't be possible for fullfsync to fail on the local
+  ** file system (on OSX), so failure indicates that FULLFSYNC
+  ** isn't supported for this file system. So, attempt an fsync
+  ** and (for now) ignore the overhead of a superfluous fcntl call.
+  ** It'd be better to detect fullfsync support once and avoid
+  ** the fcntl call every time sync is called.
+  */
+  if( rc ) rc = fsync(fd);
+
+#else
+  if( dataOnly ){
+    rc = fdatasync(fd);
+    if( OS_VXWORKS && rc==-1 && errno==ENOTSUP ){
+      rc = fsync(fd);
+    }
+  }else{
+    rc = fsync(fd);
+  }
+#endif /* ifdef SQLITE_NO_SYNC elif HAVE_FULLFSYNC */
+
+  if( OS_VXWORKS && rc!= -1 ){
+    rc = 0;
+  }
+  return rc;
+}
+
+/*
+** Make sure all writes to a particular file are committed to disk.
+**
+** If dataOnly==0 then both the file itself and its metadata (file
+** size, access time, etc) are synced.  If dataOnly!=0 then only the
+** file data is synced.
+**
+** Under Unix, also make sure that the directory entry for the file
+** has been created by fsync-ing the directory that contains the file.
+** If we do not do this and we encounter a power failure, the directory
+** entry for the journal might not exist after we reboot.  The next
+** SQLite to access the file will not know that the journal exists (because
+** the directory entry for the journal was never created) and the transaction
+** will not roll back - possibly leading to database corruption.
+*/
+static int unixSync(sqlite3_file *id, int flags){
+  int rc;
+  unixFile *pFile = (unixFile*)id;
+
+  int isDataOnly = (flags&SQLITE_SYNC_DATAONLY);
+  int isFullsync = (flags&0x0F)==SQLITE_SYNC_FULL;
+
+  /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */
+  assert((flags&0x0F)==SQLITE_SYNC_NORMAL
+      || (flags&0x0F)==SQLITE_SYNC_FULL
+  );
+
+  /* Unix cannot, but some systems may return SQLITE_FULL from here. This
+  ** line is to test that doing so does not cause any problems.
+  */
+  SimulateDiskfullError( return SQLITE_FULL );
+
+  assert( pFile );
+  OSTRACE2("SYNC    %-3d\n", pFile->h);
+  rc = full_fsync(pFile->h, isFullsync, isDataOnly);
+  SimulateIOError( rc=1 );
+  if( rc ){
+    pFile->lastErrno = errno;
+    return SQLITE_IOERR_FSYNC;
+  }
+  if( pFile->dirfd>=0 ){
+    int err;
+    OSTRACE4("DIRSYNC %-3d (have_fullfsync=%d fullsync=%d)\n", pFile->dirfd,
+            HAVE_FULLFSYNC, isFullsync);
+#ifndef SQLITE_DISABLE_DIRSYNC
+    /* The directory sync is only attempted if full_fsync is
+    ** turned off or unavailable.  If a full_fsync occurred above,
+    ** then the directory sync is superfluous.
+    */
+    if( (!HAVE_FULLFSYNC || !isFullsync) && full_fsync(pFile->dirfd,0,0) ){
+       /*
+       ** We have received multiple reports of fsync() returning
+       ** errors when applied to directories on certain file systems.
+       ** A failed directory sync is not a big deal.  So it seems
+       ** better to ignore the error.  Ticket #1657
+       */
+       /* pFile->lastErrno = errno; */
+       /* return SQLITE_IOERR; */
+    }
+#endif
+    err = close(pFile->dirfd); /* Only need to sync once, so close the */
+    if( err==0 ){              /* directory when we are done */
+      pFile->dirfd = -1;
+    }else{
+      pFile->lastErrno = errno;
+      rc = SQLITE_IOERR_DIR_CLOSE;
+    }
+  }
+  return rc;
+}
+
+/*
+** Truncate an open file to a specified size
+*/
+static int unixTruncate(sqlite3_file *id, i64 nByte){
+  int rc;
+  assert( id );
+  SimulateIOError( return SQLITE_IOERR_TRUNCATE );
+  rc = ftruncate(((unixFile*)id)->h, (off_t)nByte);
+  if( rc ){
+    ((unixFile*)id)->lastErrno = errno;
+    return SQLITE_IOERR_TRUNCATE;
+  }else{
+    return SQLITE_OK;
+  }
+}
+
+/*
+** Determine the current size of a file in bytes
+*/
+static int unixFileSize(sqlite3_file *id, i64 *pSize){
+  int rc;
+  struct stat buf;
+  assert( id );
+  rc = fstat(((unixFile*)id)->h, &buf);
+  SimulateIOError( rc=1 );
+  if( rc!=0 ){
+    ((unixFile*)id)->lastErrno = errno;
+    return SQLITE_IOERR_FSTAT;
+  }
+  *pSize = buf.st_size;
+
+  /* When opening a zero-size database, the findLockInfo() procedure
+  ** writes a single byte into that file in order to work around a bug
+  ** in the OS-X msdos filesystem.  In order to avoid problems with upper
+  ** layers, we need to report this file size as zero even though it is
+  ** really 1.   Ticket #3260.
+  */
+  if( *pSize==1 ) *pSize = 0;
+
+
+  return SQLITE_OK;
+}
+
+#if SQLITE_ENABLE_LOCKING_STYLE && defined(__DARWIN__)
+/*
+** Handler for proxy-locking file-control verbs.  Defined below in the
+** proxying locking division.
+*/
+static int proxyFileControl(sqlite3_file*,int,void*);
+#endif
 
 
 /*
 ** Information and control of an open file handle.
@@ -24236,8 +24581,18 @@
     case SQLITE_FCNTL_LOCKSTATE: {
       *(int*)pArg = ((unixFile*)id)->locktype;
       return SQLITE_OK;
     }
+    case SQLITE_LAST_ERRNO: {
+      *(int*)pArg = ((unixFile*)id)->lastErrno;
+      return SQLITE_OK;
+    }
+#if SQLITE_ENABLE_LOCKING_STYLE && defined(__DARWIN__)
+    case SQLITE_SET_LOCKPROXYFILE:
+    case SQLITE_GET_LOCKPROXYFILE: {
+      return proxyFileControl(id,op,pArg);
+    }
+#endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__DARWIN__) */
   }
   return SQLITE_ERROR;
 }
 
@@ -24264,227 +24619,370 @@
   return 0;
 }
 
 /*
-** Initialize the contents of the unixFile structure pointed to by pId.
-**
-** When locking extensions are enabled, the filepath and locking style
-** are needed to determine the unixFile pMethod to use for locking operations.
-** The locking-style specific lockingContext data structure is created
-** and assigned here also.
-*/
-static int fillInUnixFile(
-  sqlite3_vfs *pVfs,      /* Pointer to vfs object */
-  int h,                  /* Open file descriptor of file being opened */
-  int dirfd,              /* Directory file descriptor */
-  sqlite3_file *pId,      /* Write to the unixFile structure here */
-  const char *zFilename,  /* Name of the file being opened */
-  int noLock,             /* Omit locking if true */
-  int isDelete            /* Delete on close if true */
-){
-  int eLockingStyle;
-  unixFile *pNew = (unixFile *)pId;
-  int rc = SQLITE_OK;
-
-  /* Macro to define the static contents of an sqlite3_io_methods
-  ** structure for a unix backend file. Different locking methods
-  ** require different functions for the xClose, xLock, xUnlock and
-  ** xCheckReservedLock methods.
-  */
-  #define IOMETHODS(xClose, xLock, xUnlock, xCheckReservedLock) {    \
-    1,                          /* iVersion */                           \
-    xClose,                     /* xClose */                             \
-    unixRead,                   /* xRead */                              \
-    unixWrite,                  /* xWrite */                             \
-    unixTruncate,               /* xTruncate */                          \
-    unixSync,                   /* xSync */                              \
-    unixFileSize,               /* xFileSize */                          \
-    xLock,                      /* xLock */                              \
-    xUnlock,                    /* xUnlock */                            \
-    xCheckReservedLock,         /* xCheckReservedLock */                 \
-    unixFileControl,            /* xFileControl */                       \
-    unixSectorSize,             /* xSectorSize */                        \
-    unixDeviceCharacteristics   /* xDeviceCapabilities */                \
-  }
-  static sqlite3_io_methods aIoMethod[] = {
-    IOMETHODS(unixClose, unixLock, unixUnlock, unixCheckReservedLock)
-   ,IOMETHODS(nolockClose, nolockLock, nolockUnlock, nolockCheckReservedLock)
+** Here ends the implementation of all sqlite3_file methods.
+**
+********************** End sqlite3_file Methods *******************************
+******************************************************************************/
+
+/*
+** This division contains definitions of sqlite3_io_methods objects that
+** implement various file locking strategies.  It also contains definitions
+** of "finder" functions.  A finder-function is used to locate the appropriate
+** sqlite3_io_methods object for a particular database file.  The pAppData
+** field of the sqlite3_vfs VFS objects are initialized to be pointers to
+** the correct finder-function for that VFS.
+**
+** Most finder functions return a pointer to a fixed sqlite3_io_methods
+** object.  The only interesting finder-function is autolockIoFinder, which
+** looks at the filesystem type and tries to guess the best locking
+** strategy from that.
+**
+** For finder-funtion F, two objects are created:
+**
+**    (1) The real finder-function named "FImpt()".
+**
+**    (2) A constant pointer to this functio named just "F".
+**
+**
+** A pointer to the F pointer is used as the pAppData value for VFS
+** objects.  We have to do this instead of letting pAppData point
+** directly at the finder-function since C90 rules prevent a void*
+** from be cast into a function pointer.
+**
+**
+** Each instance of this macro generates two objects:
+**
+**   *  A constant sqlite3_io_methods object call METHOD that has locking
+**      methods CLOSE, LOCK, UNLOCK, CKRESLOCK.
+**
+**   *  An I/O method finder function called FINDER that returns a pointer
+**      to the METHOD object in the previous bullet.
+*/
+#define IOMETHODS(FINDER, METHOD, CLOSE, LOCK, UNLOCK, CKLOCK)               \
+static const sqlite3_io_methods METHOD = {                                   \
+   1,                          /* iVersion */                                \
+   CLOSE,                      /* xClose */                                  \
+   unixRead,                   /* xRead */                                   \
+   unixWrite,                  /* xWrite */                                  \
+   unixTruncate,               /* xTruncate */                               \
+   unixSync,                   /* xSync */                                   \
+   unixFileSize,               /* xFileSize */                               \
+   LOCK,                       /* xLock */                                   \
+   UNLOCK,                     /* xUnlock */                                 \
+   CKLOCK,                     /* xCheckReservedLock */                      \
+   unixFileControl,            /* xFileControl */                            \
+   unixSectorSize,             /* xSectorSize */                             \
+   unixDeviceCharacteristics   /* xDeviceCapabilities */                     \
+};                                                                           \
+static const sqlite3_io_methods *FINDER##Impl(const char *z, int h){         \
+  UNUSED_PARAMETER(z); UNUSED_PARAMETER(h);                                  \
+  return &METHOD;                                                            \
+}                                                                            \
+static const sqlite3_io_methods *(*const FINDER)(const char*,int)            \
+    = FINDER##Impl;
+
+/*
+** Here are all of the sqlite3_io_methods objects for each of the
+** locking strategies.  Functions that return pointers to these methods
+** are also created.
+*/
+IOMETHODS(
+  posixIoFinder,            /* Finder function name */
+  posixIoMethods,           /* sqlite3_io_methods object name */
+  unixClose,                /* xClose method */
+  unixLock,                 /* xLock method */
+  unixUnlock,               /* xUnlock method */
+  unixCheckReservedLock     /* xCheckReservedLock method */
+)
+IOMETHODS(
+  nolockIoFinder,           /* Finder function name */
+  nolockIoMethods,          /* sqlite3_io_methods object name */
+  nolockClose,              /* xClose method */
+  nolockLock,               /* xLock method */
+  nolockUnlock,             /* xUnlock method */
+  nolockCheckReservedLock   /* xCheckReservedLock method */
+)
+IOMETHODS(
+  dotlockIoFinder,          /* Finder function name */
+  dotlockIoMethods,         /* sqlite3_io_methods object name */
+  dotlockClose,             /* xClose method */
+  dotlockLock,              /* xLock method */
+  dotlockUnlock,            /* xUnlock method */
+  dotlockCheckReservedLock  /* xCheckReservedLock method */
+)
+
 #if SQLITE_ENABLE_LOCKING_STYLE
-   ,IOMETHODS(dotlockClose, dotlockLock, dotlockUnlock,dotlockCheckReservedLock)
-#if IS_VXWORKS
-   ,IOMETHODS(nolockClose, nolockLock, nolockUnlock, nolockCheckReservedLock)
-   ,IOMETHODS(nolockClose, nolockLock, nolockUnlock, nolockCheckReservedLock)
-   ,IOMETHODS(namedsemClose, namedsemLock, namedsemUnlock, namedsemCheckReservedLock)
-#else
-   ,IOMETHODS(flockClose, flockLock, flockUnlock, flockCheckReservedLock)
-   ,IOMETHODS(afpClose, afpLock, afpUnlock, afpCheckReservedLock)
-   ,IOMETHODS(nolockClose, nolockLock, nolockUnlock, nolockCheckReservedLock)
-#endif
-#endif
-  };
-  /* The order of the IOMETHODS macros above is important.  It must be the
-  ** same order as the LOCKING_STYLE numbers
-  */
-  assert(LOCKING_STYLE_POSIX==1);
-  assert(LOCKING_STYLE_NONE==2);
-  assert(LOCKING_STYLE_DOTFILE==3);
-  assert(LOCKING_STYLE_FLOCK==4);
-  assert(LOCKING_STYLE_AFP==5);
-  assert(LOCKING_STYLE_NAMEDSEM==6);
+IOMETHODS(
+  flockIoFinder,            /* Finder function name */
+  flockIoMethods,           /* sqlite3_io_methods object name */
+  flockClose,               /* xClose method */
+  flockLock,                /* xLock method */
+  flockUnlock,              /* xUnlock method */
+  flockCheckReservedLock    /* xCheckReservedLock method */
+)
+#endif
+
+#if OS_VXWORKS
+IOMETHODS(
+  semIoFinder,              /* Finder function name */
+  semIoMethods,             /* sqlite3_io_methods object name */
+  semClose,                 /* xClose method */
+  semLock,                  /* xLock method */
+  semUnlock,                /* xUnlock method */
+  semCheckReservedLock      /* xCheckReservedLock method */
+)
+#endif
+
+#if defined(__DARWIN__) && SQLITE_ENABLE_LOCKING_STYLE
+IOMETHODS(
+  afpIoFinder,              /* Finder function name */
+  afpIoMethods,             /* sqlite3_io_methods object name */
+  afpClose,                 /* xClose method */
+  afpLock,                  /* xLock method */
+  afpUnlock,                /* xUnlock method */
+  afpCheckReservedLock      /* xCheckReservedLock method */
+)
+#endif
+
+/*
+** The proxy locking method is a "super-method" in the sense that it
+** opens secondary file descriptors for the conch and lock files and
+** it uses proxy, dot-file, AFP, and flock() locking methods on those
+** secondary files.  For this reason, the division that implements
+** proxy locking is located much further down in the file.  But we need
+** to go ahead and define the sqlite3_io_methods and finder function
+** for proxy locking here.  So we forward declare the I/O methods.
+*/
+#if defined(__DARWIN__) && SQLITE_ENABLE_LOCKING_STYLE
+static int proxyClose(sqlite3_file*);
+static int proxyLock(sqlite3_file*, int);
+static int proxyUnlock(sqlite3_file*, int);
+static int proxyCheckReservedLock(sqlite3_file*, int*);
+IOMETHODS(
+  proxyIoFinder,            /* Finder function name */
+  proxyIoMethods,           /* sqlite3_io_methods object name */
+  proxyClose,               /* xClose method */
+  proxyLock,                /* xLock method */
+  proxyUnlock,              /* xUnlock method */
+  proxyCheckReservedLock    /* xCheckReservedLock method */
+)
+#endif
+
+
+#if defined(__DARWIN__) && SQLITE_ENABLE_LOCKING_STYLE
+/*
+** This "finder" function attempts to determine the best locking strategy
+** for the database file "filePath".  It then returns the sqlite3_io_methods
+** object that implements that strategy.
+**
+** This is for MacOSX only.
+*/
+static const sqlite3_io_methods *autolockIoFinderImpl(
+  const char *filePath,    /* name of the database file */
+  int fd                   /* file descriptor open on the database file */
+){
+  static const struct Mapping {
+    const char *zFilesystem;              /* Filesystem type name */
+    const sqlite3_io_methods *pMethods;   /* Appropriate locking method */
+  } aMap[] = {
+    { "hfs",    &posixIoMethods },
+    { "ufs",    &posixIoMethods },
+    { "afpfs",  &afpIoMethods },
+#ifdef SQLITE_ENABLE_AFP_LOCKING_SMB
+    { "smbfs",  &afpIoMethods },
+#else
+    { "smbfs",  &flockIoMethods },
+#endif
+    { "webdav", &nolockIoMethods },
+    { 0, 0 }
+  };
+  int i;
+  struct statfs fsInfo;
+  struct flock lockInfo;
+
+  if( !filePath ){
+    /* If filePath==NULL that means we are dealing with a transient file
+    ** that does not need to be locked. */
+    return &nolockIoMethods;
+  }
+  if( statfs(filePath, &fsInfo) != -1 ){
+    if( fsInfo.f_flags & MNT_RDONLY ){
+      return &nolockIoMethods;
+    }
+    for(i=0; aMap[i].zFilesystem; i++){
+      if( strcmp(fsInfo.f_fstypename, aMap[i].zFilesystem)==0 ){
+        return aMap[i].pMethods;
+      }
+    }
+  }
+
+  /* Default case. Handles, amongst others, "nfs".
+  ** Test byte-range lock using fcntl(). If the call succeeds,
+  ** assume that the file-system supports POSIX style locks.
+  */
+  lockInfo.l_len = 1;
+  lockInfo.l_start = 0;
+  lockInfo.l_whence = SEEK_SET;
+  lockInfo.l_type = F_RDLCK;
+  if( fcntl(fd, F_GETLK, &lockInfo)!=-1 ) {
+    return &posixIoMethods;
+  }else{
+    return &dotlockIoMethods;
+  }
+}
+static const sqlite3_io_methods (*const autolockIoFinder)(const char*,int)
+        = autolockIoFinderImpl;
+
+#endif /* defined(__DARWIN__) && SQLITE_ENABLE_LOCKING_STYLE */
+
+/*
+** An abstract type for a pointer to a IO method finder function:
+*/
+typedef const sqlite3_io_methods *(*finder_type)(const char*,int);
+
+
+/****************************************************************************
+**************************** sqlite3_vfs methods ****************************
+**
+** This division contains the implementation of methods on the
+** sqlite3_vfs object.
+*/
+
+/*
+** Initialize the contents of the unixFile structure pointed to by pId.
+*/
+static int fillInUnixFile(
+  sqlite3_vfs *pVfs,      /* Pointer to vfs object */
+  int h,                  /* Open file descriptor of file being opened */
+  int dirfd,              /* Directory file descriptor */
+  sqlite3_file *pId,      /* Write to the unixFile structure here */
+  const char *zFilename,  /* Name of the file being opened */
+  int noLock,             /* Omit locking if true */
+  int isDelete            /* Delete on close if true */
+){
+  const sqlite3_io_methods *pLockingStyle;
+  unixFile *pNew = (unixFile *)pId;
+  int rc = SQLITE_OK;
 
   assert( pNew->pLock==NULL );
   assert( pNew->pOpen==NULL );
 
-  /* Parameter isDelete is only used on vxworks. Parameter pVfs is only
-  ** used if ENABLE_LOCKING_STYLE is defined. Express this explicitly
-  ** here to prevent compiler warnings about unused parameters.
-  */
-  if( !IS_VXWORKS ) UNUSED_PARAMETER(isDelete);
-  if( !SQLITE_ENABLE_LOCKING_STYLE ) UNUSED_PARAMETER(pVfs);
-  if( !IS_VXWORKS && !SQLITE_ENABLE_LOCKING_STYLE ) UNUSED_PARAMETER(zFilename);
+  /* Parameter isDelete is only used on vxworks.
+  ** Express this explicitly here to prevent compiler warnings
+  ** about unused parameters.
+  */
+#if !OS_VXWORKS
+  UNUSED_PARAMETER(isDelete);
+#endif
 
   OSTRACE3("OPEN    %-3d %s\n", h, zFilename);
   pNew->h = h;
   pNew->dirfd = dirfd;
   SET_THREADID(pNew);
 
-#if IS_VXWORKS
-  {
-    HashElem *pElem;
-    char *zRealname = vxrealpath(zFilename, 1);
-    int n;
-    pNew->zRealpath = 0;
-    if( !zRealname ){
-      rc = SQLITE_NOMEM;
-      eLockingStyle = LOCKING_STYLE_NONE;
-    }else{
-      n = strlen(zRealname) + 1;
-      enterMutex();
-      pElem = sqlite3HashFindElem(&nameHash, zRealname, n);
-      if( pElem ){
-        long cnt = (long)pElem->data;
-        cnt++;
-        pNew->zRealpath = pElem->pKey;
-        pElem->data = (void*)cnt;
-      }else{
-        if( sqlite3HashInsert(&nameHash, zRealname, n, (void*)1)==0 ){
-          pElem = sqlite3HashFindElem(&nameHash, zRealname, n);
-          if( pElem ){
-            pNew->zRealpath = pElem->pKey;
-          }else{
-            sqlite3HashInsert(&nameHash, zRealname, n, 0);
-            rc = SQLITE_NOMEM;
-            eLockingStyle = LOCKING_STYLE_NONE;
-          }
-        }
-      }
-      leaveMutex();
-      sqlite3_free(zRealname);
-    }
+#if OS_VXWORKS
+  pNew->pId = vxworksFindFileId(zFilename);
+  if( pNew->pId==0 ){
+    noLock = 1;
+    rc = SQLITE_NOMEM;
   }
 #endif
 
   if( noLock ){
-    eLockingStyle = LOCKING_STYLE_NONE;
-  }else{
-    eLockingStyle = detectLockingStyle(pVfs, zFilename, h);
-  }
-
-  switch( eLockingStyle ){
-
-    case LOCKING_STYLE_POSIX: {
-      enterMutex();
-#if IS_VXWORKS
-      rc = findLockInfo(h, pNew->zRealpath, &pNew->pLock, &pNew->pOpen);
-#else
-      rc = findLockInfo(h, &pNew->pLock, &pNew->pOpen);
-#endif
-      leaveMutex();
-      break;
-    }
-
+    pLockingStyle = &nolockIoMethods;
+  }else{
+    pLockingStyle = (**(finder_type*)pVfs->pAppData)(zFilename, h);
 #if SQLITE_ENABLE_LOCKING_STYLE
-
-#if !IS_VXWORKS
-    case LOCKING_STYLE_AFP: {
-      /* AFP locking uses the file path so it needs to be included in
-      ** the afpLockingContext.
-      */
-      afpLockingContext *pCtx;
-      pNew->lockingContext = pCtx = sqlite3_malloc( sizeof(*pCtx) );
-      if( pCtx==0 ){
-        rc = SQLITE_NOMEM;
-      }else{
-        /* NB: zFilename exists and remains valid until the file is closed
-        ** according to requirement F11141.  So we do not need to make a
-        ** copy of the filename. */
-        pCtx->filePath = zFilename;
-        srandomdev();
-      }
-      break;
-    }
-#endif
-
-    case LOCKING_STYLE_DOTFILE: {
-      /* Dotfile locking uses the file path so it needs to be included in
-      ** the dotlockLockingContext
-      */
-      char *zLockFile;
-      int nFilename;
-      nFilename = strlen(zFilename) + 6;
-      zLockFile = (char *)sqlite3_malloc(nFilename);
-      if( zLockFile==0 ){
+    /* Cache zFilename in the locking context (AFP and dotlock override) for
+    ** proxyLock activation is possible (remote proxy is based on db name)
+    ** zFilename remains valid until file is closed, to support */
+    pNew->lockingContext = (void*)zFilename;
+#endif
+  }
+
+  if( pLockingStyle == &posixIoMethods ){
+    unixEnterMutex();
+    rc = findLockInfo(pNew, &pNew->pLock, &pNew->pOpen);
+    unixLeaveMutex();
+  }
+
+#if SQLITE_ENABLE_LOCKING_STYLE && defined(__DARWIN__)
+  else if( pLockingStyle == &afpIoMethods ){
+    /* AFP locking uses the file path so it needs to be included in
+    ** the afpLockingContext.
+    */
+    afpLockingContext *pCtx;
+    pNew->lockingContext = pCtx = sqlite3_malloc( sizeof(*pCtx) );
+    if( pCtx==0 ){
+      rc = SQLITE_NOMEM;
+    }else{
+      /* NB: zFilename exists and remains valid until the file is closed
+      ** according to requirement F11141.  So we do not need to make a
+      ** copy of the filename. */
+      pCtx->dbPath = zFilename;
+      srandomdev();
+      unixEnterMutex();
+      rc = findLockInfo(pNew, NULL, &pNew->pOpen);
+      unixLeaveMutex();
+    }
+  }
+#endif
+
+  else if( pLockingStyle == &dotlockIoMethods ){
+    /* Dotfile locking uses the file path so it needs to be included in
+    ** the dotlockLockingContext
+    */
+    char *zLockFile;
+    int nFilename;
+    nFilename = (int)strlen(zFilename) + 6;
+    zLockFile = (char *)sqlite3_malloc(nFilename);
+    if( zLockFile==0 ){
+      rc = SQLITE_NOMEM;
+    }else{
+      sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename);
+    }
+    pNew->lockingContext = zLockFile;
+  }
+
+#if OS_VXWORKS
+  else if( pLockingStyle == &semIoMethods ){
+    /* Named semaphore locking uses the file path so it needs to be
+    ** included in the semLockingContext
+    */
+    unixEnterMutex();
+    rc = findLockInfo(pNew, &pNew->pLock, &pNew->pOpen);
+    if( (rc==SQLITE_OK) && (pNew->pOpen->pSem==NULL) ){
+      char *zSemName = pNew->pOpen->aSemName;
+      int n;
+      sqlite3_snprintf(MAX_PATHNAME, zSemName, "%s.sem",
+                       pNew->pId->zCanonicalName);
+      for( n=0; zSemName[n]; n++ )
+        if( zSemName[n]=='/' ) zSemName[n] = '_';
+      pNew->pOpen->pSem = sem_open(zSemName, O_CREAT, 0666, 1);
+      if( pNew->pOpen->pSem == SEM_FAILED ){
         rc = SQLITE_NOMEM;
-      }else{
-        sqlite3_snprintf(nFilename, zLockFile, "%s.lock", zFilename);
-      }
-      pNew->lockingContext = zLockFile;
-      break;
-    }
-
-#if IS_VXWORKS
-    case LOCKING_STYLE_NAMEDSEM: {
-      /* Named semaphore locking uses the file path so it needs to be
-      ** included in the namedsemLockingContext
-      */
-      enterMutex();
-      rc = findLockInfo(h, pNew->zRealpath, &pNew->pLock, &pNew->pOpen);
-      if( (rc==SQLITE_OK) && (pNew->pOpen->pSem==NULL) ){
-        char *zSemName = pNew->pOpen->aSemName;
-        int n;
-        sqlite3_snprintf(MAX_PATHNAME, zSemName, "%s.sem", pNew->zRealpath);
-        for( n=0; zSemName[n]; n++ )
-          if( zSemName[n]=='/' ) zSemName[n] = '_';
-        pNew->pOpen->pSem = sem_open(zSemName, O_CREAT, 0666, 1);
-        if( pNew->pOpen->pSem == SEM_FAILED ){
-          rc = SQLITE_NOMEM;
-          pNew->pOpen->aSemName[0] = '\0';
-        }
-      }
-      leaveMutex();
-      break;
-    }
-#endif
-
-    case LOCKING_STYLE_FLOCK:
-    case LOCKING_STYLE_NONE:
-      break;
-#endif
-  }
+        pNew->pOpen->aSemName[0] = '\0';
+      }
+    }
+    unixLeaveMutex();
+  }
+#endif
 
   pNew->lastErrno = 0;
-#if IS_VXWORKS
+#if OS_VXWORKS
   if( rc!=SQLITE_OK ){
     unlink(zFilename);
     isDelete = 0;
   }
   pNew->isDelete = isDelete;
 #endif
   if( rc!=SQLITE_OK ){
-    if( dirfd>=0 ) close(dirfd);
+    if( dirfd>=0 ) close(dirfd); /* silent leak if fail, already in error */
     close(h);
   }else{
-    pNew->pMethod = &aIoMethod[eLockingStyle-1];
+    pNew->pMethod = pLockingStyle;
     OpenCounter(+1);
   }
   return rc;
 }
@@ -24504,9 +25002,9 @@
   int fd = -1;
   char zDirname[MAX_PATHNAME+1];
 
   sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename);
-  for(ii=strlen(zDirname); ii>=0 && zDirname[ii]!='/'; ii--);
+  for(ii=(int)strlen(zDirname); ii>=0 && zDirname[ii]!='/'; ii--);
   if( ii>0 ){
     zDirname[ii] = '\0';
     fd = open(zDirname, O_RDONLY|O_BINARY, 0);
     if( fd>=0 ){
@@ -24527,8 +25025,9 @@
 */
 static int getTempname(int nBuf, char *zBuf){
   static const char *azDirs[] = {
      0,
+     0,
      "/var/tmp",
      "/usr/tmp",
      "/tmp",
      ".",
@@ -24536,9 +25035,9 @@
   static const unsigned char zChars[] =
     "abcdefghijklmnopqrstuvwxyz"
     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
     "0123456789";
-  int i, j;
+  unsigned int i, j;
   struct stat buf;
   const char *zDir = ".";
 
   /* It's odd to simulate an io-error here, but really this is just
@@ -24547,9 +25046,13 @@
   */
   SimulateIOError( return SQLITE_IOERR );
 
   azDirs[0] = sqlite3_temp_directory;
-  for(i=0; i<ArraySize(azDirs); i++){
+  if (NULL == azDirs[1]) {
+    azDirs[1] = getenv("TMPDIR");
+  }
+
+  for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
     if( azDirs[i]==0 ) continue;
     if( stat(azDirs[i], &buf) ) continue;
     if( !S_ISDIR(buf.st_mode) ) continue;
     if( access(azDirs[i], 07) ) continue;
@@ -24565,9 +25068,9 @@
   }
 
   do{
     sqlite3_snprintf(nBuf-17, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir);
-    j = strlen(zBuf);
+    j = (int)strlen(zBuf);
     sqlite3_randomness(15, &zBuf[j]);
     for(i=0; i<15; i++, j++){
       zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
     }
@@ -24574,8 +25077,17 @@
     zBuf[j] = 0;
   }while( access(zBuf,0)==0 );
   return SQLITE_OK;
 }
+
+#if SQLITE_ENABLE_LOCKING_STYLE && defined(__DARWIN__)
+/*
+** Routine to transform a unixFile into a proxy-locking unixFile.
+** Implementation in the proxy-lock division, but used by unixOpen()
+** if SQLITE_PREFER_PROXY_LOCKING is defined.
+*/
+static int proxyTransformUnixFile(unixFile*, const char*);
+#endif
 
 
 /*
 ** Open the file zPath.
@@ -24599,19 +25111,20 @@
 ** interface, add the DELETEONCLOSE flag to those specified above for
 ** OpenExclusive().
 */
 static int unixOpen(
-  sqlite3_vfs *pVfs,
-  const char *zPath,
-  sqlite3_file *pFile,
-  int flags,
-  int *pOutFlags
+  sqlite3_vfs *pVfs,           /* The VFS for which this is the xOpen method */
+  const char *zPath,           /* Pathname of file to be opened */
+  sqlite3_file *pFile,         /* The file descriptor to be filled in */
+  int flags,                   /* Input flags to control the opening */
+  int *pOutFlags               /* Output flags returned to SQLite core */
 ){
   int fd = 0;                    /* File descriptor returned by open() */
   int dirfd = -1;                /* Directory file descriptor */
-  int oflags = 0;                /* Flags to pass to open() */
+  int openFlags = 0;             /* Flags to pass to open() */
   int eType = flags&0xFFFFFF00;  /* Type of file to open */
   int noLock;                    /* True to omit locking primitives */
+  int rc = SQLITE_OK;
 
   int isExclusive  = (flags & SQLITE_OPEN_EXCLUSIVE);
   int isDelete     = (flags & SQLITE_OPEN_DELETEONCLOSE);
   int isCreate     = (flags & SQLITE_OPEN_CREATE);
@@ -24660,9 +25173,8 @@
 
   memset(pFile, 0, sizeof(unixFile));
 
   if( !zName ){
-    int rc;
     assert(isDelete && !isOpenDirectory);
     rc = getTempname(MAX_PATHNAME+1, zTmpname);
     if( rc!=SQLITE_OK ){
       return rc;
@@ -24669,16 +25181,16 @@
     }
     zName = zTmpname;
   }
 
-  if( isReadonly )  oflags |= O_RDONLY;
-  if( isReadWrite ) oflags |= O_RDWR;
-  if( isCreate )    oflags |= O_CREAT;
-  if( isExclusive ) oflags |= (O_EXCL|O_NOFOLLOW);
-  oflags |= (O_LARGEFILE|O_BINARY);
-
-  fd = open(zName, oflags, isDelete?0600:SQLITE_DEFAULT_FILE_PERMISSIONS);
-  OSTRACE4("OPENX   %-3d %s 0%o\n", fd, zName, oflags);
+  if( isReadonly )  openFlags |= O_RDONLY;
+  if( isReadWrite ) openFlags |= O_RDWR;
+  if( isCreate )    openFlags |= O_CREAT;
+  if( isExclusive ) openFlags |= (O_EXCL|O_NOFOLLOW);
+  openFlags |= (O_LARGEFILE|O_BINARY);
+
+  fd = open(zName, openFlags, isDelete?0600:SQLITE_DEFAULT_FILE_PERMISSIONS);
+  OSTRACE4("OPENX   %-3d %s 0%o\n", fd, zName, openFlags);
   if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){
     /* Failed to open the file for read/write access. Try read-only. */
     flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
     flags |= SQLITE_OPEN_READONLY;
@@ -24687,23 +25199,28 @@
   if( fd<0 ){
     return SQLITE_CANTOPEN;
   }
   if( isDelete ){
-#if IS_VXWORKS
+#if OS_VXWORKS
     zPath = zName;
 #else
     unlink(zName);
 #endif
   }
+#if SQLITE_ENABLE_LOCKING_STYLE
+  else{
+    ((unixFile*)pFile)->openFlags = openFlags;
+  }
+#endif
   if( pOutFlags ){
     *pOutFlags = flags;
   }
 
   assert(fd!=0);
   if( isOpenDirectory ){
-    int rc = openDirectory(zPath, &dirfd);
-    if( rc!=SQLITE_OK ){
-      close(fd);
+    rc = openDirectory(zPath, &dirfd);
+    if( rc!=SQLITE_OK ){
+      close(fd); /* silently leak if fail, already in error */
       return rc;
     }
   }
 
@@ -24711,16 +25228,52 @@
   fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
 #endif
 
   noLock = eType!=SQLITE_OPEN_MAIN_DB;
+
+#if SQLITE_PREFER_PROXY_LOCKING
+  if( zPath!=NULL && !noLock ){
+    char *envforce = getenv("SQLITE_FORCE_PROXY_LOCKING");
+    int useProxy = 0;
+
+    /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy,
+    ** 0 means never use proxy, NULL means use proxy for non-local files only
+    */
+    if( envforce!=NULL ){
+      useProxy = atoi(envforce)>0;
+    }else{
+      struct statfs fsInfo;
+
+      if( statfs(zPath, &fsInfo) == -1 ){
+				((unixFile*)pFile)->lastErrno = errno;
+        if( dirfd>=0 ) close(dirfd); /* silently leak if fail, in error */
+        close(fd); /* silently leak if fail, in error */
+        return SQLITE_IOERR_ACCESS;
+      }
+      useProxy = !(fsInfo.f_flags&MNT_LOCAL);
+    }
+    if( useProxy ){
+      rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete);
+      if( rc==SQLITE_OK ){
+        rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:");
+      }
+      return rc;
+    }
+  }
+#endif
+
   return fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete);
 }
 
 /*
 ** Delete the file at zPath. If the dirSync argument is true, fsync()
 ** the directory after deleting the file.
 */
-static int unixDelete(sqlite3_vfs *NotUsed, const char *zPath, int dirSync){
+static int unixDelete(
+  sqlite3_vfs *NotUsed,     /* VFS containing this as the xDelete method */
+  const char *zPath,        /* Name of file to be deleted */
+  int dirSync               /* If true, fsync() directory after deleting file */
+){
   int rc = SQLITE_OK;
   UNUSED_PARAMETER(NotUsed);
   SimulateIOError(return SQLITE_IOERR_DELETE);
   unlink(zPath);
@@ -24728,17 +25281,19 @@
   if( dirSync ){
     int fd;
     rc = openDirectory(zPath, &fd);
     if( rc==SQLITE_OK ){
-#if IS_VXWORKS
+#if OS_VXWORKS
       if( fsync(fd)==-1 )
 #else
       if( fsync(fd) )
 #endif
       {
         rc = SQLITE_IOERR_DIR_FSYNC;
       }
-      close(fd);
+      if( close(fd)&&!rc ){
+        rc = SQLITE_IOERR_DIR_CLOSE;
+      }
     }
   }
 #endif
   return rc;
@@ -24754,12 +25309,12 @@
 **
 ** Otherwise return 0.
 */
 static int unixAccess(
-  sqlite3_vfs *NotUsed,
-  const char *zPath,
-  int flags,
-  int *pResOut
+  sqlite3_vfs *NotUsed,   /* The VFS containing this xAccess method */
+  const char *zPath,      /* Path of the file to examine */
+  int flags,              /* What do we want to learn about the zPath file? */
+  int *pResOut            /* Write result boolean here */
 ){
   int amode = 0;
   UNUSED_PARAMETER(NotUsed);
   SimulateIOError( return SQLITE_IOERR_ACCESS; );
@@ -24800,27 +25355,15 @@
 
   /* It's odd to simulate an io-error here, but really this is just
   ** using the io-error infrastructure to test that SQLite handles this
   ** function failing. This function could fail if, for example, the
-  ** current working directly has been unlinked.
+  ** current working directory has been unlinked.
   */
   SimulateIOError( return SQLITE_ERROR );
 
   assert( pVfs->mxPathname==MAX_PATHNAME );
   UNUSED_PARAMETER(pVfs);
 
-#if IS_VXWORKS
-  {
-    char *zRealname = vxrealpath(zPath, 0);
-    zOut[0] = '\0';
-    if( !zRealname ){
-      return SQLITE_CANTOPEN;
-    }
-    sqlite3_snprintf(nOut, zOut, "%s", zRealname);
-    sqlite3_free(zRealname);
-    return SQLITE_OK;
-  }
-#else
   zOut[nOut-1] = '\0';
   if( zPath[0]=='/' ){
     sqlite3_snprintf(nOut, zOut, "%s", zPath);
   }else{
@@ -24827,39 +25370,12 @@
     int nCwd;
     if( getcwd(zOut, nOut-1)==0 ){
       return SQLITE_CANTOPEN;
     }
-    nCwd = strlen(zOut);
+    nCwd = (int)strlen(zOut);
     sqlite3_snprintf(nOut-nCwd, &zOut[nCwd], "/%s", zPath);
   }
   return SQLITE_OK;
-
-#if 0
-  /*
-  ** Remove "/./" path elements and convert "/A/./" path elements
-  ** to just "/".
-  */
-  if( zFull ){
-    int i, j;
-    for(i=j=0; zFull[i]; i++){
-      if( zFull[i]=='/' ){
-        if( zFull[i+1]=='/' ) continue;
-        if( zFull[i+1]=='.' && zFull[i+2]=='/' ){
-          i += 1;
-          continue;
-        }
-        if( zFull[i+1]=='.' && zFull[i+2]=='.' && zFull[i+3]=='/' ){
-          while( j>0 && zFull[j-1]!='/' ){ j--; }
-          i += 3;
-          continue;
-        }
-      }
-      zFull[j++] = zFull[i];
-    }
-    zFull[j] = 0;
-  }
-#endif
-#endif
 }
 
 
 #ifndef SQLITE_OMIT_LOAD_EXTENSION
@@ -24882,18 +25398,37 @@
 */
 static void unixDlError(sqlite3_vfs *NotUsed, int nBuf, char *zBufOut){
   char *zErr;
   UNUSED_PARAMETER(NotUsed);
-  enterMutex();
+  unixEnterMutex();
   zErr = dlerror();
   if( zErr ){
     sqlite3_snprintf(nBuf, zBufOut, "%s", zErr);
   }
-  leaveMutex();
-}
-static void *unixDlSym(sqlite3_vfs *NotUsed, void *pHandle, const char*zSymbol){
-  UNUSED_PARAMETER(NotUsed);
-  return dlsym(pHandle, zSymbol);
+  unixLeaveMutex();
+}
+static void (*unixDlSym(sqlite3_vfs *NotUsed, void *p, const char*zSym))(void){
+  /*
+  ** GCC with -pedantic-errors says that C90 does not allow a void* to be
+  ** cast into a pointer to a function.  And yet the library dlsym() routine
+  ** returns a void* which is really a pointer to a function.  So how do we
+  ** use dlsym() with -pedantic-errors?
+  **
+  ** Variable x below is defined to be a pointer to a function taking
+  ** parameters void* and const char* and returning a pointer to a function.
+  ** We initialize x by assigning it a pointer to the dlsym() function.
+  ** (That assignment requires a cast.)  Then we call the function that
+  ** x points to.
+  **
+  ** This work-around is unlikely to work correctly on any system where
+  ** you really cannot cast a function pointer into void*.  But then, on the
+  ** other hand, dlsym() will not work on such a system either, so we have
+  ** not really lost anything.
+  */
+  void (*(*x)(void*,const char*))(void);
+  UNUSED_PARAMETER(NotUsed);
+  x = (void(*(*)(void*,const char*))(void))dlsym;
+  return (*x)(p, zSym);
 }
 static void unixDlClose(sqlite3_vfs *NotUsed, void *pHandle){
   UNUSED_PARAMETER(NotUsed);
   dlclose(pHandle);
@@ -24955,9 +25490,9 @@
 ** might be greater than or equal to the argument, but not less
 ** than the argument.
 */
 static int unixSleep(sqlite3_vfs *NotUsed, int microseconds){
-#if IS_VXWORKS
+#if OS_VXWORKS
   struct timespec sp;
 
   sp.tv_sec = microseconds / 1000000;
   sp.tv_nsec = (microseconds % 1000000) * 1000;
@@ -24974,13 +25509,14 @@
   UNUSED_PARAMETER(NotUsed);
 }
 
 /*
-** The following variable, if set to a non-zero value, becomes the result
-** returned from sqlite3OsCurrentTime().  This is used for testing.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_current_time = 0;
+** The following variable, if set to a non-zero value, is interpreted as
+** the number of seconds since 1970 and is used to set the result of
+** sqlite3OsCurrentTime() during testing.
+*/
+#ifdef SQLITE_TEST
+SQLITE_API int sqlite3_current_time = 0;  /* Fake system time in seconds since 1970. */
 #endif
 
 /*
 ** Find the current time (in Universal Coordinated Time).  Write the
@@ -24987,16 +25523,16 @@
 ** current time and date as a Julian Day number into *prNow and
 ** return 0.  Return 1 if the time and date cannot be found.
 */
 static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){
-#if IS_VXWORKS
+#if defined(NO_GETTOD)
+  time_t t;
+  time(&t);
+  *prNow = t/86400.0 + 2440587.5;
+#elif OS_VXWORKS
   struct timespec sNow;
   clock_gettime(CLOCK_REALTIME, &sNow);
   *prNow = 2440587.5 + sNow.tv_sec/86400.0 + sNow.tv_nsec/86400000000000.0;
-#elif defined(NO_GETTOD)
-  time_t t;
-  time(&t);
-  *prNow = t/86400.0 + 2440587.5;
 #else
   struct timeval sNow;
   gettimeofday(&sNow, 0);
   *prNow = 2440587.5 + sNow.tv_sec/86400.0 + sNow.tv_usec/86400000000.0;
@@ -25010,8 +25546,15 @@
   UNUSED_PARAMETER(NotUsed);
   return 0;
 }
 
+/*
+** We added the xGetLastError() method with the intention of providing
+** better low-level error messages when operating-system problems come up
+** during SQLite operation.  But so far, none of that has been implemented
+** in the core.  So this routine is never called.  For now, it is merely
+** a place-holder.
+*/
 static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
   UNUSED_PARAMETER(NotUsed);
   UNUSED_PARAMETER(NotUsed2);
   UNUSED_PARAMETER(NotUsed3);
@@ -25018,23 +25561,982 @@
   return 0;
 }
 
 /*
+************************ End of sqlite3_vfs methods ***************************
+******************************************************************************/
+
+/******************************************************************************
+************************** Begin Proxy Locking ********************************
+**
+** Proxy locking is a "uber-locking-method" in this sense:  It uses the
+** other locking methods on secondary lock files.  Proxy locking is a
+** meta-layer over top of the primitive locking implemented above.  For
+** this reason, the division that implements of proxy locking is deferred
+** until late in the file (here) after all of the other I/O methods have
+** been defined - so that the primitive locking methods are available
+** as services to help with the implementation of proxy locking.
+**
+****
+**
+** The default locking schemes in SQLite use byte-range locks on the
+** database file to coordinate safe, concurrent access by multiple readers
+** and writers [http://sqlite.org/lockingv3.html].  The five file locking
+** states (UNLOCKED, PENDING, SHARED, RESERVED, EXCLUSIVE) are implemented
+** as POSIX read & write locks over fixed set of locations (via fsctl),
+** on AFP and SMB only exclusive byte-range locks are available via fsctl
+** with _IOWR('z', 23, struct ByteRangeLockPB2) to track the same 5 states.
+** To simulate a F_RDLCK on the shared range, on AFP a randomly selected
+** address in the shared range is taken for a SHARED lock, the entire
+** shared range is taken for an EXCLUSIVE lock):
+**
+**      PENDING_BYTE        0x40000000
+**      RESERVED_BYTE       0x40000001
+**      SHARED_RANGE        0x40000002 -> 0x40000200
+**
+** This works well on the local file system, but shows a nearly 100x
+** slowdown in read performance on AFP because the AFP client disables
+** the read cache when byte-range locks are present.  Enabling the read
+** cache exposes a cache coherency problem that is present on all OS X
+** supported network file systems.  NFS and AFP both observe the
+** close-to-open semantics for ensuring cache coherency
+** [http://nfs.sourceforge.net/#faq_a8], which does not effectively
+** address the requirements for concurrent database access by multiple
+** readers and writers
+** [http://www.nabble.com/SQLite-on-NFS-cache-coherency-td15655701.html].
+**
+** To address the performance and cache coherency issues, proxy file locking
+** changes the way database access is controlled by limiting access to a
+** single host at a time and moving file locks off of the database file
+** and onto a proxy file on the local file system.
+**
+**
+** Using proxy locks
+** -----------------
+**
+** C APIs
+**
+**  sqlite3_file_control(db, dbname, SQLITE_SET_LOCKPROXYFILE,
+**                       <proxy_path> | ":auto:");
+**  sqlite3_file_control(db, dbname, SQLITE_GET_LOCKPROXYFILE, &<proxy_path>);
+**
+**
+** SQL pragmas
+**
+**  PRAGMA [database.]lock_proxy_file=<proxy_path> | :auto:
+**  PRAGMA [database.]lock_proxy_file
+**
+** Specifying ":auto:" means that if there is a conch file with a matching
+** host ID in it, the proxy path in the conch file will be used, otherwise
+** a proxy path based on the user's temp dir
+** (via confstr(_CS_DARWIN_USER_TEMP_DIR,...)) will be used and the
+** actual proxy file name is generated from the name and path of the
+** database file.  For example:
+**
+**       For database path "/Users/me/foo.db"
+**       The lock path will be "<tmpdir>/sqliteplocks/_Users_me_foo.db:auto:")
+**
+** Once a lock proxy is configured for a database connection, it can not
+** be removed, however it may be switched to a different proxy path via
+** the above APIs (assuming the conch file is not being held by another
+** connection or process).
+**
+**
+** How proxy locking works
+** -----------------------
+**
+** Proxy file locking relies primarily on two new supporting files:
+**
+**   *  conch file to limit access to the database file to a single host
+**      at a time
+**
+**   *  proxy file to act as a proxy for the advisory locks normally
+**      taken on the database
+**
+** The conch file - to use a proxy file, sqlite must first "hold the conch"
+** by taking an sqlite-style shared lock on the conch file, reading the
+** contents and comparing the host's unique host ID (see below) and lock
+** proxy path against the values stored in the conch.  The conch file is
+** stored in the same directory as the database file and the file name
+** is patterned after the database file name as ".<databasename>-conch".
+** If the conch file does not exist, or it's contents do not match the
+** host ID and/or proxy path, then the lock is escalated to an exclusive
+** lock and the conch file contents is updated with the host ID and proxy
+** path and the lock is downgraded to a shared lock again.  If the conch
+** is held by another process (with a shared lock), the exclusive lock
+** will fail and SQLITE_BUSY is returned.
+**
+** The proxy file - a single-byte file used for all advisory file locks
+** normally taken on the database file.   This allows for safe sharing
+** of the database file for multiple readers and writers on the same
+** host (the conch ensures that they all use the same local lock file).
+**
+** There is a third file - the host ID file - used as a persistent record
+** of a unique identifier for the host, a 128-byte unique host id file
+** in the path defined by the HOSTIDPATH macro (default value is
+** /Library/Caches/.com.apple.sqliteConchHostId).
+**
+** Requesting the lock proxy does not immediately take the conch, it is
+** only taken when the first request to lock database file is made.
+** This matches the semantics of the traditional locking behavior, where
+** opening a connection to a database file does not take a lock on it.
+** The shared lock and an open file descriptor are maintained until
+** the connection to the database is closed.
+**
+** The proxy file and the lock file are never deleted so they only need
+** to be created the first time they are used.
+**
+** Configuration options
+** ---------------------
+**
+**  SQLITE_PREFER_PROXY_LOCKING
+**
+**       Database files accessed on non-local file systems are
+**       automatically configured for proxy locking, lock files are
+**       named automatically using the same logic as
+**       PRAGMA lock_proxy_file=":auto:"
+**
+**  SQLITE_PROXY_DEBUG
+**
+**       Enables the logging of error messages during host id file
+**       retrieval and creation
+**
+**  HOSTIDPATH
+**
+**       Overrides the default host ID file path location
+**
+**  LOCKPROXYDIR
+**
+**       Overrides the default directory used for lock proxy files that
+**       are named automatically via the ":auto:" setting
+**
+**  SQLITE_DEFAULT_PROXYDIR_PERMISSIONS
+**
+**       Permissions to use when creating a directory for storing the
+**       lock proxy files, only used when LOCKPROXYDIR is not set.
+**
+**
+** As mentioned above, when compiled with SQLITE_PREFER_PROXY_LOCKING,
+** setting the environment variable SQLITE_FORCE_PROXY_LOCKING to 1 will
+** force proxy locking to be used for every database file opened, and 0
+** will force automatic proxy locking to be disabled for all database
+** files (explicity calling the SQLITE_SET_LOCKPROXYFILE pragma or
+** sqlite_file_control API is not affected by SQLITE_FORCE_PROXY_LOCKING).
+*/
+
+/*
+** Proxy locking is only available on MacOSX
+*/
+#if defined(__DARWIN__) && SQLITE_ENABLE_LOCKING_STYLE
+
+#ifdef SQLITE_TEST
+/* simulate multiple hosts by creating unique hostid file paths */
+SQLITE_API int sqlite3_hostid_num = 0;
+#endif
+
+/*
+** The proxyLockingContext has the path and file structures for the remote
+** and local proxy files in it
+*/
+typedef struct proxyLockingContext proxyLockingContext;
+struct proxyLockingContext {
+  unixFile *conchFile;         /* Open conch file */
+  char *conchFilePath;         /* Name of the conch file */
+  unixFile *lockProxy;         /* Open proxy lock file */
+  char *lockProxyPath;         /* Name of the proxy lock file */
+  char *dbPath;                /* Name of the open file */
+  int conchHeld;               /* True if the conch is currently held */
+  void *oldLockingContext;     /* Original lockingcontext to restore on close */
+  sqlite3_io_methods const *pOldMethod;     /* Original I/O methods for close */
+};
+
+/* HOSTIDLEN and CONCHLEN both include space for the string
+** terminating nul
+*/
+#define HOSTIDLEN         128
+#define CONCHLEN          (MAXPATHLEN+HOSTIDLEN+1)
+#ifndef HOSTIDPATH
+# define HOSTIDPATH       "/Library/Caches/.com.apple.sqliteConchHostId"
+#endif
+
+/* basically a copy of unixRandomness with different
+** test behavior built in */
+static int proxyGenerateHostID(char *pHostID){
+  int pid, fd, len;
+  unsigned char *key = (unsigned char *)pHostID;
+
+  memset(key, 0, HOSTIDLEN);
+  len = 0;
+  fd = open("/dev/urandom", O_RDONLY);
+  if( fd>=0 ){
+    len = read(fd, key, HOSTIDLEN);
+    close(fd); /* silently leak the fd if it fails */
+  }
+  if( len < HOSTIDLEN ){
+    time_t t;
+    time(&t);
+    memcpy(key, &t, sizeof(t));
+    pid = getpid();
+    memcpy(&key[sizeof(t)], &pid, sizeof(pid));
+  }
+
+#ifdef MAKE_PRETTY_HOSTID
+  {
+    int i;
+    /* filter the bytes into printable ascii characters and NUL terminate */
+    key[(HOSTIDLEN-1)] = 0x00;
+    for( i=0; i<(HOSTIDLEN-1); i++ ){
+      unsigned char pa = key[i]&0x7F;
+      if( pa<0x20 ){
+        key[i] = (key[i]&0x80 == 0x80) ? pa+0x40 : pa+0x20;
+      }else if( pa==0x7F ){
+        key[i] = (key[i]&0x80 == 0x80) ? pa=0x20 : pa+0x7E;
+      }
+    }
+  }
+#endif
+  return SQLITE_OK;
+}
+
+/* writes the host id path to path, path should be an pre-allocated buffer
+** with enough space for a path
+*/
+static void proxyGetHostIDPath(char *path, size_t len){
+  strlcpy(path, HOSTIDPATH, len);
+#ifdef SQLITE_TEST
+  if( sqlite3_hostid_num>0 ){
+    char suffix[2] = "1";
+    suffix[0] = suffix[0] + sqlite3_hostid_num;
+    strlcat(path, suffix, len);
+  }
+#endif
+  OSTRACE3("GETHOSTIDPATH  %s pid=%d\n", path, getpid());
+}
+
+/* get the host ID from a sqlite hostid file stored in the
+** user-specific tmp directory, create the ID if it's not there already
+*/
+static int proxyGetHostID(char *pHostID, int *pError){
+  int fd;
+  char path[MAXPATHLEN];
+  size_t len;
+  int rc=SQLITE_OK;
+
+  proxyGetHostIDPath(path, MAXPATHLEN);
+  /* try to create the host ID file, if it already exists read the contents */
+  fd = open(path, O_CREAT|O_WRONLY|O_EXCL, 0644);
+  if( fd<0 ){
+    int err=errno;
+
+    if( err!=EEXIST ){
+#ifdef SQLITE_PROXY_DEBUG /* set the sqlite error message instead */
+      fprintf(stderr, "sqlite error creating host ID file %s: %s\n",
+              path, strerror(err));
+#endif
+      return SQLITE_PERM;
+    }
+    /* couldn't create the file, read it instead */
+    fd = open(path, O_RDONLY|O_EXCL);
+    if( fd<0 ){
+#ifdef SQLITE_PROXY_DEBUG /* set the sqlite error message instead */
+      int err = errno;
+      fprintf(stderr, "sqlite error opening host ID file %s: %s\n",
+              path, strerror(err));
+#endif
+      return SQLITE_PERM;
+    }
+    len = pread(fd, pHostID, HOSTIDLEN, 0);
+    if( len<0 ){
+      *pError = errno;
+      rc = SQLITE_IOERR_READ;
+    }else if( len<HOSTIDLEN ){
+      *pError = 0;
+      rc = SQLITE_IOERR_SHORT_READ;
+    }
+    close(fd); /* silently leak the fd if it fails */
+    OSTRACE3("GETHOSTID  read %s pid=%d\n", pHostID, getpid());
+    return rc;
+  }else{
+    /* we're creating the host ID file (use a random string of bytes) */
+    proxyGenerateHostID(pHostID);
+    len = pwrite(fd, pHostID, HOSTIDLEN, 0);
+    if( len<0 ){
+      *pError = errno;
+      rc = SQLITE_IOERR_WRITE;
+    }else if( len<HOSTIDLEN ){
+      *pError = 0;
+      rc = SQLITE_IOERR_WRITE;
+    }
+    close(fd); /* silently leak the fd if it fails */
+    OSTRACE3("GETHOSTID  wrote %s pid=%d\n", pHostID, getpid());
+    return rc;
+  }
+}
+
+static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){
+  int len;
+  int dbLen;
+  int i;
+
+#ifdef LOCKPROXYDIR
+  len = strlcpy(lPath, LOCKPROXYDIR, maxLen);
+#else
+# ifdef _CS_DARWIN_USER_TEMP_DIR
+  {
+    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
+      if( err!=EEXIST ){
+        fprintf(stderr, "proxyGetLockPath: mkdir(%s,0%o) error %d %s\n", lPath,
+                SQLITE_DEFAULT_PROXYDIR_PERMISSIONS, err, strerror(err));
+      }
+#  endif
+    }else{
+      OSTRACE3("GETLOCKPATH  mkdir %s pid=%d\n", lPath, getpid());
+    }
+
+  }
+# else
+  len = strlcpy(lPath, "/tmp/", maxLen);
+# endif
+#endif
+
+  if( lPath[len-1]!='/' ){
+    len = strlcat(lPath, "/", maxLen);
+  }
+
+  /* transform the db path to a unique cache name */
+  dbLen = (int)strlen(dbPath);
+  for( i=0; i<dbLen && (i+len+7)<maxLen; i++){
+    char c = dbPath[i];
+    lPath[i+len] = (c=='/')?'_':c;
+  }
+  lPath[i+len]='\0';
+  strlcat(lPath, ":auto:", maxLen);
+  return SQLITE_OK;
+}
+
+/*
+** Create a new VFS file descriptor (stored in memory obtained from
+** sqlite3_malloc) and open the file named "path" in the file descriptor.
+**
+** The caller is responsible not only for closing the file descriptor
+** but also for freeing the memory associated with the file descriptor.
+*/
+static int proxyCreateUnixFile(const char *path, unixFile **ppFile) {
+  int fd;
+  int dirfd = -1;
+  unixFile *pNew;
+  int rc = SQLITE_OK;
+  sqlite3_vfs dummyVfs;
+
+  fd = open(path, O_RDWR | O_CREAT, SQLITE_DEFAULT_FILE_PERMISSIONS);
+  if( fd<0 ){
+    return SQLITE_CANTOPEN;
+  }
+
+  pNew = (unixFile *)sqlite3_malloc(sizeof(unixFile));
+  if( pNew==NULL ){
+    rc = SQLITE_NOMEM;
+    goto end_create_proxy;
+  }
+  memset(pNew, 0, sizeof(unixFile));
+
+  dummyVfs.pAppData = (void*)&autolockIoFinder;
+  rc = fillInUnixFile(&dummyVfs, fd, dirfd, (sqlite3_file*)pNew, path, 0, 0);
+  if( rc==SQLITE_OK ){
+    *ppFile = pNew;
+    return SQLITE_OK;
+  }
+end_create_proxy:
+  close(fd); /* silently leak fd if error, we're already in error */
+  sqlite3_free(pNew);
+  return rc;
+}
+
+/* takes the conch by taking a shared lock and read the contents conch, if
+** lockPath is non-NULL, the host ID and lock file path must match.  A NULL
+** lockPath means that the lockPath in the conch file will be used if the
+** host IDs match, or a new lock path will be generated automatically
+** and written to the conch file.
+*/
+static int proxyTakeConch(unixFile *pFile){
+  proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
+
+  if( pCtx->conchHeld>0 ){
+    return SQLITE_OK;
+  }else{
+    unixFile *conchFile = pCtx->conchFile;
+    char testValue[CONCHLEN];
+    char conchValue[CONCHLEN];
+    char lockPath[MAXPATHLEN];
+    char *tLockPath = NULL;
+    int rc = SQLITE_OK;
+    int readRc = SQLITE_OK;
+    int syncPerms = 0;
+
+    OSTRACE4("TAKECONCH  %d for %s pid=%d\n", conchFile->h,
+             (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), getpid());
+
+    rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK);
+    if( rc==SQLITE_OK ){
+      int pError = 0;
+      memset(testValue, 0, CONCHLEN); /* conch is fixed size */
+      rc = proxyGetHostID(testValue, &pError);
+      if( (rc&0xff)==SQLITE_IOERR ){
+        pFile->lastErrno = pError;
+      }
+      if( pCtx->lockProxyPath ){
+        strlcpy(&testValue[HOSTIDLEN], pCtx->lockProxyPath, MAXPATHLEN);
+      }
+    }
+    if( rc!=SQLITE_OK ){
+      goto end_takeconch;
+    }
+
+    readRc = unixRead((sqlite3_file *)conchFile, conchValue, CONCHLEN, 0);
+    if( readRc!=SQLITE_IOERR_SHORT_READ ){
+      if( readRc!=SQLITE_OK ){
+        if( (rc&0xff)==SQLITE_IOERR ){
+          pFile->lastErrno = conchFile->lastErrno;
+        }
+        rc = readRc;
+        goto end_takeconch;
+      }
+      /* if the conch has data compare the contents */
+      if( !pCtx->lockProxyPath ){
+        /* for auto-named local lock file, just check the host ID and we'll
+         ** use the local lock file path that's already in there */
+        if( !memcmp(testValue, conchValue, HOSTIDLEN) ){
+          tLockPath = (char *)&conchValue[HOSTIDLEN];
+          goto end_takeconch;
+        }
+      }else{
+        /* we've got the conch if conchValue matches our path and host ID */
+        if( !memcmp(testValue, conchValue, CONCHLEN) ){
+          goto end_takeconch;
+        }
+      }
+    }else{
+      /* a short read means we're "creating" the conch (even though it could
+      ** have been user-intervention), if we acquire the exclusive lock,
+      ** we'll try to match the current on-disk permissions of the database
+      */
+      syncPerms = 1;
+    }
+
+    /* either conch was emtpy or didn't match */
+    if( !pCtx->lockProxyPath ){
+      proxyGetLockPath(pCtx->dbPath, lockPath, MAXPATHLEN);
+      tLockPath = lockPath;
+      strlcpy(&testValue[HOSTIDLEN], lockPath, MAXPATHLEN);
+    }
+
+    /* update conch with host and path (this will fail if other process
+     ** has a shared lock already) */
+    rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, EXCLUSIVE_LOCK);
+    if( rc==SQLITE_OK ){
+      rc = unixWrite((sqlite3_file *)conchFile, testValue, CONCHLEN, 0);
+      if( rc==SQLITE_OK && syncPerms ){
+        struct stat buf;
+        int err = fstat(pFile->h, &buf);
+        if( err==0 ){
+          /* try to match the database file permissions, ignore failure */
+#ifndef SQLITE_PROXY_DEBUG
+          fchmod(conchFile->h, buf.st_mode);
+#else
+          if( fchmod(conchFile->h, buf.st_mode)!=0 ){
+            int code = errno;
+            fprintf(stderr, "fchmod %o FAILED with %d %s\n",
+                             buf.st_mode, code, strerror(code));
+          } else {
+            fprintf(stderr, "fchmod %o SUCCEDED\n",buf.st_mode);
+          }
+        }else{
+          int code = errno;
+          fprintf(stderr, "STAT FAILED[%d] with %d %s\n",
+                          err, code, strerror(code));
+#endif
+        }
+      }
+    }
+    conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, SHARED_LOCK);
+
+end_takeconch:
+    OSTRACE2("TRANSPROXY: CLOSE  %d\n", pFile->h);
+    if( rc==SQLITE_OK && pFile->openFlags ){
+      if( pFile->h>=0 ){
+#ifdef STRICT_CLOSE_ERROR
+        if( close(pFile->h) ){
+          pFile->lastErrno = errno;
+          return SQLITE_IOERR_CLOSE;
+        }
+#else
+        close(pFile->h); /* silently leak fd if fail */
+#endif
+      }
+      pFile->h = -1;
+      int fd = open(pCtx->dbPath, pFile->openFlags,
+                    SQLITE_DEFAULT_FILE_PERMISSIONS);
+      OSTRACE2("TRANSPROXY: OPEN  %d\n", fd);
+      if( fd>=0 ){
+        pFile->h = fd;
+      }else{
+        rc=SQLITE_CANTOPEN; /* SQLITE_BUSY? proxyTakeConch called
+                               during locking */
+      }
+    }
+    if( rc==SQLITE_OK && !pCtx->lockProxy ){
+      char *path = tLockPath ? tLockPath : pCtx->lockProxyPath;
+      /* ACS: Need to make a copy of path sometimes */
+      rc = proxyCreateUnixFile(path, &pCtx->lockProxy);
+    }
+    if( rc==SQLITE_OK ){
+      pCtx->conchHeld = 1;
+
+      if( tLockPath ){
+        pCtx->lockProxyPath = sqlite3DbStrDup(0, tLockPath);
+        if( pCtx->lockProxy->pMethod == &afpIoMethods ){
+          ((afpLockingContext *)pCtx->lockProxy->lockingContext)->dbPath =
+                     pCtx->lockProxyPath;
+        }
+      }
+    } else {
+      conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK);
+    }
+    OSTRACE3("TAKECONCH  %d %s\n", conchFile->h, rc==SQLITE_OK?"ok":"failed");
+    return rc;
+  }
+}
+
+/*
+** If pFile holds a lock on a conch file, then release that lock.
+*/
+static int proxyReleaseConch(unixFile *pFile){
+  int rc;                     /* Subroutine return code */
+  proxyLockingContext *pCtx;  /* The locking context for the proxy lock */
+  unixFile *conchFile;        /* Name of the conch file */
+
+  pCtx = (proxyLockingContext *)pFile->lockingContext;
+  conchFile = pCtx->conchFile;
+  OSTRACE4("RELEASECONCH  %d for %s pid=%d\n", conchFile->h,
+           (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"),
+           getpid());
+  pCtx->conchHeld = 0;
+  rc = conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK);
+  OSTRACE3("RELEASECONCH  %d %s\n", conchFile->h,
+           (rc==SQLITE_OK ? "ok" : "failed"));
+  return rc;
+}
+
+/*
+** Given the name of a database file, compute the name of its conch file.
+** Store the conch filename in memory obtained from sqlite3_malloc().
+** Make *pConchPath point to the new name.  Return SQLITE_OK on success
+** or SQLITE_NOMEM if unable to obtain memory.
+**
+** The caller is responsible for ensuring that the allocated memory
+** space is eventually freed.
+**
+** *pConchPath is set to NULL if a memory allocation error occurs.
+*/
+static int proxyCreateConchPathname(char *dbPath, char **pConchPath){
+  int i;                        /* Loop counter */
+  int len = (int)strlen(dbPath); /* Length of database filename - dbPath */
+  char *conchPath;              /* buffer in which to construct conch name */
+
+  /* Allocate space for the conch filename and initialize the name to
+  ** the name of the original database file. */
+  *pConchPath = conchPath = (char *)sqlite3_malloc(len + 8);
+  if( conchPath==0 ){
+    return SQLITE_NOMEM;
+  }
+  memcpy(conchPath, dbPath, len+1);
+
+  /* now insert a "." before the last / character */
+  for( i=(len-1); i>=0; i-- ){
+    if( conchPath[i]=='/' ){
+      i++;
+      break;
+    }
+  }
+  conchPath[i]='.';
+  while ( i<len ){
+    conchPath[i+1]=dbPath[i];
+    i++;
+  }
+
+  /* append the "-conch" suffix to the file */
+  memcpy(&conchPath[i+1], "-conch", 7);
+  assert( (int)strlen(conchPath) == len+7 );
+
+  return SQLITE_OK;
+}
+
+
+/* Takes a fully configured proxy locking-style unix file and switches
+** the local lock file path
+*/
+static int switchLockProxyPath(unixFile *pFile, const char *path) {
+  proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext;
+  char *oldPath = pCtx->lockProxyPath;
+  int rc = SQLITE_OK;
+
+  if( pFile->locktype!=NO_LOCK ){
+    return SQLITE_BUSY;
+  }
+
+  /* nothing to do if the path is NULL, :auto: or matches the existing path */
+  if( !path || path[0]=='\0' || !strcmp(path, ":auto:") ||
+    (oldPath && !strncmp(oldPath, path, MAXPATHLEN)) ){
+    return SQLITE_OK;
+  }else{
+    unixFile *lockProxy = pCtx->lockProxy;
+    pCtx->lockProxy=NULL;
+    pCtx->conchHeld = 0;
+    if( lockProxy!=NULL ){
+      rc=lockProxy->pMethod->xClose((sqlite3_file *)lockProxy);
+      if( rc ) return rc;
+      sqlite3_free(lockProxy);
+    }
+    sqlite3_free(oldPath);
+    pCtx->lockProxyPath = sqlite3DbStrDup(0, path);
+  }
+
+  return rc;
+}
+
+/*
+** pFile is a file that has been opened by a prior xOpen call.  dbPath
+** is a string buffer at least MAXPATHLEN+1 characters in size.
+**
+** This routine find the filename associated with pFile and writes it
+** int dbPath.
+*/
+static int proxyGetDbPathForUnixFile(unixFile *pFile, char *dbPath){
+#if defined(__DARWIN__)
+  if( pFile->pMethod == &afpIoMethods ){
+    /* afp style keeps a reference to the db path in the filePath field
+    ** of the struct */
+    assert( (int)strlen((char*)pFile->lockingContext)<=MAXPATHLEN );
+    strcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath);
+  }else
+#endif
+  if( pFile->pMethod == &dotlockIoMethods ){
+    /* dot lock style uses the locking context to store the dot lock
+    ** file path */
+    int len = strlen((char *)pFile->lockingContext) - strlen(DOTLOCK_SUFFIX);
+    memcpy(dbPath, (char *)pFile->lockingContext, len + 1);
+  }else{
+    /* all other styles use the locking context to store the db file path */
+    assert( strlen((char*)pFile->lockingContext)<=MAXPATHLEN );
+    strcpy(dbPath, (char *)pFile->lockingContext);
+  }
+  return SQLITE_OK;
+}
+
+/*
+** Takes an already filled in unix file and alters it so all file locking
+** will be performed on the local proxy lock file.  The following fields
+** are preserved in the locking context so that they can be restored and
+** the unix structure properly cleaned up at close time:
+**  ->lockingContext
+**  ->pMethod
+*/
+static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
+  proxyLockingContext *pCtx;
+  char dbPath[MAXPATHLEN+1];       /* Name of the database file */
+  char *lockPath=NULL;
+  int rc = SQLITE_OK;
+
+  if( pFile->locktype!=NO_LOCK ){
+    return SQLITE_BUSY;
+  }
+  proxyGetDbPathForUnixFile(pFile, dbPath);
+  if( !path || path[0]=='\0' || !strcmp(path, ":auto:") ){
+    lockPath=NULL;
+  }else{
+    lockPath=(char *)path;
+  }
+
+  OSTRACE4("TRANSPROXY  %d for %s pid=%d\n", pFile->h,
+           (lockPath ? lockPath : ":auto:"), getpid());
+
+  pCtx = sqlite3_malloc( sizeof(*pCtx) );
+  if( pCtx==0 ){
+    return SQLITE_NOMEM;
+  }
+  memset(pCtx, 0, sizeof(*pCtx));
+
+  rc = proxyCreateConchPathname(dbPath, &pCtx->conchFilePath);
+  if( rc==SQLITE_OK ){
+    rc = proxyCreateUnixFile(pCtx->conchFilePath, &pCtx->conchFile);
+  }
+  if( rc==SQLITE_OK && lockPath ){
+    pCtx->lockProxyPath = sqlite3DbStrDup(0, lockPath);
+  }
+
+  if( rc==SQLITE_OK ){
+    /* all memory is allocated, proxys are created and assigned,
+    ** switch the locking context and pMethod then return.
+    */
+    pCtx->dbPath = sqlite3DbStrDup(0, dbPath);
+    pCtx->oldLockingContext = pFile->lockingContext;
+    pFile->lockingContext = pCtx;
+    pCtx->pOldMethod = pFile->pMethod;
+    pFile->pMethod = &proxyIoMethods;
+  }else{
+    if( pCtx->conchFile ){
+      rc = pCtx->conchFile->pMethod->xClose((sqlite3_file *)pCtx->conchFile);
+      if( rc ) return rc;
+      sqlite3_free(pCtx->conchFile);
+    }
+    sqlite3_free(pCtx->conchFilePath);
+    sqlite3_free(pCtx);
+  }
+  OSTRACE3("TRANSPROXY  %d %s\n", pFile->h,
+           (rc==SQLITE_OK ? "ok" : "failed"));
+  return rc;
+}
+
+
+/*
+** This routine handles sqlite3_file_control() calls that are specific
+** to proxy locking.
+*/
+static int proxyFileControl(sqlite3_file *id, int op, void *pArg){
+  switch( op ){
+    case SQLITE_GET_LOCKPROXYFILE: {
+      unixFile *pFile = (unixFile*)id;
+      if( pFile->pMethod == &proxyIoMethods ){
+        proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext;
+        proxyTakeConch(pFile);
+        if( pCtx->lockProxyPath ){
+          *(const char **)pArg = pCtx->lockProxyPath;
+        }else{
+          *(const char **)pArg = ":auto: (not held)";
+        }
+      } else {
+        *(const char **)pArg = NULL;
+      }
+      return SQLITE_OK;
+    }
+    case SQLITE_SET_LOCKPROXYFILE: {
+      unixFile *pFile = (unixFile*)id;
+      int rc = SQLITE_OK;
+      int isProxyStyle = (pFile->pMethod == &proxyIoMethods);
+      if( pArg==NULL || (const char *)pArg==0 ){
+        if( isProxyStyle ){
+          /* turn off proxy locking - not supported */
+          rc = SQLITE_ERROR /*SQLITE_PROTOCOL? SQLITE_MISUSE?*/;
+        }else{
+          /* turn off proxy locking - already off - NOOP */
+          rc = SQLITE_OK;
+        }
+      }else{
+        const char *proxyPath = (const char *)pArg;
+        if( isProxyStyle ){
+          proxyLockingContext *pCtx =
+            (proxyLockingContext*)pFile->lockingContext;
+          if( !strcmp(pArg, ":auto:")
+           || (pCtx->lockProxyPath &&
+               !strncmp(pCtx->lockProxyPath, proxyPath, MAXPATHLEN))
+          ){
+            rc = SQLITE_OK;
+          }else{
+            rc = switchLockProxyPath(pFile, proxyPath);
+          }
+        }else{
+          /* turn on proxy file locking */
+          rc = proxyTransformUnixFile(pFile, proxyPath);
+        }
+      }
+      return rc;
+    }
+    default: {
+      assert( 0 );  /* The call assures that only valid opcodes are sent */
+    }
+  }
+  /*NOTREACHED*/
+  return SQLITE_ERROR;
+}
+
+/*
+** Within this division (the proxying locking implementation) the procedures
+** above this point are all utilities.  The lock-related methods of the
+** proxy-locking sqlite3_io_method object follow.
+*/
+
+
+/*
+** This routine checks if there is a RESERVED lock held on the specified
+** file by this or any other process. If such a lock is held, set *pResOut
+** to a non-zero value otherwise *pResOut is set to zero.  The return value
+** is set to SQLITE_OK unless an I/O error occurs during lock checking.
+*/
+static int proxyCheckReservedLock(sqlite3_file *id, int *pResOut) {
+  unixFile *pFile = (unixFile*)id;
+  int rc = proxyTakeConch(pFile);
+  if( rc==SQLITE_OK ){
+    proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
+    unixFile *proxy = pCtx->lockProxy;
+    return proxy->pMethod->xCheckReservedLock((sqlite3_file*)proxy, pResOut);
+  }
+  return rc;
+}
+
+/*
+** Lock the file with the lock specified by parameter locktype - one
+** of the following:
+**
+**     (1) SHARED_LOCK
+**     (2) RESERVED_LOCK
+**     (3) PENDING_LOCK
+**     (4) EXCLUSIVE_LOCK
+**
+** Sometimes when requesting one lock state, additional lock states
+** are inserted in between.  The locking might fail on one of the later
+** transitions leaving the lock state different from what it started but
+** still short of its goal.  The following chart shows the allowed
+** transitions and the inserted intermediate states:
+**
+**    UNLOCKED -> SHARED
+**    SHARED -> RESERVED
+**    SHARED -> (PENDING) -> EXCLUSIVE
+**    RESERVED -> (PENDING) -> EXCLUSIVE
+**    PENDING -> EXCLUSIVE
+**
+** This routine will only increase a lock.  Use the sqlite3OsUnlock()
+** routine to lower a locking level.
+*/
+static int proxyLock(sqlite3_file *id, int locktype) {
+  unixFile *pFile = (unixFile*)id;
+  int rc = proxyTakeConch(pFile);
+  if( rc==SQLITE_OK ){
+    proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
+    unixFile *proxy = pCtx->lockProxy;
+    rc = proxy->pMethod->xLock((sqlite3_file*)proxy, locktype);
+    pFile->locktype = proxy->locktype;
+  }
+  return rc;
+}
+
+
+/*
+** Lower the locking level on file descriptor pFile to locktype.  locktype
+** must be either NO_LOCK or SHARED_LOCK.
+**
+** If the locking level of the file descriptor is already at or below
+** the requested locking level, this routine is a no-op.
+*/
+static int proxyUnlock(sqlite3_file *id, int locktype) {
+  unixFile *pFile = (unixFile*)id;
+  int rc = proxyTakeConch(pFile);
+  if( rc==SQLITE_OK ){
+    proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
+    unixFile *proxy = pCtx->lockProxy;
+    rc = proxy->pMethod->xUnlock((sqlite3_file*)proxy, locktype);
+    pFile->locktype = proxy->locktype;
+  }
+  return rc;
+}
+
+/*
+** Close a file that uses proxy locks.
+*/
+static int proxyClose(sqlite3_file *id) {
+  if( id ){
+    unixFile *pFile = (unixFile*)id;
+    proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
+    unixFile *lockProxy = pCtx->lockProxy;
+    unixFile *conchFile = pCtx->conchFile;
+    int rc = SQLITE_OK;
+
+    if( lockProxy ){
+      rc = lockProxy->pMethod->xUnlock((sqlite3_file*)lockProxy, NO_LOCK);
+      if( rc ) return rc;
+      rc = lockProxy->pMethod->xClose((sqlite3_file*)lockProxy);
+      if( rc ) return rc;
+      sqlite3_free(lockProxy);
+      pCtx->lockProxy = 0;
+    }
+    if( conchFile ){
+      if( pCtx->conchHeld ){
+        rc = proxyReleaseConch(pFile);
+        if( rc ) return rc;
+      }
+      rc = conchFile->pMethod->xClose((sqlite3_file*)conchFile);
+      if( rc ) return rc;
+      sqlite3_free(conchFile);
+    }
+    sqlite3_free(pCtx->lockProxyPath);
+    sqlite3_free(pCtx->conchFilePath);
+    sqlite3_free(pCtx->dbPath);
+    /* restore the original locking context and pMethod then close it */
+    pFile->lockingContext = pCtx->oldLockingContext;
+    pFile->pMethod = pCtx->pOldMethod;
+    sqlite3_free(pCtx);
+    return pFile->pMethod->xClose(id);
+  }
+  return SQLITE_OK;
+}
+
+
+
+#endif /* defined(__DARWIN__) && SQLITE_ENABLE_LOCKING_STYLE */
+/*
+** The proxy locking style is intended for use with AFP filesystems.
+** And since AFP is only supported on MacOSX, the proxy locking is also
+** restricted to MacOSX.
+**
+**
+******************* End of the proxy lock implementation **********************
+******************************************************************************/
+
+/*
 ** Initialize the operating system interface.
+**
+** This routine registers all VFS implementations for unix-like operating
+** systems.  This routine, and the sqlite3_os_end() routine that follows,
+** should be the only routines in this file that are visible from other
+** files.
+**
+** This routine is called once during SQLite initialization and by a
+** single thread.  The memory allocation and mutex subsystems have not
+** necessarily been initialized when this routine is called, and so they
+** should not be used.
 */
 SQLITE_API int sqlite3_os_init(void){
-  /* Macro to define the static contents of an sqlite3_vfs structure for
-  ** the unix backend. The two parameters are the values to use for
-  ** the sqlite3_vfs.zName and sqlite3_vfs.pAppData fields, respectively.
-  **
-  */
-  #define UNIXVFS(zVfsName, pVfsAppData) {                  \
+  /*
+  ** The following macro defines an initializer for an sqlite3_vfs object.
+  ** The name of the VFS is NAME.  The pAppData is a pointer to a pointer
+  ** to the "finder" function.  (pAppData is a pointer to a pointer because
+  ** silly C90 rules prohibit a void* from being cast to a function pointer
+  ** and so we have to go through the intermediate pointer to avoid problems
+  ** when compiling with -pedantic-errors on GCC.)
+  **
+  ** The FINDER parameter to this macro is the name of the pointer to the
+  ** finder-function.  The finder-function returns a pointer to the
+  ** sqlite_io_methods object that implements the desired locking
+  ** behaviors.  See the division above that contains the IOMETHODS
+  ** macro for addition information on finder-functions.
+  **
+  ** Most finders simply return a pointer to a fixed sqlite3_io_methods
+  ** object.  But the "autolockIoFinder" available on MacOSX does a little
+  ** more than that; it looks at the filesystem type that hosts the
+  ** database file and tries to choose an locking method appropriate for
+  ** that filesystem time.
+  */
+  #define UNIXVFS(VFSNAME, FINDER) {                        \
     1,                    /* iVersion */                    \
     sizeof(unixFile),     /* szOsFile */                    \
     MAX_PATHNAME,         /* mxPathname */                  \
     0,                    /* pNext */                       \
-    zVfsName,             /* zName */                       \
-    (void *)pVfsAppData,  /* pAppData */                    \
+    VFSNAME,              /* zName */                       \
+    (void*)&FINDER,       /* pAppData */                    \
     unixOpen,             /* xOpen */                       \
     unixDelete,           /* xDelete */                     \
     unixAccess,           /* xAccess */                     \
     unixFullPathname,     /* xFullPathname */               \
@@ -25047,32 +26549,50 @@
     unixCurrentTime,      /* xCurrentTime */                \
     unixGetLastError      /* xGetLastError */               \
   }
 
-  static sqlite3_vfs unixVfs = UNIXVFS("unix", 0);
-#if SQLITE_ENABLE_LOCKING_STYLE
-  int i;
+  /*
+  ** All default VFSes for unix are contained in the following array.
+  **
+  ** Note that the sqlite3_vfs.pNext field of the VFS object is modified
+  ** by the SQLite core when the VFS is registered.  So the following
+  ** array cannot be const.
+  */
   static sqlite3_vfs aVfs[] = {
-    UNIXVFS("unix-posix",   LOCKING_STYLE_POSIX),
-    UNIXVFS("unix-afp",     LOCKING_STYLE_AFP),
-    UNIXVFS("unix-flock",   LOCKING_STYLE_FLOCK),
-    UNIXVFS("unix-dotfile", LOCKING_STYLE_DOTFILE),
-    UNIXVFS("unix-none",    LOCKING_STYLE_NONE),
-    UNIXVFS("unix-namedsem",LOCKING_STYLE_NAMEDSEM),
-  };
+#if SQLITE_ENABLE_LOCKING_STYLE && defined(__DARWIN__)
+    UNIXVFS("unix",          autolockIoFinder ),
+#else
+    UNIXVFS("unix",          posixIoFinder ),
+#endif
+    UNIXVFS("unix-none",     nolockIoFinder ),
+    UNIXVFS("unix-dotfile",  dotlockIoFinder ),
+#if OS_VXWORKS
+    UNIXVFS("unix-namedsem", semIoFinder ),
+#endif
+#if SQLITE_ENABLE_LOCKING_STYLE
+    UNIXVFS("unix-posix",    posixIoFinder ),
+    UNIXVFS("unix-flock",    flockIoFinder ),
+#endif
+#if SQLITE_ENABLE_LOCKING_STYLE && defined(__DARWIN__)
+    UNIXVFS("unix-afp",      afpIoFinder ),
+    UNIXVFS("unix-proxy",    proxyIoFinder ),
+#endif
+  };
+  unsigned int i;          /* Loop counter */
+
+  /* Register all VFSes defined in the aVfs[] array */
   for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
-    sqlite3_vfs_register(&aVfs[i], 0);
-  }
-#endif
-#if IS_VXWORKS
-  sqlite3HashInit(&nameHash, 1);
-#endif
-  sqlite3_vfs_register(&unixVfs, 1);
-  return SQLITE_OK;
-}
-
-/*
-** Shutdown the operating system interface. This is a no-op for unix.
+    sqlite3_vfs_register(&aVfs[i], i==0);
+  }
+  return SQLITE_OK;
+}
+
+/*
+** Shutdown the operating system interface.
+**
+** Some operating systems might need to do some cleanup in this routine,
+** to release dynamically allocated objects.  But not on unix.
+** This routine is a no-op for unix.
 */
 SQLITE_API int sqlite3_os_end(void){
   return SQLITE_OK;
 }
@@ -25094,9 +26614,9 @@
 ******************************************************************************
 **
 ** This file contains code that is specific to windows.
 **
-** $Id: os_win.c,v 1.140 2008/11/19 21:35:47 shane Exp $
+** $Id: os_win.c,v 1.145 2008/12/11 02:58:27 shane Exp $
 */
 #if SQLITE_OS_WIN               /* This file is used for windows only */
 
 
@@ -25960,10 +27480,10 @@
   void *pBuf,                /* Write content into this buffer */
   int amt,                   /* Number of bytes to read */
   sqlite3_int64 offset       /* Begin reading at this offset */
 ){
-  LONG upperBits = (offset>>32) & 0x7fffffff;
-  LONG lowerBits = offset & 0xffffffff;
+  LONG upperBits = (LONG)((offset>>32) & 0x7fffffff);
+  LONG lowerBits = (LONG)(offset & 0xffffffff);
   DWORD rc;
   DWORD got;
   winFile *pFile = (winFile*)id;
   assert( id!=0 );
@@ -25994,12 +27514,12 @@
   const void *pBuf,         /* The bytes to be written */
   int amt,                  /* Number of bytes to write */
   sqlite3_int64 offset      /* Offset into the file to begin writing at */
 ){
-  LONG upperBits = (offset>>32) & 0x7fffffff;
-  LONG lowerBits = offset & 0xffffffff;
+  LONG upperBits = (LONG)((offset>>32) & 0x7fffffff);
+  LONG lowerBits = (LONG)(offset & 0xffffffff);
   DWORD rc;
-  DWORD wrote;
+  DWORD wrote = 0;
   winFile *pFile = (winFile*)id;
   assert( id!=0 );
   SimulateIOError(return SQLITE_IOERR_WRITE);
   SimulateDiskfullError(return SQLITE_FULL);
@@ -26027,10 +27547,10 @@
 ** Truncate an open file to a specified size
 */
 static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
   DWORD rc;
-  LONG upperBits = (nByte>>32) & 0x7fffffff;
-  LONG lowerBits = nByte & 0xffffffff;
+  LONG upperBits = (LONG)((nByte>>32) & 0x7fffffff);
+  LONG lowerBits = (LONG)(nByte & 0xffffffff);
   winFile *pFile = (winFile*)id;
   OSTRACE3("TRUNCATE %d %lld\n", pFile->h, nByte);
   SimulateIOError(return SQLITE_IOERR_TRUNCATE);
   rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
@@ -26055,11 +27575,17 @@
 /*
 ** Make sure all writes to a particular file are committed to disk.
 */
 static int winSync(sqlite3_file *id, int flags){
+#ifndef SQLITE_NO_SYNC
   winFile *pFile = (winFile*)id;
+#else
+  UNUSED_PARAMETER(id);
+#endif
   OSTRACE3("SYNC %d lock=%d\n", pFile->h, pFile->locktype);
-#ifdef SQLITE_TEST
+#ifndef SQLITE_TEST
+  UNUSED_PARAMETER(flags);
+#else
   if( flags & SQLITE_SYNC_FULL ){
     sqlite3_fullsync_count++;
   }
   sqlite3_sync_count++;
@@ -26116,9 +27642,9 @@
 #if SQLITE_OS_WINCE==0
   }else{
     int lk;
     sqlite3_randomness(sizeof(lk), &lk);
-    pFile->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);
+    pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1));
     res = LockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
 #endif
   }
   return res;
@@ -26269,9 +27795,9 @@
     OSTRACE4("LOCK FAILED %d trying for %d but got %d\n", pFile->h,
            locktype, newLocktype);
     rc = SQLITE_BUSY;
   }
-  pFile->locktype = newLocktype;
+  pFile->locktype = (u8)newLocktype;
   return rc;
 }
 
 /*
@@ -26334,9 +27860,9 @@
   }
   if( type>=PENDING_LOCK ){
     UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
   }
-  pFile->locktype = locktype;
+  pFile->locktype = (u8)locktype;
   return rc;
 }
 
 /*
@@ -26362,15 +27888,17 @@
 ** a database and its journal file) that the sector size will be the
 ** same for both.
 */
 static int winSectorSize(sqlite3_file *id){
+  UNUSED_PARAMETER(id);
   return SQLITE_DEFAULT_SECTOR_SIZE;
 }
 
 /*
 ** Return a vector of device characteristics.
 */
 static int winDeviceCharacteristics(sqlite3_file *id){
+  UNUSED_PARAMETER(id);
   return 0;
 }
 
 /*
@@ -26461,13 +27989,13 @@
       return SQLITE_NOMEM;
     }
 #endif
   }
-  for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
+  for(i=sqlite3Strlen30(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
   zTempPath[i] = 0;
   sqlite3_snprintf(nBuf-30, zBuf,
                    "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath);
-  j = strlen(zBuf);
+  j = sqlite3Strlen30(zBuf);
   sqlite3_randomness(20, &zBuf[j]);
   for(i=0; i<20; i++, j++){
     zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
   }
@@ -26528,8 +28056,10 @@
   winFile *pFile = (winFile*)id;
   void *zConverted;                 /* Filename in OS encoding */
   const char *zUtf8Name = zName;    /* Filename in UTF-8 encoding */
   char zTmpname[MAX_PATH+1];        /* Buffer used to create temp filename */
+
+  UNUSED_PARAMETER(pVfs);
 
   /* If the second argument to this function is NULL, generate a
   ** temporary file name to use
   */
@@ -26662,10 +28192,12 @@
   int syncDir                 /* Not used on win32 */
 ){
   int cnt = 0;
   DWORD rc;
-  DWORD error;
+  DWORD error = 0;
   void *zConverted = convertUtf8Filename(zFilename);
+  UNUSED_PARAMETER(pVfs);
+  UNUSED_PARAMETER(syncDir);
   if( zConverted==0 ){
     return SQLITE_NOMEM;
   }
   SimulateIOError(return SQLITE_IOERR_DELETE);
@@ -26705,10 +28237,11 @@
   int flags,                 /* Type of test to make on this file */
   int *pResOut               /* OUT: Result */
 ){
   DWORD attr;
-  int rc;
+  int rc = 0;
   void *zConverted = convertUtf8Filename(zFilename);
+  UNUSED_PARAMETER(pVfs);
   if( zConverted==0 ){
     return SQLITE_NOMEM;
   }
   if( isNT() ){
@@ -26751,13 +28284,15 @@
   char *zFull                   /* Output buffer */
 ){
 
 #if defined(__CYGWIN__)
+  UNUSED_PARAMETER(nFull);
   cygwin_conv_to_full_win32_path(zRelative, zFull);
   return SQLITE_OK;
 #endif
 
 #if SQLITE_OS_WINCE
+  UNUSED_PARAMETER(nFull);
   /* WinCE has no concept of a relative pathname, or so I am told. */
   sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative);
   return SQLITE_OK;
 #endif
@@ -26765,8 +28300,9 @@
 #if !SQLITE_OS_WINCE && !defined(__CYGWIN__)
   int nByte;
   void *zConverted;
   char *zOut;
+  UNUSED_PARAMETER(nFull);
   zConverted = convertUtf8Filename(zRelative);
   if( isNT() ){
     WCHAR *zTemp;
     nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3;
@@ -26819,8 +28355,9 @@
 */
 static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
   HANDLE h;
   void *zConverted = convertUtf8Filename(zFilename);
+  UNUSED_PARAMETER(pVfs);
   if( zConverted==0 ){
     return 0;
   }
   if( isNT() ){
@@ -26837,21 +28374,24 @@
   free(zConverted);
   return (void*)h;
 }
 static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
+  UNUSED_PARAMETER(pVfs);
   getLastErrorMsg(nBuf, zBufOut);
 }
-void *winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
+void (*winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
+  UNUSED_PARAMETER(pVfs);
 #if SQLITE_OS_WINCE
   /* The GetProcAddressA() routine is only available on wince. */
-  return GetProcAddressA((HANDLE)pHandle, zSymbol);
+  return (void(*)(void))GetProcAddressA((HANDLE)pHandle, zSymbol);
 #else
   /* All other windows platforms expect GetProcAddress() to take
   ** an Ansi string regardless of the _UNICODE setting */
-  return GetProcAddress((HANDLE)pHandle, zSymbol);
+  return (void(*)(void))GetProcAddress((HANDLE)pHandle, zSymbol);
 #endif
 }
 void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
+  UNUSED_PARAMETER(pVfs);
   FreeLibrary((HANDLE)pHandle);
 }
 #else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
   #define winDlOpen  0
@@ -26902,8 +28442,9 @@
 ** Sleep for a little while.  Return the amount of time slept.
 */
 static int winSleep(sqlite3_vfs *pVfs, int microsec){
   Sleep((microsec+999)/1000);
+  UNUSED_PARAMETER(pVfs);
   return ((microsec+999)/1000)*1000;
 }
 
 /*
@@ -26934,8 +28475,9 @@
   }
 #else
   GetSystemTimeAsFileTime( &ft );
 #endif
+  UNUSED_PARAMETER(pVfs);
   now = ((double)ft.dwHighDateTime) * 4294967296.0;
   *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
 #ifdef SQLITE_TEST
   if( sqlite3_current_time ){
@@ -26975,8 +28517,9 @@
 ** by sqlite into the error message available to the user using
 ** sqlite3_errmsg(), possibly making IO errors easier to debug.
 */
 static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
+  UNUSED_PARAMETER(pVfs);
   return getLastErrorMsg(nBuf, zBuf);
 }
 
 /*
@@ -27417,9 +28960,9 @@
 **
 *************************************************************************
 ** This file implements that page cache.
 **
-** @(#) $Id: pcache.c,v 1.38 2008/11/19 16:52:44 danielk1977 Exp $
+** @(#) $Id: pcache.c,v 1.39 2008/12/04 20:40:10 drh Exp $
 */
 
 /*
 ** A complete page cache is an instance of this structure.
@@ -27984,9 +29527,8 @@
   }
 }
 #endif
 
-
 /************** End of pcache.c **********************************************/
 /************** Begin file pcache1.c *****************************************/
 /*
 ** 2008 November 05
@@ -28005,9 +29547,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.3 2008/11/19 09:05:27 danielk1977 Exp $
+** @(#) $Id: pcache1.c,v 1.6 2008/12/10 18:03:46 drh Exp $
 */
 
 
 typedef struct PCache1 PCache1;
@@ -28096,9 +29638,9 @@
 **
 **   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*sizeof(PgHdr1)])
+#define PAGE_TO_PGHDR1(p) (PgHdr1 *)(&((unsigned char *)p)[-1*(int)sizeof(PgHdr1)])
 
 /*
 ** Macros to enter and leave the global LRU mutex.
 */
@@ -28251,16 +29793,18 @@
     nNew = 256;
   }
 
   pcache1LeaveMutex();
+  if( p->nHash ){ sqlite3BeginBenignMalloc(); }
   apNew = (PgHdr1 **)sqlite3_malloc(sizeof(PgHdr1 *)*nNew);
+  if( p->nHash ){ sqlite3EndBenignMalloc(); }
   pcache1EnterMutex();
   if( apNew ){
     memset(apNew, 0, sizeof(PgHdr1 *)*nNew);
     for(i=0; i<p->nHash; i++){
       PgHdr1 *pPage;
       PgHdr1 *pNext = p->apHash[i];
-      while( (pPage = pNext) ){
+      while( (pPage = pNext)!=0 ){
         unsigned int h = pPage->iKey % nNew;
         pNext = pPage->pNext;
         pPage->pNext = apNew[h];
         apNew[h] = pPage;
@@ -28350,9 +29894,9 @@
   assert( sqlite3_mutex_held(pcache1.mutex) );
   for(h=0; h<pCache->nHash; h++){
     PgHdr1 **pp = &pCache->apHash[h];
     PgHdr1 *pPage;
-    while( (pPage = *pp) ){
+    while( (pPage = *pp)!=0 ){
       if( pPage->iKey>=iLimit ){
         pcache1PinPage(pPage);
         *pp = pPage->pNext;
         pcache1FreePage(pPage);
@@ -28725,8 +30269,248 @@
 }
 #endif
 
 /************** End of pcache1.c *********************************************/
+/************** Begin file rowset.c ******************************************/
+/*
+** 2008 December 3
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+*************************************************************************
+**
+** This module implements an object we call a "Row Set".
+**
+** The RowSet object is a bag of rowids.  Rowids
+** are inserted into the bag in an arbitrary order.  Then they are
+** pulled from the bag in sorted order.  Rowids only appear in the
+** bag once.  If the same rowid is inserted multiple times, the
+** second and subsequent inserts make no difference on the output.
+**
+** This implementation accumulates rowids in a linked list.  For
+** output, it first sorts the linked list (removing duplicates during
+** the sort) then returns elements one by one by walking the list.
+**
+** Big chunks of rowid/next-ptr pairs are allocated at a time, to
+** reduce the malloc overhead.
+*/
+
+/*
+** The number of rowset entries per allocation chunk.
+*/
+#define ROWSET_ENTRY_PER_CHUNK  63
+
+/*
+** Each entry in a RowSet is an instance of the following
+** structure:
+*/
+struct RowSetEntry {
+  i64 v;                        /* ROWID value for this entry */
+  struct RowSetEntry *pNext;    /* Next entry on a list of all entries */
+};
+
+/*
+** Index entries are allocated in large chunks (instances of the
+** following structure) to reduce memory allocation overhead.  The
+** chunks are kept on a linked list so that they can be deallocated
+** when the RowSet is destroyed.
+*/
+struct RowSetChunk {
+  struct RowSetChunk *pNext;             /* Next chunk on list of them all */
+  struct RowSetEntry aEntry[ROWSET_ENTRY_PER_CHUNK]; /* Allocated entries */
+};
+
+/*
+** A RowSet in an instance of the following structure.
+**
+** A typedef of this structure if found in sqliteInt.h.
+*/
+struct RowSet {
+  struct RowSetChunk *pChunk;    /* List of all chunk allocations */
+  sqlite3 *db;                   /* The database connection */
+  struct RowSetEntry *pEntry;    /* List of entries in the rowset */
+  struct RowSetEntry *pLast;     /* Last entry on the pEntry list */
+  struct RowSetEntry *pFresh;    /* Source of new entry objects */
+  u16 nFresh;                    /* Number of objects on pFresh */
+  u8 isSorted;                   /* True if content is sorted */
+};
+
+/*
+** Turn bulk memory into a RowSet object.  N bytes of memory
+** are available at pSpace.  The db pointer is used as a memory context
+** for any subsequent allocations that need to occur.
+** Return a pointer to the new RowSet object.
+**
+** If N is not sufficient memory to make even a minimum RowSet,
+** then return NULL.  If N is larger than the minimum, use
+** the surplus as an initial allocation of entries available to
+** be filled.
+*/
+SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int N){
+  RowSet *p;
+  if( N<sizeof(*p) ){
+    p = 0;
+  }else{
+    p = pSpace;
+    p->pChunk = 0;
+    p->db = db;
+    p->pEntry = 0;
+    p->pLast = 0;
+    p->pFresh = (struct RowSetEntry*)&p[1];
+    p->nFresh = (u16)((N - sizeof(*p))/sizeof(struct RowSetEntry));
+    p->isSorted = 1;
+  }
+  return p;
+}
+
+/*
+** Deallocate all chunks from a RowSet.
+*/
+SQLITE_PRIVATE void sqlite3RowSetClear(RowSet *p){
+  struct RowSetChunk *pChunk, *pNextChunk;
+  for(pChunk=p->pChunk; pChunk; pChunk = pNextChunk){
+    pNextChunk = pChunk->pNext;
+    sqlite3DbFree(p->db, pChunk);
+  }
+  p->pChunk = 0;
+  p->nFresh = 0;
+  p->pEntry = 0;
+  p->pLast = 0;
+  p->isSorted = 1;
+}
+
+/*
+** Insert a new value into a RowSet.
+**
+** The mallocFailed flag of the database connection is set if a
+** memory allocation fails.
+*/
+SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet *p, i64 rowid){
+  struct RowSetEntry *pEntry;
+  struct RowSetEntry *pLast;
+  if( p==0 ) return;  /* Must have been a malloc failure */
+  if( p->nFresh==0 ){
+    struct RowSetChunk *pNew;
+    pNew = sqlite3DbMallocRaw(p->db, sizeof(*pNew));
+    if( pNew==0 ){
+      return;
+    }
+    pNew->pNext = p->pChunk;
+    p->pChunk = pNew;
+    p->pFresh = pNew->aEntry;
+    p->nFresh = ROWSET_ENTRY_PER_CHUNK;
+  }
+  pEntry = p->pFresh++;
+  p->nFresh--;
+  pEntry->v = rowid;
+  pEntry->pNext = 0;
+  pLast = p->pLast;
+  if( pLast ){
+    if( p->isSorted && rowid<=pLast->v ){
+      p->isSorted = 0;
+    }
+    pLast->pNext = pEntry;
+  }else{
+    assert( p->pEntry==0 );
+    p->pEntry = pEntry;
+  }
+  p->pLast = pEntry;
+}
+
+/*
+** Merge two lists of RowSet entries.  Remove duplicates.
+**
+** The input lists are assumed to be in sorted order.
+*/
+static struct RowSetEntry *boolidxMerge(
+  struct RowSetEntry *pA,    /* First sorted list to be merged */
+  struct RowSetEntry *pB     /* Second sorted list to be merged */
+){
+  struct RowSetEntry head;
+  struct RowSetEntry *pTail;
+
+  pTail = &head;
+  while( pA && pB ){
+    assert( pA->pNext==0 || pA->v<=pA->pNext->v );
+    assert( pB->pNext==0 || pB->v<=pB->pNext->v );
+    if( pA->v<pB->v ){
+      pTail->pNext = pA;
+      pA = pA->pNext;
+      pTail = pTail->pNext;
+    }else if( pB->v<pA->v ){
+      pTail->pNext = pB;
+      pB = pB->pNext;
+      pTail = pTail->pNext;
+    }else{
+      pA = pA->pNext;
+    }
+  }
+  if( pA ){
+    assert( pA->pNext==0 || pA->v<=pA->pNext->v );
+    pTail->pNext = pA;
+  }else{
+    assert( pB==0 || pB->pNext==0 || pB->v<=pB->pNext->v );
+    pTail->pNext = pB;
+  }
+  return head.pNext;
+}
+
+/*
+** Sort all elements of the RowSet into ascending order.
+*/
+static void sqlite3RowSetSort(RowSet *p){
+  unsigned int i;
+  struct RowSetEntry *pEntry;
+  struct RowSetEntry *aBucket[40];
+
+  assert( p->isSorted==0 );
+  memset(aBucket, 0, sizeof(aBucket));
+  while( p->pEntry ){
+    pEntry = p->pEntry;
+    p->pEntry = pEntry->pNext;
+    pEntry->pNext = 0;
+    for(i=0; aBucket[i]; i++){
+      pEntry = boolidxMerge(aBucket[i],pEntry);
+      aBucket[i] = 0;
+    }
+    aBucket[i] = pEntry;
+  }
+  pEntry = 0;
+  for(i=0; i<sizeof(aBucket)/sizeof(aBucket[0]); i++){
+    pEntry = boolidxMerge(pEntry,aBucket[i]);
+  }
+  p->pEntry = pEntry;
+  p->pLast = 0;
+  p->isSorted = 1;
+}
+
+/*
+** Extract the next (smallest) element from the RowSet.
+** Write the element into *pRowid.  Return 1 on success.  Return
+** 0 if the RowSet is already empty.
+*/
+SQLITE_PRIVATE int sqlite3RowSetNext(RowSet *p, i64 *pRowid){
+  if( !p->isSorted ){
+    sqlite3RowSetSort(p);
+  }
+  if( p->pEntry ){
+    *pRowid = p->pEntry->v;
+    p->pEntry = p->pEntry->pNext;
+    if( p->pEntry==0 ){
+      sqlite3RowSetClear(p);
+    }
+    return 1;
+  }else{
+    return 0;
+  }
+}
+
+/************** End of rowset.c **********************************************/
 /************** Begin file pager.c *******************************************/
 /*
 ** 2001 September 15
 **
@@ -28746,9 +30530,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.506.2.1 2008/11/26 14:55:02 drh Exp $
+** @(#) $Id: pager.c,v 1.514 2008/12/10 22:15:00 drh Exp $
 */
 #ifndef SQLITE_OMIT_DISKIO
 
 /*
@@ -29408,8 +31192,17 @@
   /* The initial database size */
   put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbSize);
   /* The assumed sector size for this process */
   put32bits(&zHeader[sizeof(aJournalMagic)+12], pPager->sectorSize);
+
+  /* Initializing the tail of the buffer is not necessary.  Everything
+  ** works find if the following memset() is omitted.  But initializing
+  ** the memory prevents valgrind from complaining, so we are willing to
+  ** take the performance hit.
+  */
+  memset(&zHeader[sizeof(aJournalMagic)+16], 0,
+         nHeader-(sizeof(aJournalMagic)+16));
+
   if( pPager->journalHdr==0 ){
     /* The page size */
     put32bits(&zHeader[sizeof(aJournalMagic)+16], pPager->pageSize);
   }
@@ -29478,9 +31271,9 @@
    && iPageSize>=512
    && iPageSize<=SQLITE_MAX_PAGE_SIZE
    && ((iPageSize-1)&iPageSize)==0
   ){
-    u16 pagesize = iPageSize;
+    u16 pagesize = (u16)iPageSize;
     rc = sqlite3PagerSetPagesize(pPager, &pagesize);
   }
   if( rc ) return rc;
 
@@ -29533,9 +31326,9 @@
   if( !zMaster || pPager->setMaster ) return SQLITE_OK;
   if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ) return SQLITE_OK;
   pPager->setMaster = 1;
 
-  len = strlen(zMaster);
+  len = sqlite3Strlen30(zMaster);
   for(i=0; i<len; i++){
     cksum += zMaster[i];
   }
 
@@ -29965,15 +31758,15 @@
 
     /* Load the entire master journal file into space obtained from
     ** sqlite3_malloc() and pointed to by zMasterJournal.
     */
-    zMasterJournal = (char *)sqlite3Malloc(nMasterJournal + nMasterPtr);
+    zMasterJournal = (char *)sqlite3Malloc((int)nMasterJournal + nMasterPtr);
     if( !zMasterJournal ){
       rc = SQLITE_NOMEM;
       goto delmaster_out;
     }
     zMasterPtr = &zMasterJournal[nMasterJournal];
-    rc = sqlite3OsRead(pMaster, zMasterJournal, nMasterJournal, 0);
+    rc = sqlite3OsRead(pMaster, zMasterJournal, (int)nMasterJournal, 0);
     if( rc!=SQLITE_OK ) goto delmaster_out;
 
     zJournal = zMasterJournal;
     while( (zJournal-zMasterJournal)<nMasterJournal ){
@@ -30005,9 +31798,9 @@
           /* We have a match. Do not delete the master journal file. */
           goto delmaster_out;
         }
       }
-      zJournal += (strlen(zJournal)+1);
+      zJournal += (sqlite3Strlen30(zJournal)+1);
     }
   }
 
   rc = sqlite3OsDelete(pVfs, zMaster, 0);
@@ -30194,9 +31987,9 @@
     ** the value of nRec based on this assumption.
     */
     if( nRec==0xffffffff ){
       assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) );
-      nRec = (szJ - JOURNAL_HDR_SZ(pPager))/JOURNAL_PG_SZ(pPager);
+      nRec = (int)((szJ - JOURNAL_HDR_SZ(pPager))/JOURNAL_PG_SZ(pPager));
     }
 
     /* If nRec is 0 and this rollback is of a transaction created by this
     ** process and if this is the final header in the journal, then it means
@@ -30207,9 +32000,9 @@
     ** The third term of the test was added to fix ticket #2565.
     */
     if( nRec==0 && !isHot &&
         pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff ){
-      nRec = (szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager);
+      nRec = (int)((szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager));
     }
 
     /* If this is the first header read from the journal, truncate the
     ** database file back to its original size.
@@ -30331,9 +32124,9 @@
   ** If it is not zero, then Pager.stmtHdrOff is the offset to the start
   ** of the first journal header written during this statement transaction.
   */
   pPager->journalOff = pPager->stmtJSize;
-  pPager->cksumInit = pPager->stmtCksum;
+  pPager->cksumInit = (int)(pPager->stmtCksum & 0xffffffff);
   while( pPager->journalOff < hdrOff ){
     rc = pager_playback_one_page(pPager, pPager->jfd, pPager->journalOff, 1);
     assert( rc!=SQLITE_DONE );
     if( rc!=SQLITE_OK ) goto end_stmt_playback;
@@ -30347,9 +32140,9 @@
       assert( rc!=SQLITE_DONE );
       goto end_stmt_playback;
     }
     if( nJRec==0 ){
-      nJRec = (szJ - pPager->journalOff) / (pPager->pageSize+8);
+      nJRec = (int)((szJ - pPager->journalOff) / (pPager->pageSize+8));
     }
     for(i=nJRec-1; i>=0 && pPager->journalOff < szJ; i--){
       rc = pager_playback_one_page(pPager, pPager->jfd, pPager->journalOff, 1);
       assert( rc!=SQLITE_DONE );
@@ -30401,10 +32194,10 @@
 ** and FULL=3.
 */
 #ifndef SQLITE_OMIT_PAGER_PRAGMAS
 SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(Pager *pPager, int level, int bFullFsync){
-  pPager->noSync =  level==1 || pPager->tempFile;
-  pPager->fullSync = level==3 && !pPager->tempFile;
+  pPager->noSync =  (level==1 || pPager->tempFile) ?1:0;
+  pPager->fullSync = (level==3 && !pPager->tempFile) ?1:0;
   pPager->sync_flags = (bFullFsync?SQLITE_SYNC_FULL:SQLITE_SYNC_NORMAL);
   if( pPager->noSync ) pPager->needSync = 0;
 }
 #endif
@@ -30513,9 +32306,9 @@
     if( rc!=SQLITE_OK ){
       sqlite3_free(zPathname);
       return rc;
     }
-    nPathname = strlen(zPathname);
+    nPathname = sqlite3Strlen30(zPathname);
   }
 
   /* Allocate memory for the pager structure */
   pPager = sqlite3MallocZero(
@@ -30621,9 +32414,10 @@
   IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename))
 
   /* Fill in Pager.zDirectory[] */
   memcpy(pPager->zDirectory, pPager->zFilename, nPathname+1);
-  for(i=strlen(pPager->zDirectory); i>0 && pPager->zDirectory[i-1]!='/'; i--){}
+  for(i=sqlite3Strlen30(pPager->zDirectory);
+      i>0 && pPager->zDirectory[i-1]!='/'; i--){}
   if( i>0 ) pPager->zDirectory[i-1] = 0;
 
   /* Fill in Pager.zJournal[] */
   if( zPathname ){
@@ -30633,14 +32427,14 @@
     pPager->zJournal = 0;
   }
 
   /* pPager->journalOpen = 0; */
-  pPager->useJournal = useJournal;
-  pPager->noReadlock = noReadlock && readOnly;
+  pPager->useJournal = (u8)useJournal;
+  pPager->noReadlock = (noReadlock && readOnly) ?1:0;
   /* pPager->stmtOpen = 0; */
   /* pPager->stmtInUse = 0; */
   /* pPager->nRef = 0; */
-  pPager->dbSizeValid = memDb;
+  pPager->dbSizeValid = (u8)memDb;
   pPager->pageSize = szPageDflt;
   /* pPager->stmtSize = 0; */
   /* pPager->stmtJSize = 0; */
   /* pPager->nPage = 0; */
@@ -30648,18 +32442,18 @@
   pPager->mxPgno = SQLITE_MAX_PAGE_COUNT;
   /* pPager->state = PAGER_UNLOCK; */
   assert( pPager->state == (tempFile ? PAGER_EXCLUSIVE : PAGER_UNLOCK) );
   /* pPager->errMask = 0; */
-  pPager->tempFile = tempFile;
+  pPager->tempFile = (u8)tempFile;
   assert( tempFile==PAGER_LOCKINGMODE_NORMAL
           || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE );
   assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 );
-  pPager->exclusiveMode = tempFile;
-  pPager->memDb = memDb;
-  pPager->readOnly = readOnly;
+  pPager->exclusiveMode = (u8)tempFile;
+  pPager->memDb = (u8)memDb;
+  pPager->readOnly = (u8)readOnly;
   /* pPager->needSync = 0; */
-  pPager->noSync = pPager->tempFile || !useJournal;
-  pPager->fullSync = (pPager->noSync?0:1);
+  pPager->noSync = (pPager->tempFile || !useJournal) ?1:0;
+  pPager->fullSync = pPager->noSync ?0:1;
   pPager->sync_flags = SQLITE_SYNC_NORMAL;
   /* pPager->pFirst = 0; */
   /* pPager->pFirstSynced = 0; */
   /* pPager->pLast = 0; */
@@ -30725,9 +32519,9 @@
         pPager->pTmpSpace = pNew;
         sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
       }
     }
-    *pPageSize = pPager->pageSize;
+    *pPageSize = (u16)pPager->pageSize;
   }
   return rc;
 }
 
@@ -30837,20 +32631,20 @@
     }else{
       n /= pPager->pageSize;
     }
     if( pPager->state!=PAGER_UNLOCK ){
-      pPager->dbSize = n;
+      pPager->dbSize = (int)n;
       pPager->dbSizeValid = 1;
     }
   }
   if( n==(PENDING_BYTE/pPager->pageSize) ){
     n++;
   }
   if( n>pPager->mxPgno ){
-    pPager->mxPgno = n;
+    pPager->mxPgno = (Pgno)n;
   }
   if( pnPage ){
-    *pnPage = n;
+    *pnPage = (int)n;
   }
   return SQLITE_OK;
 }
 
@@ -30900,9 +32694,9 @@
     do {
       rc = sqlite3OsLock(pPager->fd, locktype);
     }while( rc==SQLITE_BUSY && pPager->xBusyHandler(pPager->pBusyHandlerArg) );
     if( rc==SQLITE_OK ){
-      pPager->state = locktype;
+      pPager->state = (u8)locktype;
       IOTRACE(("LOCK %p %d\n", pPager, locktype))
     }
   }
   return rc;
@@ -31222,10 +33016,10 @@
 */
 static int hasHotJournal(Pager *pPager, int *pExists){
   sqlite3_vfs *pVfs = pPager->pVfs;
   int rc = SQLITE_OK;
-  int exists;
-  int locked;
+  int exists = 0;
+  int locked = 0;
   assert( pPager!=0 );
   assert( pPager->useJournal );
   assert( pPager->fd->pMethods );
   *pExists = 0;
@@ -31311,9 +33105,9 @@
   }
 
   if( pPager->state==PAGER_UNLOCK || isErrorReset ){
     sqlite3_vfs *pVfs = pPager->pVfs;
-    int isHotJournal;
+    int isHotJournal = 0;
     assert( !MEMDB );
     assert( sqlite3PcacheRefCount(pPager->pPCache)==0 );
     if( !pPager->noReadlock ){
       rc = pager_wait_on_lock(pPager, SHARED_LOCK);
@@ -32543,9 +34337,9 @@
 /*
 ** Return TRUE if the database file is opened read-only.  Return FALSE
 ** if the database is (in theory) writable.
 */
-SQLITE_PRIVATE int sqlite3PagerIsreadonly(Pager *pPager){
+SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager *pPager){
   return pPager->readOnly;
 }
 
 /*
@@ -32877,9 +34671,9 @@
             || eMode==PAGER_LOCKINGMODE_EXCLUSIVE );
   assert( PAGER_LOCKINGMODE_QUERY<0 );
   assert( PAGER_LOCKINGMODE_NORMAL>=0 && PAGER_LOCKINGMODE_EXCLUSIVE>=0 );
   if( eMode>=0 && !pPager->tempFile ){
-    pPager->exclusiveMode = eMode;
+    pPager->exclusiveMode = (u8)eMode;
   }
   return (int)pPager->exclusiveMode;
 }
 
@@ -32907,9 +34701,9 @@
               || eMode==PAGER_JOURNALMODE_OFF
               || eMode==PAGER_JOURNALMODE_MEMORY );
     assert( PAGER_JOURNALMODE_QUERY<0 );
     if( eMode>=0 ){
-      pPager->journalMode = eMode;
+      pPager->journalMode = (u8)eMode;
     }else{
       assert( eMode==PAGER_JOURNALMODE_QUERY );
     }
   }
@@ -32961,9 +34755,9 @@
 **    May you find forgiveness for yourself and forgive others.
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btreeInt.h,v 1.36 2008/11/19 10:22:33 danielk1977 Exp $
+** $Id: btreeInt.h,v 1.37 2008/12/10 16:45:51 drh Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** For a detailed discussion of BTrees, refer to
 **
@@ -33322,12 +35116,12 @@
   Pgno nTrunc;          /* Non-zero if the db will be truncated (incr vacuum) */
 #endif
   u16 pageSize;         /* Total number of bytes on a page */
   u16 usableSize;       /* Number of usable bytes on each page */
-  int maxLocal;         /* Maximum local payload in non-LEAFDATA tables */
-  int minLocal;         /* Minimum local payload in non-LEAFDATA tables */
-  int maxLeaf;          /* Maximum local payload in a LEAFDATA table */
-  int minLeaf;          /* Minimum local payload in a LEAFDATA table */
+  u16 maxLocal;         /* Maximum local payload in non-LEAFDATA tables */
+  u16 minLocal;         /* Minimum local payload in non-LEAFDATA tables */
+  u16 maxLeaf;          /* Maximum local payload in a LEAFDATA table */
+  u16 minLeaf;          /* Minimum local payload in a LEAFDATA table */
   u8 inTransaction;     /* Transaction state */
   int nTransaction;     /* Number of open transactions (read + write) */
   void *pSchema;        /* Pointer to space allocated by sqlite3BtreeSchema() */
   void (*xFreeSchema)(void*);  /* Destructor for BtShared.pSchema */
@@ -33567,9 +35361,9 @@
 /*
 ** Read or write a two- and four-byte big-endian integer values.
 */
 #define get2byte(x)   ((x)[0]<<8 | (x)[1])
-#define put2byte(p,v) ((p)[0] = (v)>>8, (p)[1] = (v))
+#define put2byte(p,v) ((p)[0] = (u8)((v)>>8), (p)[1] = (u8)(v))
 #define get4byte sqlite3Get4byte
 #define put4byte sqlite3Put4byte
 
 /*
@@ -33894,9 +35688,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.539.2.2 2008/11/26 14:55:02 drh Exp $
+** $Id: btree.c,v 1.548 2008/12/16 13:46:30 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.
@@ -34200,11 +35994,11 @@
   ** table, then malloc space for and store the pCur->nKey bytes of key
   ** data.
   */
   if( rc==SQLITE_OK && 0==pCur->apPage[0]->intKey){
-    void *pKey = sqlite3Malloc(pCur->nKey);
+    void *pKey = sqlite3Malloc( (int)pCur->nKey );
     if( pKey ){
-      rc = sqlite3BtreeKey(pCur, 0, pCur->nKey, pKey);
+      rc = sqlite3BtreeKey(pCur, 0, (int)pCur->nKey, pKey);
       if( rc==SQLITE_OK ){
         pCur->pKey = pKey;
       }else{
         sqlite3_free(pKey);
@@ -34459,9 +36253,9 @@
   MemPage *pPage,         /* Page containing the cell */
   u8 *pCell,              /* Pointer to the cell text. */
   CellInfo *pInfo         /* Fill in this structure */
 ){
-  int n;                  /* Number bytes in cell content header */
+  u16 n;                  /* Number bytes in cell content header */
   u32 nPayload;           /* Number of bytes of cell payload */
 
   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
 
@@ -34489,14 +36283,14 @@
     ** on the local page.  No overflow is required.
     */
     int nSize;          /* Total size of cell content in bytes */
     nSize = nPayload + n;
-    pInfo->nLocal = nPayload;
+    pInfo->nLocal = (u16)nPayload;
     pInfo->iOverflow = 0;
     if( (nSize & ~3)==0 ){
       nSize = 4;        /* Minimum cell size is 4 */
     }
-    pInfo->nSize = nSize;
+    pInfo->nSize = (u16)nSize;
   }else{
     /* If the payload will not fit completely on the local page, we have
     ** to decide how much to store locally and how much to spill onto
     ** overflow pages.  The strategy is to minimize the amount of unused
@@ -34513,13 +36307,13 @@
     minLocal = pPage->minLocal;
     maxLocal = pPage->maxLocal;
     surplus = minLocal + (nPayload - minLocal)%(pPage->pBt->usableSize - 4);
     if( surplus <= maxLocal ){
-      pInfo->nLocal = surplus;
-    }else{
-      pInfo->nLocal = minLocal;
-    }
-    pInfo->iOverflow = pInfo->nLocal + n;
+      pInfo->nLocal = (u16)surplus;
+    }else{
+      pInfo->nLocal = (u16)minLocal;
+    }
+    pInfo->iOverflow = (u16)(pInfo->nLocal + n);
     pInfo->nSize = pInfo->iOverflow + 4;
   }
 }
 #define parseCell(pPage, iCell, pInfo) \
@@ -34638,8 +36432,9 @@
   data[hdr+2] = 0;
   data[hdr+7] = 0;
   addr = cellOffset+2*nCell;
   memset(&data[addr], 0, cbrk-addr);
+  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
   if( cbrk-addr!=pPage->nFree ){
     return SQLITE_CORRUPT_BKPT;
   }
   return SQLITE_OK;
@@ -34672,9 +36467,9 @@
   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
   assert( nByte>=0 );  /* Minimum cell size is 4 */
   assert( pPage->nFree>=nByte );
   assert( pPage->nOverflow==0 );
-  pPage->nFree -= nByte;
+  pPage->nFree -= (u16)nByte;
   hdr = pPage->hdrOffset;
 
   nFrag = data[hdr+7];
   if( nFrag<60 ){
@@ -34683,15 +36478,16 @@
     addr = hdr+1;
     while( (pc = get2byte(&data[addr]))>0 ){
       size = get2byte(&data[pc+2]);
       if( size>=nByte ){
+        int x = size - nByte;
         if( size<nByte+4 ){
           memcpy(&data[addr], &data[pc], 2);
-          data[hdr+7] = nFrag + size - nByte;
+          data[hdr+7] = (u8)(nFrag + x);
           return pc;
         }else{
-          put2byte(&data[pc+2], size-nByte);
-          return pc + size - nByte;
+          put2byte(&data[pc+2], x);
+          return pc + x;
         }
       }
       addr = pc;
     }
@@ -34709,8 +36505,9 @@
   }
   top -= nByte;
   assert( cellOffset + 2*nCell <= top );
   put2byte(&data[hdr+5], top);
+  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
   return top;
 }
 
 /*
@@ -34754,26 +36551,28 @@
   assert( pbegin>addr || pbegin==0 );
   put2byte(&data[addr], start);
   put2byte(&data[start], pbegin);
   put2byte(&data[start+2], size);
-  pPage->nFree += size;
+  pPage->nFree += (u16)size;
 
   /* Coalesce adjacent free blocks */
   addr = pPage->hdrOffset + 1;
   while( (pbegin = get2byte(&data[addr]))>0 ){
-    int pnext, psize;
+    int pnext, psize, x;
     assert( pbegin>addr );
     assert( pbegin<=pPage->pBt->usableSize-4 );
     pnext = get2byte(&data[pbegin]);
     psize = get2byte(&data[pbegin+2]);
     if( pbegin + psize + 3 >= pnext && pnext>0 ){
       int frag = pnext - (pbegin+psize);
-      if( (frag<0) || (frag>data[pPage->hdrOffset+7]) ){
+      if( (frag<0) || (frag>(int)data[pPage->hdrOffset+7]) ){
         return SQLITE_CORRUPT_BKPT;
       }
-      data[pPage->hdrOffset+7] -= frag;
-      put2byte(&data[pbegin], get2byte(&data[pnext]));
-      put2byte(&data[pbegin+2], pnext+get2byte(&data[pnext+2])-pbegin);
+      data[pPage->hdrOffset+7] -= (u8)frag;
+      x = get2byte(&data[pnext]);
+      put2byte(&data[pbegin], x);
+      x = pnext + get2byte(&data[pnext+2]) - pbegin;
+      put2byte(&data[pbegin+2], x);
     }else{
       addr = pbegin;
     }
   }
@@ -34782,11 +36581,12 @@
   if( data[hdr+1]==data[hdr+5] && data[hdr+2]==data[hdr+6] ){
     int top;
     pbegin = get2byte(&data[hdr+1]);
     memcpy(&data[hdr+1], &data[pbegin], 2);
-    top = get2byte(&data[hdr+5]);
-    put2byte(&data[hdr+5], top + get2byte(&data[pbegin+2]));
-  }
+    top = get2byte(&data[hdr+5]) + get2byte(&data[pbegin+2]);
+    put2byte(&data[hdr+5], top);
+  }
+  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
   return SQLITE_OK;
 }
 
 /*
@@ -34805,9 +36605,9 @@
   BtShared *pBt;     /* A copy of pPage->pBt */
 
   assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) );
   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
-  pPage->leaf = flagByte>>3;  assert( PTF_LEAF == 1<<3 );
+  pPage->leaf = (u8)(flagByte>>3);  assert( PTF_LEAF == 1<<3 );
   flagByte &= ~PTF_LEAF;
   pPage->childPtrSize = 4-4*pPage->leaf;
   pBt = pPage->pBt;
   if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){
@@ -34843,16 +36643,16 @@
   assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) );
   assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) );
 
   if( !pPage->isInit ){
-    int pc;            /* Address of a freeblock within pPage->aData[] */
-    int hdr;           /* Offset to beginning of page header */
+    u16 pc;            /* Address of a freeblock within pPage->aData[] */
+    u8 hdr;            /* Offset to beginning of page header */
     u8 *data;          /* Equal to pPage->aData */
     BtShared *pBt;        /* The main btree structure */
-    int usableSize;    /* Amount of usable space on each page */
-    int cellOffset;    /* Offset from start of page to first cell pointer */
-    int nFree;         /* Number of unused bytes on the page */
-    int top;           /* First byte of the cell content area */
+    u16 usableSize;    /* Amount of usable space on each page */
+    u16 cellOffset;    /* Offset from start of page to first cell pointer */
+    u16 nFree;         /* Number of unused bytes on the page */
+    u16 top;           /* First byte of the cell content area */
 
     pBt = pPage->pBt;
 
     hdr = pPage->hdrOffset;
@@ -34873,9 +36673,9 @@
     /* Compute the total free space on the page */
     pc = get2byte(&data[hdr+1]);
     nFree = data[hdr+7] + top - (cellOffset + 2*pPage->nCell);
     while( pc>0 ){
-      int next, size;
+      u16 next, size;
       if( pc>usableSize-4 ){
         /* Free block is off the page */
         return SQLITE_CORRUPT_BKPT;
       }
@@ -34887,9 +36687,9 @@
       }
       nFree += size;
       pc = next;
     }
-    pPage->nFree = nFree;
+    pPage->nFree = (u16)nFree;
     if( nFree>=usableSize ){
       /* Free space cannot exceed total page size */
       return SQLITE_CORRUPT_BKPT;
     }
@@ -34925,19 +36725,19 @@
 */
 static void zeroPage(MemPage *pPage, int flags){
   unsigned char *data = pPage->aData;
   BtShared *pBt = pPage->pBt;
-  int hdr = pPage->hdrOffset;
-  int first;
+  u8 hdr = pPage->hdrOffset;
+  u16 first;
 
   assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno );
   assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
   assert( sqlite3PagerGetData(pPage->pDbPage) == data );
   assert( sqlite3PagerIswriteable(pPage->pDbPage) );
   assert( sqlite3_mutex_held(pBt->mutex) );
   /*memset(&data[hdr], 0, pBt->usableSize - hdr);*/
-  data[hdr] = flags;
-  first = hdr + 8 + 4*((flags&PTF_LEAF)==0);
+  data[hdr] = (char)flags;
+  first = hdr + 8 + 4*((flags&PTF_LEAF)==0 ?1:0);
   memset(&data[hdr+1], 0, 4);
   data[hdr+7] = 0;
   put2byte(&data[hdr+5], pBt->usableSize);
   pPage->nFree = pBt->usableSize - first;
@@ -35118,9 +36918,9 @@
   sqlite3_vfs *pVfs;      /* The VFS to use for this btree */
   BtShared *pBt = 0;      /* Shared part of btree structure */
   Btree *p;               /* Handle to return */
   int rc = SQLITE_OK;
-  int nReserve;
+  u8 nReserve;
   unsigned char zDbHeader[100];
 
   /* Set the variable isMemdb to true for an in-memory database, or
   ** false for a file-based database. This symbol is only required if
@@ -35515,8 +37315,9 @@
 */
 SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve){
   int rc = SQLITE_OK;
   BtShared *pBt = p->pBt;
+  assert( nReserve>=-1 && nReserve<=255 );
   sqlite3BtreeEnter(p);
   if( pBt->pageSizeFixed ){
     sqlite3BtreeLeave(p);
     return SQLITE_READONLY;
@@ -35523,17 +37324,18 @@
   }
   if( nReserve<0 ){
     nReserve = pBt->pageSize - pBt->usableSize;
   }
+  assert( nReserve>=0 && nReserve<=255 );
   if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
         ((pageSize-1)&pageSize)==0 ){
     assert( (pageSize & 7)==0 );
     assert( !pBt->pPage1 && !pBt->pCursor );
-    pBt->pageSize = pageSize;
+    pBt->pageSize = (u16)pageSize;
     freeTempSpace(pBt);
     rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize);
   }
-  pBt->usableSize = pBt->pageSize - nReserve;
+  pBt->usableSize = pBt->pageSize - (u16)nReserve;
   sqlite3BtreeLeave(p);
   return rc;
 }
 
@@ -35576,9 +37378,9 @@
   return SQLITE_READONLY;
 #else
   BtShared *pBt = p->pBt;
   int rc = SQLITE_OK;
-  int av = (autoVacuum?1:0);
+  u8 av = autoVacuum ?1:0;
 
   sqlite3BtreeEnter(p);
   if( pBt->pageSizeFixed && av!=pBt->autoVacuum ){
     rc = SQLITE_READONLY;
@@ -35674,19 +37476,19 @@
       ** zero and return SQLITE_OK. The caller will call this function
       ** again with the correct page-size.
       */
       releasePage(pPage1);
-      pBt->usableSize = usableSize;
-      pBt->pageSize = pageSize;
+      pBt->usableSize = (u16)usableSize;
+      pBt->pageSize = (u16)pageSize;
       freeTempSpace(pBt);
       sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize);
       return SQLITE_OK;
     }
     if( usableSize<500 ){
       goto page1_init_failed;
     }
-    pBt->pageSize = pageSize;
-    pBt->usableSize = usableSize;
+    pBt->pageSize = (u16)pageSize;
+    pBt->usableSize = (u16)usableSize;
 #ifndef SQLITE_OMIT_AUTOVACUUM
     pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0);
     pBt->incrVacuum = (get4byte(&page1[36 + 7*4])?1:0);
 #endif
@@ -35796,9 +37598,10 @@
   assert( sizeof(zMagicHeader)==16 );
   put2byte(&data[16], pBt->pageSize);
   data[18] = 1;
   data[19] = 1;
-  data[20] = pBt->pageSize - pBt->usableSize;
+  assert( pBt->usableSize<=pBt->pageSize && pBt->usableSize+255>=pBt->pageSize);
+  data[20] = (u8)(pBt->pageSize - pBt->usableSize);
   data[21] = 64;
   data[22] = 32;
   data[23] = 32;
   memset(&data[24], 0, 100-24);
@@ -35951,9 +37754,9 @@
   int i;                             /* Counter variable */
   int nCell;                         /* Number of cells in page pPage */
   int rc;                            /* Return code */
   BtShared *pBt = pPage->pBt;
-  int isInitOrig = pPage->isInit;
+  u8 isInitOrig = pPage->isInit;
   Pgno pgno = pPage->pgno;
 
   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
   rc = sqlite3BtreeInitPage(pPage);
@@ -36003,16 +37806,17 @@
 **                   overflow page in the list.
 */
 static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
+  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
   if( eType==PTRMAP_OVERFLOW2 ){
     /* The pointer is always the first 4 bytes of the page in this case.  */
     if( get4byte(pPage->aData)!=iFrom ){
       return SQLITE_CORRUPT_BKPT;
     }
     put4byte(pPage->aData, iTo);
   }else{
-    int isInitOrig = pPage->isInit;
+    u8 isInitOrig = pPage->isInit;
     int i;
     int nCell;
 
     sqlite3BtreeInitPage(pPage);
@@ -36693,8 +38497,9 @@
   Pgno nPage;
   BtShared *pBt = p->pBt;
 
   assert( sqlite3BtreeHoldsMutex(p) );
+  assert( wrFlag==0 || wrFlag==1 );
   if( wrFlag ){
     if( pBt->readOnly ){
       return SQLITE_READONLY;
     }
@@ -36732,9 +38537,9 @@
   */
   pCur->pKeyInfo = pKeyInfo;
   pCur->pBtree = p;
   pCur->pBt = pBt;
-  pCur->wrFlag = wrFlag;
+  pCur->wrFlag = (u8)wrFlag;
   pCur->pNext = pBt->pCursor;
   if( pCur->pNext ){
     pCur->pNext->pPrev = pCur;
   }
@@ -36950,9 +38755,9 @@
   MemPage **ppPage,            /* OUT: MemPage handle */
   Pgno *pPgnoNext              /* OUT: Next overflow page number */
 ){
   Pgno next = 0;
-  int rc;
+  int rc = SQLITE_OK;
 
   assert( sqlite3_mutex_held(pBt->mutex) );
   /* One of these must not be NULL. Otherwise, why call this function? */
   assert(ppPage || pPgnoNext);
@@ -37095,9 +38900,9 @@
   assert( cursorHoldsMutex(pCur) );
 
   getCellInfo(pCur);
   aPayload = pCur->info.pCell + pCur->info.nHeader;
-  nKey = (pPage->intKey ? 0 : pCur->info.nKey);
+  nKey = (pPage->intKey ? 0 : (int)pCur->info.nKey);
 
   if( skipKey ){
     offset += nKey;
   }
@@ -37302,9 +39107,9 @@
   aPayload += pCur->info.nHeader;
   if( pPage->intKey ){
     nKey = 0;
   }else{
-    nKey = pCur->info.nKey;
+    nKey = (int)pCur->info.nKey;
   }
   if( skipKey ){
     aPayload += nKey;
     nLocal = pCur->info.nLocal - nKey;
@@ -37512,9 +39317,9 @@
 */
 static int moveToRightmost(BtCursor *pCur){
   Pgno pgno;
   int rc = SQLITE_OK;
-  MemPage *pPage;
+  MemPage *pPage = 0;
 
   assert( cursorHoldsMutex(pCur) );
   assert( pCur->eState==CURSOR_VALID );
   while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){
@@ -37572,9 +39377,9 @@
       assert( pCur->eState==CURSOR_VALID );
       *pRes = 0;
       rc = moveToRightmost(pCur);
       getCellInfo(pCur);
-      pCur->atLast = rc==SQLITE_OK;
+      pCur->atLast = rc==SQLITE_OK ?1:0;
     }
   }
   return rc;
 }
@@ -37656,11 +39461,11 @@
       rc = SQLITE_CORRUPT_BKPT;
       goto moveto_finish;
     }
     if( biasRight ){
-      pCur->aiIdx[pCur->iPage] = upr;
-    }else{
-      pCur->aiIdx[pCur->iPage] = (upr+lwr)/2;
+      pCur->aiIdx[pCur->iPage] = (u16)upr;
+    }else{
+      pCur->aiIdx[pCur->iPage] = (u16)((upr+lwr)/2);
     }
     if( lwr<=upr ) for(;;){
       void *pCellKey;
       i64 nCellKey;
@@ -37687,17 +39492,17 @@
         int available;
         pCellKey = (void *)fetchPayload(pCur, &available, 0);
         nCellKey = pCur->info.nKey;
         if( available>=nCellKey ){
-          c = sqlite3VdbeRecordCompare(nCellKey, pCellKey, pIdxKey);
-        }else{
-          pCellKey = sqlite3Malloc( nCellKey );
+          c = sqlite3VdbeRecordCompare((int)nCellKey, pCellKey, pIdxKey);
+        }else{
+          pCellKey = sqlite3Malloc( (int)nCellKey );
           if( pCellKey==0 ){
             rc = SQLITE_NOMEM;
             goto moveto_finish;
           }
-          rc = sqlite3BtreeKey(pCur, 0, nCellKey, (void *)pCellKey);
-          c = sqlite3VdbeRecordCompare(nCellKey, pCellKey, pIdxKey);
+          rc = sqlite3BtreeKey(pCur, 0, (int)nCellKey, (void*)pCellKey);
+          c = sqlite3VdbeRecordCompare((int)nCellKey, pCellKey, pIdxKey);
           sqlite3_free(pCellKey);
           if( rc ) goto moveto_finish;
         }
       }
@@ -37721,9 +39526,9 @@
       if( lwr>upr ){
         pCur->info.nKey = nCellKey;
         break;
       }
-      pCur->aiIdx[pCur->iPage] = (lwr+upr)/2;
+      pCur->aiIdx[pCur->iPage] = (u16)((lwr+upr)/2);
     }
     assert( lwr==upr+1 );
     assert( pPage->isInit );
     if( pPage->leaf ){
@@ -37738,9 +39543,9 @@
       if( pRes ) *pRes = c;
       rc = SQLITE_OK;
       goto moveto_finish;
     }
-    pCur->aiIdx[pCur->iPage] = lwr;
+    pCur->aiIdx[pCur->iPage] = (u16)lwr;
     pCur->info.nSize = 0;
     pCur->validNKey = 0;
     rc = moveToChild(pCur, chldPg);
     if( rc ) goto moveto_finish;
@@ -37765,9 +39570,10 @@
   UnpackedRecord *pIdxKey;   /* Unpacked index key */
   UnpackedRecord aSpace[16]; /* Temp space for pIdxKey - to avoid a malloc */
 
   if( pKey ){
-    pIdxKey = sqlite3VdbeRecordUnpack(pCur->pKeyInfo, nKey, pKey,
+    assert( nKey==(i64)(int)nKey );
+    pIdxKey = sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey,
                                       aSpace, sizeof(aSpace));
     if( pIdxKey==0 ) return SQLITE_NOMEM;
   }else{
     pIdxKey = 0;
@@ -38074,8 +39880,9 @@
           put4byte(&pNewTrunk->aData[4], k-1);
           memcpy(&pNewTrunk->aData[8], &pTrunk->aData[12], (k-1)*4);
           releasePage(pNewTrunk);
           if( !pPrevTrunk ){
+            assert( sqlite3PagerIswriteable(pPage1->pDbPage) );
             put4byte(&pPage1->aData[32], iNewTrunk);
           }else{
             rc = sqlite3PagerWrite(pPrevTrunk->pDbPage);
             if( rc ){
@@ -38129,8 +39936,9 @@
           if( closest<k-1 ){
             memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
           }
           put4byte(&aData[4], k-1);
+          assert( sqlite3PagerIswriteable(pTrunk->pDbPage) );
           rc = sqlite3BtreeGetPage(pBt, *pPgno, ppPage, 1);
           if( rc==SQLITE_OK ){
             sqlite3PagerDontRollback((*ppPage)->pDbPage);
             rc = sqlite3PagerWrite((*ppPage)->pDbPage);
@@ -38364,8 +40172,13 @@
   CellInfo info;
 
   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
 
+  /* pPage is not necessarily writeable since pCell might be auxiliary
+  ** buffer space that is separate from the pPage buffer area */
+  assert( pCell<pPage->aData || pCell>=&pPage->aData[pBt->pageSize]
+            || sqlite3PagerIswriteable(pPage->pDbPage) );
+
   /* Fill in the header. */
   nHeader = 0;
   if( !pPage->leaf ){
     nHeader += 4;
@@ -38387,11 +40200,12 @@
     pSrc = pData;
     nSrc = nData;
     nData = 0;
   }else{
-    nPayload += nKey;
+    /* TBD:  Perhaps raise SQLITE_CORRUPT if nKey is larger than 31 bits? */
+    nPayload += (int)nKey;
     pSrc = pKey;
-    nSrc = nKey;
+    nSrc = (int)nKey;
   }
   *pnSize = info.nSize;
   spaceLeft = info.nLocal;
   pPayload = &pCell[nHeader];
@@ -38398,9 +40212,8 @@
   pPrior = &pCell[info.iOverflow];
 
   while( nPayload>0 ){
     if( spaceLeft==0 ){
-      int isExact = 0;
 #ifndef SQLITE_OMIT_AUTOVACUUM
       Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */
       if( pBt->autoVacuum ){
         do{
@@ -38407,14 +40220,11 @@
           pgnoOvfl++;
         } while(
           PTRMAP_ISPAGE(pBt, pgnoOvfl) || pgnoOvfl==PENDING_BYTE_PAGE(pBt)
         );
-        if( pgnoOvfl>1 ){
-          /* isExact = 1; */
-        }
-      }
-#endif
-      rc = allocateBtreePage(pBt, &pOvfl, &pgnoOvfl, pgnoOvfl, isExact);
+      }
+#endif
+      rc = allocateBtreePage(pBt, &pOvfl, &pgnoOvfl, pgnoOvfl, 0);
 #ifndef SQLITE_OMIT_AUTOVACUUM
       /* If the database supports auto-vacuum, and the second or subsequent
       ** overflow page is being allocated, add an entry to the pointer-map
       ** for that page now.
@@ -38436,8 +40246,18 @@
       if( rc ){
         releasePage(pToRelease);
         return rc;
       }
+
+      /* If pToRelease is not zero than pPrior points into the data area
+      ** of pToRelease.  Make sure pToRelease is still writeable. */
+      assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) );
+
+      /* If pPrior is part of the data area of pPage, then make sure pPage
+      ** is still writeable */
+      assert( pPrior<pPage->aData || pPrior>=&pPage->aData[pBt->pageSize]
+            || sqlite3PagerIswriteable(pPage->pDbPage) );
+
       put4byte(pPrior, pgnoOvfl);
       releasePage(pToRelease);
       pToRelease = pOvfl;
       pPrior = pOvfl->aData;
@@ -38446,8 +40266,18 @@
       spaceLeft = pBt->usableSize - 4;
     }
     n = nPayload;
     if( n>spaceLeft ) n = spaceLeft;
+
+    /* If pToRelease is not zero than pPayload points into the data area
+    ** of pToRelease.  Make sure pToRelease is still writeable. */
+    assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) );
+
+    /* If pPayload is part of the data area of pPage, then make sure pPage
+    ** is still writeable */
+    assert( pPayload<pPage->aData || pPayload>=&pPage->aData[pBt->pageSize]
+            || sqlite3PagerIswriteable(pPage->pDbPage) );
+
     if( nSrc>0 ){
       if( n>nSrc ) n = nSrc;
       assert( pSrc );
       memcpy(pPayload, pSrc, n);
@@ -38489,9 +40319,10 @@
   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
   data = pPage->aData;
   ptr = &data[pPage->cellOffset + 2*idx];
   pc = get2byte(ptr);
-  if ( (pc<pPage->hdrOffset+6+(pPage->leaf?0:4)) || (pc+sz>pPage->pBt->usableSize) ) {
+  if( (pc<pPage->hdrOffset+6+(pPage->leaf?0:4))
+     || (pc+sz>pPage->pBt->usableSize) ){
     return SQLITE_CORRUPT_BKPT;
   }
   rc = freeSpace(pPage, pc, sz);
   if( rc!=SQLITE_OK ){
@@ -38542,8 +40373,10 @@
   u8 *data;         /* The content of the whole page */
   u8 *ptr;          /* Used for moving information around in data[] */
 
   assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
+  assert( pPage->nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=5460 );
+  assert( pPage->nOverflow<=ArraySize(pPage->aOvfl) );
   assert( sz==cellSizePtr(pPage, pCell) );
   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
   if( pPage->nOverflow || sz+2>pPage->nFree ){
     if( pTemp ){
@@ -38552,9 +40385,9 @@
     }
     j = pPage->nOverflow++;
     assert( j<(int)(sizeof(pPage->aOvfl)/sizeof(pPage->aOvfl[0])) );
     pPage->aOvfl[j].pCell = pCell;
-    pPage->aOvfl[j].idx = i;
+    pPage->aOvfl[j].idx = (u16)i;
     pPage->nFree = 0;
   }else{
     int rc = sqlite3PagerWrite(pPage->pDbPage);
     if( rc!=SQLITE_OK ){
@@ -38628,14 +40461,16 @@
   u8 *data;         /* Data for the page */
 
   assert( pPage->nOverflow==0 );
   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
+  assert( nCell>=0 && nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=5460 );
   totalSize = 0;
   for(i=0; i<nCell; i++){
     totalSize += aSize[i];
   }
   assert( totalSize+2*nCell<=pPage->nFree );
   assert( pPage->nCell==0 );
+  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
   cellptr = pPage->cellOffset;
   data = pPage->aData;
   hdr = pPage->hdrOffset;
   put2byte(&data[hdr+3], nCell);
@@ -38651,9 +40486,9 @@
       cellbody += aSize[i];
     }
     assert( cellbody==pPage->pBt->usableSize );
   }
-  pPage->nCell = nCell;
+  pPage->nCell = (u16)nCell;
 }
 
 /*
 ** The following parameters determine how many adjacent pages get involved
@@ -38713,8 +40548,9 @@
   rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);
   if( rc==SQLITE_OK ){
     pCell = pPage->aOvfl[0].pCell;
     szCell = cellSizePtr(pPage, pCell);
+    assert( sqlite3PagerIswriteable(pNew->pDbPage) );
     zeroPage(pNew, pPage->aData[0]);
     assemblePage(pNew, 1, &pCell, &szCell);
     pPage->nOverflow = 0;
 
@@ -38966,15 +40802,15 @@
     goto balance_cleanup;
   }
   szCell = (u16*)&apCell[nMaxCells];
   aCopy[0] = (u8*)&szCell[nMaxCells];
-  assert( ((aCopy[0] - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */
+  assert( ((aCopy[0] - (u8*)0) & 7)==0 ); /* 8-byte alignment required */
   for(i=1; i<NB; i++){
     aCopy[i] = &aCopy[i-1][pBt->pageSize+ROUND8(sizeof(MemPage))];
-    assert( ((aCopy[i] - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */
+    assert( ((aCopy[i] - (u8*)0) & 7)==0 ); /* 8-byte alignment required */
   }
   aSpace1 = &aCopy[NB-1][pBt->pageSize+ROUND8(sizeof(MemPage))];
-  assert( ((aSpace1 - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */
+  assert( ((aSpace1 - (u8*)0) & 7)==0 ); /* 8-byte alignment required */
   if( ISAUTOVACUUM ){
     aFrom = &aSpace1[pBt->pageSize];
   }
   aSpace2 = sqlite3PageMalloc(pBt->pageSize);
@@ -39023,9 +40859,9 @@
       apCell[nCell] = findOverflowCell(pOld, j);
       szCell[nCell] = cellSizePtr(pOld, apCell[nCell]);
       if( ISAUTOVACUUM ){
         int a;
-        aFrom[nCell] = i;
+        aFrom[nCell] = (u8)i;   assert( i>=0 && i<6 );
         for(a=0; a<pOld->nOverflow; a++){
           if( pOld->aOvfl[a].pCell==apCell[nCell] ){
             aFrom[nCell] = 0xFF;
             break;
@@ -39056,9 +40892,10 @@
         if( ISAUTOVACUUM ){
           aFrom[nCell] = 0xFF;
         }
         dropCell(pParent, nxDiv, sz);
-        szCell[nCell] -= leafCorrection;
+        assert( leafCorrection==0 || leafCorrection==4 );
+        szCell[nCell] -= (u16)leafCorrection;
         assert( get4byte(pTemp)==pgnoOld[i] );
         if( !pOld->leaf ){
           assert( leafCorrection==0 );
           /* The right pointer of the child page pOld becomes the left
@@ -39315,8 +41152,9 @@
       assert( sz<=pBt->pageSize/4 );
       assert( iSpace2<=pBt->pageSize );
       rc = insertCell(pParent, nxDiv, pCell, sz, pTemp, 4);
       if( rc!=SQLITE_OK ) goto balance_cleanup;
+      assert( sqlite3PagerIswriteable(pParent->pDbPage) );
       put4byte(findOverflowCell(pParent,nxDiv), pNew->pgno);
 
       /* If this is an auto-vacuum database, and not a leaf-data tree,
       ** then update the pointer map with an entry for the overflow page
@@ -39352,8 +41190,9 @@
         goto balance_cleanup;
       }
     }
   }
+  assert( sqlite3PagerIswriteable(pParent->pDbPage) );
   if( nxDiv==pParent->nCell+pParent->nOverflow ){
     /* Right-most sibling is the right-most child of pParent */
     put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew[nNew-1]);
   }else{
@@ -39385,8 +41224,9 @@
   }
   for(i=0; i<nNew; i++){
     releasePage(apNew[i]);
   }
+  pPage->nOverflow = 0;
 
   /* releasePage(pParent); */
   TRACE(("BALANCE: finished with %d: old=%d new=%d cells=%d\n",
           pPage->pgno, nOld, nNew, nCell));
@@ -39455,11 +41295,12 @@
           szCell[i] = cellSizePtr(pChild, apCell[i]);
         }
         assemblePage(pPage, pChild->nCell, apCell, szCell);
         /* Copy the right-pointer of the child to the parent. */
+        assert( sqlite3PagerIswriteable(pPage->pDbPage) );
         put4byte(&pPage->aData[pPage->hdrOffset+8],
             get4byte(&pChild->aData[pChild->hdrOffset+8]));
-        freePage(pChild);
+        rc = freePage(pChild);
         TRACE(("BALANCE: child %d transfer to page 1\n", pChild->pgno));
       }else{
         /* The child has more information that will fit on the root.
         ** The tree is already balanced.  Do nothing. */
@@ -39475,9 +41316,9 @@
               pChild->pgno, pPage->pgno));
     }
     assert( pPage->nOverflow==0 );
 #ifndef SQLITE_OMIT_AUTOVACUUM
-    if( ISAUTOVACUUM ){
+    if( ISAUTOVACUUM && rc==SQLITE_OK ){
       rc = setChildPtrmaps(pPage);
     }
 #endif
     releasePage(pChild);
@@ -39515,8 +41356,9 @@
   VVA_ONLY( pCur->pagesShuffled = 1 );
   pPage = pCur->apPage[0];
   pBt = pPage->pBt;
   assert( sqlite3_mutex_held(pBt->mutex) );
+  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
   rc = allocateBtreePage(pBt, &pChild, &pgnoChild, pPage->pgno, 0);
   if( rc ) return rc;
   assert( sqlite3PagerIswriteable(pChild->pDbPage) );
   usableSize = pBt->usableSize;
@@ -39536,8 +41378,9 @@
     if( pChild->nOverflow ){
       pChild->nFree = 0;
     }
     assert( pChild->nCell==pPage->nCell );
+    assert( sqlite3PagerIswriteable(pPage->pDbPage) );
     zeroPage(pPage, pChild->aData[0] & ~PTF_LEAF);
     put4byte(&pPage->aData[pPage->hdrOffset+8], pgnoChild);
     TRACE(("BALANCE: copy root %d into %d\n", pPage->pgno, pChild->pgno));
     if( ISAUTOVACUUM ){
@@ -39579,16 +41422,19 @@
   if( pCur->iPage==0 ){
     rc = sqlite3PagerWrite(pPage->pDbPage);
     if( rc==SQLITE_OK && pPage->nOverflow>0 ){
       rc = balance_deeper(pCur);
+      assert( pPage->nOverflow==0 || rc!=SQLITE_OK );
     }
     if( rc==SQLITE_OK && pPage->nCell==0 ){
       rc = balance_shallower(pCur);
+      assert( pPage->nOverflow==0 || rc!=SQLITE_OK );
     }
   }else{
     if( pPage->nOverflow>0 ||
         (!isInsert && pPage->nFree>pPage->pBt->usableSize*2/3) ){
       rc = balance_nonroot(pCur);
+      assert( pPage->nOverflow==0 || rc!=SQLITE_OK );
     }
   }
   return rc;
 }
@@ -39755,10 +41601,17 @@
   }else{
     assert( pPage->leaf );
   }
   rc = insertCell(pPage, idx, newCell, szNew, 0, 0);
-  if( rc!=SQLITE_OK ) goto end_insert;
-  rc = balance(pCur, 1);
+  if( rc==SQLITE_OK ){
+    rc = balance(pCur, 1);
+  }
+
+  /* Must make sure nOverflow is reset to zero even if the balance()
+  ** fails.  Internal data structure corruption will result otherwise. */
+  assert( pPage->nOverflow==0 || rc!=SQLITE_OK );
+  pPage->nOverflow = 0;
+
   if( rc==SQLITE_OK ){
     moveToRoot(pCur);
   }
 end_insert:
@@ -39834,9 +41687,9 @@
     ** next Cell after the one to be deleted is guaranteed to exist and
     ** to be a leaf so we can use it.
     */
     BtCursor leafCur;
-    MemPage *pLeafPage;
+    MemPage *pLeafPage = 0;
 
     unsigned char *pNext;
     int notUsed;
     unsigned char *tempCell = 0;
@@ -39905,8 +41758,9 @@
         leafCursorInvalid = 1;
       }
 
       if( rc==SQLITE_OK ){
+        assert( sqlite3PagerIswriteable(pPage->pDbPage) );
         put4byte(findOverflowCell(pPage, idx), pgnoChild);
         VVA_ONLY( pCur->pagesShuffled = 0 );
         rc = balance(pCur, 0);
       }
@@ -39944,12 +41798,11 @@
         assert( pLeafPage->pgno==leafPgno );
         assert( leafCur.aiIdx[leafCur.iPage]==0 );
       }
 
-      if( rc==SQLITE_OK ){
-        rc = sqlite3PagerWrite(pLeafPage->pDbPage);
-      }
-      if( rc==SQLITE_OK ){
+      if( SQLITE_OK==rc
+       && SQLITE_OK==(rc = sqlite3PagerWrite(pLeafPage->pDbPage))
+      ){
         dropCell(pLeafPage, 0, szNext);
         VVA_ONLY( leafCur.pagesShuffled = 0 );
         rc = balance(&leafCur, 0);
         assert( leafCursorInvalid || !leafCur.pagesShuffled
@@ -40349,9 +42202,9 @@
 ** layer (and the SetCookie and ReadCookie opcodes) the number of
 ** free pages is not visible.  So Cookie[0] is the same as Meta[1].
 */
 SQLITE_PRIVATE int sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
-  DbPage *pDbPage;
+  DbPage *pDbPage = 0;
   int rc;
   unsigned char *pP1;
   BtShared *pBt = p->pBt;
 
@@ -40432,9 +42285,9 @@
 #ifndef SQLITE_OMIT_AUTOVACUUM
       if( idx==7 ){
         assert( pBt->autoVacuum || iMeta==0 );
         assert( iMeta==0 || iMeta==1 );
-        pBt->incrVacuum = iMeta;
+        pBt->incrVacuum = (u8)iMeta;
       }
 #endif
     }
   }
@@ -40536,8 +42389,9 @@
   Pgno iPtrmapParent;
 
   rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent);
   if( rc!=SQLITE_OK ){
+    if( rc==SQLITE_NOMEM ) pCheck->mallocFailed = 1;
     checkAppendMsg(pCheck, zContext, "Failed to read ptrmap key=%d", iChild);
     return;
   }
 
@@ -40662,13 +42516,15 @@
   usableSize = pBt->usableSize;
   if( iPage==0 ) return 0;
   if( checkRef(pCheck, iPage, zParentContext) ) return 0;
   if( (rc = sqlite3BtreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){
+    if( rc==SQLITE_NOMEM ) pCheck->mallocFailed = 1;
     checkAppendMsg(pCheck, zContext,
        "unable to get the page. error code=%d", rc);
     return 0;
   }
   if( (rc = sqlite3BtreeInitPage(pPage))!=0 ){
+    if( rc==SQLITE_NOMEM ) pCheck->mallocFailed = 1;
     checkAppendMsg(pCheck, zContext,
                    "sqlite3BtreeInitPage() returns error code %d", rc);
     releasePage(pPage);
     return 0;
@@ -40688,9 +42544,9 @@
              "On tree page %d cell %d: ", iPage, i);
     pCell = findCell(pPage,i);
     sqlite3BtreeParseCellPtr(pPage, pCell, &info);
     sz = info.nData;
-    if( !pPage->intKey ) sz += info.nKey;
+    if( !pPage->intKey ) sz += (int)info.nKey;
     assert( sz==info.nPayload );
     if( sz>info.nLocal ){
       int nPage = (sz - info.nLocal + usableSize - 5)/(usableSize - 4);
       Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]);
@@ -40803,11 +42659,11 @@
 ** an array of pages numbers were each page number is the root page of
 ** a table.  nRoot is the number of entries in aRoot.
 **
 ** Write the number of error seen in *pnErr.  Except for some memory
-** allocation errors,  nn error message is held in memory obtained from
+** allocation errors,  an error message held in memory obtained from
 ** malloc is returned if *pnErr is non-zero.  If *pnErr==0 then NULL is
-** returned.
+** returned.  If a memory allocation error occurs, NULL is returned.
 */
 SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
   Btree *p,     /* The btree to be checked */
   int *aRoot,   /* An array of root pages numbers for individual trees */
@@ -41004,10 +42860,10 @@
 
   /* Variable nNewPage is the number of pages required to store the
   ** contents of pFrom using the current page-size of pTo.
   */
-  nNewPage = ((i64)nFromPage * (i64)nFromPageSize + (i64)nToPageSize - 1) /
-      (i64)nToPageSize;
+  nNewPage = (Pgno)
+     (((i64)nFromPage*(i64)nFromPageSize+(i64)nToPageSize-1)/(i64)nToPageSize);
 
   for(i=1; rc==SQLITE_OK && (i<=nToPage || i<=nNewPage); i++){
 
     /* Journal the original page.
@@ -41054,9 +42910,9 @@
         rc==SQLITE_OK && iOff<i*nToPageSize;
         iOff += nFromPageSize
       ){
         DbPage *pFromPage = 0;
-        Pgno iFrom = (iOff/nFromPageSize)+1;
+        Pgno iFrom = (Pgno)(iOff/nFromPageSize)+1;
 
         if( iFrom==PENDING_BYTE_PAGE(pBtFrom) ){
           continue;
         }
@@ -41135,9 +42991,9 @@
           rc==SQLITE_OK && iOff<(iPending+nToPageSize);
           iOff += nFromPageSize
         ){
           DbPage *pFromPage = 0;
-          Pgno iFrom = (iOff/nFromPageSize)+1;
+          Pgno iFrom = (Pgno)(iOff/nFromPageSize)+1;
 
           if( iFrom==PENDING_BYTE_PAGE(pBtFrom) || iFrom>nFromPage ){
             continue;
           }
@@ -41331,139 +43187,8 @@
 }
 #endif
 
 /************** End of btree.c ***********************************************/
-/************** Begin file vdbefifo.c ****************************************/
-/*
-** 2005 June 16
-**
-** The author disclaims copyright to this source code.  In place of
-** a legal notice, here is a blessing:
-**
-**    May you do good and not evil.
-**    May you find forgiveness for yourself and forgive others.
-**    May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file implements a FIFO queue of rowids used for processing
-** UPDATE and DELETE statements.
-**
-** $Id: vdbefifo.c,v 1.9 2008/11/17 19:18:55 danielk1977 Exp $
-*/
-
-/*
-** Constants FIFOSIZE_FIRST and FIFOSIZE_MAX are the initial
-** number of entries in a fifo page and the maximum number of
-** entries in a fifo page.
-*/
-#define FIFOSIZE_FIRST (((128-sizeof(FifoPage))/8)+1)
-#ifdef SQLITE_MALLOC_SOFT_LIMIT
-# define FIFOSIZE_MAX   (int)(((SQLITE_MALLOC_SOFT_LIMIT-sizeof(FifoPage))/8)+1)
-#else
-# define FIFOSIZE_MAX   (int)(((262144-sizeof(FifoPage))/8)+1)
-#endif
-
-/*
-** Allocate a new FifoPage and return a pointer to it.  Return NULL if
-** we run out of memory.  Leave space on the page for nEntry entries.
-*/
-static FifoPage *allocateFifoPage(sqlite3 *db, int nEntry){
-  FifoPage *pPage;
-  if( nEntry>FIFOSIZE_MAX ){
-    nEntry = FIFOSIZE_MAX;
-  }
-  pPage = sqlite3DbMallocRaw(db, sizeof(FifoPage) + sizeof(i64)*(nEntry-1) );
-  if( pPage ){
-    pPage->nSlot = nEntry;
-    pPage->iWrite = 0;
-    pPage->iRead = 0;
-    pPage->pNext = 0;
-  }
-  return pPage;
-}
-
-/*
-** Initialize a Fifo structure.
-*/
-SQLITE_PRIVATE void sqlite3VdbeFifoInit(Fifo *pFifo, sqlite3 *db){
-  memset(pFifo, 0, sizeof(*pFifo));
-  pFifo->db = db;
-}
-
-/*
-** Push a single 64-bit integer value into the Fifo.  Return SQLITE_OK
-** normally.   SQLITE_NOMEM is returned if we are unable to allocate
-** memory.
-*/
-SQLITE_PRIVATE int sqlite3VdbeFifoPush(Fifo *pFifo, i64 val){
-  FifoPage *pPage;
-  pPage = pFifo->pLast;
-  if( pPage==0 ){
-    pPage = pFifo->pLast = pFifo->pFirst =
-         allocateFifoPage(pFifo->db, FIFOSIZE_FIRST);
-    if( pPage==0 ){
-      return SQLITE_NOMEM;
-    }
-  }else if( pPage->iWrite>=pPage->nSlot ){
-    pPage->pNext = allocateFifoPage(pFifo->db, pFifo->nEntry);
-    if( pPage->pNext==0 ){
-      return SQLITE_NOMEM;
-    }
-    pPage = pFifo->pLast = pPage->pNext;
-  }
-  pPage->aSlot[pPage->iWrite++] = val;
-  pFifo->nEntry++;
-  return SQLITE_OK;
-}
-
-/*
-** Extract a single 64-bit integer value from the Fifo.  The integer
-** extracted is the one least recently inserted.  If the Fifo is empty
-** return SQLITE_DONE.
-*/
-SQLITE_PRIVATE int sqlite3VdbeFifoPop(Fifo *pFifo, i64 *pVal){
-  FifoPage *pPage;
-  if( pFifo->nEntry==0 ){
-    return SQLITE_DONE;
-  }
-  assert( pFifo->nEntry>0 );
-  pPage = pFifo->pFirst;
-  assert( pPage!=0 );
-  assert( pPage->iWrite>pPage->iRead );
-  assert( pPage->iWrite<=pPage->nSlot );
-  assert( pPage->iRead<pPage->nSlot );
-  assert( pPage->iRead>=0 );
-  *pVal = pPage->aSlot[pPage->iRead++];
-  pFifo->nEntry--;
-  if( pPage->iRead>=pPage->iWrite ){
-    pFifo->pFirst = pPage->pNext;
-    sqlite3DbFree(pFifo->db, pPage);
-    if( pFifo->nEntry==0 ){
-      assert( pFifo->pLast==pPage );
-      pFifo->pLast = 0;
-    }else{
-      assert( pFifo->pFirst!=0 );
-    }
-  }else{
-    assert( pFifo->nEntry>0 );
-  }
-  return SQLITE_OK;
-}
-
-/*
-** Delete all information from a Fifo object.   Free all memory held
-** by the Fifo.
-*/
-SQLITE_PRIVATE void sqlite3VdbeFifoClear(Fifo *pFifo){
-  FifoPage *pPage, *pNextPage;
-  for(pPage=pFifo->pFirst; pPage; pPage=pNextPage){
-    pNextPage = pPage->pNext;
-    sqlite3DbFree(pFifo->db, pPage);
-  }
-  sqlite3VdbeFifoInit(pFifo, pFifo->db);
-}
-
-/************** End of vdbefifo.c ********************************************/
 /************** Begin file vdbemem.c *****************************************/
 /*
 ** 2004 May 26
 **
@@ -41480,9 +43205,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.126 2008/11/11 00:21:30 drh Exp $
+** $Id: vdbemem.c,v 1.133 2008/12/10 19:26:24 drh Exp $
 */
 
 /*
 ** Call sqlite3VdbeMemExpandBlob() on the supplied value (type Mem*)
@@ -41504,8 +43229,11 @@
 ** between formats.
 */
 SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
   int rc;
+  assert( (pMem->flags&MEM_RowSet)==0 );
+  assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE
+           || desiredEnc==SQLITE_UTF16BE );
   if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){
     return SQLITE_OK;
   }
   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
@@ -41515,9 +43243,9 @@
 
   /* MemTranslate() may return SQLITE_OK or SQLITE_NOMEM. If NOMEM is returned,
   ** then the encoding of the value may not have changed.
   */
-  rc = sqlite3VdbeMemTranslate(pMem, desiredEnc);
+  rc = sqlite3VdbeMemTranslate(pMem, (u8)desiredEnc);
   assert(rc==SQLITE_OK    || rc==SQLITE_NOMEM);
   assert(rc==SQLITE_OK    || pMem->enc!=desiredEnc);
   assert(rc==SQLITE_NOMEM || pMem->enc==desiredEnc);
   return rc;
@@ -41543,8 +43271,9 @@
     (((pMem->flags&MEM_Dyn)&&pMem->xDel) ? 1 : 0) +
     ((pMem->flags&MEM_Ephem) ? 1 : 0) +
     ((pMem->flags&MEM_Static) ? 1 : 0)
   );
+  assert( (pMem->flags&MEM_RowSet)==0 );
 
   if( n<32 ) n = 32;
   if( sqlite3DbMallocSize(pMem->db, pMem->zMalloc)<n ){
     if( preserve && pMem->z==pMem->zMalloc ){
@@ -41583,8 +43312,9 @@
 */
 SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){
   int f;
   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+  assert( (pMem->flags&MEM_RowSet)==0 );
   expandBlob(pMem);
   f = pMem->flags;
   if( (f&(MEM_Str|MEM_Blob)) && pMem->z!=pMem->zMalloc ){
     if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){
@@ -41606,21 +43336,22 @@
 SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){
   if( pMem->flags & MEM_Zero ){
     int nByte;
     assert( pMem->flags&MEM_Blob );
+    assert( (pMem->flags&MEM_RowSet)==0 );
     assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
 
     /* Set nByte to the number of bytes required to store the expanded blob. */
-    nByte = pMem->n + pMem->u.i;
+    nByte = pMem->n + pMem->u.nZero;
     if( nByte<=0 ){
       nByte = 1;
     }
     if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){
       return SQLITE_NOMEM;
     }
 
-    memset(&pMem->z[pMem->n], 0, pMem->u.i);
-    pMem->n += pMem->u.i;
+    memset(&pMem->z[pMem->n], 0, pMem->u.nZero);
+    pMem->n += pMem->u.nZero;
     pMem->flags &= ~(MEM_Zero|MEM_Term);
   }
   return SQLITE_OK;
 }
@@ -41665,8 +43396,10 @@
   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
   assert( !(fg&MEM_Zero) );
   assert( !(fg&(MEM_Str|MEM_Blob)) );
   assert( fg&(MEM_Int|MEM_Real) );
+  assert( (pMem->flags&MEM_RowSet)==0 );
+
 
   if( sqlite3VdbeMemGrow(pMem, nByte, 0) ){
     return SQLITE_NOMEM;
   }
@@ -41682,9 +43415,9 @@
   }else{
     assert( fg & MEM_Real );
     sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->r);
   }
-  pMem->n = strlen(pMem->z);
+  pMem->n = sqlite3Strlen30(pMem->z);
   pMem->enc = SQLITE_UTF8;
   pMem->flags |= MEM_Str|MEM_Term;
   sqlite3VdbeChangeEncoding(pMem, enc);
   return rc;
@@ -41711,9 +43444,9 @@
     ctx.pFunc = pFunc;
     pFunc->xFinalize(&ctx);
     assert( 0==(pMem->flags&MEM_Dyn) && !pMem->xDel );
     sqlite3DbFree(pMem->db, pMem->zMalloc);
-    *pMem = ctx.s;
+    memcpy(pMem, &ctx.s, sizeof(ctx.s));
     rc = (ctx.isError?SQLITE_ERROR:SQLITE_OK);
   }
   return rc;
 }
@@ -41729,10 +43462,13 @@
     sqlite3VdbeMemFinalize(p, p->u.pDef);
     assert( (p->flags & MEM_Agg)==0 );
     sqlite3VdbeMemRelease(p);
   }else if( p->flags&MEM_Dyn && p->xDel ){
+    assert( (p->flags&MEM_RowSet)==0 );
     p->xDel((void *)p->z);
     p->xDel = 0;
+  }else if( p->flags&MEM_RowSet ){
+    sqlite3RowSetClear(p->u.pRowSet);
   }
 }
 
 /*
@@ -41845,8 +43581,9 @@
 ** MEM_Int if we can.
 */
 SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){
   assert( pMem->flags & MEM_Real );
+  assert( (pMem->flags & MEM_RowSet)==0 );
   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
 
   pMem->u.i = doubleToInt64(pMem->r);
   if( pMem->r==(double)pMem->u.i ){
@@ -41853,19 +43590,16 @@
     pMem->flags |= MEM_Int;
   }
 }
 
-static void setTypeFlag(Mem *pMem, int f){
-  MemSetTypeFlag(pMem, f);
-}
-
 /*
 ** Convert pMem to type integer.  Invalidate any prior representations.
 */
 SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem *pMem){
   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+  assert( (pMem->flags & MEM_RowSet)==0 );
   pMem->u.i = sqlite3VdbeIntValue(pMem);
-  setTypeFlag(pMem, MEM_Int);
+  MemSetTypeFlag(pMem, MEM_Int);
   return SQLITE_OK;
 }
 
 /*
@@ -41874,9 +43608,9 @@
 */
 SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem *pMem){
   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
   pMem->r = sqlite3VdbeRealValue(pMem);
-  setTypeFlag(pMem, MEM_Real);
+  MemSetTypeFlag(pMem, MEM_Real);
   return SQLITE_OK;
 }
 
 /*
@@ -41895,9 +43629,9 @@
   if( r1==r2 ){
     sqlite3VdbeMemIntegerify(pMem);
   }else{
     pMem->r = r1;
-    setTypeFlag(pMem, MEM_Real);
+    MemSetTypeFlag(pMem, MEM_Real);
   }
   return SQLITE_OK;
 }
 
@@ -41904,9 +43638,12 @@
 /*
 ** Delete any previous value and set the value stored in *pMem to NULL.
 */
 SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem *pMem){
-  setTypeFlag(pMem, MEM_Null);
+  if( pMem->flags & MEM_RowSet ){
+    sqlite3RowSetClear(pMem->u.pRowSet);
+  }
+  MemSetTypeFlag(pMem, MEM_Null);
   pMem->type = SQLITE_NULL;
 }
 
 /*
@@ -41914,14 +43651,14 @@
 ** n containing all zeros.
 */
 SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
   sqlite3VdbeMemRelease(pMem);
-  setTypeFlag(pMem, MEM_Blob);
+  MemSetTypeFlag(pMem, MEM_Blob);
   pMem->flags = MEM_Blob|MEM_Zero;
   pMem->type = SQLITE_BLOB;
   pMem->n = 0;
   if( n<0 ) n = 0;
-  pMem->u.i = n;
+  pMem->u.nZero = n;
   pMem->enc = SQLITE_UTF8;
 }
 
 /*
@@ -41950,8 +43687,32 @@
   }
 }
 
 /*
+** Delete any previous value and set the value of pMem to be an
+** empty boolean index.
+*/
+SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem *pMem){
+  sqlite3 *db = pMem->db;
+  assert( db!=0 );
+  if( pMem->flags & MEM_RowSet ){
+    sqlite3RowSetClear(pMem->u.pRowSet);
+  }else{
+    sqlite3VdbeMemRelease(pMem);
+    pMem->zMalloc = sqlite3DbMallocRaw(db, 64);
+  }
+  if( db->mallocFailed ){
+    pMem->flags = MEM_Null;
+  }else{
+    assert( pMem->zMalloc );
+    pMem->u.pRowSet = sqlite3RowSetInit(db, pMem->zMalloc,
+                                       sqlite3DbMallocSize(db, pMem->zMalloc));
+    assert( pMem->u.pRowSet!=0 );
+    pMem->flags = MEM_RowSet;
+  }
+}
+
+/*
 ** Return true if the Mem object contains a TEXT or BLOB that is
 ** too large - whose size exceeds SQLITE_MAX_LENGTH.
 */
 SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem *p){
@@ -41958,9 +43719,9 @@
   assert( p->db!=0 );
   if( p->flags & (MEM_Str|MEM_Blob) ){
     int n = p->n;
     if( p->flags & MEM_Zero ){
-      n += p->u.i;
+      n += p->u.nZero;
     }
     return n>p->db->aLimit[SQLITE_LIMIT_LENGTH];
   }
   return 0;
@@ -41977,8 +43738,9 @@
 ** pFrom->z is used, then pTo->z points to the same thing as pFrom->z
 ** and flags gets srcType (either MEM_Ephem or MEM_Static).
 */
 SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
+  assert( (pFrom->flags & MEM_RowSet)==0 );
   sqlite3VdbeMemReleaseExternal(pTo);
   memcpy(pTo, pFrom, MEMCELLSIZE);
   pTo->xDel = 0;
   if( (pFrom->flags&MEM_Dyn)!=0 || pFrom->z==pFrom->zMalloc ){
@@ -41994,8 +43756,9 @@
 */
 SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
   int rc = SQLITE_OK;
 
+  assert( (pFrom->flags & MEM_RowSet)==0 );
   sqlite3VdbeMemReleaseExternal(pTo);
   memcpy(pTo, pFrom, MEMCELLSIZE);
   pTo->flags &= ~MEM_Dyn;
 
@@ -42044,11 +43807,12 @@
   void (*xDel)(void*) /* Destructor function */
 ){
   int nByte = n;      /* New value for pMem->n */
   int iLimit;         /* Maximum allowed string or blob size */
-  int flags = 0;      /* New value for pMem->flags */
+  u16 flags = 0;      /* New value for pMem->flags */
 
   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+  assert( (pMem->flags & MEM_RowSet)==0 );
 
   /* If z is a NULL pointer, set pMem to contain an SQL NULL. */
   if( !z ){
     sqlite3VdbeMemSetNull(pMem);
@@ -42134,8 +43898,9 @@
   */
   f1 = pMem1->flags;
   f2 = pMem2->flags;
   combined_flags = f1|f2;
+  assert( (combined_flags & MEM_RowSet)==0 );
 
   /* If one value is NULL, it is less than the other. If both values
   ** are NULL, return 0.
   */
@@ -42156,14 +43921,14 @@
     }
     if( (f1 & f2 & MEM_Int)==0 ){
       double r1, r2;
       if( (f1&MEM_Real)==0 ){
-        r1 = pMem1->u.i;
+        r1 = (double)pMem1->u.i;
       }else{
         r1 = pMem1->r;
       }
       if( (f2&MEM_Real)==0 ){
-        r2 = pMem2->u.i;
+        r2 = (double)pMem2->u.i;
       }else{
         r2 = pMem2->r;
       }
       if( r1<r2 ) return -1;
@@ -42261,8 +44026,9 @@
   int rc = SQLITE_OK;
 
   db = sqlite3BtreeCursorDb(pCur);
   assert( sqlite3_mutex_held(db->mutex) );
+  assert( (pMem->flags & MEM_RowSet)==0 );
   if( key ){
     zData = (char *)sqlite3BtreeKeyFetch(pCur, &available);
   }else{
     zData = (char *)sqlite3BtreeDataFetch(pCur, &available);
@@ -42319,13 +44085,13 @@
       );
       /* If the string is UTF-8 encoded and nul terminated, then pMem->n
       ** must be the length of the string.  (Later:)  If the database file
       ** has been corrupted, '\000' characters might have been inserted
-      ** into the middle of the string.  In that case, the strlen() might
-      ** be less.
+      ** into the middle of the string.  In that case, the sqlite3Strlen30()
+      ** might be less.
       */
       if( pMem->enc==SQLITE_UTF8 && (flags & MEM_Term) ){
-        assert( strlen(pMem->z)<=pMem->n );
+        assert( sqlite3Strlen30(pMem->z)<=pMem->n );
         assert( pMem->z[pMem->n]==0 );
       }
     }
   }else{
@@ -42356,8 +44122,9 @@
   if( !pVal ) return 0;
 
   assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
   assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
+  assert( (pVal->flags & MEM_RowSet)==0 );
 
   if( pVal->flags&MEM_Null ){
     return 0;
   }
@@ -42375,9 +44142,9 @@
     sqlite3VdbeMemNulTerminate(pVal);
   }else{
     assert( (pVal->flags&MEM_Blob)==0 );
     sqlite3VdbeMemStringify(pVal, enc);
-    assert( 0==(1&(int)pVal->z) );
+    assert( 0==(1&SQLITE_PTR_TO_INT(pVal->z)) );
   }
   assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0
               || pVal->db->mallocFailed );
   if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){
@@ -42500,9 +44267,9 @@
 SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){
   Mem *p = (Mem*)pVal;
   if( (p->flags & MEM_Blob)!=0 || sqlite3ValueText(pVal, enc) ){
     if( p->flags & MEM_Zero ){
-      return p->n+p->u.i;
+      return p->n + p->u.nZero;
     }else{
       return p->n;
     }
   }
@@ -42526,9 +44293,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.420 2008/11/17 19:18:55 danielk1977 Exp $
+** $Id: vdbeaux.c,v 1.428 2008/12/16 17:20:38 shane Exp $
 */
 
 
 
@@ -42650,16 +44417,17 @@
   VdbeOp *pOp;
 
   i = p->nOp;
   assert( p->magic==VDBE_MAGIC_INIT );
+  assert( op>0 && op<0xff );
   if( p->nOpAlloc<=i ){
     if( growOpArray(p) ){
       return 0;
     }
   }
   p->nOp++;
   pOp = &p->aOp[i];
-  pOp->opcode = op;
+  pOp->opcode = (u8)op;
   pOp->p5 = 0;
   pOp->p1 = p1;
   pOp->p2 = p2;
   pOp->p3 = p3;
@@ -42722,11 +44490,12 @@
   int i;
   i = p->nLabel++;
   assert( p->magic==VDBE_MAGIC_INIT );
   if( i>=p->nLabelAlloc ){
-    p->nLabelAlloc = p->nLabelAlloc*2 + 10;
+    int n = p->nLabelAlloc*2 + 5;
     p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel,
-                                    p->nLabelAlloc*sizeof(p->aLabel[0]));
+                                       n*sizeof(p->aLabel[0]));
+    p->nLabelAlloc = sqlite3DbMallocSize(p->db, p->aLabel)/sizeof(p->aLabel[0]);
   }
   if( p->aLabel ){
     p->aLabel[i] = -1;
   }
@@ -43051,9 +44820,9 @@
   if( n==P4_INT32 ){
     /* Note: this cast is safe, because the origin data point was an int
     ** that was cast to a (const char *). */
     pOp->p4.i = SQLITE_PTR_TO_INT(zP4);
-    pOp->p4type = n;
+    pOp->p4type = P4_INT32;
   }else if( zP4==0 ){
     pOp->p4.p = 0;
     pOp->p4type = P4_NOTUSED;
   }else if( n==P4_KEYINFO ){
@@ -43081,11 +44850,11 @@
     pOp->p4.p = (void*)zP4;
     pOp->p4type = P4_KEYINFO;
   }else if( n<0 ){
     pOp->p4.p = (void*)zP4;
-    pOp->p4type = n;
-  }else{
-    if( n==0 ) n = strlen(zP4);
+    pOp->p4type = (signed char)n;
+  }else{
+    if( n==0 ) n = sqlite3Strlen30(zP4);
     pOp->p4.z = sqlite3DbStrNDup(p->db, zP4, n);
     pOp->p4type = P4_DYNAMIC;
   }
 }
@@ -43147,13 +44916,13 @@
     case P4_KEYINFO: {
       int i, j;
       KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
       sqlite3_snprintf(nTemp, zTemp, "keyinfo(%d", pKeyInfo->nField);
-      i = strlen(zTemp);
+      i = sqlite3Strlen30(zTemp);
       for(j=0; j<pKeyInfo->nField; j++){
         CollSeq *pColl = pKeyInfo->aColl[j];
         if( pColl ){
-          int n = strlen(pColl->zName);
+          int n = sqlite3Strlen30(pColl->zName);
           if( i+n>nTemp-6 ){
             memcpy(&zTemp[i],",...",4);
             break;
           }
@@ -43275,9 +45044,9 @@
 static void releaseMemArray(Mem *p, int N){
   if( p && N ){
     Mem *pEnd;
     sqlite3 *db = p->db;
-    int malloc_failed = db->mallocFailed;
+    u8 malloc_failed = db->mallocFailed;
     for(pEnd=&p[N]; p<pEnd; p++){
       assert( (&p[1])==pEnd || p[0].db==p[1].db );
 
       /* This block is really an inlined version of sqlite3VdbeMemRelease()
@@ -43311,8 +45080,11 @@
   int nFree = 0;
   assert( sqlite3_mutex_held(p->db->mutex) );
   for(ii=1; ii<=p->nMem; ii++){
     Mem *pMem = &p->aMem[ii];
+    if( pMem->flags & MEM_RowSet ){
+      sqlite3RowSetClear(pMem->u.pRowSet);
+    }
     if( pMem->z && pMem->flags&MEM_Dyn ){
       assert( !pMem->xDel );
       nFree += sqlite3DbMallocSize(pMem->db, pMem->z);
       sqlite3VdbeMemRelease(pMem);
@@ -43345,15 +45117,22 @@
 
   assert( p->explain );
   if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE;
   assert( db->magic==SQLITE_MAGIC_BUSY );
-  assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
+  assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM );
 
   /* Even though this opcode does not use dynamic strings for
   ** the result, result columns may become dynamic if the user calls
   ** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
   */
   releaseMemArray(pMem, p->nMem);
+
+  if( p->rc==SQLITE_NOMEM ){
+    /* This happens if a malloc() inside a call to sqlite3_column_text() or
+    ** sqlite3_column_text16() failed.  */
+    db->mallocFailed = 1;
+    return SQLITE_ERROR;
+  }
 
   do{
     i = p->pc++;
   }while( i<p->nOp && p->explain==2 && p->aOp[i].opcode!=OP_Explain );
@@ -43375,9 +45154,9 @@
 
       pMem->flags = MEM_Static|MEM_Str|MEM_Term;
       pMem->z = (char*)sqlite3OpcodeName(pOp->opcode);  /* Opcode */
       assert( pMem->z!=0 );
-      pMem->n = strlen(pMem->z);
+      pMem->n = sqlite3Strlen30(pMem->z);
       pMem->type = SQLITE_TEXT;
       pMem->enc = SQLITE_UTF8;
       pMem++;
     }
@@ -43408,9 +45187,9 @@
     if( z!=pMem->z ){
       sqlite3VdbeMemSetStr(pMem, z, -1, SQLITE_UTF8, 0);
     }else{
       assert( pMem->z!=0 );
-      pMem->n = strlen(pMem->z);
+      pMem->n = sqlite3Strlen30(pMem->z);
       pMem->enc = SQLITE_UTF8;
     }
     pMem->type = SQLITE_TEXT;
     pMem++;
@@ -43430,9 +45209,9 @@
 #ifdef SQLITE_DEBUG
       if( pOp->zComment ){
         pMem->flags = MEM_Str|MEM_Term;
         pMem->z = pOp->zComment;
-        pMem->n = strlen(pMem->z);
+        pMem->n = sqlite3Strlen30(pMem->z);
         pMem->enc = SQLITE_UTF8;
         pMem->type = SQLITE_TEXT;
       }else
 #endif
@@ -43658,18 +45437,18 @@
 */
 static void Cleanup(Vdbe *p){
   int i;
   sqlite3 *db = p->db;
+  Mem *pMem;
   closeAllCursorsExceptActiveVtabs(p);
-  for(i=1; i<=p->nMem; i++){
-    MemSetTypeFlag(&p->aMem[i], MEM_Null);
+  for(pMem=&p->aMem[1], i=1; i<=p->nMem; i++, pMem++){
+    if( pMem->flags & MEM_RowSet ){
+      sqlite3RowSetClear(pMem->u.pRowSet);
+    }
+    MemSetTypeFlag(pMem, MEM_Null);
   }
   releaseMemArray(&p->aMem[1], p->nMem);
-  sqlite3VdbeFifoClear(&p->sFifo);
-  if( p->contextStack ){
-    for(i=0; i<p->contextStackTop; i++){
-      sqlite3VdbeFifoClear(&p->contextStack[i].sFifo);
-    }
+  if( p->contextStack ){
     sqlite3DbFree(db, p->contextStack);
   }
   p->contextStack = 0;
   p->contextStackDepth = 0;
@@ -43790,9 +45569,11 @@
   ** string, it means the main database is :memory: or a temp file.  In
   ** that case we do not support atomic multi-file commits, so use the
   ** simple case then too.
   */
-  if( 0==strlen(sqlite3BtreeGetFilename(db->aDb[0].pBt)) || nTrans<=1 ){
+  if( 0==sqlite3Strlen30(sqlite3BtreeGetFilename(db->aDb[0].pBt))
+   || nTrans<=1
+  ){
     for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
       Btree *pBt = db->aDb[i].pBt;
       if( pBt ){
         rc = sqlite3BtreeCommitPhaseOne(pBt, 0);
@@ -43830,12 +45611,12 @@
     int res;
 
     /* Select a master journal file name */
     do {
-      u32 random;
+      u32 iRandom;
       sqlite3DbFree(db, zMaster);
-      sqlite3_randomness(sizeof(random), &random);
-      zMaster = sqlite3MPrintf(db, "%s-mj%08X", zMainFile, random&0x7fffffff);
+      sqlite3_randomness(sizeof(iRandom), &iRandom);
+      zMaster = sqlite3MPrintf(db, "%s-mj%08X", zMainFile, iRandom&0x7fffffff);
       if( !zMaster ){
         return SQLITE_NOMEM;
       }
       rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res);
@@ -43866,10 +45647,10 @@
         if( zFile[0]==0 ) continue;  /* Ignore :memory: databases */
         if( !needSync && !sqlite3BtreeSyncDisabled(pBt) ){
           needSync = 1;
         }
-        rc = sqlite3OsWrite(pMaster, zFile, strlen(zFile)+1, offset);
-        offset += strlen(zFile)+1;
+        rc = sqlite3OsWrite(pMaster, zFile, sqlite3Strlen30(zFile)+1, offset);
+        offset += sqlite3Strlen30(zFile)+1;
         if( rc!=SQLITE_OK ){
           sqlite3OsCloseFree(pMaster);
           sqlite3OsDelete(pVfs, zMaster, 0);
           sqlite3DbFree(db, zMaster);
@@ -44366,9 +46147,9 @@
     assert( p->isTable );
     rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res);
     if( rc ) return rc;
     p->lastRowid = keyToInt(p->movetoTarget);
-    p->rowidIsValid = res==0;
+    p->rowidIsValid = res==0 ?1:0;
     if( res<0 ){
       rc = sqlite3BtreeNext(p->pCursor, &res);
       if( rc ) return rc;
     }
@@ -44446,9 +46227,9 @@
 #   define MAX_6BYTE ((((i64)0x00008000)<<32)-1)
     i64 i = pMem->u.i;
     u64 u;
     if( file_format>=4 && (i&1)==i ){
-      return 8+i;
+      return 8+(u32)i;
     }
     u = i<0 ? -i : i;
     if( u<=127 ) return 1;
     if( u<=32767 ) return 2;
@@ -44462,9 +46243,9 @@
   }
   assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) );
   n = pMem->n;
   if( flags & MEM_Zero ){
-    n += pMem->u.i;
+    n += pMem->u.nZero;
   }
   assert( n>=0 );
   return ((n*2) + 12 + ((flags&MEM_Str)!=0));
 }
@@ -44569,23 +46350,23 @@
     }
     len = i = sqlite3VdbeSerialTypeLen(serial_type);
     assert( len<=nBuf );
     while( i-- ){
-      buf[i] = (v&0xFF);
+      buf[i] = (u8)(v&0xFF);
       v >>= 8;
     }
     return len;
   }
 
   /* String or blob */
   if( serial_type>=12 ){
-    assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.i:0)
+    assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.nZero:0)
              == sqlite3VdbeSerialTypeLen(serial_type) );
     assert( pMem->n<=nBuf );
     len = pMem->n;
     memcpy(buf, pMem->z, len);
     if( pMem->flags & MEM_Zero ){
-      len += pMem->u.i;
+      len += pMem->u.nZero;
       if( len>nBuf ){
         len = nBuf;
       }
       memset(&buf[pMem->n], 0, len-pMem->n);
@@ -44879,8 +46660,11 @@
 /*
 ** pCur points at an index entry created using the OP_MakeRecord opcode.
 ** Read the rowid (the last field in the record) and store it in *rowid.
 ** Return SQLITE_OK if everything works, or an error code otherwise.
+**
+** pCur might be pointing to text obtained from a corrupt database file.
+** So the content cannot be trusted.  Do appropriate checks on the content.
 */
 SQLITE_PRIVATE int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){
   i64 nCellKey = 0;
   int rc;
@@ -44888,26 +46672,64 @@
   u32 typeRowid;    /* Serial type of the rowid */
   u32 lenRowid;     /* Size of the rowid */
   Mem m, v;
 
+  /* Get the size of the index entry.  Only indices entries of less
+  ** than 2GiB are support - anything large must be database corruption */
   sqlite3BtreeKeySize(pCur, &nCellKey);
-  if( nCellKey<=0 ){
+  if( unlikely(nCellKey<=0 || nCellKey>0x7fffffff) ){
     return SQLITE_CORRUPT_BKPT;
   }
+
+  /* Read in the complete content of the index entry */
   m.flags = 0;
   m.db = 0;
   m.zMalloc = 0;
-  rc = sqlite3VdbeMemFromBtree(pCur, 0, nCellKey, 1, &m);
+  rc = sqlite3VdbeMemFromBtree(pCur, 0, (int)nCellKey, 1, &m);
   if( rc ){
     return rc;
   }
+
+  /* The index entry must begin with a header size */
   (void)getVarint32((u8*)m.z, szHdr);
+  testcase( szHdr==2 );
+  testcase( szHdr==m.n );
+  if( unlikely(szHdr<2 || (int)szHdr>m.n) ){
+    goto idx_rowid_corruption;
+  }
+
+  /* The last field of the index should be an integer - the ROWID.
+  ** Verify that the last entry really is an integer. */
   (void)getVarint32((u8*)&m.z[szHdr-1], typeRowid);
+  testcase( typeRowid==1 );
+  testcase( typeRowid==2 );
+  testcase( typeRowid==3 );
+  testcase( typeRowid==4 );
+  testcase( typeRowid==5 );
+  testcase( typeRowid==6 );
+  testcase( typeRowid==8 );
+  testcase( typeRowid==9 );
+  if( unlikely(typeRowid<1 || typeRowid>9 || typeRowid==7) ){
+    goto idx_rowid_corruption;
+  }
   lenRowid = sqlite3VdbeSerialTypeLen(typeRowid);
+  testcase( m.n-lenRowid==szHdr );
+  if( unlikely(m.n-lenRowid<szHdr) ){
+    goto idx_rowid_corruption;
+  }
+
+  /* Fetch the integer off the end of the index record */
   sqlite3VdbeSerialGet((u8*)&m.z[m.n-lenRowid], typeRowid, &v);
   *rowid = v.u.i;
   sqlite3VdbeMemRelease(&m);
   return SQLITE_OK;
+
+  /* Jump here if database corruption is detected after m has been
+  ** allocated.  Free the m object and return SQLITE_CORRUPT. */
+idx_rowid_corruption:
+  testcase( m.zMalloc!=0 );
+  sqlite3VdbeMemRelease(&m);
+  return SQLITE_CORRUPT_BKPT;
 }
 
 /*
 ** Compare the key of the index entry that cursor pC is point to against
@@ -44933,16 +46755,16 @@
   BtCursor *pCur = pC->pCursor;
   Mem m;
 
   sqlite3BtreeKeySize(pCur, &nCellKey);
-  if( nCellKey<=0 ){
+  if( nCellKey<=0 || nCellKey>0x7fffffff ){
     *res = 0;
     return SQLITE_OK;
   }
   m.db = 0;
   m.flags = 0;
   m.zMalloc = 0;
-  rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m);
+  rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, (int)nCellKey, 1, &m);
   if( rc ){
     return rc;
   }
   assert( pUnpacked->flags & UNPACKED_IGNORE_ROWID );
@@ -45009,9 +46831,9 @@
 **
 ** This file contains code use to implement APIs that are part of the
 ** VDBE.
 **
-** $Id: vdbeapi.c,v 1.149 2008/11/19 09:05:27 danielk1977 Exp $
+** $Id: vdbeapi.c,v 1.150 2008/12/10 18:03:47 drh Exp $
 */
 
 #if 0 && defined(SQLITE_ENABLE_MEMORY_MANAGEMENT)
 /*
@@ -45278,9 +47100,9 @@
 SQLITE_API double sqlite3_value_double(sqlite3_value *pVal){
   return sqlite3VdbeRealValue((Mem*)pVal);
 }
 SQLITE_API int sqlite3_value_int(sqlite3_value *pVal){
-  return sqlite3VdbeIntValue((Mem*)pVal);
+  return (int)sqlite3VdbeIntValue((Mem*)pVal);
 }
 SQLITE_API sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){
   return sqlite3VdbeIntValue((Mem*)pVal);
 }
@@ -45457,9 +47279,9 @@
 #ifndef SQLITE_OMIT_TRACE
     if( db->xProfile && !db->init.busy ){
       double rNow;
       sqlite3OsCurrentTime(db->pVfs, &rNow);
-      p->startTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0;
+      p->startTime = (u64)((rNow - (int)rNow)*3600.0*24.0*1000000000.0);
     }
 #endif
 
     db->activeVdbeCnt++;
@@ -45488,9 +47310,10 @@
     double rNow;
     u64 elapseTime;
 
     sqlite3OsCurrentTime(db->pVfs, &rNow);
-    elapseTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0 - p->startTime;
+    elapseTime = (u64)((rNow - (int)rNow)*3600.0*24.0*1000000000.0);
+    elapseTime -= p->startTime;
     db->xProfile(db->pProfileArg, p->aOp[0].p4.z, elapseTime);
   }
 #endif
 
@@ -46046,9 +47869,9 @@
   int i,                 /* Index of the parameter to bind */
   const void *zData,     /* Pointer to the data to be bound */
   int nData,             /* Number of bytes of data to be bound */
   void (*xDel)(void*),   /* Destructor for the data */
-  int encoding           /* Encoding for the data */
+  u8 encoding            /* Encoding for the data */
 ){
   Vdbe *p = (Vdbe *)pStmt;
   Mem *pVar;
   int rc;
@@ -46349,14 +48172,14 @@
 ** 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.788 2008/11/17 15:31:48 danielk1977 Exp $
+** $Id: vdbe.c,v 1.803 2008/12/15 15:27:52 drh Exp $
 */
 
 /*
 ** The following global variable is incremented every time a cursor
-** moves, either by the OP_MoveXX, OP_Next, or OP_Prev opcodes.  The test
+** moves, either by the OP_SeekXX, OP_Next, or OP_Prev opcodes.  The test
 ** procedures use this information to make sure that indices are
 ** working correctly.  This variable has no function other than to
 ** help verify the correct operation of the library.
 */
@@ -46492,9 +48315,9 @@
 static VdbeCursor *allocateCursor(
   Vdbe *p,              /* The virtual machine */
   int iCur,             /* Index of the new VdbeCursor */
   Op *pOp,              /* */
-  int iDb,              /* */
+  int iDb,              /* When database the cursor belongs to, or -1 */
   int isBtreeCursor     /* */
 ){
   /* Find the memory cell that will be used to store the blob of memory
   ** required for this VdbeCursor structure. It is convenient to use a
@@ -46673,14 +48496,14 @@
       c = 's';
     }
 
     sqlite3_snprintf(100, zCsr, "%c", c);
-    zCsr += strlen(zCsr);
+    zCsr += sqlite3Strlen30(zCsr);
     sqlite3_snprintf(100, zCsr, "%d[", pMem->n);
-    zCsr += strlen(zCsr);
+    zCsr += sqlite3Strlen30(zCsr);
     for(i=0; i<16 && i<pMem->n; i++){
       sqlite3_snprintf(100, zCsr, "%02X", ((int)pMem->z[i] & 0xFF));
-      zCsr += strlen(zCsr);
+      zCsr += sqlite3Strlen30(zCsr);
     }
     for(i=0; i<16 && i<pMem->n; i++){
       char z = pMem->z[i];
       if( z<32 || z>126 ) *zCsr++ = '.';
@@ -46687,12 +48510,12 @@
       else *zCsr++ = z;
     }
 
     sqlite3_snprintf(100, zCsr, "]%s", encnames[pMem->enc]);
-    zCsr += strlen(zCsr);
+    zCsr += sqlite3Strlen30(zCsr);
     if( f & MEM_Zero ){
-      sqlite3_snprintf(100, zCsr,"+%lldz",pMem->u.i);
-      zCsr += strlen(zCsr);
+      sqlite3_snprintf(100, zCsr,"+%dz",pMem->u.nZero);
+      zCsr += sqlite3Strlen30(zCsr);
     }
     *zCsr = '\0';
   }else if( f & MEM_Str ){
     int j, k;
@@ -46710,9 +48533,9 @@
       zBuf[1] = 's';
     }
     k = 2;
     sqlite3_snprintf(100, &zBuf[k], "%d", pMem->n);
-    k += strlen(&zBuf[k]);
+    k += sqlite3Strlen30(&zBuf[k]);
     zBuf[k++] = '[';
     for(j=0; j<15 && j<pMem->n; j++){
       u8 c = pMem->z[j];
       if( c>=0x20 && c<0x7f ){
@@ -46722,9 +48545,9 @@
       }
     }
     zBuf[k++] = ']';
     sqlite3_snprintf(100,&zBuf[k], encnames[pMem->enc]);
-    k += strlen(&zBuf[k]);
+    k += sqlite3Strlen30(&zBuf[k]);
     zBuf[k++] = 0;
   }
 }
 #endif
@@ -46932,10 +48755,12 @@
   Op *pOp;                   /* Current operation */
   int rc = SQLITE_OK;        /* Value to return */
   sqlite3 *db = p->db;       /* The database */
   u8 encoding = ENC(db);     /* The database encoding */
-  Mem *pIn1, *pIn2, *pIn3;   /* Input operands */
-  Mem *pOut;                 /* Output operand */
+  Mem *pIn1 = 0;             /* 1st input operand */
+  Mem *pIn2 = 0;             /* 2nd input operand */
+  Mem *pIn3 = 0;             /* 3rd input operand */
+  Mem *pOut = 0;             /* Output operand */
   u8 opProperty;
   int iCompare = 0;          /* Result of last OP_Compare operation */
   int *aPermute = 0;         /* Permuation of columns for OP_Compare */
 #ifdef VDBE_PROFILE
@@ -47173,9 +48998,9 @@
 ** Jump to the next instruction after the address in register P1.
 */
 case OP_Return: {           /* in1 */
   assert( pIn1->flags & MEM_Int );
-  pc = pIn1->u.i;
+  pc = (int)pIn1->u.i;
   break;
 }
 
 /* Opcode:  Yield P1 * * * *
@@ -47188,9 +49013,9 @@
   assert( pOp->p1<=p->nMem );
   pIn1 = &p->aMem[pOp->p1];
   assert( (pIn1->flags & MEM_Dyn)==0 );
   pIn1->flags = MEM_Int;
-  pcDest = pIn1->u.i;
+  pcDest = (int)pIn1->u.i;
   pIn1->u.i = pc;
   REGISTER_TRACE(pOp->p1, pIn1);
   pc = pcDest;
   break;
@@ -47198,9 +49023,9 @@
 
 
 /* Opcode:  Halt P1 P2 * P4 *
 **
-** Exit immediately.  All open cursors, Fifos, etc are closed
+** Exit immediately.  All open cursors, etc are closed
 ** automatically.
 **
 ** P1 is the result code returned by sqlite3_exec(), sqlite3_reset(),
 ** or sqlite3_finalize().  For a normal halt, this should be SQLITE_OK (0).
@@ -47274,9 +49099,9 @@
 */
 case OP_String8: {         /* same as TK_STRING, out2-prerelease */
   assert( pOp->p4.z!=0 );
   pOp->opcode = OP_String;
-  pOp->p1 = strlen(pOp->p4.z);
+  pOp->p1 = sqlite3Strlen30(pOp->p4.z);
 
 #ifndef SQLITE_OMIT_UTF16
   if( encoding!=SQLITE_UTF8 ){
     sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC);
@@ -47326,9 +49151,8 @@
   break;
 }
 
 
-#ifndef SQLITE_OMIT_BLOB_LITERAL
 /* Opcode: Blob P1 P2 * P4
 **
 ** P4 points to a blob of data P1 bytes long.  Store this
 ** blob in register P2. This instruction is not coded directly
@@ -47343,9 +49167,8 @@
   pOut->enc = encoding;
   UPDATE_MAX_BLOBSIZE(pOut);
   break;
 }
-#endif /* SQLITE_OMIT_BLOB_LITERAL */
 
 /* Opcode: Variable P1 P2 * * *
 **
 ** The value of variable P1 is written into register P2. A variable is
@@ -47514,9 +49337,9 @@
   if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
     goto too_big;
   }
   MemSetTypeFlag(pOut, MEM_Str);
-  if( sqlite3VdbeMemGrow(pOut, nByte+2, pOut==pIn2) ){
+  if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){
     goto no_mem;
   }
   if( pOut!=pIn2 ){
     memcpy(pOut->z, pIn2->z, pIn2->n);
@@ -47524,9 +49347,9 @@
   memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n);
   pOut->z[nByte] = 0;
   pOut->z[nByte+1] = 0;
   pOut->flags |= MEM_Term;
-  pOut->n = nByte;
+  pOut->n = (int)nByte;
   pOut->enc = encoding;
   UPDATE_MAX_BLOBSIZE(pOut);
   break;
 }
@@ -47621,9 +49444,9 @@
         i64 ia = (i64)a;
         i64 ib = (i64)b;
         if( ia==0 ) goto arithmetic_result_is_null;
         if( ia==-1 ) ia = 1;
-        b = ib % ia;
+        b = (double)(ib % ia);
         break;
       }
     }
     if( sqlite3IsNaN(b) ){
@@ -47828,38 +49651,8 @@
 */
 case OP_AddImm: {            /* in1 */
   sqlite3VdbeMemIntegerify(pIn1);
   pIn1->u.i += pOp->p2;
-  break;
-}
-
-/* Opcode: ForceInt P1 P2 P3 * *
-**
-** Convert value in register P1 into an integer.  If the value
-** in P1 is not numeric (meaning that is is a NULL or a string that
-** does not look like an integer or floating point number) then
-** jump to P2.  If the value in P1 is numeric then
-** convert it into the least integer that is greater than or equal to its
-** current value if P3==0, or to the least integer that is strictly
-** greater than its current value if P3==1.
-*/
-case OP_ForceInt: {            /* jump, in1 */
-  i64 v;
-  applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
-  if( (pIn1->flags & (MEM_Int|MEM_Real))==0 ){
-    pc = pOp->p2 - 1;
-    break;
-  }
-  if( pIn1->flags & MEM_Int ){
-    v = pIn1->u.i + (pOp->p3!=0);
-  }else{
-    assert( pIn1->flags & MEM_Real );
-    v = (sqlite3_int64)pIn1->r;
-    if( pIn1->r>(double)v ) v++;
-    if( pOp->p3 && pIn1->r==(double)v ) v++;
-  }
-  pIn1->u.i = v;
-  MemSetTypeFlag(pIn1, MEM_Int);
   break;
 }
 
 /* Opcode: MustBeInt P1 P2 * * *
@@ -48083,8 +49876,9 @@
   affinity = pOp->p5 & SQLITE_AFF_MASK;
   if( affinity ){
     applyAffinity(pIn1, affinity, encoding);
     applyAffinity(pIn3, affinity, encoding);
+    if( db->mallocFailed ) goto no_mem;
   }
 
   assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
   ExpandBlob(pIn1);
@@ -48233,33 +50027,37 @@
   }
   break;
 }
 
-/* Opcode: Not P1 * * * *
-**
-** Interpret the value in register P1 as a boolean value.  Replace it
-** with its complement.  If the value in register P1 is NULL its value
-** is unchanged.
+/* Opcode: Not P1 P2 * * *
+**
+** Interpret the value in register P1 as a boolean value.  Store the
+** boolean complement in register P2.  If the value in register P1 is
+** NULL, then a NULL is stored in P2.
 */
 case OP_Not: {                /* same as TK_NOT, in1 */
-  if( pIn1->flags & MEM_Null ) break;  /* Do nothing to NULLs */
-  sqlite3VdbeMemIntegerify(pIn1);
-  pIn1->u.i = !pIn1->u.i;
-  assert( pIn1->flags&MEM_Int );
-  break;
-}
-
-/* Opcode: BitNot P1 * * * *
-**
-** Interpret the content of register P1 as an integer.  Replace it
-** with its ones-complement.  If the value is originally NULL, leave
-** it unchanged.
+  pOut = &p->aMem[pOp->p2];
+  if( pIn1->flags & MEM_Null ){
+    sqlite3VdbeMemSetNull(pOut);
+  }else{
+    sqlite3VdbeMemSetInt64(pOut, !sqlite3VdbeIntValue(pIn1));
+  }
+  break;
+}
+
+/* Opcode: BitNot P1 P2 * * *
+**
+** Interpret the content of register P1 as an integer.  Store the
+** ones-complement of the P1 value into register P2.  If P1 holds
+** a NULL then store a NULL in P2.
 */
 case OP_BitNot: {             /* same as TK_BITNOT, in1 */
-  if( pIn1->flags & MEM_Null ) break;  /* Do nothing to NULLs */
-  sqlite3VdbeMemIntegerify(pIn1);
-  pIn1->u.i = ~pIn1->u.i;
-  assert( pIn1->flags&MEM_Int );
+  pOut = &p->aMem[pOp->p2];
+  if( pIn1->flags & MEM_Null ){
+    sqlite3VdbeMemSetNull(pOut);
+  }else{
+    sqlite3VdbeMemSetInt64(pOut, ~sqlite3VdbeIntValue(pIn1));
+  }
   break;
 }
 
 /* Opcode: If P1 P2 P3 * *
@@ -48372,11 +50170,9 @@
   char *zData;       /* Part of the record being decoded */
   Mem *pDest;        /* Where to write the extracted value */
   Mem sMem;          /* For storing the record being decoded */
 
-  sMem.flags = 0;
-  sMem.db = 0;
-  sMem.zMalloc = 0;
+  memset(&sMem, 0, sizeof(sMem));
   assert( p1<p->nCursor );
   assert( pOp->p3>0 && pOp->p3<=p->nMem );
   pDest = &p->aMem[pOp->p3];
   MemSetTypeFlag(pDest, MEM_Null);
@@ -48411,9 +50207,9 @@
       zRec = (char*)pC->aRow;
     }else if( pC->isIndex ){
       i64 payloadSize64;
       sqlite3BtreeKeySize(pCrsr, &payloadSize64);
-      payloadSize = payloadSize64;
+      payloadSize = (int)payloadSize64;
     }else{
       sqlite3BtreeDataSize(pCrsr, (u32 *)&payloadSize);
     }
     nField = pC->nField;
@@ -48449,9 +50245,9 @@
     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;       /* Number of bytes of available data */
+    int avail = 0;   /* Number of bytes of available data */
 
     assert(aType);
     pC->aOffset = aOffset = &aType[nField];
     pC->payloadSize = payloadSize;
@@ -48685,9 +50481,9 @@
     nHdr += sqlite3VarintLen(serial_type);
     if( 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.i;
+      nZero += pRec->u.nZero;
     }else if( len ){
       nZero = 0;
     }
   }
@@ -48708,9 +50504,9 @@
   ** 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, nByte, 0) ){
+  if( sqlite3VdbeMemGrow(pOut, (int)nByte, 0) ){
     goto no_mem;
   }
   zNewRecord = (u8 *)pOut->z;
 
@@ -48720,18 +50516,18 @@
     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], nByte-i, pRec, file_format);
+    i += sqlite3VdbeSerialPut(&zNewRecord[i], (int)(nByte-i), pRec,file_format);
   }
   assert( i==nByte );
 
   assert( pOp->p3>0 && pOp->p3<=p->nMem );
-  pOut->n = nByte;
+  pOut->n = (int)nByte;
   pOut->flags = MEM_Blob | MEM_Dyn;
   pOut->xDel = 0;
   if( nZero ){
-    pOut->u.i = nZero;
+    pOut->u.nZero = nZero;
     pOut->flags |= MEM_Zero;
   }
   pOut->enc = SQLITE_UTF8;  /* In case the blob is ever converted to text */
   REGISTER_TRACE(pOp->p3, pOut);
@@ -48816,12 +50612,12 @@
       assert( desiredAutoCommit==1 );
       sqlite3RollbackAll(db);
       db->autoCommit = 1;
     }else{
-      db->autoCommit = desiredAutoCommit;
+      db->autoCommit = (u8)desiredAutoCommit;
       if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
         p->pc = pc;
-        db->autoCommit = 1-desiredAutoCommit;
+        db->autoCommit = (u8)(1-desiredAutoCommit);
         p->rc = rc = SQLITE_BUSY;
         goto vdbe_return;
       }
     }
@@ -48950,13 +50746,13 @@
   /* See note about index shifting on OP_ReadCookie */
   rc = sqlite3BtreeUpdateMeta(pDb->pBt, 1+pOp->p2, (int)pIn3->u.i);
   if( pOp->p2==0 ){
     /* When the schema cookie changes, record the new cookie internally */
-    pDb->pSchema->schema_cookie = pIn3->u.i;
+    pDb->pSchema->schema_cookie = (int)pIn3->u.i;
     db->flags |= SQLITE_InternChanges;
   }else if( pOp->p2==1 ){
     /* Record changes in the file format */
-    pDb->pSchema->file_format = pIn3->u.i;
+    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 */
@@ -49090,9 +50886,9 @@
     assert( p2>0 );
     assert( p2<=p->nMem );
     pIn2 = &p->aMem[p2];
     sqlite3VdbeMemIntegerify(pIn2);
-    p2 = pIn2->u.i;
+    p2 = (int)pIn2->u.i;
     if( p2<2 ) {
       rc = SQLITE_CORRUPT_BKPT;
       goto abort_due_to_error;
     }
@@ -49125,10 +50921,10 @@
       if( (flags & 0xf0)!=0 || ((flags & 0x07)!=5 && (flags & 0x07)!=2) ){
         rc = SQLITE_CORRUPT_BKPT;
         goto abort_due_to_error;
       }
-      pCur->isTable = (flags & BTREE_INTKEY)!=0;
-      pCur->isIndex = (flags & BTREE_ZERODATA)!=0;
+      pCur->isTable = (flags & BTREE_INTKEY)!=0 ?1:0;
+      pCur->isIndex = (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
       */
@@ -49244,9 +51040,9 @@
   pCx = allocateCursor(p, i, &pOp[-1], -1, 0);
   if( pCx==0 ) goto no_mem;
   pCx->nullRow = 1;
   pCx->pseudoTable = 1;
-  pCx->ephemPseudoTable = pOp->p2;
+  pCx->ephemPseudoTable = (u8)pOp->p2;
   pCx->isTable = 1;
   pCx->isIndex = 0;
   break;
 }
@@ -49263,104 +51059,142 @@
   p->apCsr[i] = 0;
   break;
 }
 
-/* Opcode: MoveGe P1 P2 P3 P4 *
+/* Opcode: SeekGe P1 P2 P3 P4 *
 **
 ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys),
-** use the integer value in register P3 as a key. If cursor P1 refers
+** use the value in register P3 as the key.  If cursor P1 refers
 ** to an SQL index, then P3 is the first in an array of P4 registers
 ** that are used as an unpacked index key.
 **
 ** Reposition cursor P1 so that  it points to the smallest entry that
 ** is greater than or equal to the key value. If there are no records
 ** greater than or equal to the key and P2 is not zero, then jump to P2.
 **
-** A special feature of this opcode (and different from the
-** related OP_MoveGt, OP_MoveLt, and OP_MoveLe) is that if P2 is
-** zero and P1 is an SQL table (a b-tree with integer keys) then
-** the seek is deferred until it is actually needed.  It might be
-** the case that the cursor is never accessed.  By deferring the
-** seek, we avoid unnecessary seeks.
-**
-** See also: Found, NotFound, Distinct, MoveLt, MoveGt, MoveLe
-*/
-/* Opcode: MoveGt P1 P2 P3 P4 *
+** See also: Found, NotFound, Distinct, SeekLt, SeekGt, SeekLe
+*/
+/* Opcode: SeekGt P1 P2 P3 P4 *
 **
 ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys),
-** use the integer value in register P3 as a key. If cursor P1 refers
+** use the value in register P3 as a key. If cursor P1 refers
 ** to an SQL index, then P3 is the first in an array of P4 registers
 ** that are used as an unpacked index key.
 **
 ** Reposition cursor P1 so that  it points to the smallest entry that
 ** is greater than the key value. If there are no records greater than
 ** the key and P2 is not zero, then jump to P2.
 **
-** See also: Found, NotFound, Distinct, MoveLt, MoveGe, MoveLe
-*/
-/* Opcode: MoveLt P1 P2 P3 P4 *
+** See also: Found, NotFound, Distinct, SeekLt, SeekGe, SeekLe
+*/
+/* Opcode: SeekLt P1 P2 P3 P4 *
 **
 ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys),
-** use the integer value in register P3 as a key. If cursor P1 refers
+** use the value in register P3 as a key. If cursor P1 refers
 ** to an SQL index, then P3 is the first in an array of P4 registers
 ** that are used as an unpacked index key.
 **
 ** Reposition cursor P1 so that  it points to the largest entry that
 ** is less than the key value. If there are no records less than
 ** the key and P2 is not zero, then jump to P2.
 **
-** See also: Found, NotFound, Distinct, MoveGt, MoveGe, MoveLe
-*/
-/* Opcode: MoveLe P1 P2 P3 P4 *
+** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLe
+*/
+/* Opcode: SeekLe P1 P2 P3 P4 *
 **
 ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys),
-** use the integer value in register P3 as a key. If cursor P1 refers
+** use the value in register P3 as a key. If cursor P1 refers
 ** to an SQL index, then P3 is the first in an array of P4 registers
 ** that are used as an unpacked index key.
 **
 ** Reposition cursor P1 so that it points to the largest entry that
 ** is less than or equal to the key value. If there are no records
 ** less than or equal to the key and P2 is not zero, then jump to P2.
 **
-** See also: Found, NotFound, Distinct, MoveGt, MoveGe, MoveLt
-*/
-case OP_MoveLt:         /* jump, in3 */
-case OP_MoveLe:         /* jump, in3 */
-case OP_MoveGe:         /* jump, in3 */
-case OP_MoveGt: {       /* jump, in3 */
-  int i = pOp->p1;
-  VdbeCursor *pC;
-
-  assert( i>=0 && i<p->nCursor );
+** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLt
+*/
+case OP_SeekLt:         /* jump, in3 */
+case OP_SeekLe:         /* jump, in3 */
+case OP_SeekGe:         /* jump, in3 */
+case OP_SeekGt: {       /* jump, in3 */
+  int i = pOp->p1;
+  VdbeCursor *pC;
+
+  assert( i>=0 && 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 = sqlite3VdbeIntValue(pIn3);
-      if( pOp->p2==0 ){
-        assert( pOp->opcode==OP_MoveGe );
-        pC->movetoTarget = iKey;
-        pC->rowidIsValid = 0;
-        pC->deferredMoveto = 1;
-        break;
+      i64 iKey;      /* The rowid we are to seek to */
+
+      /* 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;
+
+      /* If the P3 value could not be converted into an integer without
+      ** loss of information, then special processing is required... */
+      if( (pIn3->flags & MEM_Int)==0 ){
+        if( (pIn3->flags & MEM_Real)==0 ){
+          /* If the P3 value cannot be converted into any kind of a number,
+          ** then the seek is not possible, so jump to P2 */
+          pc = pOp->p2 - 1;
+          break;
+        }
+        /* 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) ){
+          /* The P3 value is to large in magnitude to be expressed as an
+          ** integer. */
+          res = 1;
+          if( pIn3->r<0 ){
+            if( oc==OP_SeekGt || oc==OP_SeekGe ){
+              rc = sqlite3BtreeFirst(pC->pCursor, &res);
+              if( rc!=SQLITE_OK ) goto abort_due_to_error;
+            }
+          }else{
+            if( oc==OP_SeekLt || oc==OP_SeekLe ){
+              rc = sqlite3BtreeLast(pC->pCursor, &res);
+              if( rc!=SQLITE_OK ) goto abort_due_to_error;
+            }
+          }
+          if( res ){
+            pc = pOp->p2 - 1;
+          }
+          break;
+        }else if( oc==OP_SeekLt || oc==OP_SeekGe ){
+          /* Use the ceiling() function to convert real->int */
+          if( pIn3->r > (double)iKey ) 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);
       if( rc!=SQLITE_OK ){
         goto abort_due_to_error;
       }
-      pC->lastRowid = iKey;
-      pC->rowidIsValid = res==0;
+      if( res==0 ){
+        pC->rowidIsValid = 1;
+        pC->lastRowid = iKey;
+      }
     }else{
       UnpackedRecord r;
       int nField = pOp->p4.i;
       assert( pOp->p4type==P4_INT32 );
       assert( nField>0 );
       r.pKeyInfo = pC->pKeyInfo;
-      r.nField = nField;
-      if( oc==OP_MoveGt || oc==OP_MoveLe ){
+      r.nField = (u16)nField;
+      if( oc==OP_SeekGt || oc==OP_SeekLe ){
         r.flags = UNPACKED_INCRKEY;
       }else{
         r.flags = 0;
       }
@@ -49375,19 +51209,19 @@
     pC->cacheStatus = CACHE_STALE;
 #ifdef SQLITE_TEST
     sqlite3_search_count++;
 #endif
-    if( oc==OP_MoveGe || oc==OP_MoveGt ){
-      if( res<0 ){
+    if( oc==OP_SeekGe || oc==OP_SeekGt ){
+      if( res<0 || (res==0 && oc==OP_SeekGt) ){
         rc = sqlite3BtreeNext(pC->pCursor, &res);
         if( rc!=SQLITE_OK ) goto abort_due_to_error;
         pC->rowidIsValid = 0;
       }else{
         res = 0;
       }
     }else{
-      assert( oc==OP_MoveLt || oc==OP_MoveLe );
-      if( res>=0 ){
+      assert( oc==OP_SeekLt || oc==OP_SeekLe );
+      if( res>0 || (res==0 && oc==OP_SeekLt) ){
         rc = sqlite3BtreePrevious(pC->pCursor, &res);
         if( rc!=SQLITE_OK ) goto abort_due_to_error;
         pC->rowidIsValid = 0;
       }else{
@@ -49409,8 +51243,35 @@
     pc = pOp->p2 - 1;
   }
   break;
 }
+
+/* Opcode: Seek P1 P2 * * *
+**
+** P1 is an open table cursor and P2 is a rowid integer.  Arrange
+** for P1 to move so that it points to the rowid given by P2.
+**
+** This is actually a deferred seek.  Nothing actually happens until
+** the cursor is used to read a record.  That way, if no reads
+** occur, no unnecessary I/O happens.
+*/
+case OP_Seek: {    /* in2 */
+  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;
+  }
+  break;
+}
+
 
 /* Opcode: Found P1 P2 P3 * *
 **
 ** Register P3 holds a blob constructed by MakeRecord.  P1 is an index.
@@ -49602,23 +51463,18 @@
   BtCursor *pCrsr;
   assert( i>=0 && i<p->nCursor );
   assert( p->apCsr[i]!=0 );
   if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
-    int res;
+    int res = 0;
     u64 iKey;
     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;
+    pC->rowidIsValid = res==0 ?1:0;
     pC->nullRow = 0;
     pC->cacheStatus = CACHE_STALE;
-    /* res might be uninitialized if rc!=SQLITE_OK.  But if rc!=SQLITE_OK
-    ** processing is about to abort so we really do not care whether or not
-    ** the following jump is taken.  (In other words, do not stress over
-    ** the error that valgrind sometimes shows on the next statement when
-    ** running ioerr.test and similar failure-recovery test scripts.) */
     if( res!=0 ){
       pc = pOp->p2 - 1;
       assert( pC->rowidIsValid==0 );
     }
@@ -49880,9 +51736,9 @@
     pC->nullRow = 0;
   }else{
     int nZero;
     if( pData->flags & MEM_Zero ){
-      nZero = pData->u.i;
+      nZero = pData->u.nZero;
     }else{
       nZero = 0;
     }
     rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey,
@@ -50024,9 +51880,9 @@
     sqlite3BtreeKeySize(pCrsr, &n64);
     if( n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
       goto too_big;
     }
-    n = n64;
+    n = (int)n64;
   }else{
     sqlite3BtreeDataSize(pCrsr, &n);
     if( (int)n>db->aLimit[SQLITE_LIMIT_LENGTH] ){
       goto too_big;
@@ -50119,9 +51975,9 @@
   assert( pC!=0 );
   pCrsr = pC->pCursor;
   assert( pCrsr!=0 );
   rc = sqlite3BtreeLast(pCrsr, &res);
-  pC->nullRow = res;
+  pC->nullRow = (u8)res;
   pC->deferredMoveto = 0;
   pC->cacheStatus = CACHE_STALE;
   if( res && pOp->p2>0 ){
     pc = pOp->p2 - 1;
@@ -50168,15 +52024,15 @@
   pC = p->apCsr[i];
   assert( pC!=0 );
   if( (pCrsr = pC->pCursor)!=0 ){
     rc = sqlite3BtreeFirst(pCrsr, &res);
-    pC->atFirst = res==0;
+    pC->atFirst = res==0 ?1:0;
     pC->deferredMoveto = 0;
     pC->cacheStatus = CACHE_STALE;
   }else{
     res = 1;
   }
-  pC->nullRow = res;
+  pC->nullRow = (u8)res;
   assert( pOp->p2>0 && pOp->p2<p->nOp );
   if( res ){
     pc = pOp->p2 - 1;
   }
@@ -50220,9 +52076,9 @@
   res = 1;
   assert( pC->deferredMoveto==0 );
   rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(pCrsr, &res) :
                               sqlite3BtreePrevious(pCrsr, &res);
-  pC->nullRow = res;
+  pC->nullRow = (u8)res;
   pC->cacheStatus = CACHE_STALE;
   if( res==0 ){
     pc = pOp->p2 - 1;
     if( pOp->p5 ) p->aCounter[pOp->p5-1]++;
@@ -50284,9 +52140,9 @@
   if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
     int res;
     UnpackedRecord r;
     r.pKeyInfo = pC->pKeyInfo;
-    r.nField = pOp->p3;
+    r.nField = (u16)pOp->p3;
     r.flags = 0;
     r.aMem = &p->aMem[pOp->p2];
     rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res);
     if( rc==SQLITE_OK && res==0 ){
@@ -50369,9 +52225,9 @@
     assert( pC->deferredMoveto==0 );
     assert( pOp->p5==0 || pOp->p5==1 );
     assert( pOp->p4type==P4_INT32 );
     r.pKeyInfo = pC->pKeyInfo;
-    r.nField = pOp->p4.i;
+    r.nField = (u16)pOp->p4.i;
     if( pOp->p5 ){
       r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID;
     }else{
       r.flags = UNPACKED_IGNORE_ROWID;
@@ -50500,9 +52356,9 @@
 ** See documentation on OP_CreateTable for additional information.
 */
 case OP_CreateIndex:            /* out2-prerelease */
 case OP_CreateTable: {          /* out2-prerelease */
-  int pgno;
+  int pgno = 0;
   int flags;
   Db *pDb;
   assert( pOp->p1>=0 && pOp->p1<db->nDb );
   assert( (p->btreeMask & (1<<pOp->p1))!=0 );
@@ -50514,12 +52370,10 @@
   }else{
     flags = BTREE_ZERODATA;
   }
   rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags);
-  if( rc==SQLITE_OK ){
-    pOut->u.i = pgno;
-    MemSetTypeFlag(pOut, MEM_Int);
-  }
+  pOut->u.i = pgno;
+  MemSetTypeFlag(pOut, MEM_Int);
   break;
 }
 
 /* Opcode: ParseSchema P1 P2 * P4 *
@@ -50658,15 +52512,15 @@
   assert( (pnErr->flags & MEM_Int)!=0 );
   assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 );
   pIn1 = &p->aMem[pOp->p1];
   for(j=0; j<nRoot; j++){
-    aRoot[j] = sqlite3VdbeIntValue(&pIn1[j]);
+    aRoot[j] = (int)sqlite3VdbeIntValue(&pIn1[j]);
   }
   aRoot[j] = 0;
   assert( pOp->p5<db->nDb );
   assert( (p->btreeMask & (1<<pOp->p5))!=0 );
   z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot,
-                                 pnErr->u.i, &nErr);
+                                 (int)pnErr->u.i, &nErr);
   sqlite3DbFree(db, aRoot);
   pnErr->u.i -= nErr;
   sqlite3VdbeMemSetNull(pIn1);
   if( nErr==0 ){
@@ -50681,37 +52535,58 @@
   break;
 }
 #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
 
-/* Opcode: FifoWrite P1 * * * *
-**
-** Write the integer from register P1 into the Fifo.
-*/
-case OP_FifoWrite: {        /* in1 */
-  p->sFifo.db = db;
-  if( sqlite3VdbeFifoPush(&p->sFifo, sqlite3VdbeIntValue(pIn1))==SQLITE_NOMEM ){
-    goto no_mem;
-  }
-  break;
-}
-
-/* Opcode: FifoRead P1 P2 * * *
-**
-** Attempt to read a single integer from the Fifo.  Store that
-** integer in register P1.
-**
-** If the Fifo is empty jump to P2.
-*/
-case OP_FifoRead: {         /* jump */
-  CHECK_FOR_INTERRUPT;
+/* Opcode: RowSetAdd P1 P2 * * *
+**
+** Insert the integer value held by register P2 into a boolean index
+** held in register P1.
+**
+** An assertion fails if P2 is not an integer.
+*/
+case OP_RowSetAdd: {       /* in2 */
+  Mem *pIdx;
+  Mem *pVal;
+  assert( pOp->p1>0 && pOp->p1<=p->nMem );
+  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);
+  break;
+}
+
+/* Opcode: RowSetRead P1 P2 P3 * *
+**
+** Extract the smallest value from boolean index P1 and put that value into
+** register P3.  Or, if boolean index P1 is initially empty, leave P3
+** unchanged and jump to instruction P2.
+*/
+case OP_RowSetRead: {       /* jump, out3 */
+  Mem *pIdx;
+  i64 val;
   assert( pOp->p1>0 && pOp->p1<=p->nMem );
-  pOut = &p->aMem[pOp->p1];
-  MemSetTypeFlag(pOut, MEM_Int);
-  if( sqlite3VdbeFifoPop(&p->sFifo, &pOut->u.i)==SQLITE_DONE ){
+  CHECK_FOR_INTERRUPT;
+  pIdx = &p->aMem[pOp->p1];
+  if( (pIdx->flags & MEM_RowSet)==0
+   || sqlite3RowSetNext(pIdx->u.pRowSet, &val)==0
+  ){
+    /* The boolean index is empty */
+    sqlite3VdbeMemSetNull(pIdx);
     pc = pOp->p2 - 1;
-  }
-  break;
-}
+  }else{
+    /* A value was pulled from the index */
+    assert( pOp->p3>0 && pOp->p3<=p->nMem );
+    pOut = &p->aMem[pOp->p3];
+    sqlite3VdbeMemSetInt64(pOut, val);
+  }
+  break;
+}
+
 
 #ifndef SQLITE_OMIT_TRIGGER
 /* Opcode: ContextPush * * *
 **
@@ -50733,10 +52608,8 @@
   }
   pContext = &p->contextStack[i];
   pContext->lastRowid = db->lastRowid;
   pContext->nChange = p->nChange;
-  pContext->sFifo = p->sFifo;
-  sqlite3VdbeFifoInit(&p->sFifo, db);
   break;
 }
 
 /* Opcode: ContextPop * * *
@@ -50749,10 +52622,8 @@
   Context *pContext = &p->contextStack[--p->contextStackTop];
   assert( p->contextStackTop>=0 );
   db->lastRowid = pContext->lastRowid;
   p->nChange = pContext->nChange;
-  sqlite3VdbeFifoClear(&p->sFifo);
-  p->sFifo = pContext->sFifo;
   break;
 }
 #endif /* #ifndef SQLITE_OMIT_TRIGGER */
 
@@ -50972,9 +52843,9 @@
 ** used to generate an error message if the lock cannot be obtained.
 */
 case OP_TableLock: {
   int p1 = pOp->p1;
-  u8 isWriteLock = pOp->p3;
+  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);
@@ -51110,10 +52981,10 @@
   pModule = pVtab->pModule;
 
   /* Grab the index number and argc parameters */
   assert( (pQuery->flags&MEM_Int)!=0 && pArgc->flags==MEM_Int );
-  nArg = pArgc->u.i;
-  iQuery = pQuery->u.i;
+  nArg = (int)pArgc->u.i;
+  iQuery = (int)pQuery->u.i;
 
   /* Invoke the xFilter method */
   {
     int res = 0;
@@ -52141,9 +54012,9 @@
 ** This file contains code use to implement an in-memory rollback journal.
 ** The in-memory rollback journal is used to journal transactions for
 ** ":memory:" databases and when the journal_mode=MEMORY pragma is used.
 **
-** @(#) $Id: memjournal.c,v 1.5 2008/11/19 16:52:44 danielk1977 Exp $
+** @(#) $Id: memjournal.c,v 1.7 2008/12/10 21:19:57 drh Exp $
 */
 
 /* Forward references to internal structures */
 typedef struct MemJournal MemJournal;
@@ -52217,17 +54088,17 @@
   }else{
     pChunk = p->readpoint.pChunk;
   }
 
-  iChunkOffset = (iOfst%JOURNAL_CHUNKSIZE);
+  iChunkOffset = (int)(iOfst%JOURNAL_CHUNKSIZE);
   do {
     int iSpace = JOURNAL_CHUNKSIZE - iChunkOffset;
     int nCopy = MIN(nRead, (JOURNAL_CHUNKSIZE - iChunkOffset));
     memcpy(zOut, &pChunk->zChunk[iChunkOffset], nCopy);
     zOut += nCopy;
     nRead -= iSpace;
     iChunkOffset = 0;
-  } while( nRead>=0 && (pChunk=pChunk->pNext) && nRead>0 );
+  } while( nRead>=0 && (pChunk=pChunk->pNext)!=0 && nRead>0 );
   p->readpoint.iOffset = iOfst+iAmt;
   p->readpoint.pChunk = pChunk;
 
   return SQLITE_OK;
@@ -52253,9 +54124,9 @@
   UNUSED_PARAMETER(iOfst);
 
   while( nWrite>0 ){
     FileChunk *pChunk = p->endpoint.pChunk;
-    int iChunkOffset = p->endpoint.iOffset%JOURNAL_CHUNKSIZE;
+    int iChunkOffset = (int)(p->endpoint.iOffset%JOURNAL_CHUNKSIZE);
     int iSpace = MIN(nWrite, JOURNAL_CHUNKSIZE - iChunkOffset);
 
     if( iChunkOffset==0 ){
       /* New chunk is required to extend the file. */
@@ -52522,9 +54393,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.11 2008/11/17 19:18:55 danielk1977 Exp $
+** $Id: resolve.c,v 1.15 2008/12/10 19:26:24 drh Exp $
 */
 
 /*
 ** Turn the pExpr expression into an alias for the iCol-th column of the
@@ -52574,9 +54445,9 @@
   if( pDup->op!=TK_COLUMN && zType[0]!='G' ){
     pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0);
     if( pDup==0 ) return;
     if( pEList->a[iCol].iAlias==0 ){
-      pEList->a[iCol].iAlias = ++pParse->nAlias;
+      pEList->a[iCol].iAlias = (u16)(++pParse->nAlias);
     }
     pDup->iTable = pEList->a[iCol].iAlias;
   }
   if( pExpr->flags & EP_ExpCollate ){
@@ -52724,9 +54595,9 @@
     */
     if( zDb==0 && zTab!=0 && cnt==0 && pParse->trigStack!=0 ){
       TriggerStack *pTriggerStack = pParse->trigStack;
       Table *pTab = 0;
-      u32 *piColMask;
+      u32 *piColMask = 0;
       if( pTriggerStack->newIdx != -1 && sqlite3StrICmp("new", zTab) == 0 ){
         pExpr->iTable = pTriggerStack->newIdx;
         assert( pTriggerStack->pTab );
         pTab = pTriggerStack->pTab;
@@ -52988,9 +54859,9 @@
       int auth;                   /* Authorization to use the function */
       int nId;                    /* Number of characters in function name */
       const char *zId;            /* The function name. */
       FuncDef *pDef;              /* Information about the function */
-      int enc = ENC(pParse->db);  /* The database encoding */
+      u8 enc = ENC(pParse->db);   /* The database encoding */
 
       zId = (char*)pExpr->token.z;
       nId = pExpr->token.n;
       pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
@@ -53261,9 +55132,9 @@
         if( pE==0 ) return 1;
         pE->pColl = pColl;
         pE->flags |= EP_IntValue | flags;
         pE->iTable = iCol;
-        pItem->iCol = iCol;
+        pItem->iCol = (u16)iCol;
         pItem->done = 1;
       }else{
         moreToDo = 1;
       }
@@ -53365,9 +55236,9 @@
       /* If an AS-name match is found, mark this ORDER BY column as being
       ** a copy of the iCol-th result-set column.  The subsequent call to
       ** sqlite3ResolveOrderGroupBy() will convert the expression to a
       ** copy of the iCol-th result-set expression. */
-      pItem->iCol = iCol;
+      pItem->iCol = (u16)iCol;
       continue;
     }
     if( sqlite3ExprIsInteger(pE, &iCol) ){
       /* The ORDER BY term is an integer constant.  Again, set the column
@@ -53376,9 +55247,9 @@
       if( iCol<1 ){
         resolveOutOfRangeError(pParse, zType, i+1, nResult);
         return 1;
       }
-      pItem->iCol = iCol;
+      pItem->iCol = (u16)iCol;
       continue;
     }
 
     /* Otherwise, treat the ORDER BY term as an ordinary expression */
@@ -53468,9 +55339,9 @@
       struct SrcList_item *pItem = &p->pSrc->a[i];
       if( pItem->pSelect ){
         const char *zSavedContext = pParse->zAuthContext;
         if( pItem->zName ) pParse->zAuthContext = pItem->zName;
-        sqlite3ResolveSelectNames(pParse, pItem->pSelect, &sNC);
+        sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC);
         pParse->zAuthContext = zSavedContext;
         if( pParse->nErr || db->mallocFailed ) return WRC_Abort;
       }
     }
@@ -53689,9 +55560,9 @@
 *************************************************************************
 ** This file contains routines used for analyzing expressions and
 ** for generating VDBE code that evaluates expressions in SQLite.
 **
-** $Id: expr.c,v 1.404 2008/11/19 16:52:44 danielk1977 Exp $
+** $Id: expr.c,v 1.408 2008/12/15 15:27:52 drh Exp $
 */
 
 /*
 ** Return the 'affinity' of the expression pExpr if any.
@@ -53865,9 +55736,9 @@
 ** opcode (OP_Eq, OP_Ge etc.) used to compare pExpr1 and pExpr2.
 */
 static u8 binaryCompareP5(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){
   u8 aff = (char)sqlite3ExprAffinity(pExpr2);
-  aff = sqlite3CompareAffinity(pExpr1, aff) | jumpIfNull;
+  aff = (u8)sqlite3CompareAffinity(pExpr1, aff) | (u8)jumpIfNull;
   return aff;
 }
 
 /*
@@ -53947,9 +55818,9 @@
   p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight);
   p5 = binaryCompareP5(pLeft, pRight, jumpIfNull);
   addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1,
                            (void*)p4, P4_COLLSEQ);
-  sqlite3VdbeChangeP5(pParse->pVdbe, p5);
+  sqlite3VdbeChangeP5(pParse->pVdbe, (u8)p5);
   if( (p5 & SQLITE_AFF_MASK)!=SQLITE_AFF_NONE ){
     sqlite3ExprCacheAffinityChange(pParse, in1, 1);
     sqlite3ExprCacheAffinityChange(pParse, in2, 1);
   }
@@ -54072,9 +55943,9 @@
     sqlite3ExprDelete(db, pLeft);
     sqlite3ExprDelete(db, pRight);
     return 0;
   }
-  pNew->op = op;
+  pNew->op = (u8)op;
   pNew->pLeft = pLeft;
   pNew->pRight = pRight;
   pNew->iAgg = -1;
   pNew->span.z = (u8*)"";
@@ -54244,9 +56115,10 @@
     /* Wildcards of the form ":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, n;
+    int i;
+    u32 n;
     n = pToken->n;
     for(i=0; i<pParse->nVarExpr; i++){
       Expr *pE;
       if( (pE = pParse->apVarExpr[i])!=0
@@ -54510,9 +56382,9 @@
     if( a==0 ){
       goto no_mem;
     }
     pList->a = a;
-    pList->nAlloc = n;
+    pList->nAlloc = sqlite3DbMallocSize(db, a)/sizeof(a[0]);
   }
   assert( pList->a!=0 );
   if( pExpr || pName ){
     struct ExprList_item *pItem = &pList->a[pList->nExpr++];
@@ -55006,9 +56878,9 @@
         ExprList *pEList;
 
         assert( !isRowid );
         sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
-        dest.affinity = (int)affinity;
+        dest.affinity = (u8)affinity;
         assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
         if( sqlite3Select(pParse, pExpr->pSelect, &dest) ){
           return;
         }
@@ -55400,12 +57272,16 @@
 */
 static int codeAlias(Parse *pParse, int iAlias, Expr *pExpr, int target){
   sqlite3 *db = pParse->db;
   int iReg;
-  if( pParse->aAlias==0 ){
-    pParse->aAlias = sqlite3DbMallocZero(db,
+  if( pParse->nAliasAlloc<pParse->nAlias ){
+    pParse->aAlias = sqlite3DbReallocOrFree(db, pParse->aAlias,
                                  sizeof(pParse->aAlias[0])*pParse->nAlias );
+    testcase( db->mallocFailed && pParse->nAliasAlloc>0 );
     if( db->mallocFailed ) return 0;
+    memset(&pParse->aAlias[pParse->nAliasAlloc], 0,
+           (pParse->nAlias-pParse->nAliasAlloc)*sizeof(pParse->aAlias[0]));
+    pParse->nAliasAlloc = pParse->nAlias;
   }
   assert( iAlias>0 && iAlias<=pParse->nAlias );
   iReg = pParse->aAlias[iAlias-1];
   if( iReg==0 ){
@@ -55645,13 +57521,12 @@
       assert( TK_BITNOT==OP_BitNot );
       assert( TK_NOT==OP_Not );
       testcase( op==TK_BITNOT );
       testcase( op==TK_NOT );
-      inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
-      testcase( inReg==target );
-      testcase( usedAsColumnCache(pParse, inReg, inReg) );
-      inReg = sqlite3ExprWritableRegister(pParse, inReg, target);
-      sqlite3VdbeAddOp1(v, op, inReg);
+      r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
+      testcase( regFree1==0 );
+      inReg = target;
+      sqlite3VdbeAddOp2(v, op, r1, inReg);
       break;
     }
     case TK_ISNULL:
     case TK_NOTNULL: {
@@ -55735,9 +57610,9 @@
         sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
       }
       sqlite3VdbeAddOp4(v, OP_Function, constMask, r1, target,
                         (char*)pDef, P4_FUNCDEF);
-      sqlite3VdbeChangeP5(v, nExpr);
+      sqlite3VdbeChangeP5(v, (u8)nExpr);
       if( nExpr ){
         sqlite3ReleaseTempRange(pParse, r1, nExpr);
       }
       sqlite3ExprCacheAffinityChange(pParse, r1, nExpr);
@@ -55914,9 +57789,9 @@
       struct ExprList_item *aListelem;  /* Array of WHEN terms */
       Expr opCompare;                   /* The X==Ei expression */
       Expr cacheX;                      /* Cached expression X */
       Expr *pX;                         /* The X expression */
-      Expr *pTest;                      /* X==Ei (form A) or just Ei (form B) */
+      Expr *pTest = 0;                  /* X==Ei (form A) or just Ei (form B) */
 
       assert(pExpr->pList);
       assert((pExpr->pList->nExpr % 2) == 0);
       assert(pExpr->pList->nExpr > 0);
@@ -55936,8 +57811,9 @@
       }
       pParse->disableColCache++;
       for(i=0; i<nExpr; i=i+2){
         if( pX ){
+          assert( pTest!=0 );
           opCompare.pRight = aListelem[i].pExpr;
         }else{
           pTest = aListelem[i].pExpr;
         }
@@ -56791,9 +58667,9 @@
 *************************************************************************
 ** This file contains C code routines that used to generate VDBE code
 ** that implements the ALTER TABLE command.
 **
-** $Id: alter.c,v 1.50 2008/11/19 09:05:27 danielk1977 Exp $
+** $Id: alter.c,v 1.51 2008/12/10 19:26:22 drh Exp $
 */
 
 /*
 ** The code in this file only exists if we are not omitting the
@@ -57082,9 +58958,11 @@
 
   /* Make sure it is not a system table being altered, or a reserved name
   ** that the table is being renamed to.
   */
-  if( strlen(pTab->zName)>6 && 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) ){
+  if( sqlite3Strlen30(pTab->zName)>6
+   && 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7)
+  ){
     sqlite3ErrorMsg(pParse, "table %s may not be altered", pTab->zName);
     goto exit_rename_table;
   }
   if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
@@ -57415,9 +59293,9 @@
 **
 *************************************************************************
 ** This file contains code associated with the ANALYZE command.
 **
-** @(#) $Id: analyze.c,v 1.46 2008/11/19 16:52:44 danielk1977 Exp $
+** @(#) $Id: analyze.c,v 1.47 2008/12/10 16:45:51 drh Exp $
 */
 #ifndef SQLITE_OMIT_ANALYZE
 
 /*
@@ -57436,9 +59314,9 @@
 ){
   sqlite3 *db = pParse->db;
   Db *pDb;
   int iRootPage;
-  int createStat1 = 0;
+  u8 createStat1 = 0;
   Table *pStat;
   Vdbe *v = sqlite3GetVdbe(pParse);
 
   if( v==0 ) return;
@@ -57844,9 +59722,9 @@
 **
 *************************************************************************
 ** This file contains code used to implement the ATTACH and DETACH commands.
 **
-** $Id: attach.c,v 1.80 2008/11/19 09:05:27 danielk1977 Exp $
+** $Id: attach.c,v 1.81 2008/12/10 16:45:51 drh Exp $
 */
 
 #ifndef SQLITE_OMIT_ATTACH
 /*
@@ -58167,9 +60045,10 @@
 
   assert( v || db->mallocFailed );
   if( v ){
     sqlite3VdbeAddOp3(v, OP_Function, 0, regArgs+3-pFunc->nArg, regArgs+3);
-    sqlite3VdbeChangeP5(v, pFunc->nArg);
+    assert( pFunc->nArg==-1 || (pFunc->nArg&0xff)==pFunc->nArg );
+    sqlite3VdbeChangeP5(v, (u8)(pFunc->nArg));
     sqlite3VdbeChangeP4(v, -1, (char *)pFunc, P4_FUNCDEF);
 
     /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this
     ** statement only). For DETACH, set it to false (expire all existing
@@ -58631,17 +60510,17 @@
 **     BEGIN TRANSACTION
 **     COMMIT
 **     ROLLBACK
 **
-** $Id: build.c,v 1.503 2008/11/17 19:18:55 danielk1977 Exp $
+** $Id: build.c,v 1.508 2008/12/10 22:30:25 shane Exp $
 */
 
 /*
 ** This routine is called when a new SQL statement is beginning to
 ** be parsed.  Initialize the pParse structure as needed.
 */
 SQLITE_PRIVATE void sqlite3BeginParse(Parse *pParse, int explainFlag){
-  pParse->explain = explainFlag;
+  pParse->explain = (u8)explainFlag;
   pParse->nVar = 0;
 }
 
 #ifndef SQLITE_OMIT_SHARED_CACHE
@@ -58794,9 +60673,10 @@
       ** an OP_Trace) to be the complete text of the current SQL statement.
       */
       VdbeOp *pOp = sqlite3VdbeGetOp(v, 0);
       if( pOp && pOp->opcode==OP_Trace ){
-        sqlite3VdbeChangeP4(v, 0, pParse->zSql, pParse->zTail-pParse->zSql);
+        sqlite3VdbeChangeP4(v, 0, pParse->zSql,
+                            (int)(pParse->zTail - pParse->zSql));
       }
     }
 #endif /* SQLITE_OMIT_TRACE */
   }
@@ -58976,9 +60856,10 @@
 static void sqliteDeleteIndex(Index *p){
   Index *pOld;
   const char *zName = p->zName;
 
-  pOld = sqlite3HashInsert(&p->pSchema->idxHash, zName, strlen(zName)+1, 0);
+  pOld = sqlite3HashInsert(&p->pSchema->idxHash, zName,
+                           sqlite3Strlen30(zName)+1, 0);
   assert( pOld==0 || pOld==p );
   freeIndex(p);
 }
 
@@ -59141,9 +61022,9 @@
   */
   for(pFKey=pTable->pFKey; pFKey; pFKey=pNextFKey){
     pNextFKey = pFKey->pNextFrom;
     assert( sqlite3HashFind(&pTable->pSchema->aFKey,
-                           pFKey->zTo, strlen(pFKey->zTo)+1)!=pFKey );
+                           pFKey->zTo, sqlite3Strlen30(pFKey->zTo)+1)!=pFKey );
     sqlite3DbFree(db, pFKey);
   }
 #endif
 
@@ -59172,13 +61053,14 @@
   assert( db!=0 );
   assert( iDb>=0 && iDb<db->nDb );
   assert( zTabName && zTabName[0] );
   pDb = &db->aDb[iDb];
-  p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName, strlen(zTabName)+1,0);
+  p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName,
+                        sqlite3Strlen30(zTabName)+1,0);
   if( p ){
 #ifndef SQLITE_OMIT_FOREIGN_KEY
     for(pF1=p->pFKey; pF1; pF1=pF1->pNextFrom){
-      int nTo = strlen(pF1->zTo) + 1;
+      int nTo = sqlite3Strlen30(pF1->zTo) + 1;
       pF2 = sqlite3HashFind(&pDb->pSchema->aFKey, pF1->zTo, nTo);
       if( pF2==pF1 ){
         sqlite3HashInsert(&pDb->pSchema->aFKey, pF1->zTo, nTo, pF1->pNextTo);
       }else{
@@ -59233,17 +61115,17 @@
 ** does not exist.
 */
 SQLITE_PRIVATE int sqlite3FindDb(sqlite3 *db, Token *pName){
   int i = -1;    /* Database number */
-  size_t n;      /* Number of characters in the name */
+  int n;         /* Number of characters in the name */
   Db *pDb;       /* A database whose name space is being searched */
   char *zName;   /* Name we are searching for */
 
   zName = sqlite3NameFromToken(db, pName);
   if( zName ){
-    n = strlen(zName);
+    n = sqlite3Strlen30(zName);
     for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){
-      if( (!OMIT_TEMPDB || i!=1 ) && n==strlen(pDb->zName) &&
+      if( (!OMIT_TEMPDB || i!=1 ) && n==sqlite3Strlen30(pDb->zName) &&
           0==sqlite3StrICmp(pDb->zName, zName) ){
         break;
       }
     }
@@ -59600,9 +61482,9 @@
   Table *p;
   int i;
   if( (p = pParse->pNewTable)==0 ) return;
   i = p->nCol-1;
-  if( i>=0 ) p->aCol[i].notNull = onError;
+  if( i>=0 ) p->aCol[i].notNull = (u8)onError;
 }
 
 /*
 ** Scan the column type name zType (length nType) and return the
@@ -59779,9 +61661,9 @@
   }
   if( zType && sqlite3StrICmp(zType, "INTEGER")==0
         && sortOrder==SQLITE_SO_ASC ){
     pTab->iPKey = iCol;
-    pTab->keyConf = onError;
+    pTab->keyConf = (u8)onError;
     assert( autoInc==0 || autoInc==1 );
     pTab->tabFlags |= autoInc*TF_Autoincrement;
   }else if( autoInc ){
 #ifndef SQLITE_OMIT_AUTOINCREMENT
@@ -59972,9 +61854,9 @@
   for(pCol = p->aCol, i=0; i<p->nCol; i++, pCol++){
     n += identLength(pCol->zName);
     z = pCol->zType;
     if( z ){
-      n += (strlen(z) + 1);
+      n += (sqlite3Strlen30(z) + 1);
     }
   }
   n += identLength(p->zName);
   if( n<50 ){
@@ -59993,21 +61875,21 @@
     return 0;
   }
   sqlite3_snprintf(n, zStmt,
                   !OMIT_TEMPDB&&isTemp ? "CREATE TEMP TABLE ":"CREATE TABLE ");
-  k = strlen(zStmt);
+  k = sqlite3Strlen30(zStmt);
   identPut(zStmt, &k, p->zName);
   zStmt[k++] = '(';
   for(pCol=p->aCol, i=0; i<p->nCol; i++, pCol++){
     sqlite3_snprintf(n-k, &zStmt[k], zSep);
-    k += strlen(&zStmt[k]);
+    k += sqlite3Strlen30(&zStmt[k]);
     zSep = zSep2;
     identPut(zStmt, &k, pCol->zName);
     if( (z = pCol->zType)!=0 ){
       zStmt[k++] = ' ';
-      assert( (int)(strlen(z)+k+1)<=n );
+      assert( (int)(sqlite3Strlen30(z)+k+1)<=n );
       sqlite3_snprintf(n-k, &zStmt[k], "%s", z);
-      k += strlen(z);
+      k += sqlite3Strlen30(z);
     }
   }
   sqlite3_snprintf(n-k, &zStmt[k], "%s", zEnd);
   return zStmt;
@@ -60159,9 +62041,9 @@
     /* Compute the complete text of the CREATE statement */
     if( pSelect ){
       zStmt = createTableStmt(db, p, p->pSchema==db->aDb[1].pSchema);
     }else{
-      n = pEnd->z - pParse->sNameToken.z + 1;
+      n = (int)(pEnd->z - pParse->sNameToken.z) + 1;
       zStmt = sqlite3MPrintf(db,
           "CREATE %s %.*s", zType2, n, pParse->sNameToken.z
       );
     }
@@ -60213,9 +62095,10 @@
   if( db->init.busy && pParse->nErr==0 ){
     Table *pOld;
     FKey *pFKey;
     Schema *pSchema = p->pSchema;
-    pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, strlen(p->zName)+1,p);
+    pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName,
+                             sqlite3Strlen30(p->zName)+1,p);
     if( pOld ){
       assert( p==pOld );  /* Malloc must have failed inside HashInsert() */
       db->mallocFailed = 1;
       return;
@@ -60222,9 +62105,9 @@
     }
 #ifndef SQLITE_OMIT_FOREIGN_KEY
     for(pFKey=p->pFKey; pFKey; pFKey=pFKey->pNextFrom){
       void *data;
-      int nTo = strlen(pFKey->zTo) + 1;
+      int nTo = sqlite3Strlen30(pFKey->zTo) + 1;
       pFKey->pNextTo = sqlite3HashFind(&pSchema->aFKey, pFKey->zTo, nTo);
       data = sqlite3HashInsert(&pSchema->aFKey, pFKey->zTo, nTo, pFKey);
       if( data==(void *)pFKey ){
         db->mallocFailed = 1;
@@ -60242,9 +62125,9 @@
       assert( !pSelect && pCons && pEnd );
       if( pCons->z==0 ){
         pCons = pEnd;
       }
-      nName = (const char *)pCons->z - zName;
+      nName = (int)((const char *)pCons->z - zName);
       p->addColOffset = 13 + sqlite3Utf8CharLen(zName, nName);
     }
 #endif
   }
@@ -60313,9 +62196,9 @@
   if( sEnd.z[0]!=0 && sEnd.z[0]!=';' ){
     sEnd.z += sEnd.n;
   }
   sEnd.n = 0;
-  n = sEnd.z - pBegin->z;
+  n = (int)(sEnd.z - pBegin->z);
   z = (const unsigned char*)pBegin->z;
   while( n>0 && (z[n-1]==';' || isspace(z[n-1])) ){ n--; }
   sEnd.z = &z[n-1];
   sEnd.n = 1;
@@ -60653,9 +62536,8 @@
     sqlite3BeginWriteOperation(pParse, 1, iDb);
 
 #ifndef SQLITE_OMIT_VIRTUALTABLE
     if( IsVirtual(pTab) ){
-      Vdbe *v = sqlite3GetVdbe(pParse);
       if( v ){
         sqlite3VdbeAddOp0(v, OP_VBegin);
       }
     }
@@ -60780,9 +62662,9 @@
   }
   nByte = sizeof(*pFKey) + nCol*sizeof(pFKey->aCol[0]) + pTo->n + 1;
   if( pToCol ){
     for(i=0; i<pToCol->nExpr; i++){
-      nByte += strlen(pToCol->a[i].zName) + 1;
+      nByte += sqlite3Strlen30(pToCol->a[i].zName) + 1;
     }
   }
   pFKey = sqlite3DbMallocZero(db, nByte );
   if( pFKey==0 ){
@@ -60819,19 +62701,19 @@
     }
   }
   if( pToCol ){
     for(i=0; i<nCol; i++){
-      int n = strlen(pToCol->a[i].zName);
+      int n = sqlite3Strlen30(pToCol->a[i].zName);
       pFKey->aCol[i].zCol = z;
       memcpy(z, pToCol->a[i].zName, n);
       z[n] = 0;
       z += n+1;
     }
   }
   pFKey->isDeferred = 0;
-  pFKey->deleteConf = flags & 0xff;
-  pFKey->updateConf = (flags >> 8 ) & 0xff;
-  pFKey->insertConf = (flags >> 16 ) & 0xff;
+  pFKey->deleteConf = (u8)(flags & 0xff);
+  pFKey->updateConf = (u8)((flags >> 8 ) & 0xff);
+  pFKey->insertConf = (u8)((flags >> 16 ) & 0xff);
 
   /* Link the foreign key to the table as the last step.
   */
   p->pFKey = pFKey;
@@ -60855,9 +62737,10 @@
 #ifndef SQLITE_OMIT_FOREIGN_KEY
   Table *pTab;
   FKey *pFKey;
   if( (pTab = pParse->pNewTable)==0 || (pFKey = pTab->pFKey)==0 ) return;
-  pFKey->isDeferred = isDeferred;
+  assert( isDeferred==0 || isDeferred==1 );
+  pFKey->isDeferred = (u8)isDeferred;
 #endif
 }
 
 /*
@@ -61105,12 +62988,12 @@
   ** So create a fake list to simulate this.
   */
   if( pList==0 ){
     nullId.z = (u8*)pTab->aCol[pTab->nCol-1].zName;
-    nullId.n = strlen((char*)nullId.z);
+    nullId.n = sqlite3Strlen30((char*)nullId.z);
     pList = sqlite3ExprListAppend(pParse, 0, 0, &nullId);
     if( pList==0 ) goto exit_create_index;
-    pList->a[0].sortOrder = sortOrder;
+    pList->a[0].sortOrder = (u8)sortOrder;
   }
 
   /* Figure out how many bytes of space are required to store explicitly
   ** specified collation sequence names.
@@ -61118,16 +63001,16 @@
   for(i=0; i<pList->nExpr; i++){
     Expr *pExpr;
     CollSeq *pColl;
     if( (pExpr = pList->a[i].pExpr)!=0 && (pColl = pExpr->pColl)!=0 ){
-      nExtra += (1 + strlen(pColl->zName));
+      nExtra += (1 + sqlite3Strlen30(pColl->zName));
     }
   }
 
   /*
   ** Allocate the index structure.
   */
-  nName = strlen(zName);
+  nName = sqlite3Strlen30(zName);
   nCol = pList->nExpr;
   pIndex = sqlite3DbMallocZero(db,
       sizeof(Index) +              /* Index structure  */
       sizeof(int)*nCol +           /* Index.aiColumn   */
@@ -61148,10 +63031,10 @@
   zExtra = (char *)(&pIndex->zName[nName+1]);
   memcpy(pIndex->zName, zName, nName+1);
   pIndex->pTable = pTab;
   pIndex->nColumn = pList->nExpr;
-  pIndex->onError = onError;
-  pIndex->autoIndex = pName==0;
+  pIndex->onError = (u8)onError;
+  pIndex->autoIndex = (u8)(pName==0);
   pIndex->pSchema = db->aDb[iDb].pSchema;
 
   /* Check to see if we should honor DESC requests on index columns
   */
@@ -61189,9 +63072,9 @@
     if( pListItem->pExpr && pListItem->pExpr->pColl ){
       assert( pListItem->pExpr->pColl );
       zColl = zExtra;
       sqlite3_snprintf(nExtra, zExtra, "%s", pListItem->pExpr->pColl->zName);
-      zExtra += (strlen(zColl) + 1);
+      zExtra += (sqlite3Strlen30(zColl) + 1);
     }else{
       zColl = pTab->aCol[j].zColl;
       if( !zColl ){
         zColl = db->pDfltColl->zName;
@@ -61201,9 +63084,9 @@
       goto exit_create_index;
     }
     pIndex->azColl[i] = zColl;
     requestedSortOrder = pListItem->sortOrder & sortOrderMask;
-    pIndex->aSortOrder[i] = requestedSortOrder;
+    pIndex->aSortOrder[i] = (u8)requestedSortOrder;
   }
   sqlite3DefaultRowEst(pIndex);
 
   if( pTab==pParse->pNewTable ){
@@ -61262,9 +63145,10 @@
   */
   if( db->init.busy ){
     Index *p;
     p = sqlite3HashInsert(&pIndex->pSchema->idxHash,
-                         pIndex->zName, strlen(pIndex->zName)+1, pIndex);
+                          pIndex->zName, sqlite3Strlen30(pIndex->zName)+1,
+                          pIndex);
     if( p ){
       assert( p==pIndex );  /* Malloc must have failed */
       db->mallocFailed = 1;
       goto exit_create_index;
@@ -61536,9 +63420,9 @@
     if( pNew==0 ){
       *pIdx = -1;
       return pArray;
     }
-    *pnAlloc = newSize;
+    *pnAlloc = sqlite3DbMallocSize(db, pNew)/szEntry;
     pArray = pNew;
   }
   z = (char*)pArray;
   memset(&z[*pnEntry * szEntry], 0, szEntry);
@@ -61641,24 +63525,26 @@
   /* Allocate additional space if needed */
   if( pSrc->nSrc+nExtra>pSrc->nAlloc ){
     SrcList *pNew;
     int nAlloc = pSrc->nSrc+nExtra;
+    int nGot;
     pNew = sqlite3DbRealloc(db, pSrc,
                sizeof(*pSrc) + (nAlloc-1)*sizeof(pSrc->a[0]) );
     if( pNew==0 ){
       assert( db->mallocFailed );
       return pSrc;
     }
     pSrc = pNew;
-    pSrc->nAlloc = nAlloc;
+    nGot = (sqlite3DbMallocSize(db, pNew) - sizeof(*pSrc))/sizeof(pSrc->a[0])+1;
+    pSrc->nAlloc = (u16)nGot;
   }
 
   /* Move existing slots that come after the newly inserted slots
   ** out of the way */
   for(i=pSrc->nSrc-1; i>=iStart; i--){
     pSrc->a[i+nExtra] = pSrc->a[i];
   }
-  pSrc->nSrc += nExtra;
+  pSrc->nSrc += (i16)nExtra;
 
   /* Zero the newly allocated slots */
   memset(&pSrc->a[iStart], 0, sizeof(pSrc->a[0])*nExtra);
   for(i=iStart; i<iStart+nExtra; i++){
@@ -62176,9 +64062,9 @@
       assert( zColl );
       pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl, -1);
       pKey->aSortOrder[i] = pIdx->aSortOrder[i];
     }
-    pKey->nField = nCol;
+    pKey->nField = (u16)nCol;
   }
 
   if( pParse->nErr ){
     sqlite3DbFree(db, pKey);
@@ -62203,9 +64089,9 @@
 **
 ** This file contains functions used to access the internal hash tables
 ** of user defined functions and collation sequences.
 **
-** $Id: callback.c,v 1.32 2008/10/10 17:41:29 drh Exp $
+** $Id: callback.c,v 1.34 2008/12/10 21:19:57 drh Exp $
 */
 
 
 /*
@@ -62245,9 +64131,9 @@
 */
 static int synthCollSeq(sqlite3 *db, CollSeq *pColl){
   CollSeq *pColl2;
   char *z = pColl->zName;
-  int n = strlen(z);
+  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);
@@ -62476,9 +64362,9 @@
   FuncDefHash *pHash,  /* The hash table into which to insert */
   FuncDef *pDef        /* The function definition to insert */
 ){
   FuncDef *pOther;
-  int nName = strlen(pDef->zName);
+  int nName = sqlite3Strlen30(pDef->zName);
   u8 c1 = (u8)pDef->zName[0];
   int h = (sqlite3UpperToLower[c1] + nName) % ArraySize(pHash->a);
   pOther = functionSearch(pHash, h, pDef->zName, nName);
   if( pOther ){
@@ -62570,9 +64456,9 @@
   */
   if( createFlag && (bestScore<6 || pBest->nArg!=nArg) &&
       (pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){
     pBest->zName = (char *)&pBest[1];
-    pBest->nArg = nArg;
+    pBest->nArg = (u16)nArg;
     pBest->iPrefEnc = enc;
     memcpy(pBest->zName, zName, nName);
     pBest->zName[nName] = 0;
     sqlite3FuncDefInsert(&db->aFunc, pBest);
@@ -62655,9 +64541,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.187 2008/11/19 09:05:27 danielk1977 Exp $
+** $Id: delete.c,v 1.190 2008/12/10 21:19:57 drh Exp $
 */
 
 /*
 ** Look up every table that is named in pSrc.  If any table is not found,
@@ -62718,9 +64604,9 @@
   Vdbe *v;
   if( IsVirtual(pTab) ) return;
   v = sqlite3GetVdbe(p);
   assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
-  sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite), pTab->zName);
+  sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite)?1:0, pTab->zName);
   sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, pTab->nCol);
   sqlite3VdbeAddOp3(v, opcode, iCur, pTab->tnum, iDb);
   VdbeComment((v, "%s", pTab->zName));
 }
@@ -62748,9 +64634,9 @@
     Token viewName;
 
     pWhere = sqlite3ExprDup(db, pWhere);
     viewName.z = (u8*)pView->zName;
-    viewName.n = (unsigned int)strlen((const char*)viewName.z);
+    viewName.n = (unsigned int)sqlite3Strlen30((const char*)viewName.z);
     pFrom = sqlite3SrcListAppendFromTerm(pParse, 0, 0, 0, &viewName, pDup, 0,0);
     pDup = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0);
   }
   sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
@@ -62882,12 +64768,12 @@
 #ifndef SQLITE_OMIT_TRIGGER
   int isView;                  /* True if attempting to delete from a view */
   int triggers_exist = 0;      /* True if any triggers exist */
 #endif
-  int iBeginAfterTrigger;      /* Address of after trigger program */
-  int iEndAfterTrigger;        /* Exit of after trigger program */
-  int iBeginBeforeTrigger;     /* Address of before trigger program */
-  int iEndBeforeTrigger;       /* Exit of before trigger program */
+  int iBeginAfterTrigger = 0;  /* Address of after trigger program */
+  int iEndAfterTrigger = 0;    /* Exit of after trigger program */
+  int iBeginBeforeTrigger = 0; /* Address of before trigger program */
+  int iEndBeforeTrigger = 0;   /* Exit of before trigger program */
   u32 old_col_mask = 0;        /* Mask of OLD.* columns in use */
 
   sContext.pParse = 0;
   db = pParse->db;
@@ -63032,8 +64918,9 @@
   ** the table and pick which records to delete.
   */
   {
     int iRowid = ++pParse->nMem;    /* Used for storing rowid values. */
+    int iRowSet = ++pParse->nMem;   /* Register for rowset of rows to delete */
 
     /* Begin the database scan
     */
     pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0);
@@ -63041,9 +64928,9 @@
 
     /* Remember the rowid of every item to be deleted.
     */
     sqlite3VdbeAddOp2(v, IsVirtual(pTab) ? OP_VRowid : OP_Rowid, iCur, iRowid);
-    sqlite3VdbeAddOp1(v, OP_FifoWrite, iRowid);
+    sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iRowid);
     if( db->flags & SQLITE_CountRows ){
       sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1);
     }
 
@@ -63076,9 +64963,9 @@
     */
     if( triggers_exist ){
       sqlite3VdbeResolveLabel(v, addr);
     }
-    addr = sqlite3VdbeAddOp2(v, OP_FifoRead, iRowid, end);
+    addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, end, iRowid);
 
     if( triggers_exist ){
       int iData = ++pParse->nMem;   /* For storing row data of OLD table */
 
@@ -63296,9 +65183,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.206 2008/11/19 16:52:44 danielk1977 Exp $
+** $Id: func.c,v 1.209 2008/12/10 23:04:13 drh Exp $
 */
 
 /*
 ** Return the collating function associated with a function.
@@ -63487,12 +65374,12 @@
     }
     for(z2=z; *z2 && p2; p2--){
       SQLITE_SKIP_UTF8(z2);
     }
-    sqlite3_result_text(context, (char*)z, z2-z, SQLITE_TRANSIENT);
+    sqlite3_result_text(context, (char*)z, (int)(z2-z), SQLITE_TRANSIENT);
   }else{
     if( p2<0 ) p2 = 0;
-    sqlite3_result_blob(context, (char*)&z[p1], p2, SQLITE_TRANSIENT);
+    sqlite3_result_blob(context, (char*)&z[p1], (int)p2, SQLITE_TRANSIENT);
   }
 }
 
 /*
@@ -63526,9 +65413,9 @@
   if( nByte>sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH] ){
     sqlite3_result_error_toobig(context);
     z = 0;
   }else{
-    z = sqlite3Malloc(nByte);
+    z = sqlite3Malloc((int)nByte);
     if( !z && nByte>0 ){
       sqlite3_result_error_nomem(context);
     }
   }
@@ -63551,9 +65438,9 @@
     z1 = contextMalloc(context, ((i64)n)+1);
     if( z1 ){
       memcpy(z1, z2, n+1);
       for(i=0; z1[i]; i++){
-        z1[i] = toupper(z1[i]);
+        z1[i] = (char)toupper(z1[i]);
       }
       sqlite3_result_text(context, z1, -1, sqlite3_free);
     }
   }
@@ -63571,9 +65458,9 @@
     z1 = contextMalloc(context, ((i64)n)+1);
     if( z1 ){
       memcpy(z1, z2, n+1);
       for(i=0; z1[i]; i++){
-        z1[i] = tolower(z1[i]);
+        z1[i] = (char)tolower(z1[i]);
       }
       sqlite3_result_text(context, z1, -1, sqlite3_free);
     }
   }
@@ -64063,9 +65950,9 @@
   n = sqlite3_value_int64(argv[0]);
   if( n>SQLITE_MAX_LENGTH ){
     sqlite3_result_error_toobig(context);
   }else{
-    sqlite3_result_zeroblob(context, n);
+    sqlite3_result_zeroblob(context, (int)n);
   }
 }
 
 /*
@@ -64156,10 +66043,10 @@
   const unsigned char *zCharSet;    /* Set of characters to trim */
   int nIn;                          /* Number of bytes in input */
   int flags;                        /* 1: trimleft  2: trimright  3: trim */
   int i;                            /* Loop counter */
-  unsigned char *aLen;              /* Length of each character in zCharSet */
-  unsigned char **azChar;           /* Individual characters in zCharSet */
+  unsigned char *aLen = 0;          /* Length of each character in zCharSet */
+  unsigned char **azChar = 0;       /* Individual characters in zCharSet */
   int nChar;                        /* Number of characters in zCharSet */
 
   if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
     return;
@@ -64190,17 +66077,17 @@
       aLen = (unsigned char*)&azChar[nChar];
       for(z=zCharSet, nChar=0; *z; nChar++){
         azChar[nChar] = (unsigned char *)z;
         SQLITE_SKIP_UTF8(z);
-        aLen[nChar] = z - azChar[nChar];
+        aLen[nChar] = (u8)(z - azChar[nChar]);
       }
     }
   }
   if( nChar>0 ){
     flags = SQLITE_PTR_TO_INT(sqlite3_user_data(context));
     if( flags & 1 ){
       while( nIn>0 ){
-        int len;
+        int len = 0;
         for(i=0; i<nChar; i++){
           len = aLen[i];
           if( memcmp(zIn, azChar[i], len)==0 ) break;
         }
@@ -64210,9 +66097,9 @@
       }
     }
     if( flags & 2 ){
       while( nIn>0 ){
-        int len;
+        int len = 0;
         for(i=0; i<nChar; i++){
           len = aLen[i];
           if( len<=nIn && memcmp(&zIn[nIn-len],azChar[i],len)==0 ) break;
         }
@@ -64338,12 +66225,12 @@
       i64 v = sqlite3_value_int64(argv[0]);
       p->rSum += v;
       if( (p->approx|p->overflow)==0 ){
         i64 iNewSum = p->iSum + v;
-        int s1 = p->iSum >> (sizeof(i64)*8-1);
-        int s2 = v       >> (sizeof(i64)*8-1);
-        int s3 = iNewSum >> (sizeof(i64)*8-1);
-        p->overflow = (s1&s2&~s3) | (~s1&~s2&s3);
+        int s1 = (int)(p->iSum >> (sizeof(i64)*8-1));
+        int s2 = (int)(v       >> (sizeof(i64)*8-1));
+        int s3 = (int)(iNewSum >> (sizeof(i64)*8-1));
+        p->overflow = ((s1&s2&~s3) | (~s1&~s2&s3))?1:0;
         p->iSum = iNewSum;
       }
     }else{
       p->rSum += sqlite3_value_double(argv[0]);
@@ -64526,11 +66413,12 @@
 
 /*
 ** Set the LIKEOPT flag on the 2-argument function with the given name.
 */
-static void setLikeOptFlag(sqlite3 *db, const char *zName, int flagVal){
+static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){
   FuncDef *pDef;
-  pDef = sqlite3FindFunction(db, zName, strlen(zName), 2, SQLITE_UTF8, 0);
+  pDef = sqlite3FindFunction(db, zName, sqlite3Strlen30(zName),
+                             2, SQLITE_UTF8, 0);
   if( pDef ){
     pDef->flags = flagVal;
   }
 }
@@ -64691,9 +66579,9 @@
 *************************************************************************
 ** This file contains C code routines that are called by the parser
 ** to handle INSERT statements in SQLite.
 **
-** $Id: insert.c,v 1.253 2008/11/19 09:05:27 danielk1977 Exp $
+** $Id: insert.c,v 1.256 2008/12/10 21:19:57 drh Exp $
 */
 
 /*
 ** Set P4 of the most recently inserted opcode to a column affinity
@@ -65066,16 +66954,16 @@
   Db *pDb;              /* The database containing table being inserted into */
   int appendFlag = 0;   /* True if the insert is likely to be an append */
 
   /* Register allocations */
-  int regFromSelect;    /* Base register for data coming from SELECT */
+  int regFromSelect = 0;/* Base register for data coming from SELECT */
   int regAutoinc = 0;   /* Register holding the AUTOINCREMENT counter */
   int regRowCount = 0;  /* Memory cell used for the row counter */
   int regIns;           /* Block of regs holding rowid+data being inserted */
   int regRowid;         /* registers holding insert rowid */
   int regData;          /* register holding first column to insert */
   int regRecord;        /* Holds the assemblied row record */
-  int regEof;           /* Register recording end of SELECT data */
+  int regEof = 0;       /* Register recording end of SELECT data */
   int *aRegIdx = 0;     /* One register allocated to each index */
 
 
 #ifndef SQLITE_OMIT_TRIGGER
@@ -65083,8 +66971,9 @@
   int triggers_exist = 0;     /* True if there are FOR EACH ROW triggers */
 #endif
 
   db = pParse->db;
+  memset(&dest, 0, sizeof(dest));
   if( pParse->nErr || db->mallocFailed ){
     goto insert_cleanup;
   }
 
@@ -65250,26 +67139,26 @@
       **         insert row from R..R+n into temp table
       **         goto L
       **      M: ...
       */
-      int regRec;      /* Register to hold packed record */
-      int regRowid;    /* Register to hold temp table ROWID */
-      int addrTop;     /* Label "L" */
-      int addrIf;      /* Address of jump to M */
+      int regRec;          /* Register to hold packed record */
+      int regTempRowid;    /* Register to hold temp table ROWID */
+      int addrTop;         /* Label "L" */
+      int addrIf;          /* Address of jump to M */
 
       srcTab = pParse->nTab++;
       regRec = sqlite3GetTempReg(pParse);
-      regRowid = sqlite3GetTempReg(pParse);
+      regTempRowid = sqlite3GetTempReg(pParse);
       sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn);
       addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm);
       addrIf = sqlite3VdbeAddOp1(v, OP_If, regEof);
       sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec);
-      sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regRowid);
-      sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regRowid);
+      sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid);
+      sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid);
       sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
       sqlite3VdbeJumpHere(v, addrIf);
       sqlite3ReleaseTempReg(pParse, regRec);
-      sqlite3ReleaseTempReg(pParse, regRowid);
+      sqlite3ReleaseTempReg(pParse, regTempRowid);
     }
   }else{
     /* This is the case if the data for the INSERT is coming from a VALUES
     ** clause
@@ -65368,9 +67257,8 @@
 
   /* If this is not a view, open the table and and all indices */
   if( !isView ){
     int nIdx;
-    int i;
 
     baseCur = pParse->nTab;
     nIdx = sqlite3OpenTableAndIndices(pParse, pTab, baseCur, OP_OpenWrite);
     aRegIdx = sqlite3DbMallocRaw(db, sizeof(int)*(nIdx+1));
@@ -65424,9 +67312,9 @@
   /* Run the BEFORE and INSTEAD OF triggers, if there are any
   */
   endOfLoop = sqlite3VdbeMakeLabel(v);
   if( triggers_exist & TRIGGER_BEFORE ){
-    int regRowid;
+    int regTrigRowid;
     int regCols;
     int regRec;
 
     /* build the NEW.* reference row.  Note that if there is an INTEGER
@@ -65434,21 +67322,21 @@
     ** translated into a unique ID for the row.  But on a BEFORE trigger,
     ** we do not know what the unique ID will be (because the insert has
     ** not happened yet) so we substitute a rowid of -1
     */
-    regRowid = sqlite3GetTempReg(pParse);
+    regTrigRowid = sqlite3GetTempReg(pParse);
     if( keyColumn<0 ){
-      sqlite3VdbeAddOp2(v, OP_Integer, -1, regRowid);
+      sqlite3VdbeAddOp2(v, OP_Integer, -1, regTrigRowid);
     }else if( useTempTable ){
-      sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, regRowid);
+      sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, regTrigRowid);
     }else{
       int j1;
       assert( pSelect==0 );  /* Otherwise useTempTable is true */
-      sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, regRowid);
-      j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid);
-      sqlite3VdbeAddOp2(v, OP_Integer, -1, regRowid);
+      sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, regTrigRowid);
+      j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regTrigRowid);
+      sqlite3VdbeAddOp2(v, OP_Integer, -1, regTrigRowid);
       sqlite3VdbeJumpHere(v, j1);
-      sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid);
+      sqlite3VdbeAddOp1(v, OP_MustBeInt, regTrigRowid);
     }
 
     /* Cannot have triggers on a virtual table. If it were possible,
     ** this block would have to account for hidden column.
@@ -65485,11 +67373,11 @@
     */
     if( !isView ){
       sqlite3TableAffinityStr(v, pTab);
     }
-    sqlite3VdbeAddOp3(v, OP_Insert, newIdx, regRec, regRowid);
+    sqlite3VdbeAddOp3(v, OP_Insert, newIdx, regRec, regTrigRowid);
     sqlite3ReleaseTempReg(pParse, regRec);
-    sqlite3ReleaseTempReg(pParse, regRowid);
+    sqlite3ReleaseTempReg(pParse, regTrigRowid);
     sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol);
 
     /* Fire BEFORE or INSTEAD OF triggers */
     if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TRIGGER_BEFORE, pTab,
@@ -65772,9 +67660,10 @@
   int i;
   Vdbe *v;
   int nCol;
   int onError;
-  int j1, j2, j3;     /* Addresses of jump instructions */
+  int j1;             /* Addresss of jump instruction */
+  int j2 = 0, j3;     /* Addresses of jump instructions */
   int regData;        /* Register containing first data column */
   int iCur;
   Index *pIdx;
   int seenReplace = 0;
@@ -65951,12 +67840,12 @@
         int j, n1, n2;
         char zErrMsg[200];
         sqlite3_snprintf(ArraySize(zErrMsg), zErrMsg,
                          pIdx->nColumn>1 ? "columns " : "column ");
-        n1 = strlen(zErrMsg);
+        n1 = sqlite3Strlen30(zErrMsg);
         for(j=0; j<pIdx->nColumn && n1<ArraySize(zErrMsg)-30; j++){
           char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
-          n2 = strlen(zCol);
+          n2 = sqlite3Strlen30(zCol);
           if( j>0 ){
             sqlite3_snprintf(ArraySize(zErrMsg)-n1, &zErrMsg[n1], ", ");
             n1 += 2;
           }
@@ -66013,9 +67902,9 @@
   int i;
   Vdbe *v;
   int nIdx;
   Index *pIdx;
-  int pik_flags;
+  u8 pik_flags;
   int regData;
   int regRec;
 
   v = sqlite3GetVdbe(pParse);
@@ -66431,9 +68320,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: legacy.c,v 1.29 2008/08/02 03:50:39 drh Exp $
+** $Id: legacy.c,v 1.30 2008/12/10 19:26:24 drh Exp $
 */
 
 
 /*
@@ -66546,9 +68435,9 @@
   sqlite3DbFree(db, azCols);
 
   rc = sqlite3ApiExit(db, rc);
   if( rc!=SQLITE_OK && rc==sqlite3_errcode(db) && pzErrMsg ){
-    int nErrMsg = 1 + strlen(sqlite3_errmsg(db));
+    int nErrMsg = 1 + sqlite3Strlen30(sqlite3_errmsg(db));
     *pzErrMsg = sqlite3Malloc(nErrMsg);
     if( *pzErrMsg ){
       memcpy(*pzErrMsg, sqlite3_errmsg(db), nErrMsg);
     }
@@ -66576,9 +68465,9 @@
 *************************************************************************
 ** This file contains code used to dynamically load extensions into
 ** the SQLite library.
 **
-** $Id: loadext.c,v 1.56 2008/10/12 00:27:53 shane Exp $
+** $Id: loadext.c,v 1.57 2008/12/08 18:19:18 drh Exp $
 */
 
 #ifndef SQLITE_CORE
   #define SQLITE_CORE 1  /* Disable the API redefinition in sqlite3ext.h */
@@ -67426,12 +69315,12 @@
 **
 ** This list is shared across threads.  The SQLITE_MUTEX_STATIC_MASTER
 ** mutex must be held while accessing this list.
 */
-typedef struct sqlite3ExtType sqlite3ExtType;
-static SQLITE_WSD struct sqlite3ExtType {
-  int nExt;        /* Number of entries in aExt[] */
-  void **aExt;     /* Pointers to the extension init functions */
+typedef struct sqlite3AutoExtList sqlite3AutoExtList;
+static SQLITE_WSD struct sqlite3AutoExtList {
+  int nExt;              /* Number of entries in aExt[] */
+  void (**aExt)(void);   /* Pointers to the extension init functions */
 } sqlite3Autoext = { 0, 0 };
 
 /* The "wsdAutoext" macro will resolve to the autoextension
 ** state vector.  If writable static data is unsupported on the target,
@@ -67440,9 +69329,9 @@
 ** to the "sqlite3Autoext" state vector declared above.
 */
 #ifdef SQLITE_OMIT_WSD
 # define wsdAutoextInit \
-  sqlite3ExtType *x = &GLOBAL(sqlite3ExtType,sqlite3Autoext)
+  sqlite3AutoExtList *x = &GLOBAL(sqlite3AutoExtList,sqlite3Autoext)
 # define wsdAutoext x[0]
 #else
 # define wsdAutoextInit
 # define wsdAutoext sqlite3Autoext
@@ -67452,9 +69341,9 @@
 /*
 ** Register a statically linked extension that is automatically
 ** loaded by every new database connection.
 */
-SQLITE_API int sqlite3_auto_extension(void *xInit){
+SQLITE_API int sqlite3_auto_extension(void (*xInit)(void)){
   int rc = SQLITE_OK;
 #ifndef SQLITE_OMIT_AUTOINIT
   rc = sqlite3_initialize();
   if( rc ){
@@ -67472,9 +69361,9 @@
       if( wsdAutoext.aExt[i]==xInit ) break;
     }
     if( i==wsdAutoext.nExt ){
       int nByte = (wsdAutoext.nExt+1)*sizeof(wsdAutoext.aExt[0]);
-      void **aNew;
+      void (**aNew)(void);
       aNew = sqlite3_realloc(wsdAutoext.aExt, nByte);
       if( aNew==0 ){
         rc = SQLITE_NOMEM;
       }else{
@@ -67562,9 +69451,9 @@
 **
 *************************************************************************
 ** This file contains code used to implement the PRAGMA command.
 **
-** $Id: pragma.c,v 1.194 2008/11/17 19:18:55 danielk1977 Exp $
+** $Id: pragma.c,v 1.199 2008/12/10 23:04:13 drh Exp $
 */
 
 /* Ignore this whole file if pragmas are disabled
 */
@@ -67579,19 +69468,19 @@
 ** should be passed into sqlite3BtreeSetSafetyLevel().  The is done
 ** to support legacy SQL code.  The safety level used to be boolean
 ** and older scripts may have used numbers 0 for OFF and 1 for ON.
 */
-static int getSafetyLevel(const char *z){
+static u8 getSafetyLevel(const char *z){
                              /* 123456789 123456789 */
   static const char zText[] = "onoffalseyestruefull";
   static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16};
   static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 4};
   static const u8 iValue[] =  {1, 0, 0, 0, 1, 1, 2};
   int i, n;
   if( isdigit(*z) ){
-    return atoi(z);
-  }
-  n = strlen(z);
+    return (u8)atoi(z);
+  }
+  n = sqlite3Strlen30(z);
   for(i=0; i<ArraySize(iLength); i++){
     if( iLength[i]==n && sqlite3StrNICmp(&zText[iOffset[i]],z,n)==0 ){
       return iValue[i];
     }
@@ -67601,9 +69490,9 @@
 
 /*
 ** Interpret the given string as a boolean value.
 */
-static int getBoolean(const char *z){
+static u8 getBoolean(const char *z){
   return getSafetyLevel(z)&1;
 }
 
 /*
@@ -67629,9 +69518,9 @@
   if( 0==sqlite3StrICmp(z, "none") ) return BTREE_AUTOVACUUM_NONE;
   if( 0==sqlite3StrICmp(z, "full") ) return BTREE_AUTOVACUUM_FULL;
   if( 0==sqlite3StrICmp(z, "incremental") ) return BTREE_AUTOVACUUM_INCR;
   i = atoi(z);
-  return ((i>=0&&i<=2)?i:0);
+  return (u8)((i>=0&&i<=2)?i:0);
 }
 #endif /* ifndef SQLITE_OMIT_AUTOVACUUM */
 
 #ifndef SQLITE_OMIT_PAGER_PRAGMAS
@@ -67686,9 +69575,9 @@
   if( db->temp_store==ts ) return SQLITE_OK;
   if( invalidateTempStorage( pParse ) != SQLITE_OK ){
     return SQLITE_ERROR;
   }
-  db->temp_store = ts;
+  db->temp_store = (u8)ts;
   return SQLITE_OK;
 }
 #endif /* SQLITE_PAGER_PRAGMAS */
 
@@ -67943,11 +69832,9 @@
   **
   ** Return the number of pages in the specified database.
   */
   if( sqlite3StrICmp(zLeft,"page_count")==0 ){
-    Vdbe *v;
-    int iReg;
-    v = sqlite3GetVdbe(pParse);
+    int iReg;
     if( !v || sqlite3ReadSchema(pParse) ) goto pragma_out;
     sqlite3CodeVerifySchema(pParse, iDb);
     iReg = ++pParse->nMem;
     sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg);
@@ -67986,9 +69873,9 @@
         for(ii=2; ii<db->nDb; ii++){
           pPager = sqlite3BtreePager(db->aDb[ii].pBt);
           sqlite3PagerLockingMode(pPager, eMode);
         }
-        db->dfltLockMode = eMode;
+        db->dfltLockMode = (u8)eMode;
       }
       pPager = sqlite3BtreePager(pDb->pBt);
       eMode = sqlite3PagerLockingMode(pPager, eMode);
     }
@@ -68015,9 +69902,9 @@
 
     if( zRight==0 ){
       eMode = PAGER_JOURNALMODE_QUERY;
     }else{
-      int n = strlen(zRight);
+      int n = sqlite3Strlen30(zRight);
       eMode = sizeof(azModeName)/sizeof(azModeName[0]) - 1;
       while( eMode>=0 && sqlite3StrNICmp(zRight, azModeName[eMode], n)!=0 ){
         eMode--;
       }
@@ -68046,9 +69933,9 @@
             pPager = sqlite3BtreePager(db->aDb[ii].pBt);
             sqlite3PagerJournalMode(pPager, eMode);
           }
         }
-        db->dfltJournalMode = eMode;
+        db->dfltJournalMode = (u8)eMode;
       }
       pPager = sqlite3BtreePager(pDb->pBt);
       eMode = sqlite3PagerJournalMode(pPager, eMode);
     }
@@ -68103,9 +69990,9 @@
           pBt ? sqlite3BtreeGetAutoVacuum(pBt) : SQLITE_DEFAULT_AUTOVACUUM;
       returnSingleInt(pParse, "auto_vacuum", auto_vacuum);
     }else{
       int eAuto = getAutoVacuum(zRight);
-      db->nextAutovac = eAuto;
+      db->nextAutovac = (u8)eAuto;
       if( eAuto>=0 ){
         /* Call SetAutoVacuum() to set initialize the internal auto and
         ** incr-vacuum flags. This is required in case this connection
         ** creates the database file. It is important that it is created
@@ -68254,8 +70141,50 @@
       }
 #endif /* SQLITE_OMIT_WSD */
     }
   }else
+
+  /*
+   **   PRAGMA [database.]lock_proxy_file
+   **   PRAGMA [database.]lock_proxy_file = ":auto:"|"lock_file_path"
+   **
+   ** Return or set the value of the lock_proxy_file flag.  Changing
+   ** the value sets a specific file to be used for database access locks.
+   **
+   */
+  if( sqlite3StrICmp(zLeft, "lock_proxy_file")==0 ){
+    if( !zRight ){
+      Pager *pPager = sqlite3BtreePager(pDb->pBt);
+      char *proxy_file_path = NULL;
+      sqlite3_file *pFile = sqlite3PagerFile(pPager);
+      sqlite3OsFileControl(pFile, SQLITE_GET_LOCKPROXYFILE,
+                           &proxy_file_path);
+
+      if( proxy_file_path ){
+        sqlite3VdbeSetNumCols(v, 1);
+        sqlite3VdbeSetColName(v, 0, COLNAME_NAME,
+                              "lock_proxy_file", SQLITE_STATIC);
+        sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, proxy_file_path, 0);
+        sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
+      }
+    }else{
+      Pager *pPager = sqlite3BtreePager(pDb->pBt);
+      sqlite3_file *pFile = sqlite3PagerFile(pPager);
+      int res;
+      if( zRight[0] ){
+        res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE,
+                                     zRight);
+      } else {
+        res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE,
+                                     NULL);
+      }
+      if( res!=SQLITE_OK ){
+        sqlite3ErrorMsg(pParse, "failed to set lock proxy file");
+        goto pragma_out;
+      }
+    }
+  }else
+
 
   /*
   **   PRAGMA [database.]synchronous
   **   PRAGMA [database.]synchronous=OFF|ON|NORMAL|FULL
@@ -68572,9 +70501,9 @@
       }
 
       /* Do the b-tree integrity checks */
       sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1);
-      sqlite3VdbeChangeP5(v, i);
+      sqlite3VdbeChangeP5(v, (u8)i);
       addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2);
       sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
          sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName),
          P4_DYNAMIC);
@@ -68816,9 +70745,8 @@
     static const char *const azLockName[] = {
       "unlocked", "shared", "reserved", "pending", "exclusive"
     };
     int i;
-    Vdbe *v = sqlite3GetVdbe(pParse);
     sqlite3VdbeSetNumCols(v, 2);
     pParse->nMem = 2;
     sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "database", SQLITE_STATIC);
     sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "status", SQLITE_STATIC);
@@ -68855,9 +70783,9 @@
 #endif
 
 #if SQLITE_HAS_CODEC
   if( sqlite3StrICmp(zLeft, "key")==0 ){
-    sqlite3_key(db, zRight, strlen(zRight));
+    sqlite3_key(db, zRight, sqlite3Strlen30(zRight));
   }else
 #endif
 #if SQLITE_HAS_CODEC || defined(SQLITE_ENABLE_CEROD)
   if( sqlite3StrICmp(zLeft, "activate_extensions")==0 ){
@@ -68919,9 +70847,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.101 2008/11/19 16:52:44 danielk1977 Exp $
+** $Id: prepare.c,v 1.103 2008/12/10 19:26:24 drh Exp $
 */
 
 /*
 ** Fill the InitData structure with an error message that indicates
@@ -69199,9 +71127,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 = meta[1];
+  pDb->pSchema->file_format = (u8)meta[1];
   if( pDb->pSchema->file_format==0 ){
     pDb->pSchema->file_format = 1;
   }
   if( pDb->pSchema->file_format>SQLITE_MAX_FILE_FORMAT ){
@@ -69451,9 +71379,8 @@
   */
   for(i=0; i<db->nDb; i++) {
     Btree *pBt = db->aDb[i].pBt;
     if( pBt ){
-      int rc;
       rc = sqlite3BtreeSchemaLocked(pBt);
       if( rc ){
         const char *zDb = db->aDb[i].zName;
         sqlite3Error(db, SQLITE_LOCKED, "database schema is locked: %s", zDb);
@@ -69528,9 +71455,9 @@
     rc = SQLITE_MISUSE;
   }
 
   if( saveSqlFlag ){
-    sqlite3VdbeSetSql(sParse.pVdbe, zSql, sParse.zTail - zSql);
+    sqlite3VdbeSetSql(sParse.pVdbe, zSql, (int)(sParse.zTail - zSql));
   }
   if( rc!=SQLITE_OK || db->mallocFailed ){
     sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe);
     assert(!(*ppStmt));
@@ -69671,9 +71598,9 @@
     ** equivalent pointer into the UTF-16 string by counting the unicode
     ** characters between zSql8 and zTail8, and then returning a pointer
     ** the same number of characters into the UTF-16 string.
     */
-    int chars_parsed = sqlite3Utf8CharLen(zSql8, zTail8-zSql8);
+    int chars_parsed = sqlite3Utf8CharLen(zSql8, (int)(zTail8-zSql8));
     *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, chars_parsed);
   }
   sqlite3DbFree(db, zSql8);
   rc = sqlite3ApiExit(db, rc);
@@ -69731,9 +71658,9 @@
 *************************************************************************
 ** This file contains C code routines that are called by the parser
 ** to handle SELECT statements in SQLite.
 **
-** $Id: select.c,v 1.486 2008/11/19 09:05:27 danielk1977 Exp $
+** $Id: select.c,v 1.494 2008/12/10 22:15:00 drh Exp $
 */
 
 
 /*
@@ -69755,9 +71682,9 @@
 /*
 ** Initialize a SelectDest structure.
 */
 SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){
-  pDest->eDest = eDest;
+  pDest->eDest = (u8)eDest;
   pDest->iParm = iParm;
   pDest->affinity = 0;
   pDest->iMem = 0;
   pDest->nMem = 0;
@@ -69909,9 +71836,9 @@
 ** 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 ? strlen(z) : 0;
+  p->n = z ? sqlite3Strlen30(z) : 0;
   p->dyn = 0;
 }
 
 /*
@@ -69938,15 +71865,15 @@
   if( *z2 ){
     /* String contains " characters - copy and quote the string. */
     p->z = (u8 *)sqlite3MPrintf(pParse->db, "\"%w\"", z);
     if( p->z ){
-      p->n = strlen((char *)p->z);
+      p->n = sqlite3Strlen30((char *)p->z);
       p->dyn = 1;
     }
   }else{
     /* String contains no " characters - copy the pointer. */
     p->z = (u8*)z;
-    p->n = (z2 - z);
+    p->n = (int)(z2 - z);
     p->dyn = 0;
   }
 }
 
@@ -70474,10 +72401,11 @@
   nExpr = pList->nExpr;
   pInfo = sqlite3DbMallocZero(db, sizeof(*pInfo) + nExpr*(sizeof(CollSeq*)+1) );
   if( pInfo ){
     pInfo->aSortOrder = (u8*)&pInfo->aColl[nExpr];
-    pInfo->nField = nExpr;
+    pInfo->nField = (u16)nExpr;
     pInfo->enc = ENC(db);
+    pInfo->db = db;
     for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){
       CollSeq *pColl;
       pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
       if( !pColl ){
@@ -70503,10 +72431,10 @@
   Vdbe *v,          /* Generate code into this VDBE */
   int nColumn,      /* Number of columns of data */
   SelectDest *pDest /* Write the sorted results here */
 ){
-  int brk = sqlite3VdbeMakeLabel(v);
-  int cont = sqlite3VdbeMakeLabel(v);
+  int addrBreak = sqlite3VdbeMakeLabel(v);     /* Jump here to exit loop */
+  int addrContinue = sqlite3VdbeMakeLabel(v);  /* Jump here for next cycle */
   int addr;
   int iTab;
   int pseudoTab = 0;
   ExprList *pOrderBy = p->pOrderBy;
@@ -70522,10 +72450,10 @@
     pseudoTab = pParse->nTab++;
     sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, nColumn);
     sqlite3VdbeAddOp2(v, OP_OpenPseudo, pseudoTab, eDest==SRT_Output);
   }
-  addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, brk);
-  codeOffset(v, p, cont);
+  addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak);
+  codeOffset(v, p, addrContinue);
   regRow = sqlite3GetTempReg(pParse);
   regRowid = sqlite3GetTempReg(pParse);
   sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr + 1, regRow);
   switch( eDest ){
@@ -70581,15 +72509,14 @@
   assert( p->iLimit==0 );
 
   /* The bottom of the loop
   */
-  sqlite3VdbeResolveLabel(v, cont);
+  sqlite3VdbeResolveLabel(v, addrContinue);
   sqlite3VdbeAddOp2(v, OP_Next, iTab, addr);
-  sqlite3VdbeResolveLabel(v, brk);
+  sqlite3VdbeResolveLabel(v, addrBreak);
   if( eDest==SRT_Output || eDest==SRT_Coroutine ){
     sqlite3VdbeAddOp2(v, OP_Close, pseudoTab, 0);
   }
-
 }
 
 /*
 ** Return a pointer to a string containing the 'declaration type' of the
@@ -70868,15 +72795,16 @@
   ExprList *pEList,       /* Expr list from which to derive column names */
   int *pnCol,             /* Write the number of columns here */
   Column **paCol          /* Write the new column list here */
 ){
-  sqlite3 *db = pParse->db;
-  int i, j, cnt;
-  Column *aCol, *pCol;
-  int nCol;
-  Expr *p;
-  char *zName;
-  int nName;
+  sqlite3 *db = pParse->db;   /* Database connection */
+  int i, j;                   /* Loop counters */
+  int cnt;                    /* Index added to make the name unique */
+  Column *aCol, *pCol;        /* For looping over result columns */
+  int nCol;                   /* Number of columns in the result set */
+  Expr *p;                    /* Expression for a single result column */
+  char *zName;                /* Column name */
+  int nName;                  /* Size of name in zName[] */
 
   *pnCol = nCol = pEList->nExpr;
   aCol = *paCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol);
   if( aCol==0 ) return SQLITE_NOMEM;
@@ -70888,20 +72816,21 @@
     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 *pCol = p;
-      Table *pTab;
-      while( pCol->op==TK_DOT ) pCol = pCol->pRight;
-      if( pCol->op==TK_COLUMN && (pTab = pCol->pTab)!=0 ){
+      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 ){
         /* For columns use the column name name */
-        int iCol = pCol->iColumn;
+        int iCol = pColExpr->iColumn;
         if( iCol<0 ) iCol = pTab->iPKey;
         zName = sqlite3MPrintf(db, "%s",
                  iCol>=0 ? pTab->aCol[iCol].zName : "rowid");
       }else{
         /* Use the original text of the column expression as its name */
-        zName = sqlite3MPrintf(db, "%T", &pCol->span);
+        Token *pToken = (pColExpr->span.z?&pColExpr->span:&pColExpr->token);
+        zName = sqlite3MPrintf(db, "%T", pToken);
       }
     }
     if( db->mallocFailed ){
       sqlite3DbFree(db, zName);
@@ -70911,9 +72840,9 @@
 
     /* Make sure the column name is unique.  If the name is not unique,
     ** append a integer to the name so that it becomes unique.
     */
-    nName = strlen(zName);
+    nName = sqlite3Strlen30(zName);
     for(j=cnt=0; j<i; j++){
       if( sqlite3StrICmp(aCol[j].zName, zName)==0 ){
         char *zNewName;
         zName[nName] = 0;
@@ -70926,9 +72855,8 @@
     }
     pCol->zName = zName;
   }
   if( db->mallocFailed ){
-    int j;
     for(j=0; j<i; j++){
       sqlite3DbFree(db, aCol[j].zName);
     }
     sqlite3DbFree(db, aCol);
@@ -71255,9 +73183,9 @@
     }
     case TK_EXCEPT:
     case TK_UNION: {
       int unionTab;    /* Cursor number of the temporary table holding result */
-      int op = 0;      /* One of the SRT_ operations to apply to self */
+      u8 op = 0;       /* One of the SRT_ operations to apply to self */
       int priorOp;     /* The SRT_ operation to apply to prior selects */
       Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */
       int addr;
       SelectDest uniondest;
@@ -71450,9 +73378,9 @@
       goto multi_select_end;
     }
 
     pKeyInfo->enc = ENC(db);
-    pKeyInfo->nField = nCol;
+    pKeyInfo->nField = (u16)nCol;
 
     for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
       *apColl = multiSelectCollSeq(pParse, p, i);
       if( 0==*apColl ){
@@ -71751,9 +73679,9 @@
   int addrSelectB;      /* Address of the select-B coroutine */
   int regOutA;          /* Address register for the output-A subroutine */
   int regOutB;          /* Address register for the output-B subroutine */
   int addrOutA;         /* Address of the output-A subroutine */
-  int addrOutB;         /* Address of the output-B subroutine */
+  int addrOutB = 0;     /* Address of the output-B subroutine */
   int addrEofA;         /* Address of the select-A-exhausted subroutine */
   int addrEofB;         /* Address of the select-B-exhausted subroutine */
   int addrAltB;         /* Address of the A<B subroutine */
   int addrAeqB;         /* Address of the A==B subroutine */
@@ -71808,9 +73736,9 @@
         if( pNew==0 ) return SQLITE_NOMEM;
         pNew->flags |= EP_IntValue;
         pNew->iTable = i;
         pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew, 0);
-        pOrderBy->a[nOrderBy++].iCol = i;
+        pOrderBy->a[nOrderBy++].iCol = (u16)i;
       }
     }
   }
 
@@ -71831,9 +73759,9 @@
     pKeyMerge =
       sqlite3DbMallocRaw(db, sizeof(*pKeyMerge)+nOrderBy*(sizeof(CollSeq*)+1));
     if( pKeyMerge ){
       pKeyMerge->aSortOrder = (u8*)&pKeyMerge->aColl[nOrderBy];
-      pKeyMerge->nField = nOrderBy;
+      pKeyMerge->nField = (u16)nOrderBy;
       pKeyMerge->enc = ENC(db);
       for(i=0; i<nOrderBy; i++){
         CollSeq *pColl;
         Expr *pTerm = pOrderBy->a[i].pExpr;
@@ -71871,9 +73799,9 @@
     pKeyDup = sqlite3DbMallocZero(db,
                   sizeof(*pKeyDup) + nExpr*(sizeof(CollSeq*)+1) );
     if( pKeyDup ){
       pKeyDup->aSortOrder = (u8*)&pKeyDup->aColl[nExpr];
-      pKeyDup->nField = nExpr;
+      pKeyDup->nField = (u16)nExpr;
       pKeyDup->enc = ENC(db);
       for(i=0; i<nExpr; i++){
         pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i);
         pKeyDup->aSortOrder[i] = 0;
@@ -72503,9 +74431,9 @@
   ** elements we are now copying in.
   */
   for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){
     int nSubSrc;
-    int jointype = 0;
+    u8 jointype = 0;
     pSubSrc = pSub->pSrc;     /* FROM clause of subquery */
     nSubSrc = pSubSrc->nSrc;  /* Number of terms in subquery FROM clause */
     pSrc = pParent->pSrc;     /* FROM clause of the outer query */
 
@@ -72639,9 +74567,9 @@
 **
 **   2. There is a single expression in the result set, and it is
 **      either min(x) or max(x), where x is a column reference.
 */
-static int minMaxQuery(Select *p){
+static u8 minMaxQuery(Select *p){
   Expr *pExpr;
   ExprList *pEList = p->pEList;
 
   if( pEList->nExpr!=1 ) return WHERE_ORDERBY_NORMAL;
@@ -72869,9 +74797,9 @@
               assert(IsVirtual(pTab));
               continue;
             }
 
-            if( i>0 ){
+            if( i>0 && zTName==0 ){
               struct SrcList_item *pLeft = &pTabList->a[i-1];
               if( (pLeft[1].jointype & JT_NATURAL)!=0 &&
                         columnIndex(pLeft->pTab, zName)>=0 ){
                 /* In a NATURAL join, omit the join columns from the
@@ -73147,9 +75075,9 @@
       sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
     }
     sqlite3VdbeAddOp4(v, OP_AggStep, 0, regAgg, pF->iMem,
                       (void*)pF->pFunc, P4_FUNCDEF);
-    sqlite3VdbeChangeP5(v, nArg);
+    sqlite3VdbeChangeP5(v, (u8)nArg);
     sqlite3ReleaseTempRange(pParse, regAgg, nArg);
     sqlite3ExprCacheAffinityChange(pParse, regAgg, nArg);
     if( addrNext ){
       sqlite3VdbeResolveLabel(v, addrNext);
@@ -73256,19 +75184,15 @@
            pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard);
     p->selFlags &= ~SF_Distinct;
   }
   sqlite3SelectPrep(pParse, p, 0);
-  if( pParse->nErr ){
+  pTabList = p->pSrc;
+  pEList = p->pEList;
+  if( pParse->nErr || db->mallocFailed ){
     goto select_end;
   }
   p->pOrderBy = pOrderBy;
-
-
-  /* Make local copies of the parameters for this query.
-  */
-  pTabList = p->pSrc;
-  isAgg = (p->selFlags & SF_Aggregate)!=0;
-  pEList = p->pEList;
+  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
@@ -73463,15 +75387,15 @@
     /* Remove any and all aliases between the result set and the
     ** GROUP BY clause.
     */
     if( pGroupBy ){
-      int i;                        /* Loop counter */
+      int k;                        /* Loop counter */
       struct ExprList_item *pItem;  /* For looping over expression in a list */
 
-      for(i=p->pEList->nExpr, pItem=p->pEList->a; i>0; i--, pItem++){
+      for(k=p->pEList->nExpr, pItem=p->pEList->a; k>0; k--, pItem++){
         pItem->iAlias = 0;
       }
-      for(i=pGroupBy->nExpr, pItem=pGroupBy->a; i>0; i--, pItem++){
+      for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){
         pItem->iAlias = 0;
       }
     }
 
@@ -73735,9 +75659,9 @@
       flag = minMaxQuery(p);
       if( flag ){
         pDel = pMinMax = sqlite3ExprListDup(db, p->pEList->a[0].pExpr->pList);
         if( pMinMax && !db->mallocFailed ){
-          pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN;
+          pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0;
           pMinMax->a[0].pExpr->op = TK_COLUMN;
         }
       }
 
@@ -73918,9 +75842,9 @@
 **
 ** These routines are in a separate files so that they will not be linked
 ** if they are not used.
 **
-** $Id: table.c,v 1.36 2008/07/08 22:28:49 shane Exp $
+** $Id: table.c,v 1.38 2008/12/10 19:26:24 drh Exp $
 */
 
 #ifndef SQLITE_OMIT_GET_TABLE
 
@@ -73991,9 +75915,9 @@
     for(i=0; i<nCol; i++){
       if( argv[i]==0 ){
         z = 0;
       }else{
-        int n = strlen(argv[i])+1;
+        int n = sqlite3Strlen30(argv[i])+1;
         z = sqlite3_malloc( n );
         if( z==0 ) goto malloc_failed;
         memcpy(z, argv[i], n);
       }
@@ -74113,9 +76037,9 @@
 **
 *************************************************************************
 **
 **
-** $Id: trigger.c,v 1.130 2008/11/19 09:05:27 danielk1977 Exp $
+** $Id: trigger.c,v 1.132 2008/12/10 19:26:24 drh Exp $
 */
 
 #ifndef SQLITE_OMIT_TRIGGER
 /*
@@ -74166,8 +76090,10 @@
   int iTabDb;
 
   assert( pName1!=0 );   /* pName1->z might be NULL, but not pName1 itself */
   assert( pName2!=0 );
+  assert( op==TK_INSERT || op==TK_UPDATE || op==TK_DELETE );
+  assert( op>0 && op<0xff );
   if( isTemp ){
     /* If TEMP was specified, then the trigger name may not be qualified. */
     if( pName2->n>0 ){
       sqlite3ErrorMsg(pParse, "temporary trigger may not have qualified name");
@@ -74218,9 +76144,10 @@
   zName = sqlite3NameFromToken(db, pName);
   if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
     goto trigger_cleanup;
   }
-  if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash), zName,strlen(zName)) ){
+  if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),
+                      zName, sqlite3Strlen30(zName)) ){
     if( !noErr ){
       sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
     }
     goto trigger_cleanup;
@@ -74279,9 +76206,9 @@
   zName = 0;
   pTrigger->table = sqlite3DbStrDup(db, pTableName->a[0].zName);
   pTrigger->pSchema = db->aDb[iDb].pSchema;
   pTrigger->pTabSchema = pTab->pSchema;
-  pTrigger->op = op;
+  pTrigger->op = (u8)op;
   pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER;
   pTrigger->pWhen = sqlite3ExprDup(db, pWhen);
   pTrigger->pColumns = sqlite3IdListDup(db, pColumns);
   sqlite3TokenCopy(db, &pTrigger->nameToken,pName);
@@ -74355,15 +76282,15 @@
     int n;
     Table *pTab;
     Trigger *pDel;
     pDel = sqlite3HashInsert(&db->aDb[iDb].pSchema->trigHash,
-                     pTrig->name, strlen(pTrig->name), pTrig);
+                     pTrig->name, sqlite3Strlen30(pTrig->name), pTrig);
     if( pDel ){
       assert( pDel==pTrig );
       db->mallocFailed = 1;
       goto triggerfinish_cleanup;
     }
-    n = strlen(pTrig->table) + 1;
+    n = sqlite3Strlen30(pTrig->table) + 1;
     pTab = sqlite3HashFind(&pTrig->pTabSchema->tblHash, pTrig->table, n);
     assert( pTab!=0 );
     pTrig->pNext = pTab->pTrigger;
     pTab->pTrigger = pTrig;
@@ -74564,9 +76491,9 @@
 
   assert( pName->nSrc==1 );
   zDb = pName->a[0].zDatabase;
   zName = pName->a[0].zName;
-  nName = strlen(zName);
+  nName = sqlite3Strlen30(zName);
   for(i=OMIT_TEMPDB; i<db->nDb; i++){
     int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
     if( zDb && sqlite3StrICmp(db->aDb[j].zName, zDb) ) continue;
     pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName, nName);
@@ -74588,9 +76515,9 @@
 ** Return a pointer to the Table structure for the table that a trigger
 ** is set on.
 */
 static Table *tableOfTrigger(Trigger *pTrigger){
-  int n = strlen(pTrigger->table) + 1;
+  int n = sqlite3Strlen30(pTrigger->table) + 1;
   return sqlite3HashFind(&pTrigger->pTabSchema->tblHash, pTrigger->table, n);
 }
 
 
@@ -74653,9 +76580,9 @@
 ** Remove a trigger from the hash tables of the sqlite* pointer.
 */
 SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){
   Trigger *pTrigger;
-  int nName = strlen(zName);
+  int nName = sqlite3Strlen30(zName);
   pTrigger = sqlite3HashInsert(&(db->aDb[iDb].pSchema->trigHash),
                                zName, nName, 0);
   if( pTrigger ){
     Table *pTable = tableOfTrigger(pTrigger);
@@ -74744,9 +76671,9 @@
   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 = strlen((char*)sDb.z);
+    sDb.n = sqlite3Strlen30((char*)sDb.z);
     pSrc = sqlite3SrcListAppend(pParse->db, 0, &sDb, &pStep->target);
   } else {
     pSrc = sqlite3SrcListAppend(pParse->db, 0, &pStep->target, 0);
   }
@@ -74968,9 +76895,9 @@
 *************************************************************************
 ** This file contains C code routines that are called by the parser
 ** to handle UPDATE statements.
 **
-** $Id: update.c,v 1.187 2008/11/19 09:05:27 danielk1977 Exp $
+** $Id: update.c,v 1.190 2008/12/10 22:15:00 drh Exp $
 */
 
 #ifndef SQLITE_OMIT_VIRTUALTABLE
 /* Forward declaration */
@@ -75064,12 +76991,12 @@
 #ifndef SQLITE_OMIT_TRIGGER
   int isView;                  /* Trying to update a view */
   int triggers_exist = 0;      /* True if any row triggers exist */
 #endif
-  int iBeginAfterTrigger;      /* Address of after trigger program */
-  int iEndAfterTrigger;        /* Exit of after trigger program */
-  int iBeginBeforeTrigger;     /* Address of before trigger program */
-  int iEndBeforeTrigger;       /* Exit of before trigger program */
+  int iBeginAfterTrigger = 0;  /* Address of after trigger program */
+  int iEndAfterTrigger = 0;    /* Exit of after trigger program */
+  int iBeginBeforeTrigger = 0; /* Address of before trigger program */
+  int iEndBeforeTrigger = 0;   /* Exit of before trigger program */
   u32 old_col_mask = 0;        /* Mask of OLD.* columns in use */
   u32 new_col_mask = 0;        /* Mask of NEW.* columns in use */
 
   int newIdx      = -1;  /* index of trigger "new" temp table       */
@@ -75079,8 +77006,9 @@
   int regRowCount = 0;   /* A count of rows changed */
   int regOldRowid;       /* The old rowid */
   int regNewRowid;       /* The new rowid */
   int regData;           /* New data for the row */
+  int regRowSet = 0;     /* Rowset of rows to be updated */
 
   sContext.pParse = 0;
   db = pParse->db;
   if( pParse->nErr || db->mallocFailed ){
@@ -75307,9 +77235,12 @@
 
   /* Remember the rowid of every item to be updated.
   */
   sqlite3VdbeAddOp2(v, IsVirtual(pTab)?OP_VRowid:OP_Rowid, iCur, regOldRowid);
-  if( !okOnePass ) sqlite3VdbeAddOp2(v, OP_FifoWrite, regOldRowid, 0);
+  if( !okOnePass ){
+    regRowSet = ++pParse->nMem;
+    sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
+  }
 
   /* End the database scan loop.
   */
   sqlite3WhereEnd(pWInfo);
@@ -75360,9 +77291,9 @@
     int a1 = sqlite3VdbeAddOp1(v, OP_NotNull, regOldRowid);
     addr = sqlite3VdbeAddOp0(v, OP_Goto);
     sqlite3VdbeJumpHere(v, a1);
   }else{
-    addr = sqlite3VdbeAddOp2(v, OP_FifoRead, regOldRowid, 0);
+    addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet, 0, regOldRowid);
   }
 
   if( triggers_exist ){
     int regRowid;
@@ -75951,9 +77882,9 @@
 **
 *************************************************************************
 ** This file contains code used to help implement virtual tables.
 **
-** $Id: vtab.c,v 1.78 2008/11/13 19:12:36 danielk1977 Exp $
+** $Id: vtab.c,v 1.81 2008/12/10 19:26:24 drh Exp $
 */
 #ifndef SQLITE_OMIT_VIRTUALTABLE
 
 static int createModule(
@@ -75966,9 +77897,9 @@
   int rc, nName;
   Module *pMod;
 
   sqlite3_mutex_enter(db->mutex);
-  nName = strlen(zName);
+  nName = sqlite3Strlen30(zName);
   pMod = (Module *)sqlite3DbMallocRaw(db, sizeof(Module) + nName + 1);
   if( pMod ){
     Module *pDel;
     char *zCopy = (char *)(&pMod[1]);
@@ -76132,9 +78063,9 @@
   pTable->nModuleArg = 0;
   addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
   addModuleArgument(db, pTable, sqlite3DbStrDup(db, db->aDb[iDb].zName));
   addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
-  pParse->sNameToken.n = pModuleName->z + pModuleName->n - pName1->z;
+  pParse->sNameToken.n = (int)(&pModuleName->z[pModuleName->n] - pName1->z);
 
 #ifndef SQLITE_OMIT_AUTHORIZATION
   /* Creating a virtual table invokes the authorization callback twice.
   ** The first invocation, to obtain permission to INSERT a row into the
@@ -76180,9 +78111,10 @@
   if( pTab==0 ) return;
   db = pParse->db;
   if( pTab->nModuleArg<1 ) return;
   zModule = pTab->azModuleArg[0];
-  pMod = (Module *)sqlite3HashFind(&db->aModule, zModule, strlen(zModule));
+  pMod = (Module*)sqlite3HashFind(&db->aModule, zModule,
+                                  sqlite3Strlen30(zModule));
   pTab->pMod = pMod;
 
   /* If the CREATE VIRTUAL TABLE statement is being entered for the
   ** first time (in other words if the virtual table is actually being
@@ -76197,9 +78129,9 @@
     Vdbe *v;
 
     /* Compute the complete text of the CREATE VIRTUAL TABLE statement */
     if( pEnd ){
-      pParse->sNameToken.n = pEnd->z - pParse->sNameToken.z + pEnd->n;
+      pParse->sNameToken.n = (int)(pEnd->z - pParse->sNameToken.z) + pEnd->n;
     }
     zStmt = sqlite3MPrintf(db, "CREATE VIRTUAL TABLE %T", &pParse->sNameToken);
 
     /* A slot for the record has already been allocated in the
@@ -76228,9 +78160,9 @@
     sqlite3VdbeAddOp2(v, OP_Expire, 0, 0);
     zWhere = sqlite3MPrintf(db, "name='%q'", pTab->zName);
     sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 1, 0, zWhere, P4_DYNAMIC);
     sqlite3VdbeAddOp4(v, OP_VCreate, iDb, 0, 0,
-                         pTab->zName, strlen(pTab->zName) + 1);
+                         pTab->zName, sqlite3Strlen30(pTab->zName) + 1);
   }
 
   /* If we are rereading the sqlite_master table create the in-memory
   ** record of the table. If the module has already been registered,
@@ -76239,9 +78171,9 @@
   else {
     Table *pOld;
     Schema *pSchema = pTab->pSchema;
     const char *zName = pTab->zName;
-    int nName = strlen(zName) + 1;
+    int nName = sqlite3Strlen30(zName) + 1;
     pOld = sqlite3HashInsert(&pSchema->tblHash, zName, nName, pTab);
     if( pOld ){
       db->mallocFailed = 1;
       assert( pTab==pOld );  /* Malloc must have failed inside HashInsert() */
@@ -76272,9 +78204,9 @@
     pArg->z = p->z;
     pArg->n = p->n;
   }else{
     assert(pArg->z < p->z);
-    pArg->n = (p->z + p->n - pArg->z);
+    pArg->n = (int)(&p->z[p->n] - pArg->z);
   }
 }
 
 /*
@@ -76344,9 +78276,9 @@
       char *zType = pTab->aCol[iCol].zType;
       int nType;
       int i = 0;
       if( !zType ) continue;
-      nType = strlen(zType);
+      nType = sqlite3Strlen30(zType);
       if( sqlite3StrNICmp("hidden", zType, 6) || (zType[6] && zType[6]!=' ') ){
         for(i=0; i<nType; i++){
           if( (0==sqlite3StrNICmp(" hidden", &zType[i], 7))
            && (zType[i+7]=='\0' || zType[i+7]==' ')
@@ -76701,10 +78633,10 @@
 ){
   Table *pTab;
   sqlite3_vtab *pVtab;
   sqlite3_module *pMod;
-  void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
-  void *pArg;
+  void (*xFunc)(sqlite3_context*,int,sqlite3_value**) = 0;
+  void *pArg = 0;
   FuncDef *pNew;
   int rc = 0;
   char *zLowerName;
   unsigned char *z;
@@ -76743,15 +78675,16 @@
   }
 
   /* Create a new ephemeral function definition for the overloaded
   ** function */
-  pNew = sqlite3DbMallocZero(db, sizeof(*pNew) + strlen(pDef->zName) );
+  pNew = sqlite3DbMallocZero(db, sizeof(*pNew)
+                             + sqlite3Strlen30(pDef->zName) );
   if( pNew==0 ){
     return pDef;
   }
   *pNew = *pDef;
   pNew->zName = (char *)&pNew[1];
-  memcpy(pNew->zName, pDef->zName, strlen(pDef->zName)+1);
+  memcpy(pNew->zName, pDef->zName, sqlite3Strlen30(pDef->zName)+1);
   pNew->xFunc = xFunc;
   pNew->pUserData = pArg;
   pNew->flags |= SQLITE_FUNC_EPHEM;
   return pNew;
@@ -76799,9 +78732,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.330 2008/11/17 19:18:55 danielk1977 Exp $
+** $Id: where.c,v 1.337 2008/12/12 17:56:16 drh Exp $
 */
 
 /*
 ** Trace output macros
@@ -76822,9 +78755,12 @@
 
 /*
 ** The query generator uses an array of instances of this structure to
 ** help it analyze the subexpressions of the WHERE clause.  Each WHERE
-** clause subexpression is separated from the others by an AND operator.
+** clause subexpression is separated from the others by AND operators.
+** (Note: the same data structure is also reused to hold a group of terms
+** separated by OR operators.  But at the top-level, everything is AND
+** separated.)
 **
 ** All WhereTerms are collected into a single WhereClause structure.
 ** The following identity holds:
 **
@@ -76851,25 +78787,29 @@
 ** translates these sparse cursor numbers into consecutive integers
 ** beginning with 0 in order to make the best possible use of the available
 ** bits in the Bitmask.  So, in the example above, the cursor numbers
 ** would be mapped into integers 0 through 7.
+**
+** The number of terms in a join is limited by the number of bits
+** in prereqRight and prereqAll.  The default is 64 bits, hence SQLite
+** is only able to process joins with 64 or fewer tables.
 */
 typedef struct WhereTerm WhereTerm;
 struct WhereTerm {
-  Expr *pExpr;            /* Pointer to the subexpression */
-  i16 iParent;            /* Disable pWC->a[iParent] when this term disabled */
-  i16 leftCursor;         /* Cursor number of X in "X <op> <expr>" */
-  i16 leftColumn;         /* Column number of X in "X <op> <expr>" */
+  Expr *pExpr;            /* Pointer to the subexpression that is this term */
+  int iParent;            /* Disable pWC->a[iParent] when this term disabled */
+  int leftCursor;         /* Cursor number of X in "X <op> <expr>" */
+  int leftColumn;         /* Column number of X in "X <op> <expr>" */
   u16 eOperator;          /* A WO_xx value describing <op> */
-  u8 flags;               /* Bit flags.  See below */
+  u8 wtFlags;             /* TERM_xxx bit flags.  See below */
   u8 nChild;              /* Number of children that must disable us */
   WhereClause *pWC;       /* The clause this term is part of */
-  Bitmask prereqRight;    /* Bitmask of tables used by pRight */
-  Bitmask prereqAll;      /* Bitmask of tables referenced by p */
-};
-
-/*
-** Allowed values of WhereTerm.flags
+  Bitmask prereqRight;    /* Bitmask of tables used by pExpr->pRight */
+  Bitmask prereqAll;      /* Bitmask of tables referenced by pExpr */
+};
+
+/*
+** Allowed values of WhereTerm.wtFlags
 */
 #define TERM_DYNAMIC    0x01   /* Need to call sqlite3ExprDelete(db, pExpr) */
 #define TERM_VIRTUAL    0x02   /* Added by the optimizer.  Do not code */
 #define TERM_CODED      0x04   /* This term is already coded */
@@ -76885,9 +78825,9 @@
   ExprMaskSet *pMaskSet;   /* Mapping of table indices to bitmasks */
   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[10];   /* Initial static space for a[] */
+  WhereTerm aStatic[4];    /* Initial static space for a[] */
 };
 
 /*
 ** An instance of the following structure keeps track of a mapping
@@ -76925,40 +78865,45 @@
 ** Bitmasks for the operators that indices are able to exploit.  An
 ** OR-ed combination of these values can be used when searching for
 ** terms in the where clause.
 */
-#define WO_IN     1
-#define WO_EQ     2
+#define WO_IN     0x001
+#define WO_EQ     0x002
 #define WO_LT     (WO_EQ<<(TK_LT-TK_EQ))
 #define WO_LE     (WO_EQ<<(TK_LE-TK_EQ))
 #define WO_GT     (WO_EQ<<(TK_GT-TK_EQ))
 #define WO_GE     (WO_EQ<<(TK_GE-TK_EQ))
-#define WO_MATCH  64
-#define WO_ISNULL 128
-
-/*
-** Value for flags returned by bestIndex().
-**
-** The least significant byte is reserved as a mask for WO_ values above.
-** The WhereLevel.flags field is usually set to WO_IN|WO_EQ|WO_ISNULL.
-** But if the table is the right table of a left join, WhereLevel.flags
-** is set to WO_IN|WO_EQ.  The WhereLevel.flags field can then be used as
+#define WO_MATCH  0x040
+#define WO_ISNULL 0x080
+#define WO_OR     0x100
+
+#define WO_ALL    0xfff       /* Mask of all possible WO_* values */
+
+/*
+** Value for wsFlags returned by bestIndex().  These flags determine which
+** search strategies are appropriate.
+**
+** The least significant 12 bits is reserved as a mask for WO_ values above.
+** The WhereLevel.wtFlags field is usually set to WO_IN|WO_EQ|WO_ISNULL.
+** But if the table is the right table of a left join, WhereLevel.wtFlags
+** is set to WO_IN|WO_EQ.  The WhereLevel.wtFlags field can then be used as
 ** the "op" parameter to findTerm when we are resolving equality constraints.
 ** ISNULL constraints will then not be used on the right table of a left
 ** join.  Tickets #2177 and #2189.
 */
-#define WHERE_ROWID_EQ     0x000100   /* rowid=EXPR or rowid IN (...) */
-#define WHERE_ROWID_RANGE  0x000200   /* rowid<EXPR and/or rowid>EXPR */
-#define WHERE_COLUMN_EQ    0x001000   /* x=EXPR or x IN (...) */
-#define WHERE_COLUMN_RANGE 0x002000   /* x<EXPR and/or x>EXPR */
-#define WHERE_COLUMN_IN    0x004000   /* x IN (...) */
-#define WHERE_TOP_LIMIT    0x010000   /* x<EXPR or x<=EXPR constraint */
-#define WHERE_BTM_LIMIT    0x020000   /* x>EXPR or x>=EXPR constraint */
-#define WHERE_IDX_ONLY     0x080000   /* Use index only - omit table */
-#define WHERE_ORDERBY      0x100000   /* Output will appear in correct order */
-#define WHERE_REVERSE      0x200000   /* Scan in reverse order */
-#define WHERE_UNIQUE       0x400000   /* Selects no more than one row */
-#define WHERE_VIRTUALTABLE 0x800000   /* Use virtual-table processing */
+#define WHERE_ROWID_EQ     0x00001000  /* rowid=EXPR or rowid IN (...) */
+#define WHERE_ROWID_RANGE  0x00002000  /* rowid<EXPR and/or rowid>EXPR */
+#define WHERE_COLUMN_EQ    0x00010000  /* x=EXPR or x IN (...) */
+#define WHERE_COLUMN_RANGE 0x00020000  /* x<EXPR and/or x>EXPR */
+#define WHERE_COLUMN_IN    0x00040000  /* x IN (...) */
+#define WHERE_TOP_LIMIT    0x00100000  /* x<EXPR or x<=EXPR constraint */
+#define WHERE_BTM_LIMIT    0x00200000  /* x>EXPR or x>=EXPR constraint */
+#define WHERE_IDX_ONLY     0x00800000  /* Use index only - omit table */
+#define WHERE_ORDERBY      0x01000000  /* Output will appear in correct order */
+#define WHERE_REVERSE      0x02000000  /* Scan in reverse order */
+#define WHERE_UNIQUE       0x04000000  /* Selects no more than one row */
+#define WHERE_VIRTUALTABLE 0x08000000  /* Use virtual-table processing */
+#define WHERE_MULTI_OR     0x10000000  /* OR using multiple indices */
 
 /*
 ** Initialize a preallocated WhereClause structure.
 */
@@ -76982,9 +78927,9 @@
   int i;
   WhereTerm *a;
   sqlite3 *db = pWC->pParse->db;
   for(i=pWC->nTerm-1, a=pWC->a; i>=0; i--, a++){
-    if( a->flags & TERM_DYNAMIC ){
+    if( a->wtFlags & TERM_DYNAMIC ){
       sqlite3ExprDelete(db, a->pExpr);
     }
   }
   if( pWC->a!=pWC->aStatic ){
@@ -76992,28 +78937,35 @@
   }
 }
 
 /*
-** Add a new entries to the WhereClause structure.  Increase the allocated
-** space as necessary.
-**
-** If the flags argument includes TERM_DYNAMIC, then responsibility
-** for freeing the expression p is assumed by the WhereClause object.
+** Add a single new WhereTerm entry to the WhereClause object pWC.
+** The new WhereTerm object is constructed from Expr p and with wtFlags.
+** The index in pWC->a[] of the new WhereTerm is returned on success.
+** 0 is returned if the new WhereTerm could not be added due to a memory
+** allocation error.  The memory allocation failure will be recorded in
+** the db->mallocFailed flag so that higher-level functions can detect it.
+**
+** This routine will increase the size of the pWC->a[] array as necessary.
+**
+** If the wtFlags argument includes TERM_DYNAMIC, then responsibility
+** for freeing the expression p is assumed by the WhereClause object pWC.
+** This is true even if this routine fails to allocate a new WhereTerm.
 **
 ** WARNING:  This routine might reallocate the space used to store
 ** WhereTerms.  All pointers to WhereTerms should be invalidated after
 ** calling this routine.  Such pointers may be reinitialized by referencing
 ** the pWC->a[] array.
 */
-static int whereClauseInsert(WhereClause *pWC, Expr *p, int flags){
+static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
   WhereTerm *pTerm;
   int idx;
   if( pWC->nTerm>=pWC->nSlot ){
     WhereTerm *pOld = pWC->a;
     sqlite3 *db = pWC->pParse->db;
     pWC->a = sqlite3DbMallocRaw(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
     if( pWC->a==0 ){
-      if( flags & TERM_DYNAMIC ){
+      if( wtFlags & TERM_DYNAMIC ){
         sqlite3ExprDelete(db, p);
       }
       pWC->a = pOld;
       return 0;
@@ -77021,14 +78973,13 @@
     memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm);
     if( pOld!=pWC->aStatic ){
       sqlite3DbFree(db, pOld);
     }
-    pWC->nSlot *= 2;
-  }
-  pTerm = &pWC->a[idx = pWC->nTerm];
-  pWC->nTerm++;
+    pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
+  }
+  pTerm = &pWC->a[idx = pWC->nTerm++];
   pTerm->pExpr = p;
-  pTerm->flags = flags;
+  pTerm->wtFlags = wtFlags;
   pTerm->pWC = pWC;
   pTerm->iParent = -1;
   return idx;
 }
@@ -77046,9 +78997,9 @@
 ** The original WHERE clause in pExpr is unaltered.  All this routine
 ** does is make slot[] entries point to substructure within pExpr.
 **
 ** In the previous sentence and in the diagram, "slot[]" refers to
-** the WhereClause.a[] array.  This array grows as needed to contain
+** the WhereClause.a[] array.  The slot[] array grows as needed to contain
 ** all terms of the WHERE clause.
 */
 static void whereSplit(WhereClause *pWC, Expr *pExpr, int op){
   if( pExpr==0 ) return;
@@ -77157,9 +79108,9 @@
   return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL;
 }
 
 /*
-** Swap two objects of type T.
+** Swap two objects of type TYPE.
 */
 #define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
 
 /*
@@ -77196,19 +79147,23 @@
 
 /*
 ** Translate from TK_xx operator to WO_xx bitmask.
 */
-static int operatorMask(int op){
-  int c;
+static u16 operatorMask(int op){
+  u16 c;
   assert( allowedOp(op) );
   if( op==TK_IN ){
     c = WO_IN;
   }else if( op==TK_ISNULL ){
     c = WO_ISNULL;
-  }else{
-    c = WO_EQ<<(op-TK_EQ);
+  }else if( op==TK_OR ){
+    c = WO_OR;
+  }else{
+    assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff );
+    c = (u16)(WO_EQ<<(op-TK_EQ));
   }
   assert( op!=TK_ISNULL || c==WO_ISNULL );
+  assert( op!=TK_OR || c==WO_OR );
   assert( op!=TK_IN || c==WO_IN );
   assert( op!=TK_EQ || c==WO_EQ );
   assert( op!=TK_LT || c==WO_LT );
   assert( op!=TK_LE || c==WO_LE );
@@ -77227,14 +79182,15 @@
   WhereClause *pWC,     /* The WHERE clause to be searched */
   int iCur,             /* Cursor number of LHS */
   int iColumn,          /* Column number of LHS */
   Bitmask notReady,     /* RHS must not overlap with this mask */
-  u16 op,               /* Mask of WO_xx values describing operator */
+  u32 op,               /* Mask of WO_xx values describing operator */
   Index *pIdx           /* Must be compatible with this index, if not NULL */
 ){
   WhereTerm *pTerm;
   int k;
   assert( iCur>=0 );
+  op &= WO_ALL;
   for(pTerm=pWC->a, k=pWC->nTerm; k; k--, pTerm++){
     if( pTerm->leftCursor==iCur
        && (pTerm->prereqRight & notReady)==0
        && pTerm->leftColumn==iColumn
@@ -77464,15 +79420,15 @@
 ** disqualified, then return true.  If there are no duplicates, or
 ** the duplicate has also been disqualified, return false.
 */
 static int orTermHasOkDuplicate(WhereClause *pOr, WhereTerm *pOrTerm){
-  if( pOrTerm->flags & TERM_COPIED ){
+  if( pOrTerm->wtFlags & TERM_COPIED ){
     /* This is the original term.  The duplicate is to the left had
     ** has not yet been analyzed and thus has not yet been disqualified. */
     return 1;
   }
-  if( (pOrTerm->flags & TERM_VIRTUAL)!=0
-     && (pOr->a[pOrTerm->iParent].flags & TERM_OR_OK)!=0 ){
+  if( (pOrTerm->wtFlags & TERM_VIRTUAL)!=0
+     && (pOr->a[pOrTerm->iParent].wtFlags & TERM_OR_OK)!=0 ){
     /* This is a duplicate term.  The original qualified so this one
     ** does not have to. */
     return 1;
   }
@@ -77563,9 +79519,9 @@
         pNew = &pWC->a[idxNew];
         pNew->iParent = idxTerm;
         pTerm = &pWC->a[idxTerm];
         pTerm->nChild = 1;
-        pTerm->flags |= TERM_COPIED;
+        pTerm->wtFlags |= TERM_COPIED;
       }else{
         pDup = pExpr;
         pNew = pTerm;
       }
@@ -77594,8 +79550,9 @@
       int idxNew;
       pNewExpr = sqlite3Expr(db, ops[i], sqlite3ExprDup(db, pExpr->pLeft),
                              sqlite3ExprDup(db, pList->a[i].pExpr), 0);
       idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
+      testcase( idxNew==0 );
       exprAnalyze(pSrc, pWC, idxNew);
       pTerm = &pWC->a[idxTerm];
       pWC->a[idxNew].iParent = idxTerm;
     }
@@ -77622,9 +79579,9 @@
     int iColumn, iCursor;
     WhereClause sOr;
     WhereTerm *pOrTerm;
 
-    assert( (pTerm->flags & TERM_DYNAMIC)==0 );
+    assert( (pTerm->wtFlags & TERM_DYNAMIC)==0 );
     whereClauseInit(&sOr, pWC->pParse, pMaskSet);
     whereSplit(&sOr, pExpr, TK_OR);
     exprAnalyzeAll(pSrc, &sOr);
     assert( sOr.nTerm>=2 );
@@ -77639,22 +79596,22 @@
         if( pOrTerm->eOperator!=WO_EQ ){
           goto or_not_possible;
         }
         if( orTermIsOptCandidate(pOrTerm, iCursor, iColumn) ){
-          pOrTerm->flags |= TERM_OR_OK;
+          pOrTerm->wtFlags |= TERM_OR_OK;
         }else if( orTermHasOkDuplicate(&sOr, pOrTerm) ){
-          pOrTerm->flags &= ~TERM_OR_OK;
+          pOrTerm->wtFlags &= ~TERM_OR_OK;
         }else{
           ok = 0;
         }
       }
-    }while( !ok && (sOr.a[j++].flags & TERM_COPIED)!=0 && j<2 );
+    }while( !ok && (sOr.a[j++].wtFlags & TERM_COPIED)!=0 && j<2 );
     if( ok ){
       ExprList *pList = 0;
       Expr *pNew, *pDup;
       Expr *pLeft = 0;
       for(i=sOr.nTerm-1, pOrTerm=sOr.a; i>=0; i--, pOrTerm++){
-        if( (pOrTerm->flags & TERM_OR_OK)==0 ) continue;
+        if( (pOrTerm->wtFlags & TERM_OR_OK)==0 ) continue;
         pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight);
         pList = sqlite3ExprListAppend(pWC->pParse, pList, pDup, 0);
         pLeft = pOrTerm->pExpr->pLeft;
       }
@@ -77665,8 +79622,9 @@
         int idxNew;
         transferJoinMarkings(pNew, pExpr);
         pNew->pList = pList;
         idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
+        testcase( idxNew==0 );
         exprAnalyze(pSrc, pWC, idxNew);
         pTerm = &pWC->a[idxTerm];
         pWC->a[idxNew].iParent = idxTerm;
         pTerm->nChild = 1;
@@ -77717,11 +79675,13 @@
       *pC = c + 1;
     }
     pNewExpr1 = sqlite3PExpr(pParse, TK_GE, sqlite3ExprDup(db,pLeft), pStr1, 0);
     idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
+    testcase( idxNew1==0 );
     exprAnalyze(pSrc, pWC, idxNew1);
     pNewExpr2 = sqlite3PExpr(pParse, TK_LT, sqlite3ExprDup(db,pLeft), pStr2, 0);
     idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
+    testcase( idxNew2==0 );
     exprAnalyze(pSrc, pWC, idxNew2);
     pTerm = &pWC->a[idxTerm];
     if( isComplete ){
       pWC->a[idxNew1].iParent = idxTerm;
@@ -77751,8 +79711,9 @@
     if( (prereqExpr & prereqColumn)==0 ){
       Expr *pNewExpr;
       pNewExpr = sqlite3Expr(db, TK_MATCH, 0, sqlite3ExprDup(db, pRight), 0);
       idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
+      testcase( idxNew==0 );
       pNewTerm = &pWC->a[idxNew];
       pNewTerm->prereqRight = prereqExpr;
       pNewTerm->leftCursor = pLeft->iTable;
       pNewTerm->leftColumn = pLeft->iColumn;
@@ -77759,9 +79720,9 @@
       pNewTerm->eOperator = WO_MATCH;
       pNewTerm->iParent = idxTerm;
       pTerm = &pWC->a[idxTerm];
       pTerm->nChild = 1;
-      pTerm->flags |= TERM_COPIED;
+      pTerm->wtFlags |= TERM_COPIED;
       pNewTerm->prereqAll = pTerm->prereqAll;
     }
   }
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -78055,9 +80016,8 @@
   ** and initialize it now
   */
   pIdxInfo = *ppIdxInfo;
   if( pIdxInfo==0 ){
-    WhereTerm *pTerm;
     int nTerm;
     WHERETRACE(("Recomputing index info for %s...\n", pTab->zName));
 
     /* Count the number of possible WHERE clause constraints referring
@@ -78119,9 +80079,9 @@
       testcase( pTerm->eOperator==WO_ISNULL );
       if( pTerm->eOperator & (WO_IN|WO_ISNULL) ) continue;
       pIdxCons[j].iColumn = pTerm->leftColumn;
       pIdxCons[j].iTermOffset = i;
-      pIdxCons[j].op = pTerm->eOperator;
+      pIdxCons[j].op = (u8)pTerm->eOperator;
       /* The direct assignment in the previous line is possible only because
       ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical.  The
       ** following asserts verify this fact. */
       assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ );
@@ -78185,9 +80145,9 @@
   pUsage = pIdxInfo->aConstraintUsage;
   for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
     j = pIdxCons->iTermOffset;
     pTerm = &pWC->a[j];
-    pIdxCons->usable =  (pTerm->prereqRight & notReady)==0;
+    pIdxCons->usable =  (pTerm->prereqRight & notReady)==0 ?1:0;
   }
   memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint);
   if( pIdxInfo->needToFreeIdxStr ){
     sqlite3_free(pIdxInfo->idxStr);
@@ -78268,25 +80228,25 @@
   struct SrcList_item *pSrc,  /* The FROM clause term to search */
   Bitmask notReady,           /* Mask of cursors that are not available */
   ExprList *pOrderBy,         /* The order by clause */
   Index **ppIndex,            /* Make *ppIndex point to the best index */
-  int *pFlags,                /* Put flags describing this choice in *pFlags */
+  int *pWsFlags,              /* Put wsFlags describing scan strategy here */
   int *pnEq                   /* Put the number of == or IN constraints here */
 ){
   WhereTerm *pTerm;
   Index *bestIdx = 0;         /* Index that gives the lowest cost */
   double lowestCost;          /* The cost of using bestIdx */
-  int bestFlags = 0;          /* Flags associated with bestIdx */
+  int bestWsFlags = 0;        /* Flags associated with bestIdx */
   int bestNEq = 0;            /* Best value for nEq */
   int iCur = pSrc->iCursor;   /* The cursor of the table to be accessed */
   Index *pProbe;              /* An index we are evaluating */
   int rev;                    /* True to scan in reverse order */
-  int flags;                  /* Flags associated with pProbe */
+  int wsFlags;                /* Flags associated with pProbe */
   int nEq;                    /* Number of == or IN constraints */
   int eqTermMask;             /* Mask of valid equality operators */
   double cost;                /* Cost of using pProbe */
 
-  WHERETRACE(("bestIndex: tbl=%s notReady=%llx\n", pSrc->pTab->zName, notReady));
+  WHERETRACE(("bestIndex: tbl=%s notReady=%llx\n", pSrc->pTab->zName,notReady));
   lowestCost = SQLITE_BIG_DBL;
   pProbe = pSrc->pTab->pIndex;
   if( pSrc->notIndexed ){
     pProbe = 0;
@@ -78300,9 +80260,9 @@
   */
   if( pProbe==0 &&
      findTerm(pWC, iCur, -1, 0, WO_EQ|WO_IN|WO_LT|WO_LE|WO_GT|WO_GE,0)==0 &&
      (pOrderBy==0 || !sortableByRowid(iCur, pOrderBy, pWC->pMaskSet, &rev)) ){
-    *pFlags = 0;
+    *pWsFlags = 0;
     *ppIndex = 0;
     *pnEq = 0;
     return 0.0;
   }
@@ -78314,13 +80274,13 @@
     pTerm = findTerm(pWC, iCur, -1, notReady, WO_EQ|WO_IN, 0);
     if( pTerm ){
       Expr *pExpr;
       *ppIndex = 0;
-      bestFlags = WHERE_ROWID_EQ;
+      bestWsFlags = WHERE_ROWID_EQ;
       if( pTerm->eOperator & WO_EQ ){
         /* Rowid== is always the best pick.  Look no further.  Because only
         ** a single row is generated, output is always in sorted order */
-        *pFlags = WHERE_ROWID_EQ | WHERE_UNIQUE;
+        *pWsFlags = WHERE_ROWID_EQ | WHERE_UNIQUE;
         *pnEq = 1;
         WHERETRACE(("... best is rowid\n"));
         return 0.0;
       }else if( (pExpr = pTerm->pExpr)->pList!=0 ){
@@ -78341,34 +80301,34 @@
     ** entries are in the table, use 1 million as a guess.
     */
     cost = pProbe ? pProbe->aiRowEst[0] : 1000000;
     WHERETRACE(("... table scan base cost: %.9g\n", cost));
-    flags = WHERE_ROWID_RANGE;
+    wsFlags = WHERE_ROWID_RANGE;
 
     /* Check for constraints on a range of rowids in a table scan.
     */
     pTerm = findTerm(pWC, iCur, -1, notReady, WO_LT|WO_LE|WO_GT|WO_GE, 0);
     if( pTerm ){
       if( findTerm(pWC, iCur, -1, notReady, WO_LT|WO_LE, 0) ){
-        flags |= WHERE_TOP_LIMIT;
+        wsFlags |= WHERE_TOP_LIMIT;
         cost /= 3;  /* Guess that rowid<EXPR eliminates two-thirds or rows */
       }
       if( findTerm(pWC, iCur, -1, notReady, WO_GT|WO_GE, 0) ){
-        flags |= WHERE_BTM_LIMIT;
+        wsFlags |= WHERE_BTM_LIMIT;
         cost /= 3;  /* Guess that rowid>EXPR eliminates two-thirds of rows */
       }
       WHERETRACE(("... rowid range reduces cost to %.9g\n", cost));
     }else{
-      flags = 0;
+      wsFlags = 0;
     }
 
     /* If the table scan does not satisfy the ORDER BY clause, increase
     ** the cost by NlogN to cover the expense of sorting. */
     if( pOrderBy ){
       if( sortableByRowid(iCur, pOrderBy, pWC->pMaskSet, &rev) ){
-        flags |= WHERE_ORDERBY|WHERE_ROWID_RANGE;
+        wsFlags |= WHERE_ORDERBY|WHERE_ROWID_RANGE;
         if( rev ){
-          flags |= WHERE_REVERSE;
+          wsFlags |= WHERE_REVERSE;
         }
       }else{
         cost += cost*estLog(cost);
         WHERETRACE(("... sorting increases cost to %.9g\n", cost));
@@ -78375,9 +80335,9 @@
       }
     }
     if( cost<lowestCost ){
       lowestCost = cost;
-      bestFlags = flags;
+      bestWsFlags = wsFlags;
     }
   }
 
   /* If the pSrc table is the right table of a LEFT JOIN then we may not
@@ -78404,17 +80364,17 @@
 
     /* Count the number of columns in the index that are satisfied
     ** by x=EXPR constraints or x IN (...) constraints.
     */
-    flags = 0;
+    wsFlags = 0;
     for(i=0; i<pProbe->nColumn; i++){
       int j = pProbe->aiColumn[i];
       pTerm = findTerm(pWC, iCur, j, notReady, eqTermMask, pProbe);
       if( pTerm==0 ) break;
-      flags |= WHERE_COLUMN_EQ;
+      wsFlags |= WHERE_COLUMN_EQ;
       if( pTerm->eOperator & WO_IN ){
         Expr *pExpr = pTerm->pExpr;
-        flags |= WHERE_COLUMN_IN;
+        wsFlags |= WHERE_COLUMN_IN;
         if( pExpr->pSelect!=0 ){
           inMultiplier *= 25;
         }else if( ALWAYS(pExpr->pList) ){
           inMultiplier *= pExpr->pList->nExpr + 1;
@@ -78422,11 +80382,11 @@
       }
     }
     cost = pProbe->aiRowEst[i] * inMultiplier * estLog(inMultiplier);
     nEq = i;
-    if( pProbe->onError!=OE_None && (flags & WHERE_COLUMN_IN)==0
+    if( pProbe->onError!=OE_None && (wsFlags & WHERE_COLUMN_IN)==0
          && nEq==pProbe->nColumn ){
-      flags |= WHERE_UNIQUE;
+      wsFlags |= WHERE_UNIQUE;
     }
     WHERETRACE(("...... nEq=%d inMult=%.9g cost=%.9g\n",nEq,inMultiplier,cost));
 
     /* Look for range constraints
@@ -78434,15 +80394,15 @@
     if( nEq<pProbe->nColumn ){
       int j = pProbe->aiColumn[nEq];
       pTerm = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pProbe);
       if( pTerm ){
-        flags |= WHERE_COLUMN_RANGE;
+        wsFlags |= WHERE_COLUMN_RANGE;
         if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pProbe) ){
-          flags |= WHERE_TOP_LIMIT;
+          wsFlags |= WHERE_TOP_LIMIT;
           cost /= 3;
         }
         if( findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pProbe) ){
-          flags |= WHERE_BTM_LIMIT;
+          wsFlags |= WHERE_BTM_LIMIT;
           cost /= 3;
         }
         WHERETRACE(("...... range reduces cost to %.9g\n", cost));
       }
@@ -78450,16 +80410,16 @@
 
     /* Add the additional cost of sorting if that is a factor.
     */
     if( pOrderBy ){
-      if( (flags & WHERE_COLUMN_IN)==0 &&
+      if( (wsFlags & WHERE_COLUMN_IN)==0 &&
            isSortingIndex(pParse,pWC->pMaskSet,pProbe,iCur,pOrderBy,nEq,&rev) ){
-        if( flags==0 ){
-          flags = WHERE_COLUMN_RANGE;
-        }
-        flags |= WHERE_ORDERBY;
+        if( wsFlags==0 ){
+          wsFlags = WHERE_COLUMN_RANGE;
+        }
+        wsFlags |= WHERE_ORDERBY;
         if( rev ){
-          flags |= WHERE_REVERSE;
+          wsFlags |= WHERE_REVERSE;
         }
       }else{
         cost += cost*estLog(cost);
         WHERETRACE(("...... orderby increases cost to %.9g\n", cost));
@@ -78469,9 +80429,9 @@
     /* Check to see if we can get away with using just the index without
     ** ever reading the table.  If that is the case, then halve the
     ** cost of this index.
     */
-    if( flags && pSrc->colUsed < (((Bitmask)1)<<(BMS-1)) ){
+    if( wsFlags && pSrc->colUsed < (((Bitmask)1)<<(BMS-1)) ){
       Bitmask m = pSrc->colUsed;
       int j;
       for(j=0; j<pProbe->nColumn; j++){
         int x = pProbe->aiColumn[j];
@@ -78479,30 +80439,30 @@
           m &= ~(((Bitmask)1)<<x);
         }
       }
       if( m==0 ){
-        flags |= WHERE_IDX_ONLY;
+        wsFlags |= WHERE_IDX_ONLY;
         cost /= 2;
         WHERETRACE(("...... idx-only reduces cost to %.9g\n", cost));
       }
     }
 
     /* If this index has achieved the lowest cost so far, then use it.
     */
-    if( flags && cost < lowestCost ){
+    if( wsFlags && cost < lowestCost ){
       bestIdx = pProbe;
       lowestCost = cost;
-      bestFlags = flags;
+      bestWsFlags = wsFlags;
       bestNEq = nEq;
     }
   }
 
   /* Report the best result
   */
   *ppIndex = bestIdx;
-  WHERETRACE(("best index is %s, cost=%.9g, flags=%x, nEq=%d\n",
-        bestIdx ? bestIdx->zName : "(none)", lowestCost, bestFlags, bestNEq));
-  *pFlags = bestFlags | eqTermMask;
+  WHERETRACE(("best index is %s, cost=%.9g, wsFlags=%x, nEq=%d\n",
+        bestIdx ? bestIdx->zName : "(none)", lowestCost, bestWsFlags, bestNEq));
+  *pWsFlags = bestWsFlags | eqTermMask;
   *pnEq = bestNEq;
   return lowestCost;
 }
 
@@ -78531,12 +80491,12 @@
 ** the wrong answer.  See ticket #813.
 */
 static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
   if( pTerm
-      && ALWAYS((pTerm->flags & TERM_CODED)==0)
+      && ALWAYS((pTerm->wtFlags & TERM_CODED)==0)
       && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin))
   ){
-    pTerm->flags |= TERM_CODED;
+    pTerm->wtFlags |= TERM_CODED;
     if( pTerm->iParent>=0 ){
       WhereTerm *pOther = &pTerm->pWC->a[pTerm->iParent];
       if( (--pOther->nChild)==0 ){
         disableTerm(pLevel, pOther);
@@ -78599,9 +80559,9 @@
     iTab = pX->iTable;
     sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
     VdbeComment((v, "%.*s", pX->span.n, pX->span.z));
     if( pLevel->nIn==0 ){
-      pLevel->nxt = sqlite3VdbeMakeLabel(v);
+      pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
     }
     pLevel->nIn++;
     pLevel->aInLoop = sqlite3DbReallocOrFree(pParse->db, pLevel->aInLoop,
                                     sizeof(pLevel->aInLoop[0])*pLevel->nIn);
@@ -78609,11 +80569,11 @@
     if( pIn ){
       pIn += pLevel->nIn - 1;
       pIn->iCur = iTab;
       if( eType==IN_INDEX_ROWID ){
-        pIn->topAddr = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iReg);
-      }else{
-        pIn->topAddr = sqlite3VdbeAddOp3(v, OP_Column, iTab, 0, iReg);
+        pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iReg);
+      }else{
+        pIn->addrInTop = sqlite3VdbeAddOp3(v, OP_Column, iTab, 0, iReg);
       }
       sqlite3VdbeAddOp1(v, OP_IsNull, iReg);
     }else{
       pLevel->nIn = 0;
@@ -78676,19 +80636,19 @@
   assert( pIdx->nColumn>=nEq );
   for(j=0; j<nEq; j++){
     int r1;
     int k = pIdx->aiColumn[j];
-    pTerm = findTerm(pWC, iCur, k, notReady, pLevel->flags, pIdx);
+    pTerm = findTerm(pWC, iCur, k, notReady, pLevel->wsFlags, pIdx);
     if( NEVER(pTerm==0) ) break;
-    assert( (pTerm->flags & TERM_CODED)==0 );
+    assert( (pTerm->wtFlags & TERM_CODED)==0 );
     r1 = codeEqualityTerm(pParse, pTerm, pLevel, regBase+j);
     if( r1!=regBase+j ){
       sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j);
     }
     testcase( pTerm->eOperator & WO_ISNULL );
     testcase( pTerm->eOperator & WO_IN );
     if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){
-      sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->brk);
+      sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk);
     }
   }
   return regBase;
 }
@@ -78816,22 +80776,22 @@
   Parse *pParse,        /* The parser context */
   SrcList *pTabList,    /* A list of all tables to be scanned */
   Expr *pWhere,         /* The WHERE clause */
   ExprList **ppOrderBy, /* An ORDER BY clause, or NULL */
-  u8 wflags             /* One of the WHERE_* flags defined in sqliteInt.h */
+  u8 wctrlFlags         /* One of the WHERE_* flags defined in sqliteInt.h */
 ){
   int i;                     /* Loop counter */
   WhereInfo *pWInfo;         /* Will become the return value of this function */
   Vdbe *v = pParse->pVdbe;   /* The virtual database engine */
-  int brk, cont = 0;         /* Addresses used during code generation */
+  int addrBrk, addrCont = 0; /* Addresses used during code generation */
   Bitmask notReady;          /* Cursors that are not yet positioned */
   WhereTerm *pTerm;          /* A single term in the WHERE clause */
   ExprMaskSet maskSet;       /* The expression mask set */
   WhereClause wc;            /* The WHERE clause is divided into these terms */
   struct SrcList_item *pTabItem;  /* A single entry from pTabList */
   WhereLevel *pLevel;             /* A single level in the pWInfo list */
   int iFrom;                      /* First unused FROM clause element */
-  int andFlags;              /* AND-ed combination of all wc.a[].flags */
+  int andFlags;              /* AND-ed combination of all wc.a[].wtFlags */
   sqlite3 *db;               /* Database connection */
   ExprList *pOrderBy = 0;
 
   /* The number of tables in the FROM clause is limited by the number of
@@ -78915,9 +80875,9 @@
   **
   ** This loop fills in the following fields:
   **
   **   pWInfo->a[].pIdx      The index to use for this level of the loop.
-  **   pWInfo->a[].flags     WHERE_xxx flags associated with pIdx
+  **   pWInfo->a[].wsFlags   WHERE_xxx flags associated with pIdx
   **   pWInfo->a[].nEq       The number of == and IN constraints
   **   pWInfo->a[].iFrom     Which term of the FROM clause is being coded
   **   pWInfo->a[].iTabCur   The VDBE cursor for the database table
   **   pWInfo->a[].iIdxCur   The VDBE cursor for the index
@@ -78931,14 +80891,14 @@
   andFlags = ~0;
   WHERETRACE(("*** Optimizer Start ***\n"));
   for(i=iFrom=0, pLevel=pWInfo->a; i<pTabList->nSrc; i++, pLevel++){
     Index *pIdx;                /* Index for FROM table at pTabItem */
-    int flags;                  /* Flags asssociated with pIdx */
+    int wsFlags;                /* Flags describing scan strategy */
     int nEq;                    /* Number of == or IN constraints */
     double cost;                /* The cost for pIdx */
     int j;                      /* For looping over FROM tables */
     Index *pBest = 0;           /* The best index seen so far */
-    int bestFlags = 0;          /* Flags associated with pBest */
+    int bestWsFlags = 0;        /* Flags associated with pBest */
     int bestNEq = 0;            /* nEq associated with pBest */
     double lowestCost;          /* Cost of the pBest */
     int bestJ = 0;              /* The value of j */
     Bitmask m;                  /* Bitmask value for j or bestJ */
@@ -78962,12 +80922,12 @@
         sqlite3_index_info **ppIdxInfo = &pWInfo->a[j].pIdxInfo;
         cost = bestVirtualIndex(pParse, &wc, pTabItem, notReady,
                                 ppOrderBy ? *ppOrderBy : 0, i==0,
                                 ppIdxInfo);
-        flags = WHERE_VIRTUALTABLE;
+        wsFlags = WHERE_VIRTUALTABLE;
         pIndex = *ppIdxInfo;
         if( pIndex && pIndex->orderByConsumed ){
-          flags = WHERE_VIRTUALTABLE | WHERE_ORDERBY;
+          wsFlags = WHERE_VIRTUALTABLE | WHERE_ORDERBY;
         }
         pIdx = 0;
         nEq = 0;
         if( (SQLITE_BIG_DBL/2.0)<cost ){
@@ -78982,16 +80942,16 @@
 #endif
       {
         cost = bestIndex(pParse, &wc, pTabItem, notReady,
                          (i==0 && ppOrderBy) ? *ppOrderBy : 0,
-                         &pIdx, &flags, &nEq);
+                         &pIdx, &wsFlags, &nEq);
         pIndex = 0;
       }
       if( cost<lowestCost ){
         once = 1;
         lowestCost = cost;
         pBest = pIdx;
-        bestFlags = flags;
+        bestWsFlags = wsFlags;
         bestNEq = nEq;
         bestJ = j;
         pLevel->pBestIdx = pIndex;
       }
@@ -78998,13 +80958,13 @@
       if( doNotReorder ) break;
     }
     WHERETRACE(("*** Optimizer selects table %d for loop %d\n", bestJ,
            pLevel-pWInfo->a));
-    if( (bestFlags & WHERE_ORDERBY)!=0 ){
+    if( (bestWsFlags & WHERE_ORDERBY)!=0 ){
       *ppOrderBy = 0;
     }
-    andFlags &= bestFlags;
-    pLevel->flags = bestFlags;
+    andFlags &= bestWsFlags;
+    pLevel->wsFlags = bestWsFlags;
     pLevel->pIdx = pBest;
     pLevel->nEq = bestNEq;
     pLevel->aInLoop = 0;
     pLevel->nIn = 0;
@@ -79041,12 +81001,12 @@
   ** to use a one-pass algorithm, determine if this is appropriate.
   ** The one-pass algorithm only works if the WHERE clause constraints
   ** the statement to update a single row.
   */
-  assert( (wflags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 );
-  if( (wflags & WHERE_ONEPASS_DESIRED)!=0 && (andFlags & WHERE_UNIQUE)!=0 ){
+  assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 );
+  if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 && (andFlags & WHERE_UNIQUE)!=0 ){
     pWInfo->okOnePass = 1;
-    pWInfo->a[0].flags &= ~WHERE_IDX_ONLY;
+    pWInfo->a[0].wsFlags &= ~WHERE_IDX_ONLY;
   }
 
   /* Open all tables in the pTabList and any indices selected for
   ** searching those tables.
@@ -79067,9 +81027,9 @@
         zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias);
       }
       if( (pIx = pLevel->pIdx)!=0 ){
         zMsg = sqlite3MAppendf(db, zMsg, "%s WITH INDEX %s", zMsg, pIx->zName);
-      }else if( pLevel->flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
+      }else if( pLevel->wsFlags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
         zMsg = sqlite3MAppendf(db, zMsg, "%s USING PRIMARY KEY", zMsg);
       }
 #ifndef SQLITE_OMIT_VIRTUALTABLE
       else if( pLevel->pBestIdx ){
@@ -79077,9 +81037,9 @@
         zMsg = sqlite3MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg,
                     pBestIdx->idxNum, pBestIdx->idxStr);
       }
 #endif
-      if( pLevel->flags & WHERE_ORDERBY ){
+      if( pLevel->wsFlags & WHERE_ORDERBY ){
         zMsg = sqlite3MAppendf(db, zMsg, "%s ORDER BY", zMsg);
       }
       sqlite3VdbeAddOp4(v, OP_Explain, i, pLevel->iFrom, 0, zMsg, P4_DYNAMIC);
     }
@@ -79094,9 +81054,9 @@
       sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0,
                         (const char*)pTab->pVtab, P4_VTAB);
     }else
 #endif
-    if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){
+    if( (pLevel->wsFlags & WHERE_IDX_ONLY)==0 ){
       int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead;
       sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op);
       if( !pWInfo->okOnePass && pTab->nCol<BMS ){
         Bitmask b = pTabItem->colUsed;
@@ -79129,9 +81089,9 @@
   for(i=0, pLevel=pWInfo->a; i<pTabList->nSrc; i++, pLevel++){
     int j, k;
     int iCur = pTabItem->iCursor;  /* The VDBE cursor for the table */
     Index *pIdx;       /* The index we will be using */
-    int nxt;           /* Where to jump to continue with the next IN case */
+    int addrNxt;           /* Where to jump to continue with the next IN case */
     int iIdxCur;       /* The VDBE cursor for the index */
     int omitTable;     /* True if we use the index only */
     int bRev;          /* True if we need to scan in reverse order */
 
@@ -79138,23 +81098,23 @@
     pTabItem = &pTabList->a[pLevel->iFrom];
     iCur = pTabItem->iCursor;
     pIdx = pLevel->pIdx;
     iIdxCur = pLevel->iIdxCur;
-    bRev = (pLevel->flags & WHERE_REVERSE)!=0;
-    omitTable = (pLevel->flags & WHERE_IDX_ONLY)!=0;
+    bRev = (pLevel->wsFlags & WHERE_REVERSE)!=0;
+    omitTable = (pLevel->wsFlags & WHERE_IDX_ONLY)!=0;
 
     /* Create labels for the "break" and "continue" instructions
-    ** for the current loop.  Jump to brk to break out of a loop.
+    ** for the current loop.  Jump to addrBrk to break out of a loop.
     ** Jump to cont to go immediately to the next iteration of the
     ** loop.
     **
-    ** When there is an IN operator, we also have a "nxt" label that
+    ** When there is an IN operator, we also have a "addrNxt" label that
     ** means to continue with the next IN value combination.  When
-    ** there are no IN operators in the constraints, the "nxt" label
-    ** is the same as "brk".
-    */
-    brk = pLevel->brk = pLevel->nxt = sqlite3VdbeMakeLabel(v);
-    cont = pLevel->cont = sqlite3VdbeMakeLabel(v);
+    ** there are no IN operators in the constraints, the "addrNxt" label
+    ** is the same as "addrBrk".
+    */
+    addrBrk = pLevel->addrBrk = pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
+    addrCont = pLevel->addrCont = sqlite3VdbeMakeLabel(v);
 
     /* If this is the right table of a LEFT OUTER JOIN, allocate and
     ** initialize a memory cell that records if this table matches any
     ** row of the left table of the join.
@@ -79169,9 +81129,8 @@
     if( pLevel->pBestIdx ){
       /* Case 0:  The table is a virtual-table.  Use the VFilter and VNext
       **          to access the data.
       */
-      int j;
       int iReg;   /* P3 Value for OP_VFilter */
       sqlite3_index_info *pBestIdx = pLevel->pBestIdx;
       int nConstraint = pBestIdx->nConstraint;
       struct sqlite3_index_constraint_usage *aUsage =
@@ -79181,9 +81140,8 @@
 
       iReg = sqlite3GetTempRange(pParse, nConstraint+2);
       pParse->disableColCache++;
       for(j=1; j<=nConstraint; j++){
-        int k;
         for(k=0; k<nConstraint; k++){
           if( aUsage[k].argvIndex==j ){
             int iTerm = aConstraint[k].iTermOffset;
             assert( pParse->disableColCache );
@@ -79196,9 +81154,9 @@
       assert( pParse->disableColCache );
       pParse->disableColCache--;
       sqlite3VdbeAddOp2(v, OP_Integer, pBestIdx->idxNum, iReg);
       sqlite3VdbeAddOp2(v, OP_Integer, j-1, iReg+1);
-      sqlite3VdbeAddOp4(v, OP_VFilter, iCur, brk, iReg, pBestIdx->idxStr,
+      sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrBrk, iReg, pBestIdx->idxStr,
                         pBestIdx->needToFreeIdxStr ? P4_MPRINTF : P4_STATIC);
       sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
       pBestIdx->needToFreeIdxStr = 0;
       for(j=0; j<nConstraint; j++){
@@ -79212,9 +81170,9 @@
       pLevel->p2 = sqlite3VdbeCurrentAddr(v);
     }else
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
 
-    if( pLevel->flags & WHERE_ROWID_EQ ){
+    if( pLevel->wsFlags & WHERE_ROWID_EQ ){
       /* Case 1:  We can directly reference a single row using an
       **          equality comparison against the ROWID field.  Or
       **          we reference multiple rows using a "rowid IN (...)"
       **          construct.
@@ -79226,15 +81184,15 @@
       assert( pTerm->pExpr!=0 );
       assert( pTerm->leftCursor==iCur );
       assert( omitTable==0 );
       r1 = codeEqualityTerm(pParse, pTerm, pLevel, rtmp);
-      nxt = pLevel->nxt;
-      sqlite3VdbeAddOp2(v, OP_MustBeInt, r1, nxt);
-      sqlite3VdbeAddOp3(v, OP_NotExists, iCur, nxt, r1);
+      addrNxt = pLevel->addrNxt;
+      sqlite3VdbeAddOp2(v, OP_MustBeInt, r1, addrNxt);
+      sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, r1);
       sqlite3ReleaseTempReg(pParse, rtmp);
       VdbeComment((v, "pk"));
       pLevel->op = OP_Noop;
-    }else if( pLevel->flags & WHERE_ROWID_RANGE ){
+    }else if( pLevel->wsFlags & WHERE_ROWID_RANGE ){
       /* Case 2:  We have an inequality comparison against the ROWID field.
       */
       int testOp = OP_Noop;
       int start;
@@ -79248,32 +81206,35 @@
         pStart = pEnd;
         pEnd = pTerm;
       }
       if( pStart ){
-        Expr *pX;
-        int r1;
+        Expr *pX;             /* The expression that defines the start bound */
+        int r1, rTemp;        /* Registers for holding the start boundary */
+
+        /* The following constant maps TK_xx codes into corresponding
+        ** seek opcodes.  It depends on a particular ordering of TK_xx
+        */
+        const u8 aMoveOp[] = {
+             /* TK_GT */  OP_SeekGt,
+             /* TK_LE */  OP_SeekLe,
+             /* TK_LT */  OP_SeekLt,
+             /* TK_GE */  OP_SeekGe
+        };
+        assert( TK_LE==TK_GT+1 );      /* Make sure the ordering.. */
+        assert( TK_LT==TK_GT+2 );      /*  ... of the TK_xx values... */
+        assert( TK_GE==TK_GT+3 );      /*  ... is correcct. */
+
         pX = pStart->pExpr;
         assert( pX!=0 );
         assert( pStart->leftCursor==iCur );
-
-        /* The ForceInt instruction may modify the register that it operates
-        ** on. For example it may replace a real value with an integer one,
-        ** or if p3 is true it may increment the register value. For this
-        ** reason we need to make sure that register r1 is really a newly
-        ** allocated temporary register, and not part of the column-cache.
-        ** For this reason we cannot use sqlite3ExprCodeTemp() here.
-        */
-        r1 = sqlite3GetTempReg(pParse);
-        sqlite3ExprCode(pParse, pX->pRight, r1);
-
-        sqlite3VdbeAddOp3(v, OP_ForceInt, r1, brk,
-                             pX->op==TK_LE || pX->op==TK_GT);
-        sqlite3VdbeAddOp3(v, bRev ? OP_MoveLt : OP_MoveGe, iCur, brk, r1);
+        r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
+        sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1);
         VdbeComment((v, "pk"));
-        sqlite3ReleaseTempReg(pParse, r1);
+        sqlite3ExprCacheAffinityChange(pParse, r1, 1);
+        sqlite3ReleaseTempReg(pParse, rTemp);
         disableTerm(pLevel, pStart);
       }else{
-        sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, brk);
+        sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrBrk);
       }
       if( pEnd ){
         Expr *pX;
         pX = pEnd->pExpr;
@@ -79295,13 +81256,13 @@
       if( testOp!=OP_Noop ){
         int r1 = sqlite3GetTempReg(pParse);
         sqlite3VdbeAddOp2(v, OP_Rowid, iCur, r1);
         /* sqlite3VdbeAddOp2(v, OP_SCopy, pLevel->iMem, 0); */
-        sqlite3VdbeAddOp3(v, testOp, pLevel->iMem, brk, r1);
+        sqlite3VdbeAddOp3(v, testOp, pLevel->iMem, addrBrk, r1);
         sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL);
         sqlite3ReleaseTempReg(pParse, r1);
       }
-    }else if( pLevel->flags & (WHERE_COLUMN_RANGE|WHERE_COLUMN_EQ) ){
+    }else if( pLevel->wsFlags & (WHERE_COLUMN_RANGE|WHERE_COLUMN_EQ) ){
       /* Case 3: A scan using an index.
       **
       **         The WHERE clause may contain zero or more equality
       **         terms ("==" or "IN" operators) that refer to the N
@@ -79336,12 +81297,12 @@
         0,
         0,
         OP_Rewind,           /* 2: (!start_constraints && startEq &&  !bRev) */
         OP_Last,             /* 3: (!start_constraints && startEq &&   bRev) */
-        OP_MoveGt,           /* 4: (start_constraints  && !startEq && !bRev) */
-        OP_MoveLt,           /* 5: (start_constraints  && !startEq &&  bRev) */
-        OP_MoveGe,           /* 6: (start_constraints  &&  startEq && !bRev) */
-        OP_MoveLe            /* 7: (start_constraints  &&  startEq &&  bRev) */
+        OP_SeekGt,           /* 4: (start_constraints  && !startEq && !bRev) */
+        OP_SeekLt,           /* 5: (start_constraints  && !startEq &&  bRev) */
+        OP_SeekGe,           /* 6: (start_constraints  &&  startEq && !bRev) */
+        OP_SeekLe            /* 7: (start_constraints  &&  startEq &&  bRev) */
       };
       int aEndOp[] = {
         OP_Noop,             /* 0: (!end_constraints) */
         OP_IdxGE,            /* 1: (end_constraints && !bRev) */
@@ -79355,18 +81316,19 @@
       WhereTerm *pRangeEnd = 0;    /* Inequality constraint at range end */
       int startEq;                 /* True if range start uses ==, >= or <= */
       int endEq;                   /* True if range end uses ==, >= or <= */
       int start_constraints;       /* Start of range is constrained */
-      int k = pIdx->aiColumn[nEq]; /* Column for inequality constraints */
       int nConstraint;             /* Number of constraint terms */
       int op;
+
+      k = pIdx->aiColumn[nEq];     /* Column for inequality constraints */
 
       /* Generate code to evaluate all constraint terms using == or IN
       ** and store the values of those terms in an array of registers
       ** starting at regBase.
       */
       regBase = codeAllEqualityTerms(pParse, pLevel, &wc, notReady, 2);
-      nxt = pLevel->nxt;
+      addrNxt = pLevel->addrNxt;
 
       /* If this loop satisfies a sort order (pOrderBy) request that
       ** was passed to this function to implement a "SELECT min(x) ..."
       ** query, then the caller will only allow the loop to run for
@@ -79374,10 +81336,10 @@
       ** should not have a NULL value stored in 'x'. If column 'x' is
       ** the first one after the nEq equality constraints in the index,
       ** this requires some special handling.
       */
-      if( (wflags&WHERE_ORDERBY_MIN)!=0
-       && (pLevel->flags&WHERE_ORDERBY)
+      if( (wctrlFlags&WHERE_ORDERBY_MIN)!=0
+       && (pLevel->wsFlags&WHERE_ORDERBY)
        && (pIdx->nColumn>nEq)
       ){
         assert( pOrderBy->nExpr==1 );
         assert( pOrderBy->a[0].pExpr->iColumn==pIdx->aiColumn[nEq] );
@@ -79386,12 +81348,12 @@
 
       /* Find any inequality constraint terms for the start and end
       ** of the range.
       */
-      if( pLevel->flags & WHERE_TOP_LIMIT ){
+      if( pLevel->wsFlags & WHERE_TOP_LIMIT ){
         pRangeEnd = findTerm(&wc, iCur, k, notReady, (WO_LT|WO_LE), pIdx);
       }
-      if( pLevel->flags & WHERE_BTM_LIMIT ){
+      if( pLevel->wsFlags & WHERE_BTM_LIMIT ){
         pRangeStart = findTerm(&wc, iCur, k, notReady, (WO_GT|WO_GE), pIdx);
       }
 
       /* If we are doing a reverse order scan on an ascending index, or
@@ -79418,9 +81380,9 @@
           pParse->disableColCache++;
         }
         sqlite3ExprCode(pParse, pRangeStart->pExpr->pRight, regBase+nEq);
         pParse->disableColCache = dcc;
-        sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, nxt);
+        sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
         nConstraint++;
       }else if( isMinQuery ){
         sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
         nConstraint++;
@@ -79431,13 +81393,13 @@
       op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
       assert( op!=0 );
       testcase( op==OP_Rewind );
       testcase( op==OP_Last );
-      testcase( op==OP_MoveGt );
-      testcase( op==OP_MoveGe );
-      testcase( op==OP_MoveLe );
-      testcase( op==OP_MoveLt );
-      sqlite3VdbeAddOp4(v, op, iIdxCur, nxt, regBase,
+      testcase( op==OP_SeekGt );
+      testcase( op==OP_SeekGe );
+      testcase( op==OP_SeekLe );
+      testcase( op==OP_SeekLt );
+      sqlite3VdbeAddOp4(v, op, iIdxCur, addrNxt, regBase,
                         SQLITE_INT_TO_PTR(nConstraint), P4_INT32);
 
       /* Load the value for the inequality constraint at the end of the
       ** range (if any).
@@ -79444,9 +81406,9 @@
       */
       nConstraint = nEq;
       if( pRangeEnd ){
         sqlite3ExprCode(pParse, pRangeEnd->pExpr->pRight, regBase+nEq);
-        sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, nxt);
+        sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
         codeApplyAffinity(pParse, regBase, nEq+1, pIdx);
         nConstraint++;
       }
 
@@ -79457,28 +81419,28 @@
       op = aEndOp[(pRangeEnd || nEq) * (1 + bRev)];
       testcase( op==OP_Noop );
       testcase( op==OP_IdxGE );
       testcase( op==OP_IdxLT );
-      sqlite3VdbeAddOp4(v, op, iIdxCur, nxt, regBase,
+      sqlite3VdbeAddOp4(v, op, iIdxCur, addrNxt, regBase,
                         SQLITE_INT_TO_PTR(nConstraint), P4_INT32);
-      sqlite3VdbeChangeP5(v, endEq!=bRev);
+      sqlite3VdbeChangeP5(v, endEq!=bRev ?1:0);
 
       /* If there are inequality constraints, check that the value
       ** of the table column that the inequality contrains is not NULL.
       ** If it is, jump to the next iteration of the loop.
       */
       r1 = sqlite3GetTempReg(pParse);
-      testcase( pLevel->flags & WHERE_BTM_LIMIT );
-      testcase( pLevel->flags & WHERE_TOP_LIMIT );
-      if( pLevel->flags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT) ){
+      testcase( pLevel->wsFlags & WHERE_BTM_LIMIT );
+      testcase( pLevel->wsFlags & WHERE_TOP_LIMIT );
+      if( pLevel->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT) ){
         sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, nEq, r1);
-        sqlite3VdbeAddOp2(v, OP_IsNull, r1, cont);
+        sqlite3VdbeAddOp2(v, OP_IsNull, r1, addrCont);
       }
 
       /* Seek the table cursor, if required */
       if( !omitTable ){
         sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, r1);
-        sqlite3VdbeAddOp3(v, OP_MoveGe, iCur, 0, r1);  /* Deferred seek */
+        sqlite3VdbeAddOp2(v, OP_Seek, iCur, r1);  /* Deferred seek */
       }
       sqlite3ReleaseTempReg(pParse, r1);
 
       /* Record the instruction used to terminate the loop. Disable
@@ -79495,9 +81457,9 @@
       assert( omitTable==0 );
       assert( bRev==0 );
       pLevel->op = OP_Next;
       pLevel->p1 = iCur;
-      pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, OP_Rewind, iCur, brk);
+      pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, OP_Rewind, iCur, addrBrk);
       pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
     }
     notReady &= ~getMask(&maskSet, iCur);
 
@@ -79506,41 +81468,41 @@
     */
     k = 0;
     for(pTerm=wc.a, j=wc.nTerm; j>0; j--, pTerm++){
       Expr *pE;
-      testcase( pTerm->flags & TERM_VIRTUAL );
-      testcase( pTerm->flags & TERM_CODED );
-      if( pTerm->flags & (TERM_VIRTUAL|TERM_CODED) ) continue;
+      testcase( pTerm->wtFlags & TERM_VIRTUAL );
+      testcase( pTerm->wtFlags & TERM_CODED );
+      if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
       if( (pTerm->prereqAll & notReady)!=0 ) continue;
       pE = pTerm->pExpr;
       assert( pE!=0 );
       if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
         continue;
       }
       pParse->disableColCache += k;
-      sqlite3ExprIfFalse(pParse, pE, cont, SQLITE_JUMPIFNULL);
+      sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL);
       pParse->disableColCache -= k;
       k = 1;
-      pTerm->flags |= TERM_CODED;
+      pTerm->wtFlags |= TERM_CODED;
     }
 
     /* For a LEFT OUTER JOIN, generate code that will record the fact that
     ** at least one row of the right table has matched the left table.
     */
     if( pLevel->iLeftJoin ){
-      pLevel->top = sqlite3VdbeCurrentAddr(v);
+      pLevel->addrFirst = sqlite3VdbeCurrentAddr(v);
       sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
       VdbeComment((v, "record LEFT JOIN hit"));
       sqlite3ExprClearColumnCache(pParse, pLevel->iTabCur);
       sqlite3ExprClearColumnCache(pParse, pLevel->iIdxCur);
       for(pTerm=wc.a, j=0; j<wc.nTerm; j++, pTerm++){
-        testcase( pTerm->flags & TERM_VIRTUAL );
-        testcase( pTerm->flags & TERM_CODED );
-        if( pTerm->flags & (TERM_VIRTUAL|TERM_CODED) ) continue;
+        testcase( pTerm->wtFlags & TERM_VIRTUAL );
+        testcase( pTerm->wtFlags & TERM_CODED );
+        if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
         if( (pTerm->prereqAll & notReady)!=0 ) continue;
         assert( pTerm->pExpr );
-        sqlite3ExprIfFalse(pParse, pTerm->pExpr, cont, SQLITE_JUMPIFNULL);
-        pTerm->flags |= TERM_CODED;
+        sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
+        pTerm->wtFlags |= TERM_CODED;
       }
     }
   }
 
@@ -79557,11 +81519,11 @@
     pLevel = &pWInfo->a[i];
     pTabItem = &pTabList->a[pLevel->iFrom];
     z = pTabItem->zAlias;
     if( z==0 ) z = pTabItem->pTab->zName;
-    n = strlen(z);
+    n = sqlite3Strlen30(z);
     if( n+nQPlan < sizeof(sqlite3_query_plan)-10 ){
-      if( pLevel->flags & WHERE_IDX_ONLY ){
+      if( pLevel->wsFlags & WHERE_IDX_ONLY ){
         memcpy(&sqlite3_query_plan[nQPlan], "{}", 2);
         nQPlan += 2;
       }else{
         memcpy(&sqlite3_query_plan[nQPlan], z, n);
@@ -79568,18 +81530,18 @@
         nQPlan += n;
       }
       sqlite3_query_plan[nQPlan++] = ' ';
     }
-    testcase( pLevel->flags & WHERE_ROWID_EQ );
-    testcase( pLevel->flags & WHERE_ROWID_RANGE );
-    if( pLevel->flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
+    testcase( pLevel->wsFlags & WHERE_ROWID_EQ );
+    testcase( pLevel->wsFlags & WHERE_ROWID_RANGE );
+    if( pLevel->wsFlags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
       memcpy(&sqlite3_query_plan[nQPlan], "* ", 2);
       nQPlan += 2;
     }else if( pLevel->pIdx==0 ){
       memcpy(&sqlite3_query_plan[nQPlan], "{} ", 3);
       nQPlan += 3;
     }else{
-      n = strlen(pLevel->pIdx->zName);
+      n = sqlite3Strlen30(pLevel->pIdx->zName);
       if( n+nQPlan < sizeof(sqlite3_query_plan)-2 ){
         memcpy(&sqlite3_query_plan[nQPlan], pLevel->pIdx->zName, n);
         nQPlan += n;
         sqlite3_query_plan[nQPlan++] = ' ';
@@ -79595,9 +81557,9 @@
 
   /* Record the continuation address in the WhereInfo structure.  Then
   ** clean up and return.
   */
-  pWInfo->iContinue = cont;
+  pWInfo->iContinue = addrCont;
   whereClauseClear(&wc);
   return pWInfo;
 
   /* Jump here if malloc fails */
@@ -79623,33 +81585,33 @@
   */
   sqlite3ExprClearColumnCache(pParse, -1);
   for(i=pTabList->nSrc-1; i>=0; i--){
     pLevel = &pWInfo->a[i];
-    sqlite3VdbeResolveLabel(v, pLevel->cont);
+    sqlite3VdbeResolveLabel(v, pLevel->addrCont);
     if( pLevel->op!=OP_Noop ){
       sqlite3VdbeAddOp2(v, pLevel->op, pLevel->p1, pLevel->p2);
       sqlite3VdbeChangeP5(v, pLevel->p5);
     }
     if( pLevel->nIn ){
       struct InLoop *pIn;
       int j;
-      sqlite3VdbeResolveLabel(v, pLevel->nxt);
+      sqlite3VdbeResolveLabel(v, pLevel->addrNxt);
       for(j=pLevel->nIn, pIn=&pLevel->aInLoop[j-1]; j>0; j--, pIn--){
-        sqlite3VdbeJumpHere(v, pIn->topAddr+1);
-        sqlite3VdbeAddOp2(v, OP_Next, pIn->iCur, pIn->topAddr);
-        sqlite3VdbeJumpHere(v, pIn->topAddr-1);
+        sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
+        sqlite3VdbeAddOp2(v, OP_Next, pIn->iCur, pIn->addrInTop);
+        sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
       }
       sqlite3DbFree(db, pLevel->aInLoop);
     }
-    sqlite3VdbeResolveLabel(v, pLevel->brk);
+    sqlite3VdbeResolveLabel(v, pLevel->addrBrk);
     if( pLevel->iLeftJoin ){
       int addr;
       addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin);
       sqlite3VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor);
       if( pLevel->iIdxCur>=0 ){
         sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur);
       }
-      sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->top);
+      sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrFirst);
       sqlite3VdbeJumpHere(v, addr);
     }
   }
 
@@ -79664,9 +81626,9 @@
     struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom];
     Table *pTab = pTabItem->pTab;
     assert( pTab!=0 );
     if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ) continue;
-    if( !pWInfo->okOnePass && (pLevel->flags & WHERE_IDX_ONLY)==0 ){
+    if( !pWInfo->okOnePass && (pLevel->wsFlags & WHERE_IDX_ONLY)==0 ){
       sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
     }
     if( pLevel->pIdx!=0 ){
       sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur);
@@ -79688,9 +81650,9 @@
     if( pLevel->pIdx ){
       int k, j, last;
       VdbeOp *pOp;
       Index *pIdx = pLevel->pIdx;
-      int useIndexOnly = pLevel->flags & WHERE_IDX_ONLY;
+      int useIndexOnly = pLevel->wsFlags & WHERE_IDX_ONLY;
 
       assert( pIdx!=0 );
       pOp = sqlite3VdbeGetOp(v, pWInfo->iTop);
       last = sqlite3VdbeCurrentAddr(v);
@@ -79813,25 +81775,26 @@
 **    YYERRORSYMBOL      is the code number of the error symbol.  If not
 **                       defined, then do no error processing.
 */
 #define YYCODETYPE unsigned char
-#define YYNOCODE 249
+#define YYNOCODE 248
 #define YYACTIONTYPE unsigned short int
 #define YYWILDCARD 59
 #define sqlite3ParserTOKENTYPE Token
 typedef union {
+  int yyinit;
   sqlite3ParserTOKENTYPE yy0;
-  Select* yy43;
-  TriggerStep* yy75;
-  struct LimitVal yy84;
-  struct LikeOp yy86;
-  struct {int value; int mask;} yy207;
-  ExprList* yy242;
-  int yy316;
-  IdList* yy352;
-  struct TrigEvent yy354;
-  SrcList* yy419;
-  Expr* yy450;
+  int yy46;
+  struct LikeOp yy72;
+  Expr* yy172;
+  ExprList* yy174;
+  Select* yy219;
+  struct LimitVal yy234;
+  TriggerStep* yy243;
+  struct TrigEvent yy370;
+  SrcList* yy373;
+  struct {int value; int mask;} yy405;
+  IdList* yy432;
 } YYMINORTYPE;
 #ifndef YYSTACKDEPTH
 #define YYSTACKDEPTH 100
 #endif
@@ -79838,22 +81801,19 @@
 #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 598
-#define YYNRULE 315
+#define YYNSTATE 601
+#define YYNRULE 314
 #define YYFALLBACK 1
 #define YY_NO_ACTION      (YYNSTATE+YYNRULE+2)
 #define YY_ACCEPT_ACTION  (YYNSTATE+YYNRULE+1)
 #define YY_ERROR_ACTION   (YYNSTATE+YYNRULE)
 
 /* The yyzerominor constant is used to initialize instances of
 ** YYMINORTYPE objects to zero. */
-#if 0
-static YYMINORTYPE yyzerominor;
-#else
-static const YYMINORTYPE yyzerominor;
-#endif
+static const YYMINORTYPE yyzerominor = { 0 };
+
 
 /* Next are the tables used to determine what action to take based on the
 ** current state and lookahead token.  These tables are used to implement
 ** functions that take a state number and lookahead value and return an
@@ -79901,422 +81861,425 @@
 **                     shifting non-terminals after a reduce.
 **  yy_default[]       Default action for each state.
 */
 static const YYACTIONTYPE yy_action[] = {
- /*     0 */   296,  914,  120,  597,    2,  172,  425,  425,   62,   62,
- /*    10 */    62,   62,  210,   64,   64,   64,   64,   65,   65,   66,
- /*    20 */    66,   66,   67,  212,  398,  395,  432,  438,   69,   64,
- /*    30 */    64,   64,   64,   65,   65,   66,   66,   66,   67,  212,
- /*    40 */   458,  456,  327,  168,   61,   60,  301,  442,  443,  439,
- /*    50 */   439,   63,   63,   62,   62,   62,   62,  256,   64,   64,
- /*    60 */    64,   64,   65,   65,   66,   66,   66,   67,  212,  296,
- /*    70 */   498,  425,  425,  212,  427,   83,   68,  469,   70,  154,
+ /*     0 */   299,  916,  120,  600,    2,  175,  427,  427,   62,   62,
+ /*    10 */    62,   62,  487,   64,   64,   64,   64,   65,   65,   66,
+ /*    20 */    66,   66,   67,  213,  400,  397,  434,  440,   69,   64,
+ /*    30 */    64,   64,   64,   65,   65,   66,   66,   66,   67,  213,
+ /*    40 */   460,  458,  330,  171,   61,   60,  304,  444,  445,  441,
+ /*    50 */   441,   63,   63,   62,   62,   62,   62,  259,   64,   64,
+ /*    60 */    64,   64,   65,   65,   66,   66,   66,   67,  213,  299,
+ /*    70 */   501,  427,  427,  306,  429,   83,   68,  471,   70,  155,
  /*    80 */    64,   64,   64,   64,   65,   65,   66,   66,   66,   67,
- /*    90 */   212,   68,  307,   70,  154,  432,  438,  454,  214,   59,
- /*   100 */    65,   65,   66,   66,   66,   67,  212,  429,  429,  429,
- /*   110 */   497,  583,  296,   61,   60,  301,  442,  443,  439,  439,
- /*   120 */    63,   63,   62,   62,   62,   62,  321,   64,   64,   64,
- /*   130 */    64,   65,   65,   66,   66,   66,   67,  212,  432,  438,
- /*   140 */    95,   66,   66,   66,   67,  212,  403,  256,  421,   35,
- /*   150 */    57,   67,  212,  175,  417,  499,   61,   60,  301,  442,
- /*   160 */   443,  439,  439,   63,   63,   62,   62,   62,   62,   19,
+ /*    90 */   213,   68,  310,   70,  155,  434,  440,  456,  215,   59,
+ /*   100 */    65,   65,   66,   66,   66,   67,  213,  431,  431,  431,
+ /*   110 */   211,  586,  299,   61,   60,  304,  444,  445,  441,  441,
+ /*   120 */    63,   63,   62,   62,   62,   62,  324,   64,   64,   64,
+ /*   130 */    64,   65,   65,   66,   66,   66,   67,  213,  434,  440,
+ /*   140 */    95,  320,  402,  483,  598,  907,  210,  907,  423,   35,
+ /*   150 */    57,   67,  213,  203,  419,  271,   61,   60,  304,  444,
+ /*   160 */   445,  441,  441,   63,   63,   62,   62,   62,   62,  213,
  /*   170 */    64,   64,   64,   64,   65,   65,   66,   66,   66,   67,
- /*   180 */   212,  296,  225,  532,  299,  581,  109,  422,  242,  458,
- /*   190 */   416,  335,  414,   21,  502,  503,  346,  403,  527,  176,
- /*   200 */   160,  454,  214,  580,  579,  344,  500,  432,  438,  149,
- /*   210 */   150,  404,  405,  539,  514,  418,  151,  541,    8,  498,
- /*   220 */   538,  577,  578,  427,  296,   61,   60,  301,  442,  443,
- /*   230 */   439,  439,   63,   63,   62,   62,   62,   62,  196,   64,
- /*   240 */    64,   64,   64,   65,   65,   66,   66,   66,   67,  212,
- /*   250 */   432,  438,  454,  598,  398,  395,  429,  429,  429,  369,
- /*   260 */   558,  481,  404,  405,  372,  576,  213,  296,   61,   60,
- /*   270 */   301,  442,  443,  439,  439,   63,   63,   62,   62,   62,
- /*   280 */    62,  321,   64,   64,   64,   64,   65,   65,   66,   66,
- /*   290 */    66,   67,  212,  432,  438,  555,  503,  304,  557,  532,
- /*   300 */   218,  557,  552,  421,   36,  234,  397,    2,  542,   21,
- /*   310 */   540,   61,   60,  301,  442,  443,  439,  439,   63,   63,
- /*   320 */    62,   62,   62,   62,  388,   64,   64,   64,   64,   65,
- /*   330 */    65,   66,   66,   66,   67,  212,  415,  530,   85,  381,
- /*   340 */    78,  323,  296,  210,  304,  527,  493,  492,  379,  274,
- /*   350 */   273,  379,  274,  273,  347,  463,  241,  387,  268,  210,
- /*   360 */   533,  581,  210,  403,   20,  224,  144,  464,  432,  438,
- /*   370 */   485,  164,  114,  248,  349,  253,  350,  177,  554,  580,
- /*   380 */   465,  420,  331,   81,  257,  419,   61,   60,  301,  442,
- /*   390 */   443,  439,  439,   63,   63,   62,   62,   62,   62,  391,
+ /*   180 */   213,  299,  492,  535,  595,  584,  109,  424,  465,  460,
+ /*   190 */   338,  500,  416,   20,  522,  348,  272,  405,  324,   68,
+ /*   200 */   466,   70,  155,  583,  582,  542,  517,  434,  440,  150,
+ /*   210 */   151,  388,  541,  467,  523,  334,  152,  544,  271,  501,
+ /*   220 */   423,   42,  502,  429,  299,   61,   60,  304,  444,  445,
+ /*   230 */   441,  441,   63,   63,   62,   62,   62,   62,  396,   64,
+ /*   240 */    64,   64,   64,   65,   65,   66,   66,   66,   67,  213,
+ /*   250 */   434,  440,  456,  601,  400,  397,  431,  431,  431,  569,
+ /*   260 */   561,  217,  406,  407,  579,  214,  309,  299,   61,   60,
+ /*   270 */   304,  444,  445,  441,  441,   63,   63,   62,   62,   62,
+ /*   280 */    62,  324,   64,   64,   64,   64,   65,   65,   66,   66,
+ /*   290 */    66,   67,  213,  434,  440,  405,  543,  307,  560,  505,
+ /*   300 */   506,  560,  536,  423,   36,  195,   66,   66,   66,   67,
+ /*   310 */   213,   61,   60,  304,  444,  445,  441,  441,   63,   63,
+ /*   320 */    62,   62,   62,   62,  183,   64,   64,   64,   64,   65,
+ /*   330 */    65,   66,   66,   66,   67,  213,  417,  533,  584,  424,
+ /*   340 */    78,  271,  299,  259,  307,  530,  496,  236,  381,  277,
+ /*   350 */   276,  381,  277,  276,  553,  242,  583,  153,  552,  211,
+ /*   360 */   406,  407,  211,  379,   68,  225,   70,  155,  434,  440,
+ /*   370 */   370,  167,  114,  251,  351,  256,  352,  178,  226,  175,
+ /*   380 */    17,  427,  393,   81,  260,  382,   61,   60,  304,  444,
+ /*   390 */   445,  441,  441,   63,   63,   62,   62,   62,   62,  514,
  /*   400 */    64,   64,   64,   64,   65,   65,   66,   66,   66,   67,
- /*   410 */   212,  296,  224,  203,  249,  496,  403,  440,  837,  114,
- /*   420 */   248,  349,  253,  350,  177,  250,  321,  152,  404,  405,
- /*   430 */   321,  257,  303,  324,  155,  445,  445,  432,  438,  317,
- /*   440 */   400,  389,  213,   68,  209,   70,  154,  422,  421,   35,
- /*   450 */   393,  202,  421,   42,  481,   61,   60,  301,  442,  443,
- /*   460 */   439,  439,   63,   63,   62,   62,   62,   62,  422,   64,
- /*   470 */    64,   64,   64,   65,   65,   66,   66,   66,   67,  212,
- /*   480 */   296,  404,  405,  183,  513,  422,  351,  354,  355,  403,
- /*   490 */    77,  335,   79,  489,  216,  183,  334,  356,  351,  354,
- /*   500 */   355,  433,  434,  406,  407,  408,  432,  438,  235,  356,
- /*   510 */   386,   68,  291,   70,  154,  456,  531,  168,  198,  302,
- /*   520 */   449,  450,  436,  437,   61,   60,  301,  442,  443,  439,
- /*   530 */   439,   63,   63,   62,   62,   62,   62,  394,   64,   64,
- /*   540 */    64,   64,   65,   65,   66,   66,   66,   67,  212,  296,
- /*   550 */   321,  435,  422,  260,  404,  405,  321,  183,  153,  321,
- /*   560 */   351,  354,  355,  446,  332,  321,  595,  905,  321,  905,
- /*   570 */     1,  356,  421,   28,  403,  432,  438,  376,  421,   42,
- /*   580 */   477,  421,   35,  213,  548,  366,  548,  421,   50,  159,
- /*   590 */   421,   50,  422,   61,   60,  301,  442,  443,  439,  439,
- /*   600 */    63,   63,   62,   62,   62,   62,  592,   64,   64,   64,
- /*   610 */    64,   65,   65,   66,   66,   66,   67,  212,  296,  337,
- /*   620 */   217,  463,  256,   94,  339,  326,  449,  450,  172,  340,
- /*   630 */   425,  345,  532,  464,  312,  595,  904,  313,  904,  404,
- /*   640 */   405,  588,   21,  226,  432,  438,  465,  243,  504,  324,
- /*   650 */   322,  445,  445,  421,    3,  459,  230,  308,  505,  194,
- /*   660 */   278,  296,   61,   60,  301,  442,  443,  439,  439,   63,
- /*   670 */    63,   62,   62,   62,   62,  592,   64,   64,   64,   64,
- /*   680 */    65,   65,   66,   66,   66,   67,  212,  432,  438,  213,
- /*   690 */   179,  180,  181,  422,  324,  425,  445,  445,  281,  262,
- /*   700 */   279,  402,  194,  481,  296,   61,   60,  301,  442,  443,
- /*   710 */   439,  439,   63,   63,   62,   62,   62,   62,  377,   64,
- /*   720 */    64,   64,   64,   65,   65,   66,   66,   66,   67,  212,
- /*   730 */   432,  438,  591,  295,  115,  268,  422,  266,  211,  264,
- /*   740 */   373,  324,  246,  445,  445,   56,  256,  296,   61,   71,
- /*   750 */   301,  442,  443,  439,  439,   63,   63,   62,   62,   62,
- /*   760 */    62,  377,   64,   64,   64,   64,   65,   65,   66,   66,
- /*   770 */    66,   67,  212,  432,  438,  550,  269,  474,   18,  549,
- /*   780 */   280,  309,  343,  380,  171,  160,  256,  268,    5,  268,
- /*   790 */   296,  368,   60,  301,  442,  443,  439,  439,   63,   63,
- /*   800 */    62,   62,   62,   62,  321,   64,   64,   64,   64,   65,
- /*   810 */    65,   66,   66,   66,   67,  212,  432,  438,  403,   10,
- /*   820 */   403,  310,  268,  403,  268,  485,  421,   29,  566,   22,
- /*   830 */   568,  420,  428,  425,  376,  419,  301,  442,  443,  439,
- /*   840 */   439,   63,   63,   62,   62,   62,   62,  321,   64,   64,
- /*   850 */    64,   64,   65,   65,   66,   66,   66,   67,  212,   73,
- /*   860 */   328,  485,    4,  569,  268,  570,  300,  268,  147,  421,
- /*   870 */    24,  321,  359,  321,  325,   73,  328,  491,    4,  455,
- /*   880 */   321,  342,  300,  404,  405,  404,  405,  367,  404,  405,
- /*   890 */   325,  330,  321,  421,   33,  421,   54,  321,  425,  178,
- /*   900 */   229,  458,  421,   53,  321,  227,  321,  330,  228,  478,
- /*   910 */   165,  321,  315,  119,  421,   99,  333,  458,  321,  421,
- /*   920 */    97,   76,   75,  311,  268,  519,  421,  102,  421,  103,
- /*   930 */    74,  319,  320,  421,  108,  427,  467,   76,   75,  490,
- /*   940 */   421,  110,  452,  452,  321,  520,   74,  319,  320,   73,
- /*   950 */   328,  427,    4,  210,  298,  321,  300,  321,  156,  257,
- /*   960 */   321,  210,  185,  182,  325,  284,  421,   17,  429,  429,
- /*   970 */   429,  430,  431,   12,  593,  378,  188,  421,  100,  421,
- /*   980 */    34,  330,  421,   98,  429,  429,  429,  430,  431,   12,
- /*   990 */   475,  458,  422,  162,  480,  321,  422,  306,  231,  232,
- /*  1000 */   233,  105,  484,  632,  476,  321,  486,  447,  321,   23,
- /*  1010 */   422,   76,   75,  594,  207,  178,  286,  421,   25,  254,
- /*  1020 */    74,  319,  320,  287,  321,  427,  321,  421,   55,  321,
- /*  1030 */   421,  111,  321,  471,  321,  205,  515,  557,  511,  363,
- /*  1040 */   472,  204,  321,  516,  206,  321,  421,  112,  421,  113,
- /*  1050 */   321,  421,   26,  321,  421,   37,  421,   38,  429,  429,
- /*  1060 */   429,  430,  431,   12,  421,   27,  521,  421,   39,  321,
- /*  1070 */   298,  158,  421,   40,  255,  421,   41,  321,  483,  321,
- /*  1080 */   173,  523,  321,  182,  321,  522,  321,  384,  283,  273,
- /*  1090 */   321,  421,   43,  297,  534,  321,  476,  321,  210,  421,
- /*  1100 */    44,  421,   45,  321,  421,   30,  421,   31,  421,   46,
- /*  1110 */   508,  509,  421,   47,  259,  321,  182,  421,   48,  421,
- /*  1120 */    49,  321,  358,  390,  182,  421,   32,  321,  261,  518,
- /*  1130 */   517,  553,  561,  182,  173,  412,  191,  421,   11,  562,
- /*  1140 */   573,   92,   92,  421,   51,  590,  263,  294,  265,  421,
- /*  1150 */    52,  267,  272,  371,  146,  374,  375,  275,  276,  277,
- /*  1160 */   565,  575,  285,  288,  289,  587,  470,  451,  236,  453,
- /*  1170 */   329,  244,  473,  514,  251,  524,  560,  163,  401,  572,
- /*  1180 */   426,  525,  282,  528,  409,    7,  410,  411,  385,  318,
- /*  1190 */    85,  237,  338,  526,   84,  336,  353,   58,   80,  215,
- /*  1200 */   170,  468,  121,   86,  341,  348,  305,  501,  506,  124,
- /*  1210 */   511,  222,  360,  423,  252,  186,  512,  510,  221,  223,
- /*  1220 */   238,  507,  239,  535,  240,  292,  424,  529,  536,  537,
- /*  1230 */   293,  543,  187,  189,  245,  362,  482,  488,  247,  190,
- /*  1240 */   364,   89,  545,  192,  117,  370,  132,  556,  563,  195,
- /*  1250 */   382,  383,  314,  133,  134,  571,  138,  135,  136,  584,
- /*  1260 */   589,  585,  142,  399,  101,  413,  220,  586,  270,  104,
- /*  1270 */   141,  633,  634,  166,  167,  441,  444,   72,  460,  448,
- /*  1280 */   457,  546,  143,  157,    6,  461,   14,  479,  169,  462,
- /*  1290 */    93,  466,   82,  122,   13,  174,  487,   96,  123,  161,
- /*  1300 */   494,  495,   87,  125,  126,  116,  258,   88,  127,  184,
- /*  1310 */   250,  361,  219,  107,  544,  145,  128,  193,  365,  118,
- /*  1320 */   352,  357,  173,  271,  130,    9,  316,  559,  197,   90,
- /*  1330 */   547,  131,  129,   15,  199,  551,  564,  200,  567,  201,
- /*  1340 */   139,  137,  582,   91,   16,  106,  140,  208,  574,  392,
- /*  1350 */   396,  290,  148,  596,
+ /*   410 */   213,  299,  225,  558,  506,  499,  405,  391,  214,  114,
+ /*   420 */   251,  351,  256,  352,  178,  184,  324,  418,  353,  356,
+ /*   430 */   357,  260,  395,  378,  156,  530,  405,  434,  440,  358,
+ /*   440 */   184,  535,  243,  353,  356,  357,  427,  235,  423,   35,
+ /*   450 */   545,   20,  399,    2,  358,   61,   60,  304,  444,  445,
+ /*   460 */   441,  441,   63,   63,   62,   62,   62,   62,  424,   64,
+ /*   470 */    64,   64,   64,   65,   65,   66,   66,   66,   67,  213,
+ /*   480 */   299,  406,  407,  184,  516,  503,  353,  356,  357,  204,
+ /*   490 */   338,  456,  215,  324,  420,  337,  422,  358,  227,  324,
+ /*   500 */   421,  406,  407,  195,  535,  335,  434,  440,  305,  451,
+ /*   510 */   452,  580,  581,  591,   20,  423,   42,  329,  451,  452,
+ /*   520 */   162,  423,   35,  424,   61,   60,  304,  444,  445,  441,
+ /*   530 */   441,   63,   63,   62,   62,   62,   62,  424,   64,   64,
+ /*   540 */    64,   64,   65,   65,   66,   66,   66,   67,  213,  299,
+ /*   550 */   324,  495,  465,  263,  424,  340,  218,  160,  154,  324,
+ /*   560 */   343,  379,  448,  342,  466,  324,  163,  161,  461,  435,
+ /*   570 */   436,  214,  423,   28,   21,  434,  440,  467,  427,  507,
+ /*   580 */   214,  423,   50,  375,  408,  409,  410,  423,   50,  508,
+ /*   590 */   438,  439,  424,   61,   60,  304,  444,  445,  441,  441,
+ /*   600 */    63,   63,   62,   62,   62,   62,  347,   64,   64,   64,
+ /*   610 */    64,   65,   65,   66,   66,   66,   67,  213,  299,  437,
+ /*   620 */   281,  294,  555,   94,  458,  534,  171,  315,  423,    3,
+ /*   630 */     1,  594,  298,  316,  405,  598,  906,  327,  906,  447,
+ /*   640 */   447,  244,  212,  427,  434,  440,  123,  477,  327,   56,
+ /*   650 */   447,  447,  174,  161,  327,  325,  447,  447,  284,  383,
+ /*   660 */   282,  299,   61,   60,  304,  444,  445,  441,  441,   63,
+ /*   670 */    63,   62,   62,   62,   62,  595,   64,   64,   64,   64,
+ /*   680 */    65,   65,   66,   66,   66,   67,  213,  434,  440,  551,
+ /*   690 */   368,  551,  124,  327,  478,  447,  447,  483,  557,  406,
+ /*   700 */   407,  265,  302,  483,  299,   61,   60,  304,  444,  445,
+ /*   710 */   441,  441,   63,   63,   62,   62,   62,   62,  405,   64,
+ /*   720 */    64,   64,   64,   65,   65,   66,   66,   66,   67,  213,
+ /*   730 */   434,  440,  327,  404,  447,  447,  219,  271,  839,  269,
+ /*   740 */   283,  267,  247,  180,  181,  182,  483,  299,   61,   71,
+ /*   750 */   304,  444,  445,  441,  441,   63,   63,   62,   62,   62,
+ /*   760 */    62,  159,   64,   64,   64,   64,   65,   65,   66,   66,
+ /*   770 */    66,   67,  213,  434,  440,  494,  371,  211,  571,  231,
+ /*   780 */   271,  374,  346,  406,  407,  249,  478,  259,  271,  259,
+ /*   790 */   299,  380,   60,  304,  444,  445,  441,  441,   63,   63,
+ /*   800 */    62,   62,   62,   62,  349,   64,   64,   64,   64,   65,
+ /*   810 */    65,   66,   66,   66,   67,  213,  434,  440,  405,   23,
+ /*   820 */   405,  572,  311,  405,  312,  115,  487,  271,  259,  573,
+ /*   830 */     5,  422,   19,  478,  145,  421,  304,  444,  445,  441,
+ /*   840 */   441,   63,   63,   62,   62,   62,   62,  324,   64,   64,
+ /*   850 */    64,   64,   65,   65,   66,   66,   66,   67,  213,   73,
+ /*   860 */   331,  430,    4,  313,  271,  457,  303,  271,  228,  423,
+ /*   870 */    29,  324,  361,  324,  328,   73,  331,   77,    4,   79,
+ /*   880 */   324,  345,  303,  406,  407,  406,  407,  369,  406,  407,
+ /*   890 */   328,  333,  336,  423,   24,  423,   33,  324,  378,  179,
+ /*   900 */   159,  460,  423,   54,  324,  229,  324,  333,  287,  479,
+ /*   910 */   179,  480,  476,  487,  168,  318,  119,  460,  324,  423,
+ /*   920 */    53,   76,   75,  469,  199,  478,  423,   99,  423,   97,
+ /*   930 */    74,  322,  323,  454,  454,  429,  473,   76,   75,  493,
+ /*   940 */   423,  102,  390,  474,  324,  365,   74,  322,  323,   73,
+ /*   950 */   331,  429,    4,  211,  301,  324,  303,  324,  424,  260,
+ /*   960 */   324,  211,  157,  230,  328,  301,  423,  103,  431,  431,
+ /*   970 */   431,  432,  433,   11,  314,  389,  186,  423,  108,  423,
+ /*   980 */   110,  333,  423,   16,  431,  431,  431,  432,  433,   11,
+ /*   990 */   326,  460,  189,  165,  197,  324,  424,  596,  232,  233,
+ /*  1000 */   234,  105,  449,  148,   22,  324,  482,  635,  324,  486,
+ /*  1010 */   424,   76,   75,  485,  208,  176,  289,  423,  100,  488,
+ /*  1020 */    74,  322,  323,  290,  324,  429,  424,  423,   34,  324,
+ /*  1030 */   423,   98,  324,   18,  324,  206,  597,  560,  511,  512,
+ /*  1040 */   257,  205,  324,  519,  207,  324,  423,   25,  324,  518,
+ /*  1050 */   324,  423,   55,  324,  423,  111,  423,  112,  431,  431,
+ /*  1060 */   431,  432,  433,   11,  423,  113,  442,  423,   26,  324,
+ /*  1070 */   423,   37,  423,   38,  258,  423,   27,  324,  524,  324,
+ /*  1080 */   521,  520,    8,  526,  324,  183,  324,  386,  286,  276,
+ /*  1090 */   324,  423,   39,  300,   85,  324,  525,  324,  211,  423,
+ /*  1100 */    40,  423,   41,  324,  537,  324,  423,   43,  423,   44,
+ /*  1110 */   264,  252,  423,   45,  262,  324,  183,  423,   30,  423,
+ /*  1120 */    31,  324,  253,  392,  266,  423,   46,  423,   47,  324,
+ /*  1130 */   360,  324,  183,  324,  556,  324,  183,  423,   48,  564,
+ /*  1140 */   565,  176,   92,  423,   49,  268,  576,  593,   92,  297,
+ /*  1150 */   270,  423,   32,  423,   10,  423,   51,  423,   52,  192,
+ /*  1160 */   275,  373,  147,  376,  377,  278,  279,  428,  280,  568,
+ /*  1170 */   578,  288,  291,  292,  590,  453,  332,  414,  237,  455,
+ /*  1180 */   472,  475,  254,  245,  517,  355,  563,  166,  403,  575,
+ /*  1190 */   411,  528,  412,  413,  531,  285,    7,  387,   85,  321,
+ /*  1200 */   425,  527,  341,  529,   84,  339,   58,  173,   80,  216,
+ /*  1210 */   470,  121,  308,   86,  344,  350,  125,  223,  514,  362,
+ /*  1220 */   187,  504,  509,  546,  255,  222,  515,  513,  238,  224,
+ /*  1230 */   239,  510,  240,  538,  241,  295,  426,  539,  540,  532,
+ /*  1240 */   188,  190,  296,  364,  246,  191,  484,  490,  248,  548,
+ /*  1250 */   366,  193,  117,  250,   89,  491,  372,  559,  196,  133,
+ /*  1260 */   384,  385,  134,  135,  566,  317,  136,  137,  587,  588,
+ /*  1270 */   592,  139,  401,  101,  221,  574,  104,  143,  589,  142,
+ /*  1280 */   415,  636,  637,  169,  446,  170,  443,   72,  144,  273,
+ /*  1290 */   450,  549,  459,  462,  158,  172,  463,  464,  468,    6,
+ /*  1300 */    13,   82,   12,  481,  122,  164,  177,  497,   93,  498,
+ /*  1310 */   489,  220,   87,  116,  126,  185,  261,  127,   96,   88,
+ /*  1320 */   128,  253,  107,  363,  146,  547,  129,  354,  359,  194,
+ /*  1330 */   367,  176,  274,  130,  118,  554,  131,  550,    9,  319,
+ /*  1340 */   562,  132,   90,  198,   14,  200,  567,  202,  201,  570,
+ /*  1350 */   138,  140,  141,  209,   15,  106,  585,  577,  293,   91,
+ /*  1360 */   398,  394,  149,  599,
 };
 static const YYCODETYPE yy_lookahead[] = {
  /*     0 */    16,  140,  141,  142,  143,   21,   23,   23,   69,   70,
- /*    10 */    71,   72,  110,   74,   75,   76,   77,   78,   79,   80,
+ /*    10 */    71,   72,  148,   74,   75,   76,   77,   78,   79,   80,
  /*    20 */    81,   82,   83,   84,    1,    2,   42,   43,   73,   74,
  /*    30 */    75,   76,   77,   78,   79,   80,   81,   82,   83,   84,
  /*    40 */    58,  162,  163,  164,   60,   61,   62,   63,   64,   65,
  /*    50 */    66,   67,   68,   69,   70,   71,   72,  148,   74,   75,
  /*    60 */    76,   77,   78,   79,   80,   81,   82,   83,   84,   16,
- /*    70 */    88,   88,   88,   84,   92,   22,  219,  220,  221,  222,
+ /*    70 */    88,   88,   88,  209,   92,   22,  218,  219,  220,  221,
  /*    80 */    74,   75,   76,   77,   78,   79,   80,   81,   82,   83,
- /*    90 */    84,  219,  183,  221,  222,   42,   43,   78,   79,   46,
+ /*    90 */    84,  218,  183,  220,  221,   42,   43,   78,   79,   46,
  /*   100 */    78,   79,   80,   81,   82,   83,   84,  125,  126,  127,
- /*   110 */   170,  239,   16,   60,   61,   62,   63,   64,   65,   66,
+ /*   110 */   110,  238,   16,   60,   61,   62,   63,   64,   65,   66,
  /*   120 */    67,   68,   69,   70,   71,   72,  148,   74,   75,   76,
  /*   130 */    77,   78,   79,   80,   81,   82,   83,   84,   42,   43,
- /*   140 */    44,   80,   81,   82,   83,   84,   23,  148,  170,  171,
- /*   150 */    19,   83,   84,  156,   23,  170,   60,   61,   62,   63,
- /*   160 */    64,   65,   66,   67,   68,   69,   70,   71,   72,   19,
+ /*   140 */    44,  144,  145,  162,   19,   20,  149,   22,  170,  171,
+ /*   150 */    19,   83,   84,  156,   23,  148,   60,   61,   62,   63,
+ /*   160 */    64,   65,   66,   67,   68,   69,   70,   71,   72,   84,
  /*   170 */    74,   75,   76,   77,   78,   79,   80,   81,   82,   83,
- /*   180 */    84,   16,  183,  148,  151,  148,   21,  190,  148,   58,
- /*   190 */   169,  213,  157,  158,  186,  187,  218,   23,  177,  202,
- /*   200 */   203,   78,   79,  166,  167,  208,  161,   42,   43,   78,
- /*   210 */    79,   88,   89,  177,  178,  170,  181,  182,   68,   88,
- /*   220 */   184,   98,   99,   92,   16,   60,   61,   62,   63,   64,
- /*   230 */    65,   66,   67,   68,   69,   70,   71,   72,   22,   74,
+ /*   180 */    84,   16,  201,  148,   59,  148,   21,  190,   12,   58,
+ /*   190 */   212,  170,  157,  158,   30,  217,  189,   23,  148,  218,
+ /*   200 */    24,  220,  221,  166,  167,  177,  178,   42,   43,   78,
+ /*   210 */    79,  214,  184,   37,   50,   39,  181,  182,  148,   88,
+ /*   220 */   170,  171,  170,   92,   16,   60,   61,   62,   63,   64,
+ /*   230 */    65,   66,   67,   68,   69,   70,   71,   72,  241,   74,
  /*   240 */    75,   76,   77,   78,   79,   80,   81,   82,   83,   84,
- /*   250 */    42,   43,   78,    0,    1,    2,  125,  126,  127,  226,
- /*   260 */    11,  162,   88,   89,  231,  228,  229,   16,   60,   61,
+ /*   250 */    42,   43,   78,    0,    1,    2,  125,  126,  127,  189,
+ /*   260 */    11,  211,   88,   89,  227,  228,  102,   16,   60,   61,
  /*   270 */    62,   63,   64,   65,   66,   67,   68,   69,   70,   71,
  /*   280 */    72,  148,   74,   75,   76,   77,   78,   79,   80,   81,
- /*   290 */    82,   83,   84,   42,   43,  186,  187,   16,   49,  148,
- /*   300 */   201,   49,   18,  170,  171,  154,  142,  143,  157,  158,
- /*   310 */   182,   60,   61,   62,   63,   64,   65,   66,   67,   68,
- /*   320 */    69,   70,   71,   72,   91,   74,   75,   76,   77,   78,
- /*   330 */    79,   80,   81,   82,   83,   84,  168,  169,  122,   55,
- /*   340 */   132,   16,   16,  110,   16,  177,   20,   20,   99,  100,
- /*   350 */   101,   99,  100,  101,   80,   12,  223,  124,  148,  110,
- /*   360 */   182,  148,  110,   23,   19,   84,   21,   24,   42,   43,
- /*   370 */   148,   90,   91,   92,   93,   94,   95,   96,   94,  166,
- /*   380 */    37,  107,   39,  132,  103,  111,   60,   61,   62,   63,
- /*   390 */    64,   65,   66,   67,   68,   69,   70,   71,   72,  189,
+ /*   290 */    82,   83,   84,   42,   43,   23,  182,   16,   49,  186,
+ /*   300 */   187,   49,  182,  170,  171,  156,   80,   81,   82,   83,
+ /*   310 */    84,   60,   61,   62,   63,   64,   65,   66,   67,   68,
+ /*   320 */    69,   70,   71,   72,   22,   74,   75,   76,   77,   78,
+ /*   330 */    79,   80,   81,   82,   83,   84,  168,  169,  148,  190,
+ /*   340 */   132,  148,   16,  148,   16,  177,   20,  191,   99,  100,
+ /*   350 */   101,   99,  100,  101,   25,  222,  166,   22,   29,  110,
+ /*   360 */    88,   89,  110,  214,  218,   84,  220,  221,   42,   43,
+ /*   370 */    41,   90,   91,   92,   93,   94,   95,   96,  183,   21,
+ /*   380 */   231,   23,  189,  132,  103,  236,   60,   61,   62,   63,
+ /*   390 */    64,   65,   66,   67,   68,   69,   70,   71,   72,   97,
  /*   400 */    74,   75,   76,   77,   78,   79,   80,   81,   82,   83,
- /*   410 */    84,   16,   84,  156,   92,   20,   23,   92,  134,   91,
- /*   420 */    92,   93,   94,   95,   96,  103,  148,   22,   88,   89,
- /*   430 */   148,  103,  210,  106,  156,  108,  109,   42,   43,  144,
- /*   440 */   145,  228,  229,  219,  149,  221,  222,  190,  170,  171,
- /*   450 */   240,  156,  170,  171,  162,   60,   61,   62,   63,   64,
+ /*   410 */    84,   16,   84,  186,  187,   20,   23,  227,  228,   91,
+ /*   420 */    92,   93,   94,   95,   96,   90,  148,  169,   93,   94,
+ /*   430 */    95,  103,  239,  148,  156,  177,   23,   42,   43,  104,
+ /*   440 */    90,  148,  148,   93,   94,   95,   88,  154,  170,  171,
+ /*   450 */   157,  158,  142,  143,  104,   60,   61,   62,   63,   64,
  /*   460 */    65,   66,   67,   68,   69,   70,   71,   72,  190,   74,
  /*   470 */    75,   76,   77,   78,   79,   80,   81,   82,   83,   84,
- /*   480 */    16,   88,   89,   90,   20,  190,   93,   94,   95,   23,
- /*   490 */   131,  213,  133,  201,  212,   90,  218,  104,   93,   94,
- /*   500 */    95,   42,   43,    7,    8,    9,   42,   43,  191,  104,
- /*   510 */   215,  219,  159,  221,  222,  162,  163,  164,  156,  165,
- /*   520 */   166,  167,   63,   64,   60,   61,   62,   63,   64,   65,
- /*   530 */    66,   67,   68,   69,   70,   71,   72,  242,   74,   75,
+ /*   480 */    16,   88,   89,   90,   20,  161,   93,   94,   95,  156,
+ /*   490 */   212,   78,   79,  148,  170,  217,  107,  104,  213,  148,
+ /*   500 */   111,   88,   89,  156,  148,  187,   42,   43,  165,  166,
+ /*   510 */   167,   98,   99,  157,  158,  170,  171,  165,  166,  167,
+ /*   520 */   156,  170,  171,  190,   60,   61,   62,   63,   64,   65,
+ /*   530 */    66,   67,   68,   69,   70,   71,   72,  190,   74,   75,
  /*   540 */    76,   77,   78,   79,   80,   81,   82,   83,   84,   16,
- /*   550 */   148,   92,  190,   20,   88,   89,  148,   90,  156,  148,
- /*   560 */    93,   94,   95,   20,  187,  148,   19,   20,  148,   22,
- /*   570 */    19,  104,  170,  171,   23,   42,   43,  148,  170,  171,
- /*   580 */   114,  170,  171,  229,   99,  100,  101,  170,  171,  148,
- /*   590 */   170,  171,  190,   60,   61,   62,   63,   64,   65,   66,
- /*   600 */    67,   68,   69,   70,   71,   72,   59,   74,   75,   76,
- /*   610 */    77,   78,   79,   80,   81,   82,   83,   84,   16,  211,
- /*   620 */   212,   12,  148,   21,  213,  165,  166,  167,   21,  148,
- /*   630 */    23,  148,  148,   24,  217,   19,   20,  217,   22,   88,
- /*   640 */    89,  157,  158,  214,   42,   43,   37,  148,   39,  106,
- /*   650 */   148,  108,  109,  170,  171,   20,  146,  183,   49,  156,
- /*   660 */    14,   16,   60,   61,   62,   63,   64,   65,   66,   67,
+ /*   550 */   148,   20,   12,   20,  190,  210,  211,  148,  156,  148,
+ /*   560 */   148,  214,   20,  212,   24,  148,  202,  203,   20,   42,
+ /*   570 */    43,  228,  170,  171,   19,   42,   43,   37,   23,   39,
+ /*   580 */   228,  170,  171,  236,    7,    8,    9,  170,  171,   49,
+ /*   590 */    63,   64,  190,   60,   61,   62,   63,   64,   65,   66,
+ /*   600 */    67,   68,   69,   70,   71,   72,  148,   74,   75,   76,
+ /*   610 */    77,   78,   79,   80,   81,   82,   83,   84,   16,   92,
+ /*   620 */    14,  159,   18,   21,  162,  163,  164,  216,  170,  171,
+ /*   630 */    19,  244,  245,  216,   23,   19,   20,  106,   22,  108,
+ /*   640 */   109,  148,  193,   88,   42,   43,   20,  204,  106,  200,
+ /*   650 */   108,  109,  202,  203,  106,  148,  108,  109,   52,   55,
+ /*   660 */    54,   16,   60,   61,   62,   63,   64,   65,   66,   67,
  /*   670 */    68,   69,   70,   71,   72,   59,   74,   75,   76,   77,
- /*   680 */    78,   79,   80,   81,   82,   83,   84,   42,   43,  229,
- /*   690 */    99,  100,  101,  190,  106,   88,  108,  109,   52,   14,
- /*   700 */    54,  148,  156,  162,   16,   60,   61,   62,   63,   64,
- /*   710 */    65,   66,   67,   68,   69,   70,   71,   72,  215,   74,
+ /*   680 */    78,   79,   80,   81,   82,   83,   84,   42,   43,   99,
+ /*   690 */   100,  101,   20,  106,   22,  108,  109,  162,   94,   88,
+ /*   700 */    89,   14,  151,  162,   16,   60,   61,   62,   63,   64,
+ /*   710 */    65,   66,   67,   68,   69,   70,   71,   72,   23,   74,
  /*   720 */    75,   76,   77,   78,   79,   80,   81,   82,   83,   84,
- /*   730 */    42,   43,  245,  246,  148,  148,  190,   52,  193,   54,
- /*   740 */   237,  106,  201,  108,  109,  200,  148,   16,   60,   61,
+ /*   730 */    42,   43,  106,  148,  108,  109,  201,  148,  134,   52,
+ /*   740 */   134,   54,  201,   99,  100,  101,  162,   16,   60,   61,
  /*   750 */    62,   63,   64,   65,   66,   67,   68,   69,   70,   71,
- /*   760 */    72,  215,   74,   75,   76,   77,   78,   79,   80,   81,
- /*   770 */    82,   83,   84,   42,   43,   25,  189,   22,  232,   29,
- /*   780 */   134,  183,   16,  237,  202,  203,  148,  148,  192,  148,
- /*   790 */    16,   41,   61,   62,   63,   64,   65,   66,   67,   68,
- /*   800 */    69,   70,   71,   72,  148,   74,   75,   76,   77,   78,
+ /*   760 */    72,   89,   74,   75,   76,   77,   78,   79,   80,   81,
+ /*   770 */    82,   83,   84,   42,   43,   80,  225,  110,  189,  146,
+ /*   780 */   148,  230,   16,   88,   89,  201,  114,  148,  148,  148,
+ /*   790 */    16,  124,   61,   62,   63,   64,   65,   66,   67,   68,
+ /*   800 */    69,   70,   71,   72,   80,   74,   75,   76,   77,   78,
  /*   810 */    79,   80,   81,   82,   83,   84,   42,   43,   23,   19,
- /*   820 */    23,  183,  148,   23,  148,  148,  170,  171,  189,   19,
- /*   830 */   189,  107,  148,   23,  148,  111,   62,   63,   64,   65,
+ /*   820 */    23,  189,  183,   23,  183,  148,  148,  148,  148,  189,
+ /*   830 */   192,  107,   19,   22,   21,  111,   62,   63,   64,   65,
  /*   840 */    66,   67,   68,   69,   70,   71,   72,  148,   74,   75,
  /*   850 */    76,   77,   78,   79,   80,   81,   82,   83,   84,   16,
- /*   860 */    17,  148,   19,  189,  148,  189,   23,  148,  113,  170,
- /*   870 */   171,  148,   16,  148,   31,   16,   17,   80,   19,  162,
- /*   880 */   148,  115,   23,   88,   89,   88,   89,  210,   88,   89,
- /*   890 */    31,   48,  148,  170,  171,  170,  171,  148,   88,   43,
- /*   900 */   214,   58,  170,  171,  148,  189,  148,   48,  189,  114,
- /*   910 */    19,  148,  243,  244,  170,  171,  148,   58,  148,  170,
- /*   920 */   171,   78,   79,  210,  148,   30,  170,  171,  170,  171,
- /*   930 */    87,   88,   89,  170,  171,   92,  148,   78,   79,   80,
- /*   940 */   170,  171,  125,  126,  148,   50,   87,   88,   89,   16,
- /*   950 */    17,   92,   19,  110,   98,  148,   23,  148,  156,  103,
- /*   960 */   148,  110,  156,   22,   31,  189,  170,  171,  125,  126,
- /*   970 */   127,  128,  129,  130,   20,  124,  156,  170,  171,  170,
+ /*   860 */    17,  148,   19,  183,  148,  162,   23,  148,  189,  170,
+ /*   870 */   171,  148,   16,  148,   31,   16,   17,  131,   19,  133,
+ /*   880 */   148,  115,   23,   88,   89,   88,   89,  209,   88,   89,
+ /*   890 */    31,   48,  148,  170,  171,  170,  171,  148,  148,   43,
+ /*   900 */    89,   58,  170,  171,  148,  189,  148,   48,  189,  114,
+ /*   910 */    43,  114,   22,  148,   19,  242,  243,   58,  148,  170,
+ /*   920 */   171,   78,   79,  148,  156,  114,  170,  171,  170,  171,
+ /*   930 */    87,   88,   89,  125,  126,   92,   27,   78,   79,   80,
+ /*   940 */   170,  171,   91,   34,  148,  233,   87,   88,   89,   16,
+ /*   950 */    17,   92,   19,  110,   98,  148,   23,  148,  190,  103,
+ /*   960 */   148,  110,  156,  213,   31,   98,  170,  171,  125,  126,
+ /*   970 */   127,  128,  129,  130,  209,  124,  156,  170,  171,  170,
  /*   980 */   171,   48,  170,  171,  125,  126,  127,  128,  129,  130,
- /*   990 */   204,   58,  190,    5,  148,  148,  190,  102,   10,   11,
- /*  1000 */    12,   13,  148,  112,   22,  148,  148,   20,  148,   22,
- /*  1010 */   190,   78,   79,   59,   26,   43,   28,  170,  171,  148,
- /*  1020 */    87,   88,   89,   35,  148,   92,  148,  170,  171,  148,
- /*  1030 */   170,  171,  148,   27,  148,   47,  148,   49,   97,  234,
- /*  1040 */    34,   53,  148,  179,   56,  148,  170,  171,  170,  171,
+ /*   990 */    16,   58,  156,    5,   22,  148,  190,   20,   10,   11,
+ /*  1000 */    12,   13,   20,  113,   22,  148,  148,  112,  148,  148,
+ /*  1010 */   190,   78,   79,   20,   26,   22,   28,  170,  171,  148,
+ /*  1020 */    87,   88,   89,   35,  148,   92,  190,  170,  171,  148,
+ /*  1030 */   170,  171,  148,   19,  148,   47,   59,   49,    7,    8,
+ /*  1040 */   148,   53,  148,  179,   56,  148,  170,  171,  148,  148,
  /*  1050 */   148,  170,  171,  148,  170,  171,  170,  171,  125,  126,
- /*  1060 */   127,  128,  129,  130,  170,  171,  179,  170,  171,  148,
- /*  1070 */    98,   89,  170,  171,  148,  170,  171,  148,   20,  148,
- /*  1080 */    22,   20,  148,   22,  148,  179,  148,   99,  100,  101,
- /*  1090 */   148,  170,  171,  105,  148,  148,  114,  148,  110,  170,
- /*  1100 */   171,  170,  171,  148,  170,  171,  170,  171,  170,  171,
- /*  1110 */     7,    8,  170,  171,   20,  148,   22,  170,  171,  170,
- /*  1120 */   171,  148,   20,  135,   22,  170,  171,  148,  148,   91,
- /*  1130 */    92,   20,   20,   22,   22,  150,  233,  170,  171,   20,
- /*  1140 */    20,   22,   22,  170,  171,   20,  148,   22,  148,  170,
- /*  1150 */   171,  148,  148,  148,  192,  148,  148,  148,  148,  148,
- /*  1160 */   148,  148,  148,  148,  148,  148,  173,  230,  194,  230,
- /*  1170 */   225,  205,  173,  178,  173,  173,  195,    6,  147,  195,
- /*  1180 */   162,  162,  205,  162,  147,   22,  147,  147,  205,  155,
- /*  1190 */   122,  195,  119,  173,  120,  118,  174,  121,  131,  224,
- /*  1200 */   112,  153,  153,   98,  117,   98,   40,  172,  172,   19,
- /*  1210 */    97,   84,   15,  190,  172,  152,  172,  174,  227,  227,
- /*  1220 */   196,  180,  197,  172,  198,  175,  199,  180,  172,  172,
- /*  1230 */   175,  153,  152,  152,  206,  153,  207,  207,  206,  153,
- /*  1240 */    38,  131,  153,  152,   60,  153,   19,  185,  195,  185,
- /*  1250 */   153,   15,  153,  188,  188,  195,  185,  188,  188,   33,
- /*  1260 */   138,  153,  216,    1,  160,   20,  176,  153,  235,  176,
- /*  1270 */   216,  112,  112,  112,  112,   92,  107,   19,   11,   20,
- /*  1280 */    20,  236,   19,   19,  116,   20,  116,  114,   22,   20,
- /*  1290 */   238,   20,   22,   19,   22,  116,  115,  238,   20,  112,
- /*  1300 */    20,   20,   19,   19,   19,   32,   20,   19,   19,   96,
- /*  1310 */   103,   16,   44,  241,   17,   21,   98,   98,   36,  244,
- /*  1320 */    44,   44,   22,  134,   19,    5,  247,    1,  123,   68,
- /*  1330 */    51,  102,   45,   19,  113,   45,    1,   14,   17,  117,
- /*  1340 */   102,  113,   20,   68,   19,   14,  123,  136,  124,   57,
- /*  1350 */     3,  137,   19,    4,
-};
-#define YY_SHIFT_USE_DFLT (-99)
-#define YY_SHIFT_MAX 396
+ /*  1060 */   127,  128,  129,  130,  170,  171,   92,  170,  171,  148,
+ /*  1070 */   170,  171,  170,  171,  148,  170,  171,  148,  179,  148,
+ /*  1080 */    91,   92,   68,   20,  148,   22,  148,   99,  100,  101,
+ /*  1090 */   148,  170,  171,  105,  122,  148,  179,  148,  110,  170,
+ /*  1100 */   171,  170,  171,  148,  148,  148,  170,  171,  170,  171,
+ /*  1110 */   148,   92,  170,  171,   20,  148,   22,  170,  171,  170,
+ /*  1120 */   171,  148,  103,  135,  148,  170,  171,  170,  171,  148,
+ /*  1130 */    20,  148,   22,  148,   20,  148,   22,  170,  171,   20,
+ /*  1140 */    20,   22,   22,  170,  171,  148,   20,   20,   22,   22,
+ /*  1150 */   148,  170,  171,  170,  171,  170,  171,  170,  171,  232,
+ /*  1160 */   148,  148,  192,  148,  148,  148,  148,  162,  148,  148,
+ /*  1170 */   148,  148,  148,  148,  148,  229,  224,  150,  194,  229,
+ /*  1180 */   173,  173,  173,  205,  178,  174,  195,    6,  147,  195,
+ /*  1190 */   147,  162,  147,  147,  162,  205,   22,  205,  122,  155,
+ /*  1200 */   190,  173,  119,  173,  120,  118,  121,  112,  131,  223,
+ /*  1210 */   153,  153,   40,   98,  117,   98,   19,   84,   97,   15,
+ /*  1220 */   152,  172,  172,  153,  172,  226,  172,  174,  195,  226,
+ /*  1230 */   196,  180,  197,  172,  198,  175,  199,  172,  172,  180,
+ /*  1240 */   152,  152,  175,  153,  206,  153,  207,  207,  206,  153,
+ /*  1250 */    38,  152,   60,  206,  131,  207,  153,  185,  185,   19,
+ /*  1260 */   153,   15,  188,  188,  195,  153,  188,  188,   33,  153,
+ /*  1270 */   138,  185,    1,  160,  176,  195,  176,  215,  153,  215,
+ /*  1280 */    20,  112,  112,  112,  107,  112,   92,   19,   19,  234,
+ /*  1290 */    20,  235,   20,   11,   19,   22,   20,   20,   20,  116,
+ /*  1300 */   116,   22,   22,  114,   19,  112,  116,   20,  237,   20,
+ /*  1310 */   115,   44,   19,   32,   19,   96,   20,   19,  237,   19,
+ /*  1320 */    19,  103,  240,   16,   21,   17,   98,   44,   44,   98,
+ /*  1330 */    36,   22,  134,   45,  243,   45,   19,   51,    5,  246,
+ /*  1340 */     1,  102,   68,  123,   19,  113,    1,  117,   14,   17,
+ /*  1350 */   113,  102,  123,  136,   19,   14,   20,  124,  137,   68,
+ /*  1360 */     3,   57,   19,    4,
+};
+#define YY_SHIFT_USE_DFLT (-62)
+#define YY_SHIFT_MAX 398
 static const short yy_shift_ofst[] = {
- /*     0 */    23,  843,  988,  -16,  843,  933,  933,  393,  123,  252,
- /*    10 */   -98,   96,  933,  933,  933,  933,  933,  -45,  249,  174,
- /*    20 */   340,  -17,   19,   19,   53,  165,  208,  251,  326,  395,
+ /*     0 */    23,  843,  988,  -16,  843,  933,  933,  393,  413,  252,
+ /*    10 */    96,  933,  933,  933,  933,  933,  -45,  249,  174,  272,
+ /*    20 */   -17,   19,   19,    0,   53,  165,  208,  251,  326,  395,
  /*    30 */   464,  533,  602,  645,  688,  645,  645,  645,  645,  645,
  /*    40 */   645,  645,  645,  645,  645,  645,  645,  645,  645,  645,
  /*    50 */   645,  645,  645,  731,  774,  774,  859,  933,  933,  933,
  /*    60 */   933,  933,  933,  933,  933,  933,  933,  933,  933,  933,
  /*    70 */   933,  933,  933,  933,  933,  933,  933,  933,  933,  933,
  /*    80 */   933,  933,  933,  933,  933,  933,  933,  933,  933,  933,
  /*    90 */   933,  933,  933,  933,  933,  933,  933,  -61,  -61,    6,
- /*   100 */     6,  281,   22,   61,  856,  284,  340,  340,   68,  -17,
- /*   110 */   -11,  -99,  -99,  -99,  131,  328,  609,  609,  547,  616,
- /*   120 */   253,  607,  340,  607,  340,  340,  340,  340,  340,  340,
- /*   130 */   340,  340,  340,  340,  340,  340,  340,  340,  340,  340,
- /*   140 */   340,  233,  851,  -98,  -98,  -98,  -99,  -99,  -99,  -18,
- /*   150 */   -18,  405,  467,  327,  551,  543,  635,  343,  466,  795,
- /*   160 */   800,  797,  496,  340,  340,  274,  340,  340,  810,  340,
- /*   170 */   340,  982,  340,  340,  340,  588,  982,  340,  340,  895,
- /*   180 */   895,  895,  340,  340,  340,  588,  340,  340,  588,  340,
- /*   190 */   750,  485,  340,  340,  588,  340,  340,  340,  588,  340,
- /*   200 */   340,  340,  588,  588,  340,  340,  340,  340,  340,  345,
- /*   210 */   724,  755,  -17,  817,  817,  359, 1006, 1006,  766, 1006,
- /*   220 */   972, 1006,  -17, 1006,  -17,  941,  216,  766,  766,  216,
- /*   230 */  1171, 1171, 1171, 1171, 1163,  -98, 1068, 1073, 1074, 1077,
- /*   240 */  1076, 1067, 1088, 1088, 1105, 1087, 1105, 1087, 1107, 1107,
- /*   250 */  1166, 1107, 1113, 1107, 1190, 1127, 1127, 1166, 1107, 1107,
- /*   260 */  1107, 1190, 1197, 1088, 1197, 1088, 1197, 1088, 1088, 1202,
- /*   270 */  1110, 1197, 1088, 1184, 1184, 1227, 1068, 1088, 1236, 1236,
- /*   280 */  1236, 1236, 1068, 1184, 1227, 1088, 1226, 1226, 1088, 1088,
- /*   290 */  1122,  -99,  -99,  -99,  -99,  -99,  459,  646,  591,  685,
- /*   300 */   891,  325,  987, 1058,  322, 1103, 1038, 1061, 1094, 1102,
- /*   310 */  1111, 1112, 1119, 1120,  150, 1125,  954, 1262, 1245, 1159,
- /*   320 */  1160, 1161, 1162, 1183, 1169, 1258, 1259, 1260, 1263, 1267,
- /*   330 */  1264, 1265, 1266, 1269, 1271, 1270, 1168, 1272, 1170, 1270,
- /*   340 */  1173, 1274, 1179, 1181, 1278, 1187, 1280, 1281, 1273, 1268,
- /*   350 */  1283, 1276, 1284, 1286, 1285, 1288, 1277, 1289, 1213, 1207,
- /*   360 */  1295, 1297, 1294, 1218, 1282, 1279, 1287, 1300, 1290, 1189,
- /*   370 */  1219, 1305, 1320, 1326, 1229, 1261, 1275, 1205, 1314, 1221,
- /*   380 */  1335, 1323, 1222, 1321, 1228, 1238, 1223, 1325, 1224, 1322,
- /*   390 */  1331, 1292, 1211, 1214, 1333, 1347, 1349,
-};
-#define YY_REDUCE_USE_DFLT (-144)
-#define YY_REDUCE_MAX 295
+ /*   100 */     6,  281,   22,  226,  856,  604,  272,  272,   68,  -17,
+ /*   110 */    85,  -62,  -62,  -62,  131,  328,  540,  540,  125,  616,
+ /*   120 */   253,  358,  272,  358,  358,  272,  272,  272,  272,  272,
+ /*   130 */   272,  272,  272,  272,  272,  272,  272,  272,  272,  272,
+ /*   140 */   272,  272,  851,  667,    0,    0,    0,  -62,  -62,  -62,
+ /*   150 */   -18,  -18,  335,  350,  531,  611,  542,  548,  176,  795,
+ /*   160 */   797,  800,  626,  672,  695,  577,  272,  272,  724,  272,
+ /*   170 */   272,  555,  272,  272,  811,  272,  272,  272,  272,  272,
+ /*   180 */   164,  164,  164,  272,  272,  272,  587,  272,  272,  587,
+ /*   190 */   272,  329,  590,  272,  272,  587,  272,  272,  272,  587,
+ /*   200 */   272,  272,  272,  587,  587,  272,  272,  272,  272,  272,
+ /*   210 */   813,  389,  890,  -17,  808,  808,  746,  909,  909,  766,
+ /*   220 */   909,  867,  909,  -17,  909,  -17,  302,  972,  766,  766,
+ /*   230 */   972, 1181, 1181, 1181, 1181, 1174,    0, 1076, 1083, 1084,
+ /*   240 */  1087, 1085, 1077, 1095, 1095, 1115, 1097, 1115, 1097, 1115,
+ /*   250 */  1097, 1117, 1117, 1172, 1117, 1121, 1117, 1197, 1133, 1133,
+ /*   260 */  1172, 1117, 1117, 1117, 1197, 1204, 1095, 1204, 1095, 1204,
+ /*   270 */  1095, 1095, 1212, 1123, 1204, 1095, 1192, 1192, 1240, 1076,
+ /*   280 */  1095, 1246, 1246, 1246, 1246, 1076, 1192, 1240, 1095, 1235,
+ /*   290 */  1235, 1095, 1095, 1132,  -62,  -62,  -62,  -62,  -62,  527,
+ /*   300 */   606,  644,  687,  895,  974,  982,  993, 1019, 1031,  989,
+ /*   310 */  1063, 1094, 1110, 1114, 1119, 1120, 1126, 1014, 1127,  977,
+ /*   320 */  1271, 1260, 1169, 1170, 1171, 1173, 1194, 1177, 1268, 1270,
+ /*   330 */  1272, 1269, 1282, 1275, 1276, 1273, 1277, 1278, 1279, 1183,
+ /*   340 */  1280, 1184, 1279, 1189, 1285, 1190, 1195, 1193, 1287, 1289,
+ /*   350 */  1281, 1267, 1293, 1283, 1295, 1296, 1298, 1300, 1284, 1301,
+ /*   360 */  1219, 1218, 1307, 1308, 1303, 1228, 1294, 1286, 1288, 1309,
+ /*   370 */  1290, 1198, 1231, 1317, 1333, 1339, 1239, 1274, 1291, 1220,
+ /*   380 */  1325, 1232, 1345, 1334, 1230, 1332, 1237, 1249, 1229, 1335,
+ /*   390 */  1233, 1336, 1341, 1304, 1217, 1221, 1343, 1357, 1359,
+};
+#define YY_REDUCE_USE_DFLT (-143)
+#define YY_REDUCE_MAX 298
 static const short yy_reduce_ofst[] = {
- /*     0 */  -139,  278,  295,  292,  402,  -22,  408,   35,   37,  546,
- /*    10 */    -3, -128,  133,  282,  411,  417,  420, -143,  503,  213,
- /*    20 */   151,  353,  354,  460,  224,  224,  224,  224,  224,  224,
- /*    30 */   224,  224,  224,  224,  224,  224,  224,  224,  224,  224,
- /*    40 */   224,  224,  224,  224,  224,  224,  224,  224,  224,  224,
- /*    50 */   224,  224,  224,  224,  224,  224,  483,  656,  699,  723,
- /*    60 */   725,  732,  744,  749,  756,  758,  763,  770,  796,  807,
- /*    70 */   809,  812,  847,  857,  860,  876,  878,  881,  884,  886,
- /*    80 */   894,  897,  902,  905,  921,  929,  931,  934,  936,  938,
- /*    90 */   942,  947,  949,  955,  967,  973,  979,  224,  224,  224,
- /*   100 */   224,  168,  224,  224,   36,   33,  210,  484,  224, -121,
- /*   110 */   224,  224,  224,  224,   45,   21,    8,  109,  487,  487,
- /*   120 */   164,   99,  222,  541,  -91,   -1,  474,  598,  587,  677,
- /*   130 */   638,  429,  713,  639,  641,  674,  676,  716,  719,  686,
- /*   140 */   776,  257,  362,  802,  806,  820,  545,  582,  669,  -60,
- /*   150 */   -15,  128,  178,  317,   40,  317,  317,  377,  441,  481,
- /*   160 */   499,  502,  510,  553,  586,  596,  502,  684,  717,  768,
- /*   170 */   788,  786,  846,  854,  858,  317,  786,  871,  888,  864,
- /*   180 */   887,  906,  926,  946,  980,  317,  998, 1000,  317, 1003,
- /*   190 */   903,  805, 1004, 1005,  317, 1007, 1008, 1009,  317, 1010,
- /*   200 */  1011, 1012,  317,  317, 1013, 1014, 1015, 1016, 1017,  985,
- /*   210 */   962,  974, 1018,  937,  939,  945,  993,  999,  966, 1001,
- /*   220 */   995, 1002, 1019, 1020, 1021, 1022,  981,  977,  983,  984,
- /*   230 */  1031, 1037, 1039, 1040, 1034, 1023,  996, 1024, 1025, 1026,
- /*   240 */  1027,  975, 1048, 1049, 1028, 1029, 1032, 1030, 1035, 1036,
- /*   250 */  1041, 1042, 1043, 1044, 1050,  991,  992, 1047, 1051, 1056,
- /*   260 */  1057, 1055, 1063, 1078, 1080, 1082, 1081, 1086, 1089, 1033,
- /*   270 */  1045, 1091, 1092, 1062, 1064, 1046, 1053, 1097, 1065, 1066,
- /*   280 */  1069, 1070, 1060, 1071, 1054, 1099, 1052, 1059, 1108, 1114,
- /*   290 */  1072, 1104, 1090, 1093, 1075, 1079,
+ /*     0 */  -139,  278,   -3,  -19,  402,  -22,  345,   35,   37,  149,
+ /*    10 */  -127,  133,   50,  351,  411,  417, -142,  347,  190,  293,
+ /*    20 */   462,  343,  352,  364,  146,  146,  146,  146,  146,  146,
+ /*    30 */   146,  146,  146,  146,  146,  146,  146,  146,  146,  146,
+ /*    40 */   146,  146,  146,  146,  146,  146,  146,  146,  146,  146,
+ /*    50 */   146,  146,  146,  146,  146,  146,  458,  699,  723,  725,
+ /*    60 */   732,  749,  756,  758,  770,  796,  807,  809,  812,  847,
+ /*    70 */   857,  860,  876,  881,  884,  886,  894,  897,  900,  902,
+ /*    80 */   905,  921,  929,  931,  936,  938,  942,  947,  949,  955,
+ /*    90 */   957,  967,  973,  981,  983,  985,  987,  146,  146,  146,
+ /*   100 */   146,  168,  146,  146,   28,  551,  193,  356,  146, -121,
+ /*   110 */   146,  146,  146,  146,  324,  258,  113,  227,  387,  387,
+ /*   120 */   310,  535, -136,  541,  584,  -91,  195,  639,  641,    7,
+ /*   130 */   678,  680,  285,  765,   70,  589,  632,  640,  679,  716,
+ /*   140 */   750,  719,  333,  768,  806,  820,  836,  449,  450,  673,
+ /*   150 */    21,   52,  114,  120,  156,  294,  156,  156,  318,  409,
+ /*   160 */   412,  493,  156,  443,  507,  633,  585,  677,  638,  507,
+ /*   170 */   713,  703,  744,  775,  443,  858,  861,  871,  892,  901,
+ /*   180 */   864,  899,  917,  926,  956,  962,  156,  976,  997,  156,
+ /*   190 */  1002,  927,  712, 1012, 1013,  156, 1015, 1016, 1017,  156,
+ /*   200 */  1018, 1020, 1021,  156,  156, 1022, 1023, 1024, 1025, 1026,
+ /*   210 */  1027,  970,  984, 1005,  946,  950,  952, 1007, 1008,  978,
+ /*   220 */  1009, 1006, 1028, 1029, 1030, 1032, 1011,  991,  990,  992,
+ /*   230 */   994, 1041, 1043, 1045, 1046, 1044, 1010, 1033, 1034, 1035,
+ /*   240 */  1036, 1037,  986, 1057, 1058, 1038, 1039, 1042, 1040, 1047,
+ /*   250 */  1048, 1049, 1050, 1051, 1052, 1053, 1054, 1060,  999, 1003,
+ /*   260 */  1059, 1061, 1065, 1066, 1067, 1068, 1070, 1088, 1090, 1089,
+ /*   270 */  1092, 1096, 1055, 1056, 1099, 1103, 1072, 1073, 1062, 1069,
+ /*   280 */  1107, 1074, 1075, 1078, 1079, 1080, 1086, 1064, 1112, 1071,
+ /*   290 */  1081, 1116, 1125, 1082, 1113, 1098, 1100, 1091, 1093,
 };
 static const YYACTIONTYPE yy_default[] = {
- /*     0 */   603,  832,  913,  719,  913,  832,  913,  913,  859,  913,
- /*    10 */   723,  888,  830,  913,  913,  913,  913,  804,  913,  859,
- /*    20 */   913,  635,  859,  859,  755,  913,  913,  913,  913,  913,
- /*    30 */   913,  913,  913,  756,  913,  834,  829,  825,  827,  826,
- /*    40 */   833,  757,  746,  753,  760,  735,  872,  762,  763,  769,
- /*    50 */   770,  889,  887,  792,  791,  810,  913,  913,  913,  913,
- /*    60 */   913,  913,  913,  913,  913,  913,  913,  913,  913,  913,
- /*    70 */   913,  913,  913,  913,  913,  913,  913,  913,  913,  913,
- /*    80 */   913,  913,  913,  913,  913,  913,  913,  913,  913,  913,
- /*    90 */   913,  913,  913,  913,  913,  913,  913,  794,  816,  793,
- /*   100 */   803,  628,  795,  796,  688,  623,  913,  913,  797,  913,
- /*   110 */   798,  811,  812,  813,  913,  913,  913,  913,  913,  913,
- /*   120 */   603,  719,  913,  719,  913,  913,  913,  913,  913,  913,
- /*   130 */   913,  913,  913,  913,  913,  913,  913,  913,  913,  913,
- /*   140 */   913,  913,  913,  913,  913,  913,  713,  723,  906,  913,
- /*   150 */   913,  679,  913,  913,  913,  913,  913,  913,  913,  913,
- /*   160 */   913,  913,  611,  609,  913,  711,  913,  913,  637,  913,
- /*   170 */   913,  721,  913,  913,  913,  726,  727,  913,  913,  913,
- /*   180 */   913,  913,  913,  913,  913,  625,  913,  913,  700,  913,
- /*   190 */   865,  913,  913,  913,  879,  913,  913,  913,  877,  913,
- /*   200 */   913,  913,  702,  765,  845,  913,  892,  894,  913,  913,
- /*   210 */   711,  720,  913,  913,  913,  828,  749,  749,  737,  749,
- /*   220 */   658,  749,  913,  749,  913,  661,  759,  737,  737,  759,
- /*   230 */   608,  608,  608,  608,  678,  913,  759,  750,  752,  742,
- /*   240 */   754,  913,  728,  728,  736,  741,  736,  741,  690,  690,
- /*   250 */   675,  690,  661,  690,  838,  842,  842,  675,  690,  690,
- /*   260 */   690,  838,  620,  728,  620,  728,  620,  728,  728,  869,
- /*   270 */   871,  620,  728,  692,  692,  771,  759,  728,  699,  699,
- /*   280 */   699,  699,  759,  692,  771,  728,  891,  891,  728,  728,
- /*   290 */   899,  645,  663,  663,  906,  911,  913,  913,  913,  913,
- /*   300 */   778,  913,  913,  913,  913,  913,  913,  913,  913,  913,
- /*   310 */   913,  913,  913,  913,  852,  913,  913,  913,  913,  783,
- /*   320 */   779,  913,  780,  913,  705,  913,  913,  913,  913,  913,
- /*   330 */   913,  913,  913,  913,  913,  831,  913,  743,  913,  751,
- /*   340 */   913,  913,  913,  913,  913,  913,  913,  913,  913,  913,
- /*   350 */   913,  913,  913,  913,  913,  913,  913,  913,  913,  913,
- /*   360 */   913,  913,  913,  913,  913,  913,  867,  868,  913,  913,
- /*   370 */   913,  913,  913,  913,  913,  913,  913,  913,  913,  913,
- /*   380 */   913,  913,  913,  913,  913,  913,  913,  913,  913,  913,
- /*   390 */   913,  898,  913,  913,  901,  604,  913,  599,  601,  602,
- /*   400 */   606,  607,  610,  632,  633,  634,  612,  613,  614,  615,
- /*   410 */   616,  617,  618,  624,  626,  644,  646,  630,  648,  709,
- /*   420 */   710,  775,  703,  704,  708,  631,  786,  777,  781,  782,
- /*   430 */   784,  785,  799,  800,  802,  808,  815,  818,  801,  806,
- /*   440 */   807,  809,  814,  817,  706,  707,  821,  638,  639,  642,
- /*   450 */   643,  855,  857,  856,  858,  641,  640,  787,  790,  823,
- /*   460 */   824,  880,  881,  882,  883,  884,  819,  729,  822,  805,
- /*   470 */   744,  747,  748,  745,  712,  722,  731,  732,  733,  734,
- /*   480 */   717,  718,  724,  740,  773,  774,  738,  739,  725,  714,
- /*   490 */   715,  716,  820,  776,  788,  789,  649,  650,  783,  651,
- /*   500 */   652,  653,  691,  694,  695,  696,  654,  673,  676,  677,
- /*   510 */   655,  662,  656,  657,  664,  665,  666,  669,  670,  671,
- /*   520 */   672,  667,  668,  839,  840,  843,  841,  659,  660,  674,
- /*   530 */   647,  636,  629,  680,  683,  684,  685,  686,  687,  689,
- /*   540 */   681,  682,  627,  619,  621,  730,  861,  870,  866,  862,
- /*   550 */   863,  864,  622,  835,  836,  693,  767,  768,  860,  873,
- /*   560 */   875,  772,  876,  878,  874,  903,  697,  698,  701,  844,
- /*   570 */   885,  758,  761,  764,  766,  846,  847,  848,  849,  850,
- /*   580 */   853,  854,  851,  886,  890,  893,  895,  896,  897,  900,
- /*   590 */   902,  907,  908,  909,  912,  910,  605,  600,
+ /*     0 */   606,  834,  915,  722,  915,  834,  915,  915,  861,  915,
+ /*    10 */   890,  832,  915,  915,  915,  915,  806,  915,  861,  915,
+ /*    20 */   638,  861,  861,  726,  757,  915,  915,  915,  915,  915,
+ /*    30 */   915,  915,  915,  758,  915,  836,  831,  827,  829,  828,
+ /*    40 */   835,  759,  748,  755,  762,  737,  874,  764,  765,  771,
+ /*    50 */   772,  891,  889,  794,  793,  812,  915,  915,  915,  915,
+ /*    60 */   915,  915,  915,  915,  915,  915,  915,  915,  915,  915,
+ /*    70 */   915,  915,  915,  915,  915,  915,  915,  915,  915,  915,
+ /*    80 */   915,  915,  915,  915,  915,  915,  915,  915,  915,  915,
+ /*    90 */   915,  915,  915,  915,  915,  915,  915,  796,  818,  795,
+ /*   100 */   805,  631,  797,  798,  691,  626,  915,  915,  799,  915,
+ /*   110 */   800,  813,  814,  815,  915,  915,  915,  915,  915,  915,
+ /*   120 */   606,  722,  915,  722,  722,  915,  915,  915,  915,  915,
+ /*   130 */   915,  915,  915,  915,  915,  915,  915,  915,  915,  915,
+ /*   140 */   915,  915,  915,  915,  915,  915,  915,  716,  726,  908,
+ /*   150 */   915,  915,  682,  915,  915,  915,  915,  915,  915,  915,
+ /*   160 */   915,  915,  915,  915,  915,  614,  612,  915,  714,  915,
+ /*   170 */   915,  640,  915,  915,  724,  915,  915,  915,  915,  915,
+ /*   180 */   915,  915,  915,  915,  915,  915,  628,  915,  915,  703,
+ /*   190 */   915,  867,  915,  915,  915,  881,  915,  915,  915,  879,
+ /*   200 */   915,  915,  915,  705,  767,  847,  915,  894,  896,  915,
+ /*   210 */   915,  714,  723,  915,  915,  915,  830,  751,  751,  739,
+ /*   220 */   751,  661,  751,  915,  751,  915,  664,  761,  739,  739,
+ /*   230 */   761,  611,  611,  611,  611,  681,  915,  761,  752,  754,
+ /*   240 */   744,  756,  915,  730,  730,  738,  743,  738,  743,  738,
+ /*   250 */   743,  693,  693,  678,  693,  664,  693,  840,  844,  844,
+ /*   260 */   678,  693,  693,  693,  840,  623,  730,  623,  730,  623,
+ /*   270 */   730,  730,  871,  873,  623,  730,  695,  695,  773,  761,
+ /*   280 */   730,  702,  702,  702,  702,  761,  695,  773,  730,  893,
+ /*   290 */   893,  730,  730,  901,  648,  666,  666,  908,  913,  915,
+ /*   300 */   915,  915,  915,  780,  915,  915,  915,  915,  915,  915,
+ /*   310 */   915,  915,  915,  915,  915,  915,  915,  854,  915,  915,
+ /*   320 */   915,  915,  785,  781,  915,  782,  915,  708,  915,  915,
+ /*   330 */   915,  915,  915,  915,  915,  915,  915,  915,  833,  915,
+ /*   340 */   745,  915,  753,  915,  915,  915,  915,  915,  915,  915,
+ /*   350 */   915,  915,  915,  915,  915,  915,  915,  915,  915,  915,
+ /*   360 */   915,  915,  915,  915,  915,  915,  915,  915,  869,  870,
+ /*   370 */   915,  915,  915,  915,  915,  915,  915,  915,  915,  915,
+ /*   380 */   915,  915,  915,  915,  915,  915,  915,  915,  915,  915,
+ /*   390 */   915,  915,  915,  900,  915,  915,  903,  607,  915,  602,
+ /*   400 */   604,  605,  609,  610,  613,  635,  636,  637,  615,  616,
+ /*   410 */   617,  618,  619,  620,  621,  627,  629,  647,  649,  633,
+ /*   420 */   651,  712,  713,  777,  706,  707,  711,  634,  788,  779,
+ /*   430 */   783,  784,  786,  787,  801,  802,  804,  810,  817,  820,
+ /*   440 */   803,  808,  809,  811,  816,  819,  709,  710,  823,  641,
+ /*   450 */   642,  645,  646,  857,  859,  858,  860,  644,  643,  789,
+ /*   460 */   792,  825,  826,  882,  883,  884,  885,  886,  821,  731,
+ /*   470 */   824,  807,  746,  749,  750,  747,  715,  725,  733,  734,
+ /*   480 */   735,  736,  720,  721,  727,  742,  775,  776,  740,  741,
+ /*   490 */   728,  729,  717,  718,  719,  822,  778,  790,  791,  652,
+ /*   500 */   653,  785,  654,  655,  656,  694,  697,  698,  699,  657,
+ /*   510 */   676,  679,  680,  658,  665,  659,  660,  667,  668,  669,
+ /*   520 */   672,  673,  674,  675,  670,  671,  841,  842,  845,  843,
+ /*   530 */   662,  663,  677,  650,  639,  632,  683,  686,  687,  688,
+ /*   540 */   689,  690,  692,  684,  685,  630,  622,  624,  732,  863,
+ /*   550 */   872,  868,  864,  865,  866,  625,  837,  838,  696,  769,
+ /*   560 */   770,  862,  875,  877,  774,  878,  880,  876,  905,  700,
+ /*   570 */   701,  704,  846,  887,  760,  763,  766,  768,  848,  849,
+ /*   580 */   850,  851,  852,  855,  856,  853,  888,  892,  895,  897,
+ /*   590 */   898,  899,  902,  904,  909,  910,  911,  914,  912,  608,
+ /*   600 */   603,
 };
 #define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0]))
 
 /* The next table maps tokens into fallback tokens.  If a construct
@@ -80598,18 +82561,18 @@
   "distinct",      "selcollist",    "from",          "where_opt",
   "groupby_opt",   "having_opt",    "orderby_opt",   "limit_opt",
   "sclp",          "as",            "seltablist",    "stl_prefix",
   "joinop",        "indexed_opt",   "on_opt",        "using_opt",
-  "seltablist_paren",  "joinop2",       "inscollist",    "sortlist",
-  "sortitem",      "nexprlist",     "setlist",       "insert_cmd",
-  "inscollist_opt",  "itemlist",      "exprlist",      "likeop",
-  "escape",        "between_op",    "in_op",         "case_operand",
-  "case_exprlist",  "case_else",     "uniqueflag",    "collate",
-  "nmnum",         "plus_opt",      "number",        "trigger_decl",
-  "trigger_cmd_list",  "trigger_time",  "trigger_event",  "foreach_clause",
-  "when_clause",   "trigger_cmd",   "database_kw_opt",  "key_opt",
-  "add_column_fullname",  "kwcolumn_opt",  "create_vtab",   "vtabarglist",
-  "vtabarg",       "vtabargtoken",  "lp",            "anylist",
+  "joinop2",       "inscollist",    "sortlist",      "sortitem",
+  "nexprlist",     "setlist",       "insert_cmd",    "inscollist_opt",
+  "itemlist",      "exprlist",      "likeop",        "escape",
+  "between_op",    "in_op",         "case_operand",  "case_exprlist",
+  "case_else",     "uniqueflag",    "collate",       "nmnum",
+  "plus_opt",      "number",        "trigger_decl",  "trigger_cmd_list",
+  "trigger_time",  "trigger_event",  "foreach_clause",  "when_clause",
+  "trigger_cmd",   "database_kw_opt",  "key_opt",       "add_column_fullname",
+  "kwcolumn_opt",  "create_vtab",   "vtabarglist",   "vtabarg",
+  "vtabargtoken",  "lp",            "anylist",
 };
 #endif /* NDEBUG */
 
 #ifndef NDEBUG
@@ -80742,196 +82705,195 @@
  /* 123 */ "from ::= FROM seltablist",
  /* 124 */ "stl_prefix ::= seltablist joinop",
  /* 125 */ "stl_prefix ::=",
  /* 126 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
- /* 127 */ "seltablist ::= stl_prefix LP seltablist_paren RP as on_opt using_opt",
- /* 128 */ "seltablist_paren ::= select",
- /* 129 */ "seltablist_paren ::= seltablist",
- /* 130 */ "dbnm ::=",
- /* 131 */ "dbnm ::= DOT nm",
- /* 132 */ "fullname ::= nm dbnm",
- /* 133 */ "joinop ::= COMMA|JOIN",
- /* 134 */ "joinop ::= JOIN_KW JOIN",
- /* 135 */ "joinop ::= JOIN_KW nm JOIN",
- /* 136 */ "joinop ::= JOIN_KW nm nm JOIN",
- /* 137 */ "on_opt ::= ON expr",
- /* 138 */ "on_opt ::=",
- /* 139 */ "indexed_opt ::=",
- /* 140 */ "indexed_opt ::= INDEXED BY nm",
- /* 141 */ "indexed_opt ::= NOT INDEXED",
- /* 142 */ "using_opt ::= USING LP inscollist RP",
- /* 143 */ "using_opt ::=",
- /* 144 */ "orderby_opt ::=",
- /* 145 */ "orderby_opt ::= ORDER BY sortlist",
- /* 146 */ "sortlist ::= sortlist COMMA sortitem sortorder",
- /* 147 */ "sortlist ::= sortitem sortorder",
- /* 148 */ "sortitem ::= expr",
- /* 149 */ "sortorder ::= ASC",
- /* 150 */ "sortorder ::= DESC",
- /* 151 */ "sortorder ::=",
- /* 152 */ "groupby_opt ::=",
- /* 153 */ "groupby_opt ::= GROUP BY nexprlist",
- /* 154 */ "having_opt ::=",
- /* 155 */ "having_opt ::= HAVING expr",
- /* 156 */ "limit_opt ::=",
- /* 157 */ "limit_opt ::= LIMIT expr",
- /* 158 */ "limit_opt ::= LIMIT expr OFFSET expr",
- /* 159 */ "limit_opt ::= LIMIT expr COMMA expr",
- /* 160 */ "cmd ::= DELETE FROM fullname indexed_opt where_opt",
- /* 161 */ "where_opt ::=",
- /* 162 */ "where_opt ::= WHERE expr",
- /* 163 */ "cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt",
- /* 164 */ "setlist ::= setlist COMMA nm EQ expr",
- /* 165 */ "setlist ::= nm EQ expr",
- /* 166 */ "cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP",
- /* 167 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select",
- /* 168 */ "cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES",
- /* 169 */ "insert_cmd ::= INSERT orconf",
- /* 170 */ "insert_cmd ::= REPLACE",
- /* 171 */ "itemlist ::= itemlist COMMA expr",
- /* 172 */ "itemlist ::= expr",
- /* 173 */ "inscollist_opt ::=",
- /* 174 */ "inscollist_opt ::= LP inscollist RP",
- /* 175 */ "inscollist ::= inscollist COMMA nm",
- /* 176 */ "inscollist ::= nm",
- /* 177 */ "expr ::= term",
- /* 178 */ "expr ::= LP expr RP",
- /* 179 */ "term ::= NULL",
- /* 180 */ "expr ::= ID",
- /* 181 */ "expr ::= JOIN_KW",
- /* 182 */ "expr ::= nm DOT nm",
- /* 183 */ "expr ::= nm DOT nm DOT nm",
- /* 184 */ "term ::= INTEGER|FLOAT|BLOB",
- /* 185 */ "term ::= STRING",
- /* 186 */ "expr ::= REGISTER",
- /* 187 */ "expr ::= VARIABLE",
- /* 188 */ "expr ::= expr COLLATE ids",
- /* 189 */ "expr ::= CAST LP expr AS typetoken RP",
- /* 190 */ "expr ::= ID LP distinct exprlist RP",
- /* 191 */ "expr ::= ID LP STAR RP",
- /* 192 */ "term ::= CTIME_KW",
- /* 193 */ "expr ::= expr AND expr",
- /* 194 */ "expr ::= expr OR expr",
- /* 195 */ "expr ::= expr LT|GT|GE|LE expr",
- /* 196 */ "expr ::= expr EQ|NE expr",
- /* 197 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
- /* 198 */ "expr ::= expr PLUS|MINUS expr",
- /* 199 */ "expr ::= expr STAR|SLASH|REM expr",
- /* 200 */ "expr ::= expr CONCAT expr",
- /* 201 */ "likeop ::= LIKE_KW",
- /* 202 */ "likeop ::= NOT LIKE_KW",
- /* 203 */ "likeop ::= MATCH",
- /* 204 */ "likeop ::= NOT MATCH",
- /* 205 */ "escape ::= ESCAPE expr",
- /* 206 */ "escape ::=",
- /* 207 */ "expr ::= expr likeop expr escape",
- /* 208 */ "expr ::= expr ISNULL|NOTNULL",
- /* 209 */ "expr ::= expr IS NULL",
- /* 210 */ "expr ::= expr NOT NULL",
- /* 211 */ "expr ::= expr IS NOT NULL",
- /* 212 */ "expr ::= NOT expr",
- /* 213 */ "expr ::= BITNOT expr",
- /* 214 */ "expr ::= MINUS expr",
- /* 215 */ "expr ::= PLUS expr",
- /* 216 */ "between_op ::= BETWEEN",
- /* 217 */ "between_op ::= NOT BETWEEN",
- /* 218 */ "expr ::= expr between_op expr AND expr",
- /* 219 */ "in_op ::= IN",
- /* 220 */ "in_op ::= NOT IN",
- /* 221 */ "expr ::= expr in_op LP exprlist RP",
- /* 222 */ "expr ::= LP select RP",
- /* 223 */ "expr ::= expr in_op LP select RP",
- /* 224 */ "expr ::= expr in_op nm dbnm",
- /* 225 */ "expr ::= EXISTS LP select RP",
- /* 226 */ "expr ::= CASE case_operand case_exprlist case_else END",
- /* 227 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
- /* 228 */ "case_exprlist ::= WHEN expr THEN expr",
- /* 229 */ "case_else ::= ELSE expr",
- /* 230 */ "case_else ::=",
- /* 231 */ "case_operand ::= expr",
- /* 232 */ "case_operand ::=",
- /* 233 */ "exprlist ::= nexprlist",
- /* 234 */ "exprlist ::=",
- /* 235 */ "nexprlist ::= nexprlist COMMA expr",
- /* 236 */ "nexprlist ::= expr",
- /* 237 */ "cmd ::= CREATE uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP",
- /* 238 */ "uniqueflag ::= UNIQUE",
- /* 239 */ "uniqueflag ::=",
- /* 240 */ "idxlist_opt ::=",
- /* 241 */ "idxlist_opt ::= LP idxlist RP",
- /* 242 */ "idxlist ::= idxlist COMMA nm collate sortorder",
- /* 243 */ "idxlist ::= nm collate sortorder",
- /* 244 */ "collate ::=",
- /* 245 */ "collate ::= COLLATE ids",
- /* 246 */ "cmd ::= DROP INDEX ifexists fullname",
- /* 247 */ "cmd ::= VACUUM",
- /* 248 */ "cmd ::= VACUUM nm",
- /* 249 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
- /* 250 */ "cmd ::= PRAGMA nm dbnm EQ ON",
- /* 251 */ "cmd ::= PRAGMA nm dbnm EQ DELETE",
- /* 252 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
- /* 253 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
- /* 254 */ "cmd ::= PRAGMA nm dbnm",
- /* 255 */ "nmnum ::= plus_num",
- /* 256 */ "nmnum ::= nm",
- /* 257 */ "plus_num ::= plus_opt number",
- /* 258 */ "minus_num ::= MINUS number",
- /* 259 */ "number ::= INTEGER|FLOAT",
- /* 260 */ "plus_opt ::= PLUS",
- /* 261 */ "plus_opt ::=",
- /* 262 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END",
- /* 263 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
- /* 264 */ "trigger_time ::= BEFORE",
- /* 265 */ "trigger_time ::= AFTER",
- /* 266 */ "trigger_time ::= INSTEAD OF",
- /* 267 */ "trigger_time ::=",
- /* 268 */ "trigger_event ::= DELETE|INSERT",
- /* 269 */ "trigger_event ::= UPDATE",
- /* 270 */ "trigger_event ::= UPDATE OF inscollist",
- /* 271 */ "foreach_clause ::=",
- /* 272 */ "foreach_clause ::= FOR EACH ROW",
- /* 273 */ "when_clause ::=",
- /* 274 */ "when_clause ::= WHEN expr",
- /* 275 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
- /* 276 */ "trigger_cmd_list ::= trigger_cmd SEMI",
- /* 277 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt",
- /* 278 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP",
- /* 279 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select",
- /* 280 */ "trigger_cmd ::= DELETE FROM nm where_opt",
- /* 281 */ "trigger_cmd ::= select",
- /* 282 */ "expr ::= RAISE LP IGNORE RP",
- /* 283 */ "expr ::= RAISE LP raisetype COMMA nm RP",
- /* 284 */ "raisetype ::= ROLLBACK",
- /* 285 */ "raisetype ::= ABORT",
- /* 286 */ "raisetype ::= FAIL",
- /* 287 */ "cmd ::= DROP TRIGGER ifexists fullname",
- /* 288 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
- /* 289 */ "cmd ::= DETACH database_kw_opt expr",
- /* 290 */ "key_opt ::=",
- /* 291 */ "key_opt ::= KEY expr",
- /* 292 */ "database_kw_opt ::= DATABASE",
- /* 293 */ "database_kw_opt ::=",
- /* 294 */ "cmd ::= REINDEX",
- /* 295 */ "cmd ::= REINDEX nm dbnm",
- /* 296 */ "cmd ::= ANALYZE",
- /* 297 */ "cmd ::= ANALYZE nm dbnm",
- /* 298 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
- /* 299 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column",
- /* 300 */ "add_column_fullname ::= fullname",
- /* 301 */ "kwcolumn_opt ::=",
- /* 302 */ "kwcolumn_opt ::= COLUMNKW",
- /* 303 */ "cmd ::= create_vtab",
- /* 304 */ "cmd ::= create_vtab LP vtabarglist RP",
- /* 305 */ "create_vtab ::= CREATE VIRTUAL TABLE nm dbnm USING nm",
- /* 306 */ "vtabarglist ::= vtabarg",
- /* 307 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
- /* 308 */ "vtabarg ::=",
- /* 309 */ "vtabarg ::= vtabarg vtabargtoken",
- /* 310 */ "vtabargtoken ::= ANY",
- /* 311 */ "vtabargtoken ::= lp anylist RP",
- /* 312 */ "lp ::= LP",
- /* 313 */ "anylist ::=",
- /* 314 */ "anylist ::= anylist ANY",
+ /* 127 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
+ /* 128 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
+ /* 129 */ "dbnm ::=",
+ /* 130 */ "dbnm ::= DOT nm",
+ /* 131 */ "fullname ::= nm dbnm",
+ /* 132 */ "joinop ::= COMMA|JOIN",
+ /* 133 */ "joinop ::= JOIN_KW JOIN",
+ /* 134 */ "joinop ::= JOIN_KW nm JOIN",
+ /* 135 */ "joinop ::= JOIN_KW nm nm JOIN",
+ /* 136 */ "on_opt ::= ON expr",
+ /* 137 */ "on_opt ::=",
+ /* 138 */ "indexed_opt ::=",
+ /* 139 */ "indexed_opt ::= INDEXED BY nm",
+ /* 140 */ "indexed_opt ::= NOT INDEXED",
+ /* 141 */ "using_opt ::= USING LP inscollist RP",
+ /* 142 */ "using_opt ::=",
+ /* 143 */ "orderby_opt ::=",
+ /* 144 */ "orderby_opt ::= ORDER BY sortlist",
+ /* 145 */ "sortlist ::= sortlist COMMA sortitem sortorder",
+ /* 146 */ "sortlist ::= sortitem sortorder",
+ /* 147 */ "sortitem ::= expr",
+ /* 148 */ "sortorder ::= ASC",
+ /* 149 */ "sortorder ::= DESC",
+ /* 150 */ "sortorder ::=",
+ /* 151 */ "groupby_opt ::=",
+ /* 152 */ "groupby_opt ::= GROUP BY nexprlist",
+ /* 153 */ "having_opt ::=",
+ /* 154 */ "having_opt ::= HAVING expr",
+ /* 155 */ "limit_opt ::=",
+ /* 156 */ "limit_opt ::= LIMIT expr",
+ /* 157 */ "limit_opt ::= LIMIT expr OFFSET expr",
+ /* 158 */ "limit_opt ::= LIMIT expr COMMA expr",
+ /* 159 */ "cmd ::= DELETE FROM fullname indexed_opt where_opt",
+ /* 160 */ "where_opt ::=",
+ /* 161 */ "where_opt ::= WHERE expr",
+ /* 162 */ "cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt",
+ /* 163 */ "setlist ::= setlist COMMA nm EQ expr",
+ /* 164 */ "setlist ::= nm EQ expr",
+ /* 165 */ "cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP",
+ /* 166 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select",
+ /* 167 */ "cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES",
+ /* 168 */ "insert_cmd ::= INSERT orconf",
+ /* 169 */ "insert_cmd ::= REPLACE",
+ /* 170 */ "itemlist ::= itemlist COMMA expr",
+ /* 171 */ "itemlist ::= expr",
+ /* 172 */ "inscollist_opt ::=",
+ /* 173 */ "inscollist_opt ::= LP inscollist RP",
+ /* 174 */ "inscollist ::= inscollist COMMA nm",
+ /* 175 */ "inscollist ::= nm",
+ /* 176 */ "expr ::= term",
+ /* 177 */ "expr ::= LP expr RP",
+ /* 178 */ "term ::= NULL",
+ /* 179 */ "expr ::= ID",
+ /* 180 */ "expr ::= JOIN_KW",
+ /* 181 */ "expr ::= nm DOT nm",
+ /* 182 */ "expr ::= nm DOT nm DOT nm",
+ /* 183 */ "term ::= INTEGER|FLOAT|BLOB",
+ /* 184 */ "term ::= STRING",
+ /* 185 */ "expr ::= REGISTER",
+ /* 186 */ "expr ::= VARIABLE",
+ /* 187 */ "expr ::= expr COLLATE ids",
+ /* 188 */ "expr ::= CAST LP expr AS typetoken RP",
+ /* 189 */ "expr ::= ID LP distinct exprlist RP",
+ /* 190 */ "expr ::= ID LP STAR RP",
+ /* 191 */ "term ::= CTIME_KW",
+ /* 192 */ "expr ::= expr AND expr",
+ /* 193 */ "expr ::= expr OR expr",
+ /* 194 */ "expr ::= expr LT|GT|GE|LE expr",
+ /* 195 */ "expr ::= expr EQ|NE expr",
+ /* 196 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
+ /* 197 */ "expr ::= expr PLUS|MINUS expr",
+ /* 198 */ "expr ::= expr STAR|SLASH|REM expr",
+ /* 199 */ "expr ::= expr CONCAT expr",
+ /* 200 */ "likeop ::= LIKE_KW",
+ /* 201 */ "likeop ::= NOT LIKE_KW",
+ /* 202 */ "likeop ::= MATCH",
+ /* 203 */ "likeop ::= NOT MATCH",
+ /* 204 */ "escape ::= ESCAPE expr",
+ /* 205 */ "escape ::=",
+ /* 206 */ "expr ::= expr likeop expr escape",
+ /* 207 */ "expr ::= expr ISNULL|NOTNULL",
+ /* 208 */ "expr ::= expr IS NULL",
+ /* 209 */ "expr ::= expr NOT NULL",
+ /* 210 */ "expr ::= expr IS NOT NULL",
+ /* 211 */ "expr ::= NOT expr",
+ /* 212 */ "expr ::= BITNOT expr",
+ /* 213 */ "expr ::= MINUS expr",
+ /* 214 */ "expr ::= PLUS expr",
+ /* 215 */ "between_op ::= BETWEEN",
+ /* 216 */ "between_op ::= NOT BETWEEN",
+ /* 217 */ "expr ::= expr between_op expr AND expr",
+ /* 218 */ "in_op ::= IN",
+ /* 219 */ "in_op ::= NOT IN",
+ /* 220 */ "expr ::= expr in_op LP exprlist RP",
+ /* 221 */ "expr ::= LP select RP",
+ /* 222 */ "expr ::= expr in_op LP select RP",
+ /* 223 */ "expr ::= expr in_op nm dbnm",
+ /* 224 */ "expr ::= EXISTS LP select RP",
+ /* 225 */ "expr ::= CASE case_operand case_exprlist case_else END",
+ /* 226 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
+ /* 227 */ "case_exprlist ::= WHEN expr THEN expr",
+ /* 228 */ "case_else ::= ELSE expr",
+ /* 229 */ "case_else ::=",
+ /* 230 */ "case_operand ::= expr",
+ /* 231 */ "case_operand ::=",
+ /* 232 */ "exprlist ::= nexprlist",
+ /* 233 */ "exprlist ::=",
+ /* 234 */ "nexprlist ::= nexprlist COMMA expr",
+ /* 235 */ "nexprlist ::= expr",
+ /* 236 */ "cmd ::= CREATE uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP",
+ /* 237 */ "uniqueflag ::= UNIQUE",
+ /* 238 */ "uniqueflag ::=",
+ /* 239 */ "idxlist_opt ::=",
+ /* 240 */ "idxlist_opt ::= LP idxlist RP",
+ /* 241 */ "idxlist ::= idxlist COMMA nm collate sortorder",
+ /* 242 */ "idxlist ::= nm collate sortorder",
+ /* 243 */ "collate ::=",
+ /* 244 */ "collate ::= COLLATE ids",
+ /* 245 */ "cmd ::= DROP INDEX ifexists fullname",
+ /* 246 */ "cmd ::= VACUUM",
+ /* 247 */ "cmd ::= VACUUM nm",
+ /* 248 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
+ /* 249 */ "cmd ::= PRAGMA nm dbnm EQ ON",
+ /* 250 */ "cmd ::= PRAGMA nm dbnm EQ DELETE",
+ /* 251 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
+ /* 252 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
+ /* 253 */ "cmd ::= PRAGMA nm dbnm",
+ /* 254 */ "nmnum ::= plus_num",
+ /* 255 */ "nmnum ::= nm",
+ /* 256 */ "plus_num ::= plus_opt number",
+ /* 257 */ "minus_num ::= MINUS number",
+ /* 258 */ "number ::= INTEGER|FLOAT",
+ /* 259 */ "plus_opt ::= PLUS",
+ /* 260 */ "plus_opt ::=",
+ /* 261 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END",
+ /* 262 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
+ /* 263 */ "trigger_time ::= BEFORE",
+ /* 264 */ "trigger_time ::= AFTER",
+ /* 265 */ "trigger_time ::= INSTEAD OF",
+ /* 266 */ "trigger_time ::=",
+ /* 267 */ "trigger_event ::= DELETE|INSERT",
+ /* 268 */ "trigger_event ::= UPDATE",
+ /* 269 */ "trigger_event ::= UPDATE OF inscollist",
+ /* 270 */ "foreach_clause ::=",
+ /* 271 */ "foreach_clause ::= FOR EACH ROW",
+ /* 272 */ "when_clause ::=",
+ /* 273 */ "when_clause ::= WHEN expr",
+ /* 274 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
+ /* 275 */ "trigger_cmd_list ::= trigger_cmd SEMI",
+ /* 276 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt",
+ /* 277 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP",
+ /* 278 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select",
+ /* 279 */ "trigger_cmd ::= DELETE FROM nm where_opt",
+ /* 280 */ "trigger_cmd ::= select",
+ /* 281 */ "expr ::= RAISE LP IGNORE RP",
+ /* 282 */ "expr ::= RAISE LP raisetype COMMA nm RP",
+ /* 283 */ "raisetype ::= ROLLBACK",
+ /* 284 */ "raisetype ::= ABORT",
+ /* 285 */ "raisetype ::= FAIL",
+ /* 286 */ "cmd ::= DROP TRIGGER ifexists fullname",
+ /* 287 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
+ /* 288 */ "cmd ::= DETACH database_kw_opt expr",
+ /* 289 */ "key_opt ::=",
+ /* 290 */ "key_opt ::= KEY expr",
+ /* 291 */ "database_kw_opt ::= DATABASE",
+ /* 292 */ "database_kw_opt ::=",
+ /* 293 */ "cmd ::= REINDEX",
+ /* 294 */ "cmd ::= REINDEX nm dbnm",
+ /* 295 */ "cmd ::= ANALYZE",
+ /* 296 */ "cmd ::= ANALYZE nm dbnm",
+ /* 297 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
+ /* 298 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column",
+ /* 299 */ "add_column_fullname ::= fullname",
+ /* 300 */ "kwcolumn_opt ::=",
+ /* 301 */ "kwcolumn_opt ::= COLUMNKW",
+ /* 302 */ "cmd ::= create_vtab",
+ /* 303 */ "cmd ::= create_vtab LP vtabarglist RP",
+ /* 304 */ "create_vtab ::= CREATE VIRTUAL TABLE nm dbnm USING nm",
+ /* 305 */ "vtabarglist ::= vtabarg",
+ /* 306 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
+ /* 307 */ "vtabarg ::=",
+ /* 308 */ "vtabarg ::= vtabarg vtabargtoken",
+ /* 309 */ "vtabargtoken ::= ANY",
+ /* 310 */ "vtabargtoken ::= lp anylist RP",
+ /* 311 */ "lp ::= LP",
+ /* 312 */ "anylist ::=",
+ /* 313 */ "anylist ::= anylist ANY",
 };
 #endif /* NDEBUG */
 
 
@@ -81010,26 +82972,25 @@
     ** inside the C code.
     */
     case 156: /* select */
     case 190: /* oneselect */
-    case 208: /* seltablist_paren */
-{
-sqlite3SelectDelete(pParse->db, (yypminor->yy43));
+{
+sqlite3SelectDelete(pParse->db, (yypminor->yy219));
 }
       break;
     case 170: /* term */
     case 171: /* expr */
     case 195: /* where_opt */
     case 197: /* having_opt */
     case 206: /* on_opt */
-    case 212: /* sortitem */
-    case 220: /* escape */
-    case 223: /* case_operand */
-    case 225: /* case_else */
-    case 236: /* when_clause */
-    case 239: /* key_opt */
-{
-sqlite3ExprDelete(pParse->db, (yypminor->yy450));
+    case 211: /* sortitem */
+    case 219: /* escape */
+    case 222: /* case_operand */
+    case 224: /* case_else */
+    case 235: /* when_clause */
+    case 238: /* key_opt */
+{
+sqlite3ExprDelete(pParse->db, (yypminor->yy172));
 }
       break;
     case 175: /* idxlist_opt */
     case 183: /* idxlist */
@@ -81036,42 +82997,42 @@
     case 193: /* selcollist */
     case 196: /* groupby_opt */
     case 198: /* orderby_opt */
     case 200: /* sclp */
-    case 211: /* sortlist */
-    case 213: /* nexprlist */
-    case 214: /* setlist */
-    case 217: /* itemlist */
-    case 218: /* exprlist */
-    case 224: /* case_exprlist */
-{
-sqlite3ExprListDelete(pParse->db, (yypminor->yy242));
+    case 210: /* sortlist */
+    case 212: /* nexprlist */
+    case 213: /* setlist */
+    case 216: /* itemlist */
+    case 217: /* exprlist */
+    case 223: /* case_exprlist */
+{
+sqlite3ExprListDelete(pParse->db, (yypminor->yy174));
 }
       break;
     case 189: /* fullname */
     case 194: /* from */
     case 202: /* seltablist */
     case 203: /* stl_prefix */
 {
-sqlite3SrcListDelete(pParse->db, (yypminor->yy419));
+sqlite3SrcListDelete(pParse->db, (yypminor->yy373));
 }
       break;
     case 207: /* using_opt */
-    case 210: /* inscollist */
-    case 216: /* inscollist_opt */
-{
-sqlite3IdListDelete(pParse->db, (yypminor->yy352));
-}
-      break;
-    case 232: /* trigger_cmd_list */
-    case 237: /* trigger_cmd */
-{
-sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy75));
-}
-      break;
-    case 234: /* trigger_event */
-{
-sqlite3IdListDelete(pParse->db, (yypminor->yy354).b);
+    case 209: /* inscollist */
+    case 215: /* inscollist_opt */
+{
+sqlite3IdListDelete(pParse->db, (yypminor->yy432));
+}
+      break;
+    case 231: /* trigger_cmd_list */
+    case 236: /* trigger_cmd */
+{
+sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy243));
+}
+      break;
+    case 233: /* trigger_event */
+{
+sqlite3IdListDelete(pParse->db, (yypminor->yy370).b);
 }
       break;
     default:  break;   /* If no destructor action specified: do nothing */
   }
@@ -81160,9 +83121,9 @@
   i += iLookAhead;
   if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
     if( iLookAhead>0 ){
 #ifdef YYFALLBACK
-      int iFallback;            /* Fallback token */
+      YYCODETYPE iFallback;            /* Fallback token */
       if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
              && (iFallback = yyFallback[iLookAhead])!=0 ){
 #ifndef NDEBUG
         if( yyTraceFILE ){
@@ -81243,8 +83204,9 @@
    while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
    /* Here code is inserted which will execute if the parser
    ** stack every overflows */
 
+  UNUSED_PARAMETER(yypMinor); /* Silence some compiler warnings */
   sqlite3ErrorMsg(pParse, "parser stack overflow");
   pParse->parseError = 1;
    sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument var */
 }
@@ -81279,10 +83241,10 @@
     }
   }
 #endif
   yytos = &yypParser->yystack[yypParser->yyidx];
-  yytos->stateno = yyNewState;
-  yytos->major = yyMajor;
+  yytos->stateno = (YYACTIONTYPE)yyNewState;
+  yytos->major = (YYCODETYPE)yyMajor;
   yytos->minor = *yypMinor;
 #ifndef NDEBUG
   if( yyTraceFILE && yypParser->yyidx>0 ){
     int i;
@@ -81429,10 +83391,9 @@
   { 203, 2 },
   { 203, 0 },
   { 202, 7 },
   { 202, 7 },
-  { 208, 1 },
-  { 208, 1 },
+  { 202, 7 },
   { 153, 0 },
   { 153, 2 },
   { 189, 2 },
   { 204, 1 },
@@ -81447,11 +83408,11 @@
   { 207, 4 },
   { 207, 0 },
   { 198, 0 },
   { 198, 3 },
-  { 211, 4 },
-  { 211, 2 },
-  { 212, 1 },
+  { 210, 4 },
+  { 210, 2 },
+  { 211, 1 },
   { 173, 1 },
   { 173, 1 },
   { 173, 0 },
   { 196, 0 },
@@ -81465,21 +83426,21 @@
   { 145, 5 },
   { 195, 0 },
   { 195, 2 },
   { 145, 7 },
-  { 214, 5 },
-  { 214, 3 },
+  { 213, 5 },
+  { 213, 3 },
   { 145, 8 },
   { 145, 5 },
   { 145, 6 },
-  { 215, 2 },
-  { 215, 1 },
-  { 217, 3 },
-  { 217, 1 },
-  { 216, 0 },
+  { 214, 2 },
+  { 214, 1 },
   { 216, 3 },
-  { 210, 3 },
-  { 210, 1 },
+  { 216, 1 },
+  { 215, 0 },
+  { 215, 3 },
+  { 209, 3 },
+  { 209, 1 },
   { 171, 1 },
   { 171, 3 },
   { 170, 1 },
   { 171, 1 },
@@ -81502,14 +83463,14 @@
   { 171, 3 },
   { 171, 3 },
   { 171, 3 },
   { 171, 3 },
-  { 219, 1 },
-  { 219, 2 },
-  { 219, 1 },
+  { 218, 1 },
+  { 218, 2 },
+  { 218, 1 },
+  { 218, 2 },
   { 219, 2 },
-  { 220, 2 },
-  { 220, 0 },
+  { 219, 0 },
   { 171, 4 },
   { 171, 2 },
   { 171, 3 },
   { 171, 3 },
@@ -81517,38 +83478,38 @@
   { 171, 2 },
   { 171, 2 },
   { 171, 2 },
   { 171, 2 },
+  { 220, 1 },
+  { 220, 2 },
+  { 171, 5 },
   { 221, 1 },
   { 221, 2 },
-  { 171, 5 },
-  { 222, 1 },
-  { 222, 2 },
   { 171, 5 },
   { 171, 3 },
   { 171, 5 },
   { 171, 4 },
   { 171, 4 },
   { 171, 5 },
-  { 224, 5 },
-  { 224, 4 },
-  { 225, 2 },
-  { 225, 0 },
-  { 223, 1 },
-  { 223, 0 },
-  { 218, 1 },
-  { 218, 0 },
-  { 213, 3 },
-  { 213, 1 },
+  { 223, 5 },
+  { 223, 4 },
+  { 224, 2 },
+  { 224, 0 },
+  { 222, 1 },
+  { 222, 0 },
+  { 217, 1 },
+  { 217, 0 },
+  { 212, 3 },
+  { 212, 1 },
   { 145, 11 },
-  { 226, 1 },
-  { 226, 0 },
+  { 225, 1 },
+  { 225, 0 },
   { 175, 0 },
   { 175, 3 },
   { 183, 5 },
   { 183, 3 },
-  { 227, 0 },
-  { 227, 2 },
+  { 226, 0 },
+  { 226, 2 },
   { 145, 4 },
   { 145, 1 },
   { 145, 2 },
   { 145, 5 },
@@ -81556,35 +83517,35 @@
   { 145, 5 },
   { 145, 5 },
   { 145, 6 },
   { 145, 3 },
-  { 228, 1 },
-  { 228, 1 },
+  { 227, 1 },
+  { 227, 1 },
   { 166, 2 },
   { 167, 2 },
-  { 230, 1 },
   { 229, 1 },
-  { 229, 0 },
+  { 228, 1 },
+  { 228, 0 },
   { 145, 5 },
-  { 231, 11 },
+  { 230, 11 },
+  { 232, 1 },
+  { 232, 1 },
+  { 232, 2 },
+  { 232, 0 },
   { 233, 1 },
   { 233, 1 },
-  { 233, 2 },
-  { 233, 0 },
-  { 234, 1 },
-  { 234, 1 },
+  { 233, 3 },
+  { 234, 0 },
   { 234, 3 },
   { 235, 0 },
-  { 235, 3 },
-  { 236, 0 },
-  { 236, 2 },
-  { 232, 3 },
-  { 232, 2 },
-  { 237, 6 },
-  { 237, 8 },
-  { 237, 5 },
-  { 237, 4 },
-  { 237, 1 },
+  { 235, 2 },
+  { 231, 3 },
+  { 231, 2 },
+  { 236, 6 },
+  { 236, 8 },
+  { 236, 5 },
+  { 236, 4 },
+  { 236, 1 },
   { 171, 4 },
   { 171, 6 },
   { 187, 1 },
   { 187, 1 },
@@ -81591,33 +83552,33 @@
   { 187, 1 },
   { 145, 4 },
   { 145, 6 },
   { 145, 3 },
-  { 239, 0 },
-  { 239, 2 },
-  { 238, 1 },
   { 238, 0 },
+  { 238, 2 },
+  { 237, 1 },
+  { 237, 0 },
   { 145, 1 },
   { 145, 3 },
   { 145, 1 },
   { 145, 3 },
   { 145, 6 },
   { 145, 6 },
-  { 240, 1 },
-  { 241, 0 },
-  { 241, 1 },
+  { 239, 1 },
+  { 240, 0 },
+  { 240, 1 },
   { 145, 1 },
   { 145, 4 },
-  { 242, 7 },
-  { 243, 1 },
-  { 243, 3 },
-  { 244, 0 },
-  { 244, 2 },
+  { 241, 7 },
+  { 242, 1 },
+  { 242, 3 },
+  { 243, 0 },
+  { 243, 2 },
+  { 244, 1 },
+  { 244, 3 },
   { 245, 1 },
-  { 245, 3 },
-  { 246, 1 },
-  { 247, 0 },
-  { 247, 2 },
+  { 246, 0 },
+  { 246, 2 },
 };
 
 static void yy_accept(yyParser*);  /* Forward Declaration */
 
@@ -81693,20 +83654,20 @@
       case 82: /* conslist ::= conslist COMMA tcons */
       case 83: /* conslist ::= conslist tcons */
       case 84: /* conslist ::= tcons */
       case 85: /* tcons ::= CONSTRAINT nm */
-      case 260: /* plus_opt ::= PLUS */
-      case 261: /* plus_opt ::= */
-      case 271: /* foreach_clause ::= */
-      case 272: /* foreach_clause ::= FOR EACH ROW */
-      case 292: /* database_kw_opt ::= DATABASE */
-      case 293: /* database_kw_opt ::= */
-      case 301: /* kwcolumn_opt ::= */
-      case 302: /* kwcolumn_opt ::= COLUMNKW */
-      case 306: /* vtabarglist ::= vtabarg */
-      case 307: /* vtabarglist ::= vtabarglist COMMA vtabarg */
-      case 309: /* vtabarg ::= vtabarg vtabargtoken */
-      case 313: /* anylist ::= */
+      case 259: /* plus_opt ::= PLUS */
+      case 260: /* plus_opt ::= */
+      case 270: /* foreach_clause ::= */
+      case 271: /* foreach_clause ::= FOR EACH ROW */
+      case 291: /* database_kw_opt ::= DATABASE */
+      case 292: /* database_kw_opt ::= */
+      case 300: /* kwcolumn_opt ::= */
+      case 301: /* kwcolumn_opt ::= COLUMNKW */
+      case 305: /* vtabarglist ::= vtabarg */
+      case 306: /* vtabarglist ::= vtabarglist COMMA vtabarg */
+      case 308: /* vtabarg ::= vtabarg vtabargtoken */
+      case 312: /* anylist ::= */
 {
 }
         break;
       case 5: /* explain ::= */
@@ -81721,19 +83682,19 @@
       case 8: /* cmdx ::= cmd */
 { sqlite3FinishCoding(pParse); }
         break;
       case 9: /* cmd ::= BEGIN transtype trans_opt */
-{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy316);}
+{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy46);}
         break;
       case 13: /* transtype ::= */
-{yygotominor.yy316 = TK_DEFERRED;}
+{yygotominor.yy46 = TK_DEFERRED;}
         break;
       case 14: /* transtype ::= DEFERRED */
       case 15: /* transtype ::= IMMEDIATE */
       case 16: /* transtype ::= EXCLUSIVE */
       case 107: /* multiselect_op ::= UNION */
       case 109: /* multiselect_op ::= EXCEPT|INTERSECT */
-{yygotominor.yy316 = yymsp[0].major;}
+{yygotominor.yy46 = yymsp[0].major;}
         break;
       case 17: /* cmd ::= COMMIT trans_opt */
       case 18: /* cmd ::= END trans_opt */
 {sqlite3CommitTransaction(pParse);}
@@ -81742,9 +83703,9 @@
 {sqlite3RollbackTransaction(pParse);}
         break;
       case 21: /* create_table ::= CREATE temp TABLE ifnotexists nm dbnm */
 {
-   sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy316,0,0,yymsp[-2].minor.yy316);
+   sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy46,0,0,yymsp[-2].minor.yy46);
 }
         break;
       case 22: /* ifnotexists ::= */
       case 25: /* temp ::= */
@@ -81754,21 +83715,21 @@
       case 90: /* defer_subclause_opt ::= */
       case 101: /* ifexists ::= */
       case 112: /* distinct ::= ALL */
       case 113: /* distinct ::= */
-      case 216: /* between_op ::= BETWEEN */
-      case 219: /* in_op ::= IN */
-{yygotominor.yy316 = 0;}
+      case 215: /* between_op ::= BETWEEN */
+      case 218: /* in_op ::= IN */
+{yygotominor.yy46 = 0;}
         break;
       case 23: /* ifnotexists ::= IF NOT EXISTS */
       case 24: /* temp ::= TEMP */
       case 64: /* autoinc ::= AUTOINCR */
       case 78: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
       case 100: /* ifexists ::= IF EXISTS */
       case 111: /* distinct ::= DISTINCT */
-      case 217: /* between_op ::= NOT BETWEEN */
-      case 220: /* in_op ::= NOT IN */
-{yygotominor.yy316 = 1;}
+      case 216: /* between_op ::= NOT BETWEEN */
+      case 219: /* in_op ::= NOT IN */
+{yygotominor.yy46 = 1;}
         break;
       case 26: /* create_table_args ::= LP columnlist conslist_opt RP */
 {
   sqlite3EndTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0);
@@ -81775,16 +83736,16 @@
 }
         break;
       case 27: /* create_table_args ::= AS select */
 {
-  sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy43);
-  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy43);
+  sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy219);
+  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy219);
 }
         break;
       case 30: /* column ::= columnid type carglist */
 {
   yygotominor.yy0.z = yymsp[-2].minor.yy0.z;
-  yygotominor.yy0.n = (pParse->sLastToken.z-yymsp[-2].minor.yy0.z) + pParse->sLastToken.n;
+  yygotominor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-2].minor.yy0.z) + pParse->sLastToken.n;
 }
         break;
       case 31: /* columnid ::= nm */
 {
@@ -81800,16 +83761,16 @@
       case 39: /* typetoken ::= typename */
       case 42: /* typename ::= ids */
       case 119: /* as ::= AS nm */
       case 120: /* as ::= ids */
-      case 131: /* dbnm ::= DOT nm */
-      case 140: /* indexed_opt ::= INDEXED BY nm */
-      case 245: /* collate ::= COLLATE ids */
-      case 255: /* nmnum ::= plus_num */
-      case 256: /* nmnum ::= nm */
-      case 257: /* plus_num ::= plus_opt number */
-      case 258: /* minus_num ::= MINUS number */
-      case 259: /* number ::= INTEGER|FLOAT */
+      case 130: /* dbnm ::= DOT nm */
+      case 139: /* indexed_opt ::= INDEXED BY nm */
+      case 244: /* collate ::= COLLATE ids */
+      case 254: /* nmnum ::= plus_num */
+      case 255: /* nmnum ::= nm */
+      case 256: /* plus_num ::= plus_opt number */
+      case 257: /* minus_num ::= MINUS number */
+      case 258: /* number ::= INTEGER|FLOAT */
 {yygotominor.yy0 = yymsp[0].minor.yy0;}
         break;
       case 38: /* type ::= typetoken */
 {sqlite3AddColumnType(pParse,&yymsp[0].minor.yy0);}
@@ -81816,31 +83777,31 @@
         break;
       case 40: /* typetoken ::= typename LP signed RP */
 {
   yygotominor.yy0.z = yymsp[-3].minor.yy0.z;
-  yygotominor.yy0.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z;
+  yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z);
 }
         break;
       case 41: /* typetoken ::= typename LP signed COMMA signed RP */
 {
   yygotominor.yy0.z = yymsp[-5].minor.yy0.z;
-  yygotominor.yy0.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z;
+  yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z);
 }
         break;
       case 43: /* typename ::= typename ids */
-{yygotominor.yy0.z=yymsp[-1].minor.yy0.z; yygotominor.yy0.n=yymsp[0].minor.yy0.n+(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);}
+{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 50: /* ccons ::= DEFAULT term */
       case 52: /* ccons ::= DEFAULT PLUS term */
-{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy450);}
+{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy172);}
         break;
       case 51: /* ccons ::= DEFAULT LP expr RP */
-{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy450);}
+{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy172);}
         break;
       case 53: /* ccons ::= DEFAULT MINUS term */
 {
-  Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy450, 0, 0);
-  sqlite3ExprSpan(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy450->span);
+  Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy172, 0, 0);
+  sqlite3ExprSpan(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy172->span);
   sqlite3AddDefaultValue(pParse,p);
 }
         break;
       case 54: /* ccons ::= DEFAULT id */
@@ -81849,66 +83810,66 @@
   sqlite3AddDefaultValue(pParse,p);
 }
         break;
       case 56: /* ccons ::= NOT NULL onconf */
-{sqlite3AddNotNull(pParse, yymsp[0].minor.yy316);}
+{sqlite3AddNotNull(pParse, yymsp[0].minor.yy46);}
         break;
       case 57: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
-{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy316,yymsp[0].minor.yy316,yymsp[-2].minor.yy316);}
+{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy46,yymsp[0].minor.yy46,yymsp[-2].minor.yy46);}
         break;
       case 58: /* ccons ::= UNIQUE onconf */
-{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy316,0,0,0,0);}
+{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy46,0,0,0,0);}
         break;
       case 59: /* ccons ::= CHECK LP expr RP */
-{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy450);}
+{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy172);}
         break;
       case 60: /* ccons ::= REFERENCES nm idxlist_opt refargs */
-{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy242,yymsp[0].minor.yy316);}
+{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy174,yymsp[0].minor.yy46);}
         break;
       case 61: /* ccons ::= defer_subclause */
-{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy316);}
+{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy46);}
         break;
       case 62: /* ccons ::= COLLATE ids */
 {sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
         break;
       case 65: /* refargs ::= */
-{ yygotominor.yy316 = OE_Restrict * 0x010101; }
+{ yygotominor.yy46 = OE_Restrict * 0x010101; }
         break;
       case 66: /* refargs ::= refargs refarg */
-{ yygotominor.yy316 = (yymsp[-1].minor.yy316 & ~yymsp[0].minor.yy207.mask) | yymsp[0].minor.yy207.value; }
+{ yygotominor.yy46 = (yymsp[-1].minor.yy46 & ~yymsp[0].minor.yy405.mask) | yymsp[0].minor.yy405.value; }
         break;
       case 67: /* refarg ::= MATCH nm */
-{ yygotominor.yy207.value = 0;     yygotominor.yy207.mask = 0x000000; }
+{ yygotominor.yy405.value = 0;     yygotominor.yy405.mask = 0x000000; }
         break;
       case 68: /* refarg ::= ON DELETE refact */
-{ yygotominor.yy207.value = yymsp[0].minor.yy316;     yygotominor.yy207.mask = 0x0000ff; }
+{ yygotominor.yy405.value = yymsp[0].minor.yy46;     yygotominor.yy405.mask = 0x0000ff; }
         break;
       case 69: /* refarg ::= ON UPDATE refact */
-{ yygotominor.yy207.value = yymsp[0].minor.yy316<<8;  yygotominor.yy207.mask = 0x00ff00; }
+{ yygotominor.yy405.value = yymsp[0].minor.yy46<<8;  yygotominor.yy405.mask = 0x00ff00; }
         break;
       case 70: /* refarg ::= ON INSERT refact */
-{ yygotominor.yy207.value = yymsp[0].minor.yy316<<16; yygotominor.yy207.mask = 0xff0000; }
+{ yygotominor.yy405.value = yymsp[0].minor.yy46<<16; yygotominor.yy405.mask = 0xff0000; }
         break;
       case 71: /* refact ::= SET NULL */
-{ yygotominor.yy316 = OE_SetNull; }
+{ yygotominor.yy46 = OE_SetNull; }
         break;
       case 72: /* refact ::= SET DEFAULT */
-{ yygotominor.yy316 = OE_SetDflt; }
+{ yygotominor.yy46 = OE_SetDflt; }
         break;
       case 73: /* refact ::= CASCADE */
-{ yygotominor.yy316 = OE_Cascade; }
+{ yygotominor.yy46 = OE_Cascade; }
         break;
       case 74: /* refact ::= RESTRICT */
-{ yygotominor.yy316 = OE_Restrict; }
+{ yygotominor.yy46 = OE_Restrict; }
         break;
       case 75: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
       case 76: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
       case 91: /* defer_subclause_opt ::= defer_subclause */
       case 93: /* onconf ::= ON CONFLICT resolvetype */
       case 95: /* orconf ::= OR resolvetype */
       case 96: /* resolvetype ::= raisetype */
-      case 169: /* insert_cmd ::= INSERT orconf */
-{yygotominor.yy316 = yymsp[0].minor.yy316;}
+      case 168: /* insert_cmd ::= INSERT orconf */
+{yygotominor.yy46 = yymsp[0].minor.yy46;}
         break;
       case 80: /* conslist_opt ::= */
 {yygotominor.yy0.n = 0; yygotominor.yy0.z = 0;}
         break;
@@ -81915,759 +83876,764 @@
       case 81: /* conslist_opt ::= COMMA conslist */
 {yygotominor.yy0 = yymsp[-1].minor.yy0;}
         break;
       case 86: /* tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf */
-{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy242,yymsp[0].minor.yy316,yymsp[-2].minor.yy316,0);}
+{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy174,yymsp[0].minor.yy46,yymsp[-2].minor.yy46,0);}
         break;
       case 87: /* tcons ::= UNIQUE LP idxlist RP onconf */
-{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy242,yymsp[0].minor.yy316,0,0,0,0);}
+{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy174,yymsp[0].minor.yy46,0,0,0,0);}
         break;
       case 88: /* tcons ::= CHECK LP expr RP onconf */
-{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy450);}
+{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy172);}
         break;
       case 89: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt */
 {
-    sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy242, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy242, yymsp[-1].minor.yy316);
-    sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy316);
+    sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy174, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy174, yymsp[-1].minor.yy46);
+    sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy46);
 }
         break;
       case 92: /* onconf ::= */
       case 94: /* orconf ::= */
-{yygotominor.yy316 = OE_Default;}
+{yygotominor.yy46 = OE_Default;}
         break;
       case 97: /* resolvetype ::= IGNORE */
-{yygotominor.yy316 = OE_Ignore;}
+{yygotominor.yy46 = OE_Ignore;}
         break;
       case 98: /* resolvetype ::= REPLACE */
-      case 170: /* insert_cmd ::= REPLACE */
-{yygotominor.yy316 = OE_Replace;}
+      case 169: /* insert_cmd ::= REPLACE */
+{yygotominor.yy46 = OE_Replace;}
         break;
       case 99: /* cmd ::= DROP TABLE ifexists fullname */
 {
-  sqlite3DropTable(pParse, yymsp[0].minor.yy419, 0, yymsp[-1].minor.yy316);
+  sqlite3DropTable(pParse, yymsp[0].minor.yy373, 0, yymsp[-1].minor.yy46);
 }
         break;
       case 102: /* cmd ::= CREATE temp VIEW ifnotexists nm dbnm AS select */
 {
-  sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy43, yymsp[-6].minor.yy316, yymsp[-4].minor.yy316);
+  sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy219, yymsp[-6].minor.yy46, yymsp[-4].minor.yy46);
 }
         break;
       case 103: /* cmd ::= DROP VIEW ifexists fullname */
 {
-  sqlite3DropTable(pParse, yymsp[0].minor.yy419, 1, yymsp[-1].minor.yy316);
+  sqlite3DropTable(pParse, yymsp[0].minor.yy373, 1, yymsp[-1].minor.yy46);
 }
         break;
       case 104: /* cmd ::= select */
 {
   SelectDest dest = {SRT_Output, 0, 0, 0, 0};
-  sqlite3Select(pParse, yymsp[0].minor.yy43, &dest);
-  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy43);
+  sqlite3Select(pParse, yymsp[0].minor.yy219, &dest);
+  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy219);
 }
         break;
       case 105: /* select ::= oneselect */
-      case 128: /* seltablist_paren ::= select */
-{yygotominor.yy43 = yymsp[0].minor.yy43;}
+{yygotominor.yy219 = yymsp[0].minor.yy219;}
         break;
       case 106: /* select ::= select multiselect_op oneselect */
 {
-  if( yymsp[0].minor.yy43 ){
-    yymsp[0].minor.yy43->op = yymsp[-1].minor.yy316;
-    yymsp[0].minor.yy43->pPrior = yymsp[-2].minor.yy43;
-  }else{
-    sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy43);
-  }
-  yygotominor.yy43 = yymsp[0].minor.yy43;
+  if( yymsp[0].minor.yy219 ){
+    yymsp[0].minor.yy219->op = (u8)yymsp[-1].minor.yy46;
+    yymsp[0].minor.yy219->pPrior = yymsp[-2].minor.yy219;
+  }else{
+    sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy219);
+  }
+  yygotominor.yy219 = yymsp[0].minor.yy219;
 }
         break;
       case 108: /* multiselect_op ::= UNION ALL */
-{yygotominor.yy316 = TK_ALL;}
+{yygotominor.yy46 = TK_ALL;}
         break;
       case 110: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
 {
-  yygotominor.yy43 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy242,yymsp[-5].minor.yy419,yymsp[-4].minor.yy450,yymsp[-3].minor.yy242,yymsp[-2].minor.yy450,yymsp[-1].minor.yy242,yymsp[-7].minor.yy316,yymsp[0].minor.yy84.pLimit,yymsp[0].minor.yy84.pOffset);
+  yygotominor.yy219 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy174,yymsp[-5].minor.yy373,yymsp[-4].minor.yy172,yymsp[-3].minor.yy174,yymsp[-2].minor.yy172,yymsp[-1].minor.yy174,yymsp[-7].minor.yy46,yymsp[0].minor.yy234.pLimit,yymsp[0].minor.yy234.pOffset);
 }
         break;
       case 114: /* sclp ::= selcollist COMMA */
-      case 241: /* idxlist_opt ::= LP idxlist RP */
-{yygotominor.yy242 = yymsp[-1].minor.yy242;}
+      case 240: /* idxlist_opt ::= LP idxlist RP */
+{yygotominor.yy174 = yymsp[-1].minor.yy174;}
         break;
       case 115: /* sclp ::= */
-      case 144: /* orderby_opt ::= */
-      case 152: /* groupby_opt ::= */
-      case 234: /* exprlist ::= */
-      case 240: /* idxlist_opt ::= */
-{yygotominor.yy242 = 0;}
+      case 143: /* orderby_opt ::= */
+      case 151: /* groupby_opt ::= */
+      case 233: /* exprlist ::= */
+      case 239: /* idxlist_opt ::= */
+{yygotominor.yy174 = 0;}
         break;
       case 116: /* selcollist ::= sclp expr as */
 {
-   yygotominor.yy242 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy242,yymsp[-1].minor.yy450,yymsp[0].minor.yy0.n?&yymsp[0].minor.yy0:0);
+   yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy174,yymsp[-1].minor.yy172,yymsp[0].minor.yy0.n?&yymsp[0].minor.yy0:0);
 }
         break;
       case 117: /* selcollist ::= sclp STAR */
 {
   Expr *p = sqlite3PExpr(pParse, TK_ALL, 0, 0, 0);
-  yygotominor.yy242 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy242, p, 0);
+  yygotominor.yy174 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy174, p, 0);
 }
         break;
       case 118: /* 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.yy242 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy242, pDot, 0);
+  yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy174, pDot, 0);
 }
         break;
       case 121: /* as ::= */
 {yygotominor.yy0.n = 0;}
         break;
       case 122: /* from ::= */
-{yygotominor.yy419 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy419));}
+{yygotominor.yy373 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy373));}
         break;
       case 123: /* from ::= FROM seltablist */
 {
-  yygotominor.yy419 = yymsp[0].minor.yy419;
-  sqlite3SrcListShiftJoinType(yygotominor.yy419);
+  yygotominor.yy373 = yymsp[0].minor.yy373;
+  sqlite3SrcListShiftJoinType(yygotominor.yy373);
 }
         break;
       case 124: /* stl_prefix ::= seltablist joinop */
 {
-   yygotominor.yy419 = yymsp[-1].minor.yy419;
-   if( yygotominor.yy419 && yygotominor.yy419->nSrc>0 ) yygotominor.yy419->a[yygotominor.yy419->nSrc-1].jointype = yymsp[0].minor.yy316;
+   yygotominor.yy373 = yymsp[-1].minor.yy373;
+   if( yygotominor.yy373 && yygotominor.yy373->nSrc>0 ) yygotominor.yy373->a[yygotominor.yy373->nSrc-1].jointype = (u8)yymsp[0].minor.yy46;
 }
         break;
       case 125: /* stl_prefix ::= */
-{yygotominor.yy419 = 0;}
+{yygotominor.yy373 = 0;}
         break;
       case 126: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
 {
-  yygotominor.yy419 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy419,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy450,yymsp[0].minor.yy352);
-  sqlite3SrcListIndexedBy(pParse, yygotominor.yy419, &yymsp[-2].minor.yy0);
-}
-        break;
-      case 127: /* seltablist ::= stl_prefix LP seltablist_paren RP as on_opt using_opt */
-{
-    yygotominor.yy419 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy419,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy43,yymsp[-1].minor.yy450,yymsp[0].minor.yy352);
-  }
-        break;
-      case 129: /* seltablist_paren ::= seltablist */
-{
-     sqlite3SrcListShiftJoinType(yymsp[0].minor.yy419);
-     yygotominor.yy43 = sqlite3SelectNew(pParse,0,yymsp[0].minor.yy419,0,0,0,0,0,0,0);
-  }
-        break;
-      case 130: /* dbnm ::= */
-      case 139: /* indexed_opt ::= */
+  yygotominor.yy373 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy373,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy172,yymsp[0].minor.yy432);
+  sqlite3SrcListIndexedBy(pParse, yygotominor.yy373, &yymsp[-2].minor.yy0);
+}
+        break;
+      case 127: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+{
+    yygotominor.yy373 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy373,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy219,yymsp[-1].minor.yy172,yymsp[0].minor.yy432);
+  }
+        break;
+      case 128: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+{
+    if( yymsp[-6].minor.yy373==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy172==0 && yymsp[0].minor.yy432==0 ){
+      yygotominor.yy373 = yymsp[-4].minor.yy373;
+    }else{
+      Select *pSubquery;
+      sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy373);
+      pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy373,0,0,0,0,0,0,0);
+      yygotominor.yy373 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy373,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy172,yymsp[0].minor.yy432);
+    }
+  }
+        break;
+      case 129: /* dbnm ::= */
+      case 138: /* indexed_opt ::= */
 {yygotominor.yy0.z=0; yygotominor.yy0.n=0;}
         break;
-      case 132: /* fullname ::= nm dbnm */
-{yygotominor.yy419 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
-        break;
-      case 133: /* joinop ::= COMMA|JOIN */
-{ yygotominor.yy316 = JT_INNER; }
-        break;
-      case 134: /* joinop ::= JOIN_KW JOIN */
-{ yygotominor.yy316 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
-        break;
-      case 135: /* joinop ::= JOIN_KW nm JOIN */
-{ yygotominor.yy316 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); }
-        break;
-      case 136: /* joinop ::= JOIN_KW nm nm JOIN */
-{ yygotominor.yy316 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); }
-        break;
-      case 137: /* on_opt ::= ON expr */
-      case 148: /* sortitem ::= expr */
-      case 155: /* having_opt ::= HAVING expr */
-      case 162: /* where_opt ::= WHERE expr */
-      case 177: /* expr ::= term */
-      case 205: /* escape ::= ESCAPE expr */
-      case 229: /* case_else ::= ELSE expr */
-      case 231: /* case_operand ::= expr */
-{yygotominor.yy450 = yymsp[0].minor.yy450;}
-        break;
-      case 138: /* on_opt ::= */
-      case 154: /* having_opt ::= */
-      case 161: /* where_opt ::= */
-      case 206: /* escape ::= */
-      case 230: /* case_else ::= */
-      case 232: /* case_operand ::= */
-{yygotominor.yy450 = 0;}
-        break;
-      case 141: /* indexed_opt ::= NOT INDEXED */
+      case 131: /* fullname ::= nm dbnm */
+{yygotominor.yy373 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
+        break;
+      case 132: /* joinop ::= COMMA|JOIN */
+{ yygotominor.yy46 = JT_INNER; }
+        break;
+      case 133: /* joinop ::= JOIN_KW JOIN */
+{ yygotominor.yy46 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
+        break;
+      case 134: /* joinop ::= JOIN_KW nm JOIN */
+{ yygotominor.yy46 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); }
+        break;
+      case 135: /* joinop ::= JOIN_KW nm nm JOIN */
+{ yygotominor.yy46 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); }
+        break;
+      case 136: /* on_opt ::= ON expr */
+      case 147: /* sortitem ::= expr */
+      case 154: /* having_opt ::= HAVING expr */
+      case 161: /* where_opt ::= WHERE expr */
+      case 176: /* expr ::= term */
+      case 204: /* escape ::= ESCAPE expr */
+      case 228: /* case_else ::= ELSE expr */
+      case 230: /* case_operand ::= expr */
+{yygotominor.yy172 = yymsp[0].minor.yy172;}
+        break;
+      case 137: /* on_opt ::= */
+      case 153: /* having_opt ::= */
+      case 160: /* where_opt ::= */
+      case 205: /* escape ::= */
+      case 229: /* case_else ::= */
+      case 231: /* case_operand ::= */
+{yygotominor.yy172 = 0;}
+        break;
+      case 140: /* indexed_opt ::= NOT INDEXED */
 {yygotominor.yy0.z=0; yygotominor.yy0.n=1;}
         break;
-      case 142: /* using_opt ::= USING LP inscollist RP */
-      case 174: /* inscollist_opt ::= LP inscollist RP */
-{yygotominor.yy352 = yymsp[-1].minor.yy352;}
-        break;
-      case 143: /* using_opt ::= */
-      case 173: /* inscollist_opt ::= */
-{yygotominor.yy352 = 0;}
-        break;
-      case 145: /* orderby_opt ::= ORDER BY sortlist */
-      case 153: /* groupby_opt ::= GROUP BY nexprlist */
-      case 233: /* exprlist ::= nexprlist */
-{yygotominor.yy242 = yymsp[0].minor.yy242;}
-        break;
-      case 146: /* sortlist ::= sortlist COMMA sortitem sortorder */
-{
-  yygotominor.yy242 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy242,yymsp[-1].minor.yy450,0);
-  if( yygotominor.yy242 ) yygotominor.yy242->a[yygotominor.yy242->nExpr-1].sortOrder = yymsp[0].minor.yy316;
-}
-        break;
-      case 147: /* sortlist ::= sortitem sortorder */
-{
-  yygotominor.yy242 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy450,0);
-  if( yygotominor.yy242 && yygotominor.yy242->a ) yygotominor.yy242->a[0].sortOrder = yymsp[0].minor.yy316;
-}
-        break;
-      case 149: /* sortorder ::= ASC */
-      case 151: /* sortorder ::= */
-{yygotominor.yy316 = SQLITE_SO_ASC;}
-        break;
-      case 150: /* sortorder ::= DESC */
-{yygotominor.yy316 = SQLITE_SO_DESC;}
-        break;
-      case 156: /* limit_opt ::= */
-{yygotominor.yy84.pLimit = 0; yygotominor.yy84.pOffset = 0;}
-        break;
-      case 157: /* limit_opt ::= LIMIT expr */
-{yygotominor.yy84.pLimit = yymsp[0].minor.yy450; yygotominor.yy84.pOffset = 0;}
-        break;
-      case 158: /* limit_opt ::= LIMIT expr OFFSET expr */
-{yygotominor.yy84.pLimit = yymsp[-2].minor.yy450; yygotominor.yy84.pOffset = yymsp[0].minor.yy450;}
-        break;
-      case 159: /* limit_opt ::= LIMIT expr COMMA expr */
-{yygotominor.yy84.pOffset = yymsp[-2].minor.yy450; yygotominor.yy84.pLimit = yymsp[0].minor.yy450;}
-        break;
-      case 160: /* cmd ::= DELETE FROM fullname indexed_opt where_opt */
-{
-  sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy419, &yymsp[-1].minor.yy0);
-  sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy419,yymsp[0].minor.yy450);
-}
-        break;
-      case 163: /* cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt */
-{
-  sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy419, &yymsp[-3].minor.yy0);
-  sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy242,"set list");
-  sqlite3Update(pParse,yymsp[-4].minor.yy419,yymsp[-1].minor.yy242,yymsp[0].minor.yy450,yymsp[-5].minor.yy316);
-}
-        break;
-      case 164: /* setlist ::= setlist COMMA nm EQ expr */
-{yygotominor.yy242 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy242,yymsp[0].minor.yy450,&yymsp[-2].minor.yy0);}
-        break;
-      case 165: /* setlist ::= nm EQ expr */
-{yygotominor.yy242 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy450,&yymsp[-2].minor.yy0);}
-        break;
-      case 166: /* cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP */
-{sqlite3Insert(pParse, yymsp[-5].minor.yy419, yymsp[-1].minor.yy242, 0, yymsp[-4].minor.yy352, yymsp[-7].minor.yy316);}
-        break;
-      case 167: /* cmd ::= insert_cmd INTO fullname inscollist_opt select */
-{sqlite3Insert(pParse, yymsp[-2].minor.yy419, 0, yymsp[0].minor.yy43, yymsp[-1].minor.yy352, yymsp[-4].minor.yy316);}
-        break;
-      case 168: /* cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES */
-{sqlite3Insert(pParse, yymsp[-3].minor.yy419, 0, 0, yymsp[-2].minor.yy352, yymsp[-5].minor.yy316);}
-        break;
-      case 171: /* itemlist ::= itemlist COMMA expr */
-      case 235: /* nexprlist ::= nexprlist COMMA expr */
-{yygotominor.yy242 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy242,yymsp[0].minor.yy450,0);}
-        break;
-      case 172: /* itemlist ::= expr */
-      case 236: /* nexprlist ::= expr */
-{yygotominor.yy242 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy450,0);}
-        break;
-      case 175: /* inscollist ::= inscollist COMMA nm */
-{yygotominor.yy352 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy352,&yymsp[0].minor.yy0);}
-        break;
-      case 176: /* inscollist ::= nm */
-{yygotominor.yy352 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);}
-        break;
-      case 178: /* expr ::= LP expr RP */
-{yygotominor.yy450 = yymsp[-1].minor.yy450; sqlite3ExprSpan(yygotominor.yy450,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); }
-        break;
-      case 179: /* term ::= NULL */
-      case 184: /* term ::= INTEGER|FLOAT|BLOB */
-      case 185: /* term ::= STRING */
-{yygotominor.yy450 = sqlite3PExpr(pParse, yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);}
-        break;
-      case 180: /* expr ::= ID */
-      case 181: /* expr ::= JOIN_KW */
-{yygotominor.yy450 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);}
-        break;
-      case 182: /* expr ::= nm DOT nm */
+      case 141: /* using_opt ::= USING LP inscollist RP */
+      case 173: /* inscollist_opt ::= LP inscollist RP */
+{yygotominor.yy432 = yymsp[-1].minor.yy432;}
+        break;
+      case 142: /* using_opt ::= */
+      case 172: /* inscollist_opt ::= */
+{yygotominor.yy432 = 0;}
+        break;
+      case 144: /* orderby_opt ::= ORDER BY sortlist */
+      case 152: /* groupby_opt ::= GROUP BY nexprlist */
+      case 232: /* exprlist ::= nexprlist */
+{yygotominor.yy174 = yymsp[0].minor.yy174;}
+        break;
+      case 145: /* sortlist ::= sortlist COMMA sortitem sortorder */
+{
+  yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy174,yymsp[-1].minor.yy172,0);
+  if( yygotominor.yy174 ) yygotominor.yy174->a[yygotominor.yy174->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy46;
+}
+        break;
+      case 146: /* sortlist ::= sortitem sortorder */
+{
+  yygotominor.yy174 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy172,0);
+  if( yygotominor.yy174 && yygotominor.yy174->a ) yygotominor.yy174->a[0].sortOrder = (u8)yymsp[0].minor.yy46;
+}
+        break;
+      case 148: /* sortorder ::= ASC */
+      case 150: /* sortorder ::= */
+{yygotominor.yy46 = SQLITE_SO_ASC;}
+        break;
+      case 149: /* sortorder ::= DESC */
+{yygotominor.yy46 = SQLITE_SO_DESC;}
+        break;
+      case 155: /* limit_opt ::= */
+{yygotominor.yy234.pLimit = 0; yygotominor.yy234.pOffset = 0;}
+        break;
+      case 156: /* limit_opt ::= LIMIT expr */
+{yygotominor.yy234.pLimit = yymsp[0].minor.yy172; yygotominor.yy234.pOffset = 0;}
+        break;
+      case 157: /* limit_opt ::= LIMIT expr OFFSET expr */
+{yygotominor.yy234.pLimit = yymsp[-2].minor.yy172; yygotominor.yy234.pOffset = yymsp[0].minor.yy172;}
+        break;
+      case 158: /* limit_opt ::= LIMIT expr COMMA expr */
+{yygotominor.yy234.pOffset = yymsp[-2].minor.yy172; yygotominor.yy234.pLimit = yymsp[0].minor.yy172;}
+        break;
+      case 159: /* cmd ::= DELETE FROM fullname indexed_opt where_opt */
+{
+  sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy373, &yymsp[-1].minor.yy0);
+  sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy373,yymsp[0].minor.yy172);
+}
+        break;
+      case 162: /* cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt */
+{
+  sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy373, &yymsp[-3].minor.yy0);
+  sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy174,"set list");
+  sqlite3Update(pParse,yymsp[-4].minor.yy373,yymsp[-1].minor.yy174,yymsp[0].minor.yy172,yymsp[-5].minor.yy46);
+}
+        break;
+      case 163: /* setlist ::= setlist COMMA nm EQ expr */
+{yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy174,yymsp[0].minor.yy172,&yymsp[-2].minor.yy0);}
+        break;
+      case 164: /* setlist ::= nm EQ expr */
+{yygotominor.yy174 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy172,&yymsp[-2].minor.yy0);}
+        break;
+      case 165: /* cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP */
+{sqlite3Insert(pParse, yymsp[-5].minor.yy373, yymsp[-1].minor.yy174, 0, yymsp[-4].minor.yy432, yymsp[-7].minor.yy46);}
+        break;
+      case 166: /* cmd ::= insert_cmd INTO fullname inscollist_opt select */
+{sqlite3Insert(pParse, yymsp[-2].minor.yy373, 0, yymsp[0].minor.yy219, yymsp[-1].minor.yy432, yymsp[-4].minor.yy46);}
+        break;
+      case 167: /* cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES */
+{sqlite3Insert(pParse, yymsp[-3].minor.yy373, 0, 0, yymsp[-2].minor.yy432, yymsp[-5].minor.yy46);}
+        break;
+      case 170: /* itemlist ::= itemlist COMMA expr */
+      case 234: /* nexprlist ::= nexprlist COMMA expr */
+{yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy174,yymsp[0].minor.yy172,0);}
+        break;
+      case 171: /* itemlist ::= expr */
+      case 235: /* nexprlist ::= expr */
+{yygotominor.yy174 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy172,0);}
+        break;
+      case 174: /* inscollist ::= inscollist COMMA nm */
+{yygotominor.yy432 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy432,&yymsp[0].minor.yy0);}
+        break;
+      case 175: /* inscollist ::= nm */
+{yygotominor.yy432 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);}
+        break;
+      case 177: /* expr ::= LP expr RP */
+{yygotominor.yy172 = yymsp[-1].minor.yy172; sqlite3ExprSpan(yygotominor.yy172,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); }
+        break;
+      case 178: /* term ::= NULL */
+      case 183: /* term ::= INTEGER|FLOAT|BLOB */
+      case 184: /* term ::= STRING */
+{yygotominor.yy172 = sqlite3PExpr(pParse, yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);}
+        break;
+      case 179: /* expr ::= ID */
+      case 180: /* expr ::= JOIN_KW */
+{yygotominor.yy172 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);}
+        break;
+      case 181: /* 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.yy450 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
-}
-        break;
-      case 183: /* expr ::= nm DOT nm DOT nm */
+  yygotominor.yy172 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
+}
+        break;
+      case 182: /* expr ::= nm DOT nm DOT nm */
 {
   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.yy450 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
-}
-        break;
-      case 186: /* expr ::= REGISTER */
-{yygotominor.yy450 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);}
-        break;
-      case 187: /* expr ::= VARIABLE */
+  yygotominor.yy172 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
+}
+        break;
+      case 185: /* expr ::= REGISTER */
+{yygotominor.yy172 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);}
+        break;
+      case 186: /* expr ::= VARIABLE */
 {
   Token *pToken = &yymsp[0].minor.yy0;
-  Expr *pExpr = yygotominor.yy450 = sqlite3PExpr(pParse, TK_VARIABLE, 0, 0, pToken);
+  Expr *pExpr = yygotominor.yy172 = sqlite3PExpr(pParse, TK_VARIABLE, 0, 0, pToken);
   sqlite3ExprAssignVarNumber(pParse, pExpr);
 }
         break;
-      case 188: /* expr ::= expr COLLATE ids */
-{
-  yygotominor.yy450 = sqlite3ExprSetColl(pParse, yymsp[-2].minor.yy450, &yymsp[0].minor.yy0);
-}
-        break;
-      case 189: /* expr ::= CAST LP expr AS typetoken RP */
-{
-  yygotominor.yy450 = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy450, 0, &yymsp[-1].minor.yy0);
-  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
-}
-        break;
-      case 190: /* expr ::= ID LP distinct exprlist RP */
-{
-  if( yymsp[-1].minor.yy242 && yymsp[-1].minor.yy242->nExpr>SQLITE_MAX_FUNCTION_ARG ){
+      case 187: /* expr ::= expr COLLATE ids */
+{
+  yygotominor.yy172 = sqlite3ExprSetColl(pParse, yymsp[-2].minor.yy172, &yymsp[0].minor.yy0);
+}
+        break;
+      case 188: /* expr ::= CAST LP expr AS typetoken RP */
+{
+  yygotominor.yy172 = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy172, 0, &yymsp[-1].minor.yy0);
+  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
+}
+        break;
+      case 189: /* expr ::= ID LP distinct exprlist RP */
+{
+  if( yymsp[-1].minor.yy174 && yymsp[-1].minor.yy174->nExpr>SQLITE_MAX_FUNCTION_ARG ){
     sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
   }
-  yygotominor.yy450 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy242, &yymsp[-4].minor.yy0);
-  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
-  if( yymsp[-2].minor.yy316 && yygotominor.yy450 ){
-    yygotominor.yy450->flags |= EP_Distinct;
-  }
-}
-        break;
-      case 191: /* expr ::= ID LP STAR RP */
-{
-  yygotominor.yy450 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
-  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
-}
-        break;
-      case 192: /* term ::= CTIME_KW */
+  yygotominor.yy172 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy174, &yymsp[-4].minor.yy0);
+  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
+  if( yymsp[-2].minor.yy46 && yygotominor.yy172 ){
+    yygotominor.yy172->flags |= EP_Distinct;
+  }
+}
+        break;
+      case 190: /* expr ::= ID LP STAR RP */
+{
+  yygotominor.yy172 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
+  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
+}
+        break;
+      case 191: /* term ::= CTIME_KW */
 {
   /* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are
   ** treated as functions that return constants */
-  yygotominor.yy450 = sqlite3ExprFunction(pParse, 0,&yymsp[0].minor.yy0);
-  if( yygotominor.yy450 ){
-    yygotominor.yy450->op = TK_CONST_FUNC;
-    yygotominor.yy450->span = yymsp[0].minor.yy0;
-  }
-}
-        break;
-      case 193: /* expr ::= expr AND expr */
-      case 194: /* expr ::= expr OR expr */
-      case 195: /* expr ::= expr LT|GT|GE|LE expr */
-      case 196: /* expr ::= expr EQ|NE expr */
-      case 197: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
-      case 198: /* expr ::= expr PLUS|MINUS expr */
-      case 199: /* expr ::= expr STAR|SLASH|REM expr */
-      case 200: /* expr ::= expr CONCAT expr */
-{yygotominor.yy450 = sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy450,yymsp[0].minor.yy450,0);}
-        break;
-      case 201: /* likeop ::= LIKE_KW */
-      case 203: /* likeop ::= MATCH */
-{yygotominor.yy86.eOperator = yymsp[0].minor.yy0; yygotominor.yy86.not = 0;}
-        break;
-      case 202: /* likeop ::= NOT LIKE_KW */
-      case 204: /* likeop ::= NOT MATCH */
-{yygotominor.yy86.eOperator = yymsp[0].minor.yy0; yygotominor.yy86.not = 1;}
-        break;
-      case 207: /* expr ::= expr likeop expr escape */
+  yygotominor.yy172 = sqlite3ExprFunction(pParse, 0,&yymsp[0].minor.yy0);
+  if( yygotominor.yy172 ){
+    yygotominor.yy172->op = TK_CONST_FUNC;
+    yygotominor.yy172->span = yymsp[0].minor.yy0;
+  }
+}
+        break;
+      case 192: /* expr ::= expr AND expr */
+      case 193: /* expr ::= expr OR expr */
+      case 194: /* expr ::= expr LT|GT|GE|LE expr */
+      case 195: /* expr ::= expr EQ|NE expr */
+      case 196: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
+      case 197: /* expr ::= expr PLUS|MINUS expr */
+      case 198: /* expr ::= expr STAR|SLASH|REM expr */
+      case 199: /* expr ::= expr CONCAT expr */
+{yygotominor.yy172 = sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy172,yymsp[0].minor.yy172,0);}
+        break;
+      case 200: /* likeop ::= LIKE_KW */
+      case 202: /* likeop ::= MATCH */
+{yygotominor.yy72.eOperator = yymsp[0].minor.yy0; yygotominor.yy72.not = 0;}
+        break;
+      case 201: /* likeop ::= NOT LIKE_KW */
+      case 203: /* likeop ::= NOT MATCH */
+{yygotominor.yy72.eOperator = yymsp[0].minor.yy0; yygotominor.yy72.not = 1;}
+        break;
+      case 206: /* expr ::= expr likeop expr escape */
 {
   ExprList *pList;
-  pList = sqlite3ExprListAppend(pParse,0, yymsp[-1].minor.yy450, 0);
-  pList = sqlite3ExprListAppend(pParse,pList, yymsp[-3].minor.yy450, 0);
-  if( yymsp[0].minor.yy450 ){
-    pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy450, 0);
-  }
-  yygotominor.yy450 = sqlite3ExprFunction(pParse, pList, &yymsp[-2].minor.yy86.eOperator);
-  if( yymsp[-2].minor.yy86.not ) yygotominor.yy450 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy450, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy450, &yymsp[-3].minor.yy450->span, &yymsp[-1].minor.yy450->span);
-  if( yygotominor.yy450 ) yygotominor.yy450->flags |= EP_InfixFunc;
-}
-        break;
-      case 208: /* expr ::= expr ISNULL|NOTNULL */
-{
-  yygotominor.yy450 = sqlite3PExpr(pParse, yymsp[0].major, yymsp[-1].minor.yy450, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-1].minor.yy450->span,&yymsp[0].minor.yy0);
-}
-        break;
-      case 209: /* expr ::= expr IS NULL */
-{
-  yygotominor.yy450 = sqlite3PExpr(pParse, TK_ISNULL, yymsp[-2].minor.yy450, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-2].minor.yy450->span,&yymsp[0].minor.yy0);
-}
-        break;
-      case 210: /* expr ::= expr NOT NULL */
-{
-  yygotominor.yy450 = sqlite3PExpr(pParse, TK_NOTNULL, yymsp[-2].minor.yy450, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-2].minor.yy450->span,&yymsp[0].minor.yy0);
-}
-        break;
-      case 211: /* expr ::= expr IS NOT NULL */
-{
-  yygotominor.yy450 = sqlite3PExpr(pParse, TK_NOTNULL, yymsp[-3].minor.yy450, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-3].minor.yy450->span,&yymsp[0].minor.yy0);
-}
-        break;
-      case 212: /* expr ::= NOT expr */
-      case 213: /* expr ::= BITNOT expr */
-{
-  yygotominor.yy450 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy450, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy450->span);
-}
-        break;
-      case 214: /* expr ::= MINUS expr */
-{
-  yygotominor.yy450 = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy450, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy450->span);
-}
-        break;
-      case 215: /* expr ::= PLUS expr */
-{
-  yygotominor.yy450 = sqlite3PExpr(pParse, TK_UPLUS, yymsp[0].minor.yy450, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy450->span);
-}
-        break;
-      case 218: /* expr ::= expr between_op expr AND expr */
-{
-  ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy450, 0);
-  pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy450, 0);
-  yygotominor.yy450 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy450, 0, 0);
-  if( yygotominor.yy450 ){
-    yygotominor.yy450->pList = pList;
+  pList = sqlite3ExprListAppend(pParse,0, yymsp[-1].minor.yy172, 0);
+  pList = sqlite3ExprListAppend(pParse,pList, yymsp[-3].minor.yy172, 0);
+  if( yymsp[0].minor.yy172 ){
+    pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy172, 0);
+  }
+  yygotominor.yy172 = sqlite3ExprFunction(pParse, pList, &yymsp[-2].minor.yy72.eOperator);
+  if( yymsp[-2].minor.yy72.not ) yygotominor.yy172 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy172, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy172, &yymsp[-3].minor.yy172->span, &yymsp[-1].minor.yy172->span);
+  if( yygotominor.yy172 ) yygotominor.yy172->flags |= EP_InfixFunc;
+}
+        break;
+      case 207: /* expr ::= expr ISNULL|NOTNULL */
+{
+  yygotominor.yy172 = sqlite3PExpr(pParse, yymsp[0].major, yymsp[-1].minor.yy172, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-1].minor.yy172->span,&yymsp[0].minor.yy0);
+}
+        break;
+      case 208: /* expr ::= expr IS NULL */
+{
+  yygotominor.yy172 = sqlite3PExpr(pParse, TK_ISNULL, yymsp[-2].minor.yy172, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-2].minor.yy172->span,&yymsp[0].minor.yy0);
+}
+        break;
+      case 209: /* expr ::= expr NOT NULL */
+{
+  yygotominor.yy172 = sqlite3PExpr(pParse, TK_NOTNULL, yymsp[-2].minor.yy172, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-2].minor.yy172->span,&yymsp[0].minor.yy0);
+}
+        break;
+      case 210: /* expr ::= expr IS NOT NULL */
+{
+  yygotominor.yy172 = sqlite3PExpr(pParse, TK_NOTNULL, yymsp[-3].minor.yy172, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-3].minor.yy172->span,&yymsp[0].minor.yy0);
+}
+        break;
+      case 211: /* expr ::= NOT expr */
+      case 212: /* expr ::= BITNOT expr */
+{
+  yygotominor.yy172 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy172, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy172->span);
+}
+        break;
+      case 213: /* expr ::= MINUS expr */
+{
+  yygotominor.yy172 = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy172, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy172->span);
+}
+        break;
+      case 214: /* expr ::= PLUS expr */
+{
+  yygotominor.yy172 = sqlite3PExpr(pParse, TK_UPLUS, yymsp[0].minor.yy172, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy172->span);
+}
+        break;
+      case 217: /* expr ::= expr between_op expr AND expr */
+{
+  ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy172, 0);
+  pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy172, 0);
+  yygotominor.yy172 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy172, 0, 0);
+  if( yygotominor.yy172 ){
+    yygotominor.yy172->pList = pList;
   }else{
     sqlite3ExprListDelete(pParse->db, pList);
   }
-  if( yymsp[-3].minor.yy316 ) yygotominor.yy450 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy450, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-4].minor.yy450->span,&yymsp[0].minor.yy450->span);
-}
-        break;
-      case 221: /* expr ::= expr in_op LP exprlist RP */
-{
-    yygotominor.yy450 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy450, 0, 0);
-    if( yygotominor.yy450 ){
-      yygotominor.yy450->pList = yymsp[-1].minor.yy242;
-      sqlite3ExprSetHeight(pParse, yygotominor.yy450);
-    }else{
-      sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy242);
-    }
-    if( yymsp[-3].minor.yy316 ) yygotominor.yy450 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy450, 0, 0);
-    sqlite3ExprSpan(yygotominor.yy450,&yymsp[-4].minor.yy450->span,&yymsp[0].minor.yy0);
-  }
-        break;
-      case 222: /* expr ::= LP select RP */
-{
-    yygotominor.yy450 = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
-    if( yygotominor.yy450 ){
-      yygotominor.yy450->pSelect = yymsp[-1].minor.yy43;
-      sqlite3ExprSetHeight(pParse, yygotominor.yy450);
-    }else{
-      sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy43);
-    }
-    sqlite3ExprSpan(yygotominor.yy450,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
-  }
-        break;
-      case 223: /* expr ::= expr in_op LP select RP */
-{
-    yygotominor.yy450 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy450, 0, 0);
-    if( yygotominor.yy450 ){
-      yygotominor.yy450->pSelect = yymsp[-1].minor.yy43;
-      sqlite3ExprSetHeight(pParse, yygotominor.yy450);
-    }else{
-      sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy43);
-    }
-    if( yymsp[-3].minor.yy316 ) yygotominor.yy450 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy450, 0, 0);
-    sqlite3ExprSpan(yygotominor.yy450,&yymsp[-4].minor.yy450->span,&yymsp[0].minor.yy0);
-  }
-        break;
-      case 224: /* expr ::= expr in_op nm dbnm */
+  if( yymsp[-3].minor.yy46 ) yygotominor.yy172 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy172, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-4].minor.yy172->span,&yymsp[0].minor.yy172->span);
+}
+        break;
+      case 220: /* expr ::= expr in_op LP exprlist RP */
+{
+    yygotominor.yy172 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy172, 0, 0);
+    if( yygotominor.yy172 ){
+      yygotominor.yy172->pList = yymsp[-1].minor.yy174;
+      sqlite3ExprSetHeight(pParse, yygotominor.yy172);
+    }else{
+      sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy174);
+    }
+    if( yymsp[-3].minor.yy46 ) yygotominor.yy172 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy172, 0, 0);
+    sqlite3ExprSpan(yygotominor.yy172,&yymsp[-4].minor.yy172->span,&yymsp[0].minor.yy0);
+  }
+        break;
+      case 221: /* expr ::= LP select RP */
+{
+    yygotominor.yy172 = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
+    if( yygotominor.yy172 ){
+      yygotominor.yy172->pSelect = yymsp[-1].minor.yy219;
+      sqlite3ExprSetHeight(pParse, yygotominor.yy172);
+    }else{
+      sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy219);
+    }
+    sqlite3ExprSpan(yygotominor.yy172,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
+  }
+        break;
+      case 222: /* expr ::= expr in_op LP select RP */
+{
+    yygotominor.yy172 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy172, 0, 0);
+    if( yygotominor.yy172 ){
+      yygotominor.yy172->pSelect = yymsp[-1].minor.yy219;
+      sqlite3ExprSetHeight(pParse, yygotominor.yy172);
+    }else{
+      sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy219);
+    }
+    if( yymsp[-3].minor.yy46 ) yygotominor.yy172 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy172, 0, 0);
+    sqlite3ExprSpan(yygotominor.yy172,&yymsp[-4].minor.yy172->span,&yymsp[0].minor.yy0);
+  }
+        break;
+      case 223: /* expr ::= expr in_op nm dbnm */
 {
     SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);
-    yygotominor.yy450 = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy450, 0, 0);
-    if( yygotominor.yy450 ){
-      yygotominor.yy450->pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
-      sqlite3ExprSetHeight(pParse, yygotominor.yy450);
-    }else{
-      sqlite3SrcListDelete(pParse->db, pSrc);
-    }
-    if( yymsp[-2].minor.yy316 ) yygotominor.yy450 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy450, 0, 0);
-    sqlite3ExprSpan(yygotominor.yy450,&yymsp[-3].minor.yy450->span,yymsp[0].minor.yy0.z?&yymsp[0].minor.yy0:&yymsp[-1].minor.yy0);
-  }
-        break;
-      case 225: /* expr ::= EXISTS LP select RP */
-{
-    Expr *p = yygotominor.yy450 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
+    yygotominor.yy172 = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy172, 0, 0);
+    if( yygotominor.yy172 ){
+      yygotominor.yy172->pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
+      sqlite3ExprSetHeight(pParse, yygotominor.yy172);
+    }else{
+      sqlite3SrcListDelete(pParse->db, pSrc);
+    }
+    if( yymsp[-2].minor.yy46 ) yygotominor.yy172 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy172, 0, 0);
+    sqlite3ExprSpan(yygotominor.yy172,&yymsp[-3].minor.yy172->span,yymsp[0].minor.yy0.z?&yymsp[0].minor.yy0:&yymsp[-1].minor.yy0);
+  }
+        break;
+      case 224: /* expr ::= EXISTS LP select RP */
+{
+    Expr *p = yygotominor.yy172 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
     if( p ){
-      p->pSelect = yymsp[-1].minor.yy43;
+      p->pSelect = yymsp[-1].minor.yy219;
       sqlite3ExprSpan(p,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
-      sqlite3ExprSetHeight(pParse, yygotominor.yy450);
-    }else{
-      sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy43);
-    }
-  }
-        break;
-      case 226: /* expr ::= CASE case_operand case_exprlist case_else END */
-{
-  yygotominor.yy450 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy450, yymsp[-1].minor.yy450, 0);
-  if( yygotominor.yy450 ){
-    yygotominor.yy450->pList = yymsp[-2].minor.yy242;
-    sqlite3ExprSetHeight(pParse, yygotominor.yy450);
-  }else{
-    sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy242);
-  }
-  sqlite3ExprSpan(yygotominor.yy450, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0);
-}
-        break;
-      case 227: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
-{
-  yygotominor.yy242 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy242, yymsp[-2].minor.yy450, 0);
-  yygotominor.yy242 = sqlite3ExprListAppend(pParse,yygotominor.yy242, yymsp[0].minor.yy450, 0);
-}
-        break;
-      case 228: /* case_exprlist ::= WHEN expr THEN expr */
-{
-  yygotominor.yy242 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy450, 0);
-  yygotominor.yy242 = sqlite3ExprListAppend(pParse,yygotominor.yy242, yymsp[0].minor.yy450, 0);
-}
-        break;
-      case 237: /* cmd ::= CREATE uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP */
+      sqlite3ExprSetHeight(pParse, yygotominor.yy172);
+    }else{
+      sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy219);
+    }
+  }
+        break;
+      case 225: /* expr ::= CASE case_operand case_exprlist case_else END */
+{
+  yygotominor.yy172 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy172, yymsp[-1].minor.yy172, 0);
+  if( yygotominor.yy172 ){
+    yygotominor.yy172->pList = yymsp[-2].minor.yy174;
+    sqlite3ExprSetHeight(pParse, yygotominor.yy172);
+  }else{
+    sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy174);
+  }
+  sqlite3ExprSpan(yygotominor.yy172, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0);
+}
+        break;
+      case 226: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
+{
+  yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy174, yymsp[-2].minor.yy172, 0);
+  yygotominor.yy174 = sqlite3ExprListAppend(pParse,yygotominor.yy174, yymsp[0].minor.yy172, 0);
+}
+        break;
+      case 227: /* case_exprlist ::= WHEN expr THEN expr */
+{
+  yygotominor.yy174 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy172, 0);
+  yygotominor.yy174 = sqlite3ExprListAppend(pParse,yygotominor.yy174, yymsp[0].minor.yy172, 0);
+}
+        break;
+      case 236: /* cmd ::= CREATE uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP */
 {
   sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0,
-                     sqlite3SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy0,0), yymsp[-1].minor.yy242, yymsp[-9].minor.yy316,
-                      &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy316);
-}
-        break;
-      case 238: /* uniqueflag ::= UNIQUE */
-      case 285: /* raisetype ::= ABORT */
-{yygotominor.yy316 = OE_Abort;}
-        break;
-      case 239: /* uniqueflag ::= */
-{yygotominor.yy316 = OE_None;}
-        break;
-      case 242: /* idxlist ::= idxlist COMMA nm collate sortorder */
+                     sqlite3SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy0,0), yymsp[-1].minor.yy174, yymsp[-9].minor.yy46,
+                      &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy46);
+}
+        break;
+      case 237: /* uniqueflag ::= UNIQUE */
+      case 284: /* raisetype ::= ABORT */
+{yygotominor.yy46 = OE_Abort;}
+        break;
+      case 238: /* uniqueflag ::= */
+{yygotominor.yy46 = OE_None;}
+        break;
+      case 241: /* idxlist ::= idxlist COMMA nm collate sortorder */
+{
+  Expr *p = 0;
+  if( yymsp[-1].minor.yy0.n>0 ){
+    p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
+    sqlite3ExprSetColl(pParse, p, &yymsp[-1].minor.yy0);
+  }
+  yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy174, p, &yymsp[-2].minor.yy0);
+  sqlite3ExprListCheckLength(pParse, yygotominor.yy174, "index");
+  if( yygotominor.yy174 ) yygotominor.yy174->a[yygotominor.yy174->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy46;
+}
+        break;
+      case 242: /* idxlist ::= nm collate sortorder */
 {
   Expr *p = 0;
   if( yymsp[-1].minor.yy0.n>0 ){
     p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
     sqlite3ExprSetColl(pParse, p, &yymsp[-1].minor.yy0);
   }
-  yygotominor.yy242 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy242, p, &yymsp[-2].minor.yy0);
-  sqlite3ExprListCheckLength(pParse, yygotominor.yy242, "index");
-  if( yygotominor.yy242 ) yygotominor.yy242->a[yygotominor.yy242->nExpr-1].sortOrder = yymsp[0].minor.yy316;
-}
-        break;
-      case 243: /* idxlist ::= nm collate sortorder */
-{
-  Expr *p = 0;
-  if( yymsp[-1].minor.yy0.n>0 ){
-    p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
-    sqlite3ExprSetColl(pParse, p, &yymsp[-1].minor.yy0);
-  }
-  yygotominor.yy242 = sqlite3ExprListAppend(pParse,0, p, &yymsp[-2].minor.yy0);
-  sqlite3ExprListCheckLength(pParse, yygotominor.yy242, "index");
-  if( yygotominor.yy242 ) yygotominor.yy242->a[yygotominor.yy242->nExpr-1].sortOrder = yymsp[0].minor.yy316;
-}
-        break;
-      case 244: /* collate ::= */
+  yygotominor.yy174 = sqlite3ExprListAppend(pParse,0, p, &yymsp[-2].minor.yy0);
+  sqlite3ExprListCheckLength(pParse, yygotominor.yy174, "index");
+  if( yygotominor.yy174 ) yygotominor.yy174->a[yygotominor.yy174->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy46;
+}
+        break;
+      case 243: /* collate ::= */
 {yygotominor.yy0.z = 0; yygotominor.yy0.n = 0;}
         break;
-      case 246: /* cmd ::= DROP INDEX ifexists fullname */
-{sqlite3DropIndex(pParse, yymsp[0].minor.yy419, yymsp[-1].minor.yy316);}
-        break;
-      case 247: /* cmd ::= VACUUM */
-      case 248: /* cmd ::= VACUUM nm */
+      case 245: /* cmd ::= DROP INDEX ifexists fullname */
+{sqlite3DropIndex(pParse, yymsp[0].minor.yy373, yymsp[-1].minor.yy46);}
+        break;
+      case 246: /* cmd ::= VACUUM */
+      case 247: /* cmd ::= VACUUM nm */
 {sqlite3Vacuum(pParse);}
         break;
-      case 249: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
-      case 250: /* cmd ::= PRAGMA nm dbnm EQ ON */
-      case 251: /* cmd ::= PRAGMA nm dbnm EQ DELETE */
+      case 248: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
+      case 249: /* cmd ::= PRAGMA nm dbnm EQ ON */
+      case 250: /* cmd ::= PRAGMA nm dbnm EQ DELETE */
 {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
         break;
-      case 252: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
+      case 251: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
 {
   sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);
 }
         break;
-      case 253: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
+      case 252: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
 {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
         break;
-      case 254: /* cmd ::= PRAGMA nm dbnm */
+      case 253: /* cmd ::= PRAGMA nm dbnm */
 {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
         break;
-      case 262: /* cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END */
+      case 261: /* cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END */
 {
   Token all;
   all.z = yymsp[-3].minor.yy0.z;
-  all.n = (yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
-  sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy75, &all);
-}
-        break;
-      case 263: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+  all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
+  sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy243, &all);
+}
+        break;
+      case 262: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
 {
-  sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy316, yymsp[-4].minor.yy354.a, yymsp[-4].minor.yy354.b, yymsp[-2].minor.yy419, yymsp[0].minor.yy450, yymsp[-10].minor.yy316, yymsp[-8].minor.yy316);
+  sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy46, yymsp[-4].minor.yy370.a, yymsp[-4].minor.yy370.b, yymsp[-2].minor.yy373, yymsp[0].minor.yy172, yymsp[-10].minor.yy46, yymsp[-8].minor.yy46);
   yygotominor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0);
 }
         break;
-      case 264: /* trigger_time ::= BEFORE */
-      case 267: /* trigger_time ::= */
-{ yygotominor.yy316 = TK_BEFORE; }
-        break;
-      case 265: /* trigger_time ::= AFTER */
-{ yygotominor.yy316 = TK_AFTER;  }
-        break;
-      case 266: /* trigger_time ::= INSTEAD OF */
-{ yygotominor.yy316 = TK_INSTEAD;}
-        break;
-      case 268: /* trigger_event ::= DELETE|INSERT */
-      case 269: /* trigger_event ::= UPDATE */
-{yygotominor.yy354.a = yymsp[0].major; yygotominor.yy354.b = 0;}
-        break;
-      case 270: /* trigger_event ::= UPDATE OF inscollist */
-{yygotominor.yy354.a = TK_UPDATE; yygotominor.yy354.b = yymsp[0].minor.yy352;}
-        break;
-      case 273: /* when_clause ::= */
-      case 290: /* key_opt ::= */
-{ yygotominor.yy450 = 0; }
-        break;
-      case 274: /* when_clause ::= WHEN expr */
-      case 291: /* key_opt ::= KEY expr */
-{ yygotominor.yy450 = yymsp[0].minor.yy450; }
-        break;
-      case 275: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+      case 263: /* trigger_time ::= BEFORE */
+      case 266: /* trigger_time ::= */
+{ yygotominor.yy46 = TK_BEFORE; }
+        break;
+      case 264: /* trigger_time ::= AFTER */
+{ yygotominor.yy46 = TK_AFTER;  }
+        break;
+      case 265: /* trigger_time ::= INSTEAD OF */
+{ yygotominor.yy46 = TK_INSTEAD;}
+        break;
+      case 267: /* trigger_event ::= DELETE|INSERT */
+      case 268: /* trigger_event ::= UPDATE */
+{yygotominor.yy370.a = yymsp[0].major; yygotominor.yy370.b = 0;}
+        break;
+      case 269: /* trigger_event ::= UPDATE OF inscollist */
+{yygotominor.yy370.a = TK_UPDATE; yygotominor.yy370.b = yymsp[0].minor.yy432;}
+        break;
+      case 272: /* when_clause ::= */
+      case 289: /* key_opt ::= */
+{ yygotominor.yy172 = 0; }
+        break;
+      case 273: /* when_clause ::= WHEN expr */
+      case 290: /* key_opt ::= KEY expr */
+{ yygotominor.yy172 = yymsp[0].minor.yy172; }
+        break;
+      case 274: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+{
+/*
+  if( yymsp[-2].minor.yy243 ){
+    yymsp[-2].minor.yy243->pLast->pNext = yymsp[-1].minor.yy243;
+  }else{
+    yymsp[-2].minor.yy243 = yymsp[-1].minor.yy243;
+  }
+*/
+  assert( yymsp[-2].minor.yy243!=0 );
+  yymsp[-2].minor.yy243->pLast->pNext = yymsp[-1].minor.yy243;
+  yymsp[-2].minor.yy243->pLast = yymsp[-1].minor.yy243;
+  yygotominor.yy243 = yymsp[-2].minor.yy243;
+}
+        break;
+      case 275: /* trigger_cmd_list ::= trigger_cmd SEMI */
+{
+  /* if( yymsp[-1].minor.yy243 ) */
+  assert( yymsp[-1].minor.yy243!=0 );
+  yymsp[-1].minor.yy243->pLast = yymsp[-1].minor.yy243;
+  yygotominor.yy243 = yymsp[-1].minor.yy243;
+}
+        break;
+      case 276: /* trigger_cmd ::= UPDATE orconf nm SET setlist where_opt */
+{ yygotominor.yy243 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy174, yymsp[0].minor.yy172, yymsp[-4].minor.yy46); }
+        break;
+      case 277: /* trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP */
+{yygotominor.yy243 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy432, yymsp[-1].minor.yy174, 0, yymsp[-7].minor.yy46);}
+        break;
+      case 278: /* trigger_cmd ::= insert_cmd INTO nm inscollist_opt select */
+{yygotominor.yy243 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy432, 0, yymsp[0].minor.yy219, yymsp[-4].minor.yy46);}
+        break;
+      case 279: /* trigger_cmd ::= DELETE FROM nm where_opt */
+{yygotominor.yy243 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-1].minor.yy0, yymsp[0].minor.yy172);}
+        break;
+      case 280: /* trigger_cmd ::= select */
+{yygotominor.yy243 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy219); }
+        break;
+      case 281: /* expr ::= RAISE LP IGNORE RP */
+{
+  yygotominor.yy172 = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
+  if( yygotominor.yy172 ){
+    yygotominor.yy172->iColumn = OE_Ignore;
+    sqlite3ExprSpan(yygotominor.yy172, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0);
+  }
+}
+        break;
+      case 282: /* expr ::= RAISE LP raisetype COMMA nm RP */
+{
+  yygotominor.yy172 = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0);
+  if( yygotominor.yy172 ) {
+    yygotominor.yy172->iColumn = yymsp[-3].minor.yy46;
+    sqlite3ExprSpan(yygotominor.yy172, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0);
+  }
+}
+        break;
+      case 283: /* raisetype ::= ROLLBACK */
+{yygotominor.yy46 = OE_Rollback;}
+        break;
+      case 285: /* raisetype ::= FAIL */
+{yygotominor.yy46 = OE_Fail;}
+        break;
+      case 286: /* cmd ::= DROP TRIGGER ifexists fullname */
 {
-/*
-  if( yymsp[-2].minor.yy75 ){
-    yymsp[-2].minor.yy75->pLast->pNext = yymsp[-1].minor.yy75;
-  }else{
-    yymsp[-2].minor.yy75 = yymsp[-1].minor.yy75;
-  }
-*/
-  assert( yymsp[-2].minor.yy75!=0 );
-  yymsp[-2].minor.yy75->pLast->pNext = yymsp[-1].minor.yy75;
-  yymsp[-2].minor.yy75->pLast = yymsp[-1].minor.yy75;
-  yygotominor.yy75 = yymsp[-2].minor.yy75;
-}
-        break;
-      case 276: /* trigger_cmd_list ::= trigger_cmd SEMI */
+  sqlite3DropTrigger(pParse,yymsp[0].minor.yy373,yymsp[-1].minor.yy46);
+}
+        break;
+      case 287: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
 {
-  /* if( yymsp[-1].minor.yy75 ) */
-  assert( yymsp[-1].minor.yy75!=0 );
-  yymsp[-1].minor.yy75->pLast = yymsp[-1].minor.yy75;
-  yygotominor.yy75 = yymsp[-1].minor.yy75;
-}
-        break;
-      case 277: /* trigger_cmd ::= UPDATE orconf nm SET setlist where_opt */
-{ yygotominor.yy75 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy242, yymsp[0].minor.yy450, yymsp[-4].minor.yy316); }
-        break;
-      case 278: /* trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP */
-{yygotominor.yy75 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy352, yymsp[-1].minor.yy242, 0, yymsp[-7].minor.yy316);}
-        break;
-      case 279: /* trigger_cmd ::= insert_cmd INTO nm inscollist_opt select */
-{yygotominor.yy75 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy352, 0, yymsp[0].minor.yy43, yymsp[-4].minor.yy316);}
-        break;
-      case 280: /* trigger_cmd ::= DELETE FROM nm where_opt */
-{yygotominor.yy75 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-1].minor.yy0, yymsp[0].minor.yy450);}
-        break;
-      case 281: /* trigger_cmd ::= select */
-{yygotominor.yy75 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy43); }
-        break;
-      case 282: /* expr ::= RAISE LP IGNORE RP */
+  sqlite3Attach(pParse, yymsp[-3].minor.yy172, yymsp[-1].minor.yy172, yymsp[0].minor.yy172);
+}
+        break;
+      case 288: /* cmd ::= DETACH database_kw_opt expr */
 {
-  yygotominor.yy450 = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
-  if( yygotominor.yy450 ){
-    yygotominor.yy450->iColumn = OE_Ignore;
-    sqlite3ExprSpan(yygotominor.yy450, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0);
-  }
-}
-        break;
-      case 283: /* expr ::= RAISE LP raisetype COMMA nm RP */
-{
-  yygotominor.yy450 = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0);
-  if( yygotominor.yy450 ) {
-    yygotominor.yy450->iColumn = yymsp[-3].minor.yy316;
-    sqlite3ExprSpan(yygotominor.yy450, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0);
-  }
-}
-        break;
-      case 284: /* raisetype ::= ROLLBACK */
-{yygotominor.yy316 = OE_Rollback;}
-        break;
-      case 286: /* raisetype ::= FAIL */
-{yygotominor.yy316 = OE_Fail;}
-        break;
-      case 287: /* cmd ::= DROP TRIGGER ifexists fullname */
-{
-  sqlite3DropTrigger(pParse,yymsp[0].minor.yy419,yymsp[-1].minor.yy316);
-}
-        break;
-      case 288: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
-{
-  sqlite3Attach(pParse, yymsp[-3].minor.yy450, yymsp[-1].minor.yy450, yymsp[0].minor.yy450);
-}
-        break;
-      case 289: /* cmd ::= DETACH database_kw_opt expr */
-{
-  sqlite3Detach(pParse, yymsp[0].minor.yy450);
-}
-        break;
-      case 294: /* cmd ::= REINDEX */
+  sqlite3Detach(pParse, yymsp[0].minor.yy172);
+}
+        break;
+      case 293: /* cmd ::= REINDEX */
 {sqlite3Reindex(pParse, 0, 0);}
         break;
-      case 295: /* cmd ::= REINDEX nm dbnm */
+      case 294: /* cmd ::= REINDEX nm dbnm */
 {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
         break;
-      case 296: /* cmd ::= ANALYZE */
+      case 295: /* cmd ::= ANALYZE */
 {sqlite3Analyze(pParse, 0, 0);}
         break;
-      case 297: /* cmd ::= ANALYZE nm dbnm */
+      case 296: /* cmd ::= ANALYZE nm dbnm */
 {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
         break;
-      case 298: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
+      case 297: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
 {
-  sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy419,&yymsp[0].minor.yy0);
-}
-        break;
-      case 299: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */
+  sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy373,&yymsp[0].minor.yy0);
+}
+        break;
+      case 298: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */
 {
   sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy0);
 }
         break;
-      case 300: /* add_column_fullname ::= fullname */
+      case 299: /* add_column_fullname ::= fullname */
 {
-  sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy419);
-}
-        break;
-      case 303: /* cmd ::= create_vtab */
+  sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy373);
+}
+        break;
+      case 302: /* cmd ::= create_vtab */
 {sqlite3VtabFinishParse(pParse,0);}
         break;
-      case 304: /* cmd ::= create_vtab LP vtabarglist RP */
+      case 303: /* cmd ::= create_vtab LP vtabarglist RP */
 {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
         break;
-      case 305: /* create_vtab ::= CREATE VIRTUAL TABLE nm dbnm USING nm */
+      case 304: /* create_vtab ::= CREATE VIRTUAL TABLE nm dbnm USING nm */
 {
     sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
 }
         break;
-      case 308: /* vtabarg ::= */
+      case 307: /* vtabarg ::= */
 {sqlite3VtabArgInit(pParse);}
         break;
-      case 310: /* vtabargtoken ::= ANY */
-      case 311: /* vtabargtoken ::= lp anylist RP */
-      case 312: /* lp ::= LP */
-      case 314: /* anylist ::= anylist ANY */
+      case 309: /* vtabargtoken ::= ANY */
+      case 310: /* vtabargtoken ::= lp anylist RP */
+      case 311: /* lp ::= LP */
+      case 313: /* anylist ::= anylist ANY */
 {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
         break;
   };
   yygoto = yyRuleInfo[yyruleno].lhs;
   yysize = yyRuleInfo[yyruleno].nrhs;
   yypParser->yyidx -= yysize;
-  yyact = yy_find_reduce_action(yymsp[-yysize].stateno,yygoto);
+  yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto);
   if( yyact < YYNSTATE ){
 #ifdef NDEBUG
     /* If we are not debugging and the reduce action popped at least
     ** one element off the stack, then we can push the new element back
@@ -82718,8 +84684,9 @@
 ){
   sqlite3ParserARG_FETCH;
 #define TOKEN (yyminor.yy0)
 
+  UNUSED_PARAMETER(yymajor);  /* Silence some compiler warnings */
   assert( TOKEN.z[0] );  /* The tokenizer always gives us a token */
   sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
   pParse->parseError = 1;
   sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
@@ -82802,9 +84769,9 @@
   }
 #endif
 
   do{
-    yyact = yy_find_shift_action(yypParser,yymajor);
+    yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
     if( yyact<YYNSTATE ){
       assert( !yyendofinput );  /* Impossible to shift the $ token */
       yy_shift(yypParser,yyact,yymajor,&yyminorunion);
       yypParser->yyerrcnt--;
@@ -82851,9 +84818,9 @@
           fprintf(yyTraceFILE,"%sDiscard input token %s\n",
              yyTracePrompt,yyTokenName[yymajor]);
         }
 #endif
-        yy_destructor(yypParser, yymajor,&yyminorunion);
+        yy_destructor(yypParser, (YYCODETYPE)yymajor,&yyminorunion);
         yymajor = YYNOCODE;
       }else{
          while(
           yypParser->yyidx >= 0 &&
@@ -82864,9 +84831,9 @@
         ){
           yy_pop_parser_stack(yypParser);
         }
         if( yypParser->yyidx < 0 || yymajor==0 ){
-          yy_destructor(yypParser,yymajor,&yyminorunion);
+          yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
           yy_parse_failed(yypParser);
           yymajor = YYNOCODE;
         }else if( yymx!=YYERRORSYMBOL ){
           YYMINORTYPE u2;
@@ -82889,9 +84856,9 @@
       if( yypParser->yyerrcnt<=0 ){
         yy_syntax_error(yypParser,yymajor,yyminorunion);
       }
       yypParser->yyerrcnt = 3;
-      yy_destructor(yypParser,yymajor,&yyminorunion);
+      yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
       if( yyendofinput ){
         yy_parse_failed(yypParser);
       }
       yymajor = YYNOCODE;
@@ -82972,9 +84939,9 @@
 /***** This file contains automatically generated code ******
 **
 ** The code in this file has been automatically generated by
 **
-**     $Header: /sqlite/sqlite/tool/mkkeywordhash.c,v 1.32 2008/10/06 05:32:19 danielk1977 Exp $
+**     $Header: /sqlite/sqlite/tool/mkkeywordhash.c,v 1.34 2008/12/10 20:11:01 shane Exp $
 **
 ** The code in this file implements a function that determines whether
 ** or not a given identifier is really an SQL keyword.  The same thing
 ** might be implemented more directly using a hand-written hash table.
@@ -82984,18 +84951,49 @@
 */
 /* Hash score: 167 */
 static int keywordCode(const char *z, int n){
   /* zText[] encodes 783 bytes of keywords in 528 bytes */
-  static const char zText[528] =
-    "REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECTABLE"
-    "FTHENDEFERRABLELSEXCEPTRANSACTIONATURALTERAISEXCLUSIVEXISTSCONSTRAINT"
-    "ERSECTRIGGEREFERENCESUNIQUERYATTACHAVINGROUPDATEMPORARYBEGINNER"
-    "ENAMEBETWEENOTNULLIKECASCADELETECASECOLLATECREATECURRENT_DATE"
-    "DETACHIMMEDIATEJOINSERTMATCHPLANALYZEPRAGMABORTVALUESVIRTUALIMIT"
-    "WHENWHEREPLACEAFTERESTRICTANDEFAULTAUTOINCREMENTCASTCOLUMNCOMMIT"
-    "CONFLICTCROSSCURRENT_TIMESTAMPRIMARYDEFERREDISTINCTDROPFAILFROM"
-    "FULLGLOBYIFINTOFFSETISNULLORDERIGHTOUTEROLLBACKROWUNIONUSINGVACUUM"
-    "VIEWINITIALLY";
+  /*   REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT       */
+  /*   ABLEFTHENDEFERRABLELSEXCEPTRANSACTIONATURALTERAISEXCLUSIVE         */
+  /*   XISTSCONSTRAINTERSECTRIGGEREFERENCESUNIQUERYATTACHAVINGROUP        */
+  /*   DATEMPORARYBEGINNERENAMEBETWEENOTNULLIKECASCADELETECASECOLLATE     */
+  /*   CREATECURRENT_DATEDETACHIMMEDIATEJOINSERTMATCHPLANALYZEPRAGMA      */
+  /*   BORTVALUESVIRTUALIMITWHENWHEREPLACEAFTERESTRICTANDEFAULT           */
+  /*   AUTOINCREMENTCASTCOLUMNCOMMITCONFLICTCROSSCURRENT_TIMESTAMP        */
+  /*   RIMARYDEFERREDISTINCTDROPFAILFROMFULLGLOBYIFINTOFFSETISNULL        */
+  /*   ORDERIGHTOUTEROLLBACKROWUNIONUSINGVACUUMVIEWINITIALLY              */
+  static const char zText[528] = {
+    'R','E','I','N','D','E','X','E','D','E','S','C','A','P','E','A','C','H',
+    'E','C','K','E','Y','B','E','F','O','R','E','I','G','N','O','R','E','G',
+    'E','X','P','L','A','I','N','S','T','E','A','D','D','A','T','A','B','A',
+    'S','E','L','E','C','T','A','B','L','E','F','T','H','E','N','D','E','F',
+    'E','R','R','A','B','L','E','L','S','E','X','C','E','P','T','R','A','N',
+    'S','A','C','T','I','O','N','A','T','U','R','A','L','T','E','R','A','I',
+    'S','E','X','C','L','U','S','I','V','E','X','I','S','T','S','C','O','N',
+    'S','T','R','A','I','N','T','E','R','S','E','C','T','R','I','G','G','E',
+    'R','E','F','E','R','E','N','C','E','S','U','N','I','Q','U','E','R','Y',
+    'A','T','T','A','C','H','A','V','I','N','G','R','O','U','P','D','A','T',
+    'E','M','P','O','R','A','R','Y','B','E','G','I','N','N','E','R','E','N',
+    'A','M','E','B','E','T','W','E','E','N','O','T','N','U','L','L','I','K',
+    'E','C','A','S','C','A','D','E','L','E','T','E','C','A','S','E','C','O',
+    'L','L','A','T','E','C','R','E','A','T','E','C','U','R','R','E','N','T',
+    '_','D','A','T','E','D','E','T','A','C','H','I','M','M','E','D','I','A',
+    'T','E','J','O','I','N','S','E','R','T','M','A','T','C','H','P','L','A',
+    'N','A','L','Y','Z','E','P','R','A','G','M','A','B','O','R','T','V','A',
+    'L','U','E','S','V','I','R','T','U','A','L','I','M','I','T','W','H','E',
+    'N','W','H','E','R','E','P','L','A','C','E','A','F','T','E','R','E','S',
+    'T','R','I','C','T','A','N','D','E','F','A','U','L','T','A','U','T','O',
+    'I','N','C','R','E','M','E','N','T','C','A','S','T','C','O','L','U','M',
+    'N','C','O','M','M','I','T','C','O','N','F','L','I','C','T','C','R','O',
+    'S','S','C','U','R','R','E','N','T','_','T','I','M','E','S','T','A','M',
+    'P','R','I','M','A','R','Y','D','E','F','E','R','R','E','D','I','S','T',
+    'I','N','C','T','D','R','O','P','F','A','I','L','F','R','O','M','F','U',
+    'L','L','G','L','O','B','Y','I','F','I','N','T','O','F','F','S','E','T',
+    'I','S','N','U','L','L','O','R','D','E','R','I','G','H','T','O','U','T',
+    'E','R','O','L','L','B','A','C','K','R','O','W','U','N','I','O','N','U',
+    'S','I','N','G','V','A','C','U','U','M','V','I','E','W','I','N','I','T',
+    'I','A','L','L','Y',0
+  };
   static const unsigned char aHash[127] = {
       65,  94, 110,  63,   0,  44,   0,   0,  71,   0,  66,   0,   0,
      104,  12,  67,  15,   0, 108,  74, 105, 101,   0,  19,   0,   0,
      114,   0, 112,  78,   0,  22,  82,   0,   9,   0,   0,  59,  60,
@@ -83829,9 +85827,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.514 2008/11/19 09:05:27 danielk1977 Exp $
+** $Id: main.c,v 1.519 2008/12/10 23:04:13 drh Exp $
 */
 
 #ifdef SQLITE_ENABLE_FTS3
 /************** Include fts3.h in the middle of main.c ***********************/
@@ -83933,9 +85931,11 @@
 
 /*
 ** The version of the library
 */
+#ifndef SQLITE_AMALGAMATION
 SQLITE_API const char sqlite3_version[] = SQLITE_VERSION;
+#endif
 SQLITE_API const char *sqlite3_libversion(void){ return sqlite3_version; }
 SQLITE_API int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }
 SQLITE_API int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; }
 
@@ -84302,10 +86302,10 @@
     sqlite3_free(db->lookaside.pStart);
   }
   db->lookaside.pStart = pStart;
   db->lookaside.pFree = 0;
-  db->lookaside.sz = sz;
-  db->lookaside.bMalloced = pBuf==0;
+  db->lookaside.sz = (u16)sz;
+  db->lookaside.bMalloced = pBuf==0 ?1:0;
   if( pStart ){
     int i;
     LookasideSlot *p;
     p = (LookasideSlot*)pStart;
@@ -84819,9 +86819,9 @@
   ** and there are active VMs, then return SQLITE_BUSY. If a function
   ** is being overridden/deleted but there are no active VMs, allow the
   ** operation to continue but invalidate all precompiled statements.
   */
-  p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 0);
+  p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0);
   if( p && p->iPrefEnc==enc && p->nArg==nArg ){
     if( db->activeVdbeCnt ){
       sqlite3Error(db, SQLITE_BUSY,
         "Unable to delete/modify user-function due to active statements");
@@ -84831,9 +86831,9 @@
       sqlite3ExpirePreparedStatements(db);
     }
   }
 
-  p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 1);
+  p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 1);
   assert(p || db->mallocFailed);
   if( !p ){
     return SQLITE_NOMEM;
   }
@@ -84841,9 +86841,9 @@
   p->xFunc = xFunc;
   p->xStep = xStep;
   p->xFinalize = xFinal;
   p->pUserData = pUserData;
-  p->nArg = nArg;
+  p->nArg = (u16)nArg;
   return SQLITE_OK;
 }
 
 /*
@@ -85106,8 +87106,11 @@
   }
   if( !sqlite3SafetyCheckSickOrOk(db) ){
     return sqlite3ErrStr(SQLITE_MISUSE);
   }
+  if( db->mallocFailed ){
+    return sqlite3ErrStr(SQLITE_NOMEM);
+  }
   sqlite3_mutex_enter(db->mutex);
   assert( !db->mallocFailed );
   z = (char*)sqlite3_value_text(db->pErr);
   assert( !db->mallocFailed );
@@ -85261,9 +87264,9 @@
   if( pColl ){
     pColl->xCmp = xCompare;
     pColl->pUser = pCtx;
     pColl->xDel = xDel;
-    pColl->enc = enc2 | (enc & SQLITE_UTF16_ALIGNED);
+    pColl->enc = (u8)(enc2 | (enc & SQLITE_UTF16_ALIGNED));
   }
   sqlite3Error(db, SQLITE_OK, 0);
   return SQLITE_OK;
 }