Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Update sqlite3 to version 3.7.14
Baptiste Daroussin committed 13 years ago
commit ab207d7720ef81e6e6ab63576c24c195eae6410a
parent 67b68fb
3 files changed +1276 -3149
modified external/sqlite/shell.c
@@ -36,7 +36,7 @@
#include <ctype.h>
#include <stdarg.h>

-
#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__)
+
#if !defined(_WIN32) && !defined(WIN32)
# include <signal.h>
# if !defined(__RTP__) && !defined(_WRS_KERNEL)
#  include <pwd.h>
@@ -45,10 +45,6 @@
# include <sys/types.h>
#endif

-
#ifdef __OS2__
-
# include <unistd.h>
-
#endif
-

#ifdef HAVE_EDITLINE
# include <editline/editline.h>
#endif
@@ -68,7 +64,9 @@
# include <io.h>
#define isatty(h) _isatty(h)
#define access(f,m) _access((f),(m))
+
#undef popen
#define popen(a,b) _popen((a),(b))
+
#undef pclose
#define pclose(x) _pclose(x)
#else
/* Make sure isatty() has a prototype.
@@ -92,7 +90,7 @@ static int enableTimer = 0;
#define IsDigit(X)  isdigit((unsigned char)X)
#define ToLower(X)  (char)tolower((unsigned char)X)

-
#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL)
+
#if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL)
#include <sys/time.h>
#include <sys/resource.h>

@@ -1453,6 +1451,7 @@ static int process_input(struct callback_data *p, FILE *in);
*/
static void open_db(struct callback_data *p){
  if( p->db==0 ){
+
    sqlite3_initialize();
    sqlite3_open(p->zDbFilename, &p->db);
    db = p->db;
    if( db && sqlite3_errcode(db)==SQLITE_OK ){
@@ -2468,7 +2467,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
    open_db(p);
    output_file_close(p->traceOut);
    p->traceOut = output_file_open(azArg[1]);
-
#ifndef SQLITE_OMIT_TRACE
+
#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
    if( p->traceOut==0 ){
      sqlite3_trace(p->db, 0, 0);
    }else{
@@ -2696,11 +2695,13 @@ static char *find_home_dir(void){
  static char *home_dir = NULL;
  if( home_dir ) return home_dir;

-
#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
-
  struct passwd *pwent;
-
  uid_t uid = getuid();
-
  if( (pwent=getpwuid(uid)) != NULL) {
-
    home_dir = pwent->pw_dir;
+
#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
+
  {
+
    struct passwd *pwent;
+
    uid_t uid = getuid();
+
    if( (pwent=getpwuid(uid)) != NULL) {
+
      home_dir = pwent->pw_dir;
+
    }
  }
#endif

@@ -2710,7 +2711,7 @@ static char *find_home_dir(void){
  home_dir = "/";
#else

-
#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
+
#if defined(_WIN32) || defined(WIN32)
  if (!home_dir) {
    home_dir = getenv("USERPROFILE");
  }
@@ -2720,7 +2721,7 @@ static char *find_home_dir(void){
    home_dir = getenv("HOME");
  }

-
#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
+
#if defined(_WIN32) || defined(WIN32)
  if (!home_dir) {
    char *zDrive, *zPath;
    int n;
@@ -2773,6 +2774,7 @@ static int process_sqliterc(
#endif
      return 1;
    }
+
    sqlite3_initialize();
    zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
    sqliterc = zBuf;
  }
modified external/sqlite/sqlite3.c
@@ -1,6 +1,6 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-
** version 3.7.13.  By combining all the individual C code files into this 
+
** version 3.7.14.  By combining all the individual C code files into this 
** single large file, the entire code can be compiled as a single translation
** unit.  This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately.  Performance improvements
@@ -389,6 +389,7 @@
**
**     SQLITE_SYSTEM_MALLOC          // Use normal system malloc()
**     SQLITE_WIN32_MALLOC           // Use Win32 native heap API
+
**     SQLITE_ZERO_MALLOC            // Use a stub allocator that always fails
**     SQLITE_MEMDEBUG               // Debugging version of system malloc()
**
** On Windows, if the SQLITE_WIN32_MALLOC_VALIDATE macro is defined and the
@@ -402,11 +403,19 @@
** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as
** the default.
*/
-
#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)>1
-
# error "At most one of the following compile-time configuration options\
-
 is allows: SQLITE_SYSTEM_MALLOC, SQLITE_WIN32_MALLOC, SQLITE_MEMDEBUG"
-
#endif
-
#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)==0
+
#if defined(SQLITE_SYSTEM_MALLOC) \
+
  + defined(SQLITE_WIN32_MALLOC) \
+
  + defined(SQLITE_ZERO_MALLOC) \
+
  + defined(SQLITE_MEMDEBUG)>1
+
# error "Two or more of the following compile-time configuration options\
+
 are defined but at most one is allowed:\
+
 SQLITE_SYSTEM_MALLOC, SQLITE_WIN32_MALLOC, SQLITE_MEMDEBUG,\
+
 SQLITE_ZERO_MALLOC"
+
#endif
+
#if defined(SQLITE_SYSTEM_MALLOC) \
+
  + defined(SQLITE_WIN32_MALLOC) \
+
  + defined(SQLITE_ZERO_MALLOC) \
+
  + defined(SQLITE_MEMDEBUG)==0
# define SQLITE_SYSTEM_MALLOC 1
#endif

@@ -664,9 +673,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-
#define SQLITE_VERSION        "3.7.13"
-
#define SQLITE_VERSION_NUMBER 3007013
-
#define SQLITE_SOURCE_ID      "2012-06-11 02:05:22 f5b5a13f7394dc143aa136f1d4faba6839eaa6dc"
+
#define SQLITE_VERSION        "3.7.14"
+
#define SQLITE_VERSION_NUMBER 3007014
+
#define SQLITE_SOURCE_ID      "2012-09-03 15:42:36 c0d89d4a9752922f9e367362366efde4f1b06f2a"

/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -776,7 +785,8 @@ SQLITE_API int sqlite3_threadsafe(void);
** the opaque structure named "sqlite3".  It is useful to think of an sqlite3
** pointer as an object.  The [sqlite3_open()], [sqlite3_open16()], and
** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()]
-
** is its destructor.  There are many other interfaces (such as
+
** and [sqlite3_close_v2()] are its destructors.  There are many other
+
** interfaces (such as
** [sqlite3_prepare_v2()], [sqlite3_create_function()], and
** [sqlite3_busy_timeout()] to name but three) that are methods on an
** sqlite3 object.
@@ -823,28 +833,46 @@ typedef sqlite_uint64 sqlite3_uint64;
/*
** CAPI3REF: Closing A Database Connection
**
-
** ^The sqlite3_close() routine is the destructor for the [sqlite3] object.
-
** ^Calls to sqlite3_close() return SQLITE_OK if the [sqlite3] object is
-
** successfully destroyed and all associated resources are deallocated.
-
**
-
** Applications must [sqlite3_finalize | finalize] all [prepared statements]
-
** and [sqlite3_blob_close | close] all [BLOB handles] associated with
-
** the [sqlite3] object prior to attempting to close the object.  ^If
+
** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors
+
** for the [sqlite3] object.
+
** ^Calls to sqlite3_close() and sqlite3_close_v2() return SQLITE_OK if
+
** the [sqlite3] object is successfully destroyed and all associated
+
** resources are deallocated.
+
**
+
** ^If the database connection is associated with unfinalized prepared
+
** statements or unfinished sqlite3_backup objects then sqlite3_close()
+
** will leave the database connection open and return [SQLITE_BUSY].
+
** ^If sqlite3_close_v2() is called with unfinalized prepared statements
+
** and unfinished sqlite3_backups, then the database connection becomes
+
** an unusable "zombie" which will automatically be deallocated when the
+
** last prepared statement is finalized or the last sqlite3_backup is
+
** finished.  The sqlite3_close_v2() interface is intended for use with
+
** host languages that are garbage collected, and where the order in which
+
** destructors are called is arbitrary.
+
**
+
** Applications should [sqlite3_finalize | finalize] all [prepared statements],
+
** [sqlite3_blob_close | close] all [BLOB handles], and 
+
** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
+
** with the [sqlite3] object prior to attempting to close the object.  ^If
** sqlite3_close() is called on a [database connection] that still has
-
** outstanding [prepared statements] or [BLOB handles], then it returns
-
** SQLITE_BUSY.
+
** outstanding [prepared statements], [BLOB handles], and/or
+
** [sqlite3_backup] objects then it returns SQLITE_OK but the deallocation
+
** of resources is deferred until all [prepared statements], [BLOB handles],
+
** and [sqlite3_backup] objects are also destroyed.
**
-
** ^If [sqlite3_close()] is invoked while a transaction is open,
+
** ^If an [sqlite3] object is destroyed while a transaction is open,
** the transaction is automatically rolled back.
**
-
** The C parameter to [sqlite3_close(C)] must be either a NULL
+
** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)]
+
** must be either a NULL
** pointer or an [sqlite3] object pointer obtained
** from [sqlite3_open()], [sqlite3_open16()], or
** [sqlite3_open_v2()], and not previously closed.
-
** ^Calling sqlite3_close() with a NULL pointer argument is a 
-
** harmless no-op.
+
** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer
+
** argument is a harmless no-op.
*/
-
SQLITE_API int sqlite3_close(sqlite3 *);
+
SQLITE_API int sqlite3_close(sqlite3*);
+
SQLITE_API int sqlite3_close_v2(sqlite3*);

/*
** The type for a callback function.
@@ -1055,7 +1083,7 @@ SQLITE_API int sqlite3_exec(
** CAPI3REF: Device Characteristics
**
** The xDeviceCharacteristics method of the [sqlite3_io_methods]
-
** object returns an integer which is a vector of the these
+
** object returns an integer which is a vector of these
** bit values expressing I/O characteristics of the mass storage
** device that holds the file that the [sqlite3_io_methods]
** refers to.
@@ -3205,6 +3233,12 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** codepage is currently defined.  Filenames containing international
** characters must be converted to UTF-8 prior to passing them into
** sqlite3_open() or sqlite3_open_v2().
+
**
+
** <b>Note to Windows Runtime users:</b>  The temporary directory must be set
+
** prior to calling sqlite3_open() or sqlite3_open_v2().  Otherwise, various
+
** features that require the use of temporary files may fail.
+
**
+
** See also: [sqlite3_temp_directory]
*/
SQLITE_API int sqlite3_open(
  const char *filename,   /* Database filename (UTF-8) */
@@ -3697,8 +3731,11 @@ typedef struct sqlite3_context sqlite3_context;
** ^(In those routines that have a fourth argument, its value is the
** number of bytes in the parameter.  To be clear: the value is the
** number of <u>bytes</u> in the value, not the number of characters.)^
-
** ^If the fourth parameter is negative, the length of the string is
+
** ^If the fourth parameter to sqlite3_bind_text() or sqlite3_bind_text16()
+
** is negative, then the length of the string is
** the number of bytes up to the first zero terminator.
+
** If the fourth parameter to sqlite3_bind_blob() is negative, then
+
** the behavior is undefined.
** If a non-negative fourth parameter is provided to sqlite3_bind_text()
** or sqlite3_bind_text16() then that parameter must be the byte offset
** where the NUL terminator would occur assuming the string were NUL
@@ -4695,11 +4732,11 @@ typedef void (*sqlite3_destructor_type)(void*);
** the error code is SQLITE_ERROR.  ^A subsequent call to sqlite3_result_error()
** or sqlite3_result_error16() resets the error code to SQLITE_ERROR.
**
-
** ^The sqlite3_result_toobig() interface causes SQLite to throw an error
-
** indicating that a string or BLOB is too long to represent.
+
** ^The sqlite3_result_error_toobig() interface causes SQLite to throw an
+
** error indicating that a string or BLOB is too long to represent.
**
-
** ^The sqlite3_result_nomem() interface causes SQLite to throw an error
-
** indicating that a memory allocation failed.
+
** ^The sqlite3_result_error_nomem() interface causes SQLite to throw an
+
** error indicating that a memory allocation failed.
**
** ^The sqlite3_result_int() interface sets the return value
** of the application-defined function to be the 32-bit signed integer
@@ -5006,6 +5043,21 @@ SQLITE_API int sqlite3_sleep(int);
** Hence, if this variable is modified directly, either it should be
** made NULL or made to point to memory obtained from [sqlite3_malloc]
** or else the use of the [temp_store_directory pragma] should be avoided.
+
**
+
** <b>Note to Windows Runtime users:</b>  The temporary directory must be set
+
** prior to calling [sqlite3_open] or [sqlite3_open_v2].  Otherwise, various
+
** features that require the use of temporary files may fail.  Here is an
+
** example of how to do this using C++ with the Windows Runtime:
+
**
+
** <blockquote><pre>
+
** LPCWSTR zPath = Windows::Storage::ApplicationData::Current->
+
** &nbsp;     TemporaryFolder->Path->Data();
+
** char zPathBuf&#91;MAX_PATH + 1&#93;;
+
** memset(zPathBuf, 0, sizeof(zPathBuf));
+
** WideCharToMultiByte(CP_UTF8, 0, zPath, -1, zPathBuf, sizeof(zPathBuf),
+
** &nbsp;     NULL, NULL);
+
** sqlite3_temp_directory = sqlite3_mprintf("%s", zPathBuf);
+
** </pre></blockquote>
*/
SQLITE_API char *sqlite3_temp_directory;

@@ -6051,7 +6103,6 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
** implementations are available in the SQLite core:
**
** <ul>
-
** <li>   SQLITE_MUTEX_OS2
** <li>   SQLITE_MUTEX_PTHREADS
** <li>   SQLITE_MUTEX_W32
** <li>   SQLITE_MUTEX_NOOP
@@ -6059,9 +6110,9 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
**
** ^The SQLITE_MUTEX_NOOP implementation is a set of routines
** that does no real locking and is appropriate for use in
-
** a single-threaded application.  ^The SQLITE_MUTEX_OS2,
-
** SQLITE_MUTEX_PTHREADS, and SQLITE_MUTEX_W32 implementations
-
** are appropriate for use on OS/2, Unix, and Windows.
+
** a single-threaded application.  ^The SQLITE_MUTEX_PTHREADS and
+
** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix
+
** and Windows.
**
** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex
@@ -8372,6 +8423,12 @@ SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
#define BTREE_USER_VERSION        6
#define BTREE_INCR_VACUUM         7

+
/*
+
** Values that may be OR'd together to form the second argument of an
+
** sqlite3BtreeCursorHints() call.
+
*/
+
#define BTREE_BULKLOAD 0x00000001
+

SQLITE_PRIVATE int sqlite3BtreeCursor(
  Btree*,                              /* BTree containing table to open */
  int iTable,                          /* Index of root page */
@@ -8415,8 +8472,8 @@ SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*);
SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*);
SQLITE_PRIVATE void sqlite3BtreeCacheOverflow(BtCursor *);
SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *);
-

SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
+
SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask);

#ifndef NDEBUG
SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*);
@@ -9290,7 +9347,7 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void);
/*
** Figure out if we are dealing with Unix, Windows, or some other
** operating system.  After the following block of preprocess macros,
-
** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, SQLITE_OS_OS2, and SQLITE_OS_OTHER 
+
** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, and SQLITE_OS_OTHER 
** will defined to either 1 or 0.  One of the four will be 1.  The other 
** three will be 0.
*/
@@ -9300,8 +9357,6 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void);
#   define SQLITE_OS_UNIX 0
#   undef SQLITE_OS_WIN
#   define SQLITE_OS_WIN 0
-
#   undef SQLITE_OS_OS2
-
#   define SQLITE_OS_OS2 0
# else
#   undef SQLITE_OS_OTHER
# endif
@@ -9312,19 +9367,12 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void);
#   if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
#     define SQLITE_OS_WIN 1
#     define SQLITE_OS_UNIX 0
-
#     define SQLITE_OS_OS2 0
-
#   elif defined(__EMX__) || defined(_OS2) || defined(OS2) || defined(_OS2_) || defined(__OS2__)
-
#     define SQLITE_OS_WIN 0
-
#     define SQLITE_OS_UNIX 0
-
#     define SQLITE_OS_OS2 1
#   else
#     define SQLITE_OS_WIN 0
#     define SQLITE_OS_UNIX 1
-
#     define SQLITE_OS_OS2 0
#  endif
# else
#  define SQLITE_OS_UNIX 0
-
#  define SQLITE_OS_OS2 0
# endif
#else
# ifndef SQLITE_OS_WIN
@@ -9336,21 +9384,6 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void);
# include <windows.h>
#endif

-
#if SQLITE_OS_OS2
-
# if (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 3) && defined(OS2_HIGH_MEMORY)
-
#  include <os2safe.h> /* has to be included before os2.h for linking to work */
-
# endif
-
# define INCL_DOSDATETIME
-
# define INCL_DOSFILEMGR
-
# define INCL_DOSERRORS
-
# define INCL_DOSMISC
-
# define INCL_DOSPROCESS
-
# define INCL_DOSMODULEMGR
-
# define INCL_DOSSEMAPHORES
-
# include <os2.h>
-
# include <uconv.h>
-
#endif
-

/*
** Determine if we are dealing with Windows NT.
**
@@ -9383,8 +9416,8 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void);
#endif

/*
-
** Determine if we are dealing with WindowsRT (Metro) as this has a different and
-
** incompatible API from win32.
+
** Determine if we are dealing with WinRT, which provides only a subset of
+
** the full Win32 API.
*/
#if !defined(SQLITE_OS_WINRT)
# define SQLITE_OS_WINRT 0
@@ -9620,8 +9653,6 @@ SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *);
**   SQLITE_MUTEX_PTHREADS     For multi-threaded applications on Unix.
**
**   SQLITE_MUTEX_W32          For multi-threaded applications on Win32.
-
**
-
**   SQLITE_MUTEX_OS2          For multi-threaded applications on OS/2.
*/
#if !SQLITE_THREADSAFE
# define SQLITE_MUTEX_OMIT
@@ -9631,8 +9662,6 @@ SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *);
#    define SQLITE_MUTEX_PTHREADS
#  elif SQLITE_OS_WIN
#    define SQLITE_MUTEX_W32
-
#  elif SQLITE_OS_OS2
-
#    define SQLITE_MUTEX_OS2
#  else
#    define SQLITE_MUTEX_NOOP
#  endif
@@ -9953,6 +9982,7 @@ struct sqlite3 {
#define SQLITE_MAGIC_SICK     0x4b771290  /* Error and awaiting close */
#define SQLITE_MAGIC_BUSY     0xf03b7906  /* Database currently in use */
#define SQLITE_MAGIC_ERROR    0xb5357930  /* An SQLITE_MISUSE error occurred */
+
#define SQLITE_MAGIC_ZOMBIE   0x64cffc7f  /* Close with last statement close */

/*
** Each SQL function is defined by an instance of the following
@@ -10659,8 +10689,9 @@ struct Expr {
  i16 iAgg;              /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
  i16 iRightJoinTable;   /* If EP_FromJoin, the right table of the join */
  u8 flags2;             /* Second set of flags.  EP2_... */
-
  u8 op2;                /* If a TK_REGISTER, the original value of Expr.op */
-
                         /* If TK_COLUMN, the value of p5 for OP_Column */
+
  u8 op2;                /* TK_REGISTER: original value of Expr.op
+
                         ** TK_COLUMN: the value of p5 for OP_Column
+
                         ** TK_AGG_FUNCTION: nesting depth */
  AggInfo *pAggInfo;     /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
  Table *pTab;           /* Table for TK_COLUMN expressions. */
#if SQLITE_MAX_EXPR_DEPTH>0
@@ -10885,7 +10916,7 @@ struct WherePlan {
/*
** For each nested loop in a WHERE clause implementation, the WhereInfo
** structure contains a single instance of this structure.  This structure
-
** is intended to be private the the where.c module and should not be
+
** is intended to be private to the where.c module and should not be
** access or modified by other modules.
**
** The pIdxInfo field is used to help pick the best index on a
@@ -10915,6 +10946,7 @@ struct WhereLevel {
        int addrInTop;         /* Top of the IN loop */
      } *aInLoop;           /* Information about each nested IN operator */
    } in;                 /* Used when plan.wsFlags&WHERE_IN_ABLE */
+
    Index *pCovidx;       /* Possible covering index for WHERE_MULTI_OR */
  } u;

  /* The following field is really not part of the current level.  But
@@ -11087,10 +11119,10 @@ struct Select {
typedef struct SelectDest SelectDest;
struct SelectDest {
  u8 eDest;         /* How to dispose of the results */
-
  u8 affinity;      /* Affinity used when eDest==SRT_Set */
-
  int iParm;        /* A parameter used by the eDest disposal method */
-
  int iMem;         /* Base register where results are written */
-
  int nMem;         /* Number of registers allocated */
+
  u8 affSdst;       /* Affinity used when eDest==SRT_Set */
+
  int iSDParm;      /* A parameter used by the eDest disposal method */
+
  int iSdst;        /* Base register where results are written */
+
  int nSdst;        /* Number of registers allocated */
};

/*
@@ -11286,6 +11318,8 @@ struct AuthContext {
#define OPFLAG_CLEARCACHE    0x20    /* Clear pseudo-table cache in OP_Column */
#define OPFLAG_LENGTHARG     0x40    /* OP_Column only used for length() */
#define OPFLAG_TYPEOFARG     0x80    /* OP_Column only used for typeof() */
+
#define OPFLAG_BULKCSR       0x01    /* OP_Open** used to open bulk cursor */
+
#define OPFLAG_P2ISREG       0x02    /* P2 to OP_Open** is a register number */

/*
 * Each trigger present in the database schema is stored as an instance of
@@ -11465,10 +11499,12 @@ struct Walker {
  int (*xExprCallback)(Walker*, Expr*);     /* Callback for expressions */
  int (*xSelectCallback)(Walker*,Select*);  /* Callback for SELECTs */
  Parse *pParse;                            /* Parser context.  */
+
  int walkerDepth;                          /* Number of subqueries */
  union {                                   /* Extra data for callback */
    NameContext *pNC;                          /* Naming context */
    int i;                                     /* Integer value */
    SrcList *pSrcList;                         /* FROM clause */
+
    struct SrcCount *pSrcCount;                /* Counting column references */
  } u;
};

@@ -11770,7 +11806,8 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse *, SrcList *, Expr *, ExprList *, E
#endif
SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
-
SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**,ExprList*,u16);
+
SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
+
    Parse*,SrcList*,Expr*,ExprList**,ExprList*,u16,int);
SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
@@ -11802,6 +11839,7 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*);
SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*);
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
+
SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*);
SQLITE_PRIVATE void sqlite3PrngSaveState(void);
SQLITE_PRIVATE void sqlite3PrngRestoreState(void);
@@ -11814,6 +11852,7 @@ SQLITE_PRIVATE void sqlite3CommitTransaction(Parse*);
SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse*);
SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*);
SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *);
+
SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*);
SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*);
SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*);
@@ -13355,11 +13394,11 @@ SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p);
#else
SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *);
SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *);
-
SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(VdbeCursor *, Mem *);
-
SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, VdbeCursor *, int *);
-
SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *, VdbeCursor *, int *);
-
SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *, VdbeCursor *, Mem *);
-
SQLITE_PRIVATE int sqlite3VdbeSorterCompare(VdbeCursor *, Mem *, int *);
+
SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *);
+
SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *);
+
SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *, const VdbeCursor *, int *);
+
SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *, const VdbeCursor *, Mem *);
+
SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int *);
#endif

#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
@@ -15506,14 +15545,14 @@ static int sqlite3MemInit(void *NotUsed){
  }else{
    /* only 1 core, use our own zone to contention over global locks, 
    ** e.g. we have our own dedicated locks */
-
    bool success;		
+
    bool success;
    malloc_zone_t* newzone = malloc_create_zone(4096, 0);
    malloc_set_zone_name(newzone, "Sqlite_Heap");
    do{
      success = OSAtomicCompareAndSwapPtrBarrier(NULL, newzone, 
                                 (void * volatile *)&_sqliteZone_);
    }while(!_sqliteZone_);
-
    if( !success ){	
+
    if( !success ){
      /* somebody registered a zone first */
      malloc_destroy_zone(newzone);
    }
@@ -17719,282 +17758,6 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
#endif /* !defined(SQLITE_MUTEX_OMIT) */

/************** End of mutex_noop.c ******************************************/
-
/************** Begin file mutex_os2.c ***************************************/
-
/*
-
** 2007 August 28
-
**
-
** The author disclaims copyright to this source code.  In place of
-
** a legal notice, here is a blessing:
-
**
-
**    May you do good and not evil.
-
**    May you find forgiveness for yourself and forgive others.
-
**    May you share freely, never taking more than you give.
-
**
-
*************************************************************************
-
** This file contains the C functions that implement mutexes for OS/2
-
*/
-

-
/*
-
** The code in this file is only used if SQLITE_MUTEX_OS2 is defined.
-
** See the mutex.h file for details.
-
*/
-
#ifdef SQLITE_MUTEX_OS2
-

-
/********************** OS/2 Mutex Implementation **********************
-
**
-
** This implementation of mutexes is built using the OS/2 API.
-
*/
-

-
/*
-
** The mutex object
-
** Each recursive mutex is an instance of the following structure.
-
*/
-
struct sqlite3_mutex {
-
  HMTX mutex;       /* Mutex controlling the lock */
-
  int  id;          /* Mutex type */
-
#ifdef SQLITE_DEBUG
-
 int   trace;       /* True to trace changes */
-
#endif
-
};
-

-
#ifdef SQLITE_DEBUG
-
#define SQLITE3_MUTEX_INITIALIZER { 0, 0, 0 }
-
#else
-
#define SQLITE3_MUTEX_INITIALIZER { 0, 0 }
-
#endif
-

-
/*
-
** Initialize and deinitialize the mutex subsystem.
-
*/
-
static int os2MutexInit(void){ return SQLITE_OK; }
-
static int os2MutexEnd(void){ return SQLITE_OK; }
-

-
/*
-
** The sqlite3_mutex_alloc() routine allocates a new
-
** mutex and returns a pointer to it.  If it returns NULL
-
** that means that a mutex could not be allocated. 
-
** SQLite will unwind its stack and return an error.  The argument
-
** to sqlite3_mutex_alloc() is one of these integer constants:
-
**
-
** <ul>
-
** <li>  SQLITE_MUTEX_FAST
-
** <li>  SQLITE_MUTEX_RECURSIVE
-
** <li>  SQLITE_MUTEX_STATIC_MASTER
-
** <li>  SQLITE_MUTEX_STATIC_MEM
-
** <li>  SQLITE_MUTEX_STATIC_MEM2
-
** <li>  SQLITE_MUTEX_STATIC_PRNG
-
** <li>  SQLITE_MUTEX_STATIC_LRU
-
** <li>  SQLITE_MUTEX_STATIC_LRU2
-
** </ul>
-
**
-
** The first two constants cause sqlite3_mutex_alloc() to create
-
** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
-
** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
-
** The mutex implementation does not need to make a distinction
-
** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
-
** not want to.  But SQLite will only request a recursive mutex in
-
** cases where it really needs one.  If a faster non-recursive mutex
-
** implementation is available on the host platform, the mutex subsystem
-
** might return such a mutex in response to SQLITE_MUTEX_FAST.
-
**
-
** The other allowed parameters to sqlite3_mutex_alloc() each return
-
** a pointer to a static preexisting mutex.  Six static mutexes are
-
** used by the current version of SQLite.  Future versions of SQLite
-
** may add additional static mutexes.  Static mutexes are for internal
-
** use by SQLite only.  Applications that use SQLite mutexes should
-
** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
-
** SQLITE_MUTEX_RECURSIVE.
-
**
-
** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
-
** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
-
** returns a different mutex on every call.  But for the static
-
** mutex types, the same mutex is returned on every call that has
-
** the same type number.
-
*/
-
static sqlite3_mutex *os2MutexAlloc(int iType){
-
  sqlite3_mutex *p = NULL;
-
  switch( iType ){
-
    case SQLITE_MUTEX_FAST:
-
    case SQLITE_MUTEX_RECURSIVE: {
-
      p = sqlite3MallocZero( sizeof(*p) );
-
      if( p ){
-
        p->id = iType;
-
        if( DosCreateMutexSem( 0, &p->mutex, 0, FALSE ) != NO_ERROR ){
-
          sqlite3_free( p );
-
          p = NULL;
-
        }
-
      }
-
      break;
-
    }
-
    default: {
-
      static volatile int isInit = 0;
-
      static sqlite3_mutex staticMutexes[6] = {
-
        SQLITE3_MUTEX_INITIALIZER,
-
        SQLITE3_MUTEX_INITIALIZER,
-
        SQLITE3_MUTEX_INITIALIZER,
-
        SQLITE3_MUTEX_INITIALIZER,
-
        SQLITE3_MUTEX_INITIALIZER,
-
        SQLITE3_MUTEX_INITIALIZER,
-
      };
-
      if ( !isInit ){
-
        APIRET rc;
-
        PTIB ptib;
-
        PPIB ppib;
-
        HMTX mutex;
-
        char name[32];
-
        DosGetInfoBlocks( &ptib, &ppib );
-
        sqlite3_snprintf( sizeof(name), name, "\\SEM32\\SQLITE%04x",
-
                          ppib->pib_ulpid );
-
        while( !isInit ){
-
          mutex = 0;
-
          rc = DosCreateMutexSem( name, &mutex, 0, FALSE);
-
          if( rc == NO_ERROR ){
-
            unsigned int i;
-
            if( !isInit ){
-
              for( i = 0; i < sizeof(staticMutexes)/sizeof(staticMutexes[0]); i++ ){
-
                DosCreateMutexSem( 0, &staticMutexes[i].mutex, 0, FALSE );
-
              }
-
              isInit = 1;
-
            }
-
            DosCloseMutexSem( mutex );
-
          }else if( rc == ERROR_DUPLICATE_NAME ){
-
            DosSleep( 1 );
-
          }else{
-
            return p;
-
          }
-
        }
-
      }
-
      assert( iType-2 >= 0 );
-
      assert( iType-2 < sizeof(staticMutexes)/sizeof(staticMutexes[0]) );
-
      p = &staticMutexes[iType-2];
-
      p->id = iType;
-
      break;
-
    }
-
  }
-
  return p;
-
}
-

-

-
/*
-
** This routine deallocates a previously allocated mutex.
-
** SQLite is careful to deallocate every mutex that it allocates.
-
*/
-
static void os2MutexFree(sqlite3_mutex *p){
-
#ifdef SQLITE_DEBUG
-
  TID tid;
-
  PID pid;
-
  ULONG ulCount;
-
  DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
-
  assert( ulCount==0 );
-
  assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
-
#endif
-
  DosCloseMutexSem( p->mutex );
-
  sqlite3_free( p );
-
}
-

-
#ifdef SQLITE_DEBUG
-
/*
-
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
-
** intended for use inside assert() statements.
-
*/
-
static int os2MutexHeld(sqlite3_mutex *p){
-
  TID tid;
-
  PID pid;
-
  ULONG ulCount;
-
  PTIB ptib;
-
  DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
-
  if( ulCount==0 || ( ulCount>1 && p->id!=SQLITE_MUTEX_RECURSIVE ) )
-
    return 0;
-
  DosGetInfoBlocks(&ptib, NULL);
-
  return tid==ptib->tib_ptib2->tib2_ultid;
-
}
-
static int os2MutexNotheld(sqlite3_mutex *p){
-
  TID tid;
-
  PID pid;
-
  ULONG ulCount;
-
  PTIB ptib;
-
  DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
-
  if( ulCount==0 )
-
    return 1;
-
  DosGetInfoBlocks(&ptib, NULL);
-
  return tid!=ptib->tib_ptib2->tib2_ultid;
-
}
-
static void os2MutexTrace(sqlite3_mutex *p, char *pAction){
-
  TID   tid;
-
  PID   pid;
-
  ULONG ulCount;
-
  DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
-
  printf("%s mutex %p (%d) with nRef=%ld\n", pAction, (void*)p, p->trace, ulCount);
-
}
-
#endif
-

-
/*
-
** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
-
** to enter a mutex.  If another thread is already within the mutex,
-
** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
-
** SQLITE_BUSY.  The sqlite3_mutex_try() interface returns SQLITE_OK
-
** upon successful entry.  Mutexes created using SQLITE_MUTEX_RECURSIVE can
-
** be entered multiple times by the same thread.  In such cases the,
-
** mutex must be exited an equal number of times before another thread
-
** can enter.  If the same thread tries to enter any other kind of mutex
-
** more than once, the behavior is undefined.
-
*/
-
static void os2MutexEnter(sqlite3_mutex *p){
-
  assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) );
-
  DosRequestMutexSem(p->mutex, SEM_INDEFINITE_WAIT);
-
#ifdef SQLITE_DEBUG
-
  if( p->trace ) os2MutexTrace(p, "enter");
-
#endif
-
}
-
static int os2MutexTry(sqlite3_mutex *p){
-
  int rc = SQLITE_BUSY;
-
  assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) );
-
  if( DosRequestMutexSem(p->mutex, SEM_IMMEDIATE_RETURN) == NO_ERROR ) {
-
    rc = SQLITE_OK;
-
#ifdef SQLITE_DEBUG
-
    if( p->trace ) os2MutexTrace(p, "try");
-
#endif
-
  }
-
  return rc;
-
}
-

-
/*
-
** The sqlite3_mutex_leave() routine exits a mutex that was
-
** previously entered by the same thread.  The behavior
-
** is undefined if the mutex is not currently entered or
-
** is not currently allocated.  SQLite will never do either.
-
*/
-
static void os2MutexLeave(sqlite3_mutex *p){
-
  assert( os2MutexHeld(p) );
-
  DosReleaseMutexSem(p->mutex);
-
#ifdef SQLITE_DEBUG
-
  if( p->trace ) os2MutexTrace(p, "leave");
-
#endif
-
}
-

-
SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
-
  static const sqlite3_mutex_methods sMutex = {
-
    os2MutexInit,
-
    os2MutexEnd,
-
    os2MutexAlloc,
-
    os2MutexFree,
-
    os2MutexEnter,
-
    os2MutexTry,
-
    os2MutexLeave,
-
#ifdef SQLITE_DEBUG
-
    os2MutexHeld,
-
    os2MutexNotheld
-
#else
-
    0,
-
    0
-
#endif
-
  };
-

-
  return &sMutex;
-
}
-
#endif /* SQLITE_MUTEX_OS2 */
-

-
/************** End of mutex_os2.c *******************************************/
/************** Begin file mutex_unix.c **************************************/
/*
** 2007 August 28
@@ -18459,7 +18222,7 @@ static int winMutex_isInit = 0;
*/
static long winMutex_lock = 0;

-
SQLITE_API extern void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
+
SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */

static int winMutexInit(void){ 
  /* The first to increment to 1 does actual initialization */
@@ -19602,7 +19365,8 @@ static const et_info fmtinfo[] = {
static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
  int digit;
  LONGDOUBLE_TYPE d;
-
  if( (*cnt)++ >= 16 ) return '0';
+
  if( (*cnt)<=0 ) return '0';
+
  (*cnt)--;
  digit = (int)*val;
  d = digit;
  digit += '0';
@@ -19906,9 +19670,12 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
          break;
        }
        if( realvalue>0.0 ){
-
          while( realvalue>=1e32 && exp<=350 ){ realvalue *= 1e-32; exp+=32; }
-
          while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; }
-
          while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; }
+
          LONGDOUBLE_TYPE scale = 1.0;
+
          while( realvalue>=1e100*scale && exp<=350 ){ scale *= 1e100;exp+=100;}
+
          while( realvalue>=1e64*scale && exp<=350 ){ scale *= 1e64; exp+=64; }
+
          while( realvalue>=1e8*scale && exp<=350 ){ scale *= 1e8; exp+=8; }
+
          while( realvalue>=10.0*scale && exp<=350 ){ scale *= 10.0; exp++; }
+
          realvalue /= scale;
          while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; }
          while( realvalue<1.0 ){ realvalue *= 10.0; exp--; }
          if( exp>350 ){
@@ -19941,7 +19708,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
            xtype = etFLOAT;
          }
        }else{
-
          flag_rtz = 0;
+
          flag_rtz = flag_altform2;
        }
        if( xtype==etEXP ){
          e2 = 0;
@@ -19956,7 +19723,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
          }
        }
        zOut = bufpt;
-
        nsd = 0;
+
        nsd = 16 + flag_altform2*10;
        flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
        /* The sign in front of the number */
        if( prefix ){
@@ -21529,7 +21296,7 @@ do_atof_calc:
    /* if exponent, scale significand as appropriate
    ** and store in result. */
    if( e ){
-
      double scale = 1.0;
+
      LONGDOUBLE_TYPE scale = 1.0;
      /* attempt to handle extremely small/large numbers better */
      if( e>307 && e<342 ){
        while( e%308 ) { scale *= 1.0e+1; e -= 1; }
@@ -22458,7 +22225,11 @@ static int rehash(Hash *pH, unsigned int new_size){

  /* The inability to allocates space for a larger hash table is
  ** a performance hit but it is not a fatal error.  So mark the
-
  ** allocation as a benign.
+
  ** allocation as a benign. Use sqlite3Malloc()/memset(0) instead of 
+
  ** sqlite3MallocZero() to make the allocation, as sqlite3MallocZero()
+
  ** only zeroes the requested number of bytes whereas this module will
+
  ** use the actual amount of space allocated for the hash table (which
+
  ** may be larger than the requested amount).
  */
  sqlite3BeginBenignMalloc();
  new_ht = (struct _ht *)sqlite3Malloc( new_size*sizeof(struct _ht) );
@@ -22784,9 +22555,9 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
#endif

/************** End of opcodes.c *********************************************/
-
/************** Begin file os_os2.c ******************************************/
+
/************** Begin file os_unix.c *****************************************/
/*
-
** 2006 Feb 14
+
** 2004 May 22
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
@@ -22797,2396 +22568,262 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
**
******************************************************************************
**
-
** This file contains code that is specific to OS/2.
+
** 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().
*/
+
#if SQLITE_OS_UNIX              /* This file is used on unix only */

+
/*
+
** 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(__APPLE__)
+
#    define SQLITE_ENABLE_LOCKING_STYLE 1
+
#  else
+
#    define SQLITE_ENABLE_LOCKING_STYLE 0
+
#  endif
+
#endif

-
#if SQLITE_OS_OS2
+
/*
+
** Define the OS_VXWORKS pre-processor macro to 1 if building on 
+
** vxworks, or 0 otherwise.
+
*/
+
#ifndef OS_VXWORKS
+
#  if defined(__RTP__) || defined(_WRS_KERNEL)
+
#    define OS_VXWORKS 1
+
#  else
+
#    define OS_VXWORKS 0
+
#  endif
+
#endif

/*
-
** A Note About Memory Allocation:
-
**
-
** This driver uses malloc()/free() directly rather than going through
-
** the SQLite-wrappers sqlite3_malloc()/sqlite3_free().  Those wrappers
-
** are designed for use on embedded systems where memory is scarce and
-
** malloc failures happen frequently.  OS/2 does not typically run on
-
** embedded systems, and when it does the developers normally have bigger
-
** problems to worry about than running out of memory.  So there is not
-
** a compelling need to use the wrappers.
+
** These #defines should enable >2GB file support on Posix if the
+
** underlying operating system supports it.  If the OS lacks
+
** large file support, these should be no-ops.
**
-
** But there is a good reason to not use the wrappers.  If we use the
-
** wrappers then we will get simulated malloc() failures within this
-
** driver.  And that causes all kinds of problems for our tests.  We
-
** could enhance SQLite to deal with simulated malloc failures within
-
** the OS driver, but the code to deal with those failure would not
-
** be exercised on Linux (which does not need to malloc() in the driver)
-
** and so we would have difficulty writing coverage tests for that
-
** code.  Better to leave the code out, we think.
+
** 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
+
** 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 point of this discussion is as follows:  When creating a new
-
** OS layer for an embedded system, if you use this file as an example,
-
** avoid the use of malloc()/free().  Those routines work ok on OS/2
-
** desktops but not so well in embedded systems.
+
** 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
+
#   define _FILE_OFFSET_BITS 64
+
# endif
+
# define _LARGEFILE_SOURCE 1
+
#endif
+

+
/*
+
** standard include files.
+
*/
+
#include <sys/types.h>
+
#include <sys/stat.h>
+
#include <fcntl.h>
+
#include <unistd.h>
+
/* #include <time.h> */
+
#include <sys/time.h>
+
#include <errno.h>
+
#ifndef SQLITE_OMIT_WAL
+
#include <sys/mman.h>
+
#endif
+

+

+
#if SQLITE_ENABLE_LOCKING_STYLE
+
# include <sys/ioctl.h>
+
# if OS_VXWORKS
+
#  include <semaphore.h>
+
#  include <limits.h>
+
# else
+
#  include <sys/file.h>
+
#  include <sys/param.h>
+
# endif
+
#endif /* SQLITE_ENABLE_LOCKING_STYLE */
+

+
#if defined(__APPLE__) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS)
+
# include <sys/mount.h>
+
#endif
+

+
#ifdef HAVE_UTIME
+
# include <utime.h>
+
#endif
+

+
/*
+
** Allowed values of unixFile.fsFlags
+
*/
+
#define SQLITE_FSFLAGS_IS_MSDOS     0x1
+

+
/*
+
** If we are to be thread-safe, include the pthreads header and define
+
** the SQLITE_UNIX_THREADS macro.
*/
+
#if SQLITE_THREADSAFE
+
/* # include <pthread.h> */
+
# define SQLITE_UNIX_THREADS 1
+
#endif
+

+
/*
+
** Default permissions when creating a new file
+
*/
+
#ifndef SQLITE_DEFAULT_FILE_PERMISSIONS
+
# define SQLITE_DEFAULT_FILE_PERMISSIONS 0644
+
#endif

/*
-
** Macros used to determine whether or not to use threads.
+
** Default permissions when creating auto proxy dir
*/
-
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE
-
# define SQLITE_OS2_THREADS 1
+
#ifndef SQLITE_DEFAULT_PROXYDIR_PERMISSIONS
+
# define SQLITE_DEFAULT_PROXYDIR_PERMISSIONS 0755
#endif

/*
+
** Maximum supported path-length.
+
*/
+
#define MAX_PATHNAME 512
+

+
/*
+
** 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))
+

+
/* Forward references */
+
typedef struct unixShm unixShm;               /* Connection shared memory */
+
typedef struct unixShmNode unixShmNode;       /* Shared memory instance */
+
typedef struct unixInodeInfo unixInodeInfo;   /* An i-node */
+
typedef struct UnixUnusedFd UnixUnusedFd;     /* An unused file descriptor */
+

+
/*
+
** Sometimes, after a file handle is closed by SQLite, the file descriptor
+
** cannot be closed immediately. In these cases, instances of the following
+
** structure are used to store the file descriptor while waiting for an
+
** opportunity to either close or reuse it.
+
*/
+
struct UnixUnusedFd {
+
  int fd;                   /* File descriptor to close */
+
  int flags;                /* Flags this file descriptor was opened with */
+
  UnixUnusedFd *pNext;      /* Next unused file descriptor on same file */
+
};
+

+
/*
+
** 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 */
+
  sqlite3_vfs *pVfs;                  /* The VFS that created this unixFile */
+
  unixInodeInfo *pInode;              /* Info about locks on this inode */
+
  int h;                              /* The file descriptor */
+
  unsigned char eFileLock;            /* The type of lock held on this fd */
+
  unsigned short int ctrlFlags;       /* Behavioral bits.  UNIXFILE_* flags */
+
  int lastErrno;                      /* The unix errno from last I/O error */
+
  void *lockingContext;               /* Locking style specific state */
+
  UnixUnusedFd *pUnused;              /* Pre-allocated UnixUnusedFd */
+
  const char *zPath;                  /* Name of the file */
+
  unixShm *pShm;                      /* Shared memory segment information */
+
  int szChunk;                        /* Configured by FCNTL_CHUNK_SIZE */
+
#if SQLITE_ENABLE_LOCKING_STYLE
+
  int openFlags;                      /* The flags specified at open() */
+
#endif
+
#if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__)
+
  unsigned fsFlags;                   /* cached details from statfs() */
+
#endif
+
#if OS_VXWORKS
+
  struct vxworksFileId *pId;          /* Unique file ID */
+
#endif
+
#ifdef SQLITE_DEBUG
+
  /* The next group of variables are used to track whether or not the
+
  ** transaction counter in bytes 24-27 of database files are updated
+
  ** whenever any part of the database changes.  An assertion fault will
+
  ** occur if a file is updated without also updating the transaction
+
  ** counter.  This test is made to avoid new problems similar to the
+
  ** one described by ticket #3584. 
+
  */
+
  unsigned char transCntrChng;   /* True if the transaction counter changed */
+
  unsigned char dbUpdate;        /* True if any part of database file changed */
+
  unsigned char inNormalWrite;   /* True if in a normal write operation */
+
#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
+
};
+

+
/*
+
** Allowed values for the unixFile.ctrlFlags bitmask:
+
*/
+
#define UNIXFILE_EXCL        0x01     /* Connections from one process only */
+
#define UNIXFILE_RDONLY      0x02     /* Connection is read only */
+
#define UNIXFILE_PERSIST_WAL 0x04     /* Persistent WAL mode */
+
#ifndef SQLITE_DISABLE_DIRSYNC
+
# define UNIXFILE_DIRSYNC    0x08     /* Directory sync needed */
+
#else
+
# define UNIXFILE_DIRSYNC    0x00
+
#endif
+
#define UNIXFILE_PSOW        0x10     /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
+
#define UNIXFILE_DELETE      0x20     /* Delete on close */
+
#define UNIXFILE_URI         0x40     /* Filename might have query parameters */
+
#define UNIXFILE_NOLOCK      0x80     /* Do no file locking */
+

+
/*
** Include code that is common to all os_*.c files
*/
-
/************** Include os_common.h in the middle of os_os2.c ****************/
-
/************** Begin file os_common.h ***************************************/
-
/*
-
** 2004 May 22
-
**
-
** The author disclaims copyright to this source code.  In place of
-
** a legal notice, here is a blessing:
-
**
-
**    May you do good and not evil.
-
**    May you find forgiveness for yourself and forgive others.
-
**    May you share freely, never taking more than you give.
-
**
-
******************************************************************************
-
**
-
** This file contains macros and a little bit of code that is common to
-
** all of the platform-specific files (os_*.c) and is #included into those
-
** files.
-
**
-
** This file should be #included by the os_*.c files only.  It is not a
-
** general purpose header file.
-
*/
-
#ifndef _OS_COMMON_H_
-
#define _OS_COMMON_H_
-

-
/*
-
** At least two bugs have slipped in because we changed the MEMORY_DEBUG
-
** macro to SQLITE_DEBUG and some older makefiles have not yet made the
-
** switch.  The following code should catch this problem at compile-time.
-
*/
-
#ifdef MEMORY_DEBUG
-
# error "The MEMORY_DEBUG macro is obsolete.  Use SQLITE_DEBUG instead."
-
#endif
-

-
#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
-
# ifndef SQLITE_DEBUG_OS_TRACE
-
#   define SQLITE_DEBUG_OS_TRACE 0
-
# endif
-
  int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE;
-
# define OSTRACE(X)          if( sqlite3OSTrace ) sqlite3DebugPrintf X
-
#else
-
# define OSTRACE(X)
-
#endif
-

-
/*
-
** Macros for performance tracing.  Normally turned off.  Only works
-
** on i486 hardware.
-
*/
-
#ifdef SQLITE_PERFORMANCE_TRACE
-

-
/* 
-
** hwtime.h contains inline assembler code for implementing 
-
** high-performance timing routines.
-
*/
-
/************** Include hwtime.h in the middle of os_common.h ****************/
-
/************** Begin file hwtime.h ******************************************/
-
/*
-
** 2008 May 27
-
**
-
** The author disclaims copyright to this source code.  In place of
-
** a legal notice, here is a blessing:
-
**
-
**    May you do good and not evil.
-
**    May you find forgiveness for yourself and forgive others.
-
**    May you share freely, never taking more than you give.
-
**
-
******************************************************************************
-
**
-
** This file contains inline asm code for retrieving "high-performance"
-
** counters for x86 class CPUs.
-
*/
-
#ifndef _HWTIME_H_
-
#define _HWTIME_H_
-

-
/*
-
** The following routine only works on pentium-class (or newer) processors.
-
** It uses the RDTSC opcode to read the cycle count value out of the
-
** processor and returns that value.  This can be used for high-res
-
** profiling.
-
*/
-
#if (defined(__GNUC__) || defined(_MSC_VER)) && \
-
      (defined(i386) || defined(__i386__) || defined(_M_IX86))
-

-
  #if defined(__GNUC__)
-

-
  __inline__ sqlite_uint64 sqlite3Hwtime(void){
-
     unsigned int lo, hi;
-
     __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
-
     return (sqlite_uint64)hi << 32 | lo;
-
  }
-

-
  #elif defined(_MSC_VER)
-

-
  __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
-
     __asm {
-
        rdtsc
-
        ret       ; return value at EDX:EAX
-
     }
-
  }
-

-
  #endif
-

-
#elif (defined(__GNUC__) && defined(__x86_64__))
-

-
  __inline__ sqlite_uint64 sqlite3Hwtime(void){
-
      unsigned long val;
-
      __asm__ __volatile__ ("rdtsc" : "=A" (val));
-
      return val;
-
  }
-
 
-
#elif (defined(__GNUC__) && defined(__ppc__))
-

-
  __inline__ sqlite_uint64 sqlite3Hwtime(void){
-
      unsigned long long retval;
-
      unsigned long junk;
-
      __asm__ __volatile__ ("\n\
-
          1:      mftbu   %1\n\
-
                  mftb    %L0\n\
-
                  mftbu   %0\n\
-
                  cmpw    %0,%1\n\
-
                  bne     1b"
-
                  : "=r" (retval), "=r" (junk));
-
      return retval;
-
  }
-

-
#else
-

-
  #error Need implementation of sqlite3Hwtime() for your platform.
-

-
  /*
-
  ** To compile without implementing sqlite3Hwtime() for your platform,
-
  ** you can remove the above #error and use the following
-
  ** stub function.  You will lose timing support for many
-
  ** of the debugging and testing utilities, but it should at
-
  ** least compile and run.
-
  */
-
SQLITE_PRIVATE   sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
-

-
#endif
-

-
#endif /* !defined(_HWTIME_H_) */
-

-
/************** End of hwtime.h **********************************************/
-
/************** Continuing where we left off in os_common.h ******************/
-

-
static sqlite_uint64 g_start;
-
static sqlite_uint64 g_elapsed;
-
#define TIMER_START       g_start=sqlite3Hwtime()
-
#define TIMER_END         g_elapsed=sqlite3Hwtime()-g_start
-
#define TIMER_ELAPSED     g_elapsed
-
#else
-
#define TIMER_START
-
#define TIMER_END
-
#define TIMER_ELAPSED     ((sqlite_uint64)0)
-
#endif
-

-
/*
-
** If we compile with the SQLITE_TEST macro set, then the following block
-
** of code will give us the ability to simulate a disk I/O error.  This
-
** is used for testing the I/O recovery logic.
-
*/
-
#ifdef SQLITE_TEST
-
SQLITE_API int sqlite3_io_error_hit = 0;            /* Total number of I/O Errors */
-
SQLITE_API int sqlite3_io_error_hardhit = 0;        /* Number of non-benign errors */
-
SQLITE_API int sqlite3_io_error_pending = 0;        /* Count down to first I/O error */
-
SQLITE_API int sqlite3_io_error_persist = 0;        /* True if I/O errors persist */
-
SQLITE_API int sqlite3_io_error_benign = 0;         /* True if errors are benign */
-
SQLITE_API int sqlite3_diskfull_pending = 0;
-
SQLITE_API int sqlite3_diskfull = 0;
-
#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X)
-
#define SimulateIOError(CODE)  \
-
  if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \
-
       || sqlite3_io_error_pending-- == 1 )  \
-
              { local_ioerr(); CODE; }
-
static void local_ioerr(){
-
  IOTRACE(("IOERR\n"));
-
  sqlite3_io_error_hit++;
-
  if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++;
-
}
-
#define SimulateDiskfullError(CODE) \
-
   if( sqlite3_diskfull_pending ){ \
-
     if( sqlite3_diskfull_pending == 1 ){ \
-
       local_ioerr(); \
-
       sqlite3_diskfull = 1; \
-
       sqlite3_io_error_hit = 1; \
-
       CODE; \
-
     }else{ \
-
       sqlite3_diskfull_pending--; \
-
     } \
-
   }
-
#else
-
#define SimulateIOErrorBenign(X)
-
#define SimulateIOError(A)
-
#define SimulateDiskfullError(A)
-
#endif
-

-
/*
-
** When testing, keep a count of the number of open files.
-
*/
-
#ifdef SQLITE_TEST
-
SQLITE_API int sqlite3_open_file_count = 0;
-
#define OpenCounter(X)  sqlite3_open_file_count+=(X)
-
#else
-
#define OpenCounter(X)
-
#endif
-

-
#endif /* !defined(_OS_COMMON_H_) */
-

-
/************** End of os_common.h *******************************************/
-
/************** Continuing where we left off in os_os2.c *********************/
-

-
/* Forward references */
-
typedef struct os2File os2File;         /* The file structure */
-
typedef struct os2ShmNode os2ShmNode;   /* A shared descritive memory node */
-
typedef struct os2ShmLink os2ShmLink;   /* A connection to shared-memory */
-

-
/*
-
** The os2File structure is subclass of sqlite3_file specific for the OS/2
-
** protability layer.
-
*/
-
struct os2File {
-
  const sqlite3_io_methods *pMethod;  /* Always the first entry */
-
  HFILE h;                  /* Handle for accessing the file */
-
  int flags;                /* Flags provided to os2Open() */
-
  int locktype;             /* Type of lock currently held on this file */
-
  int szChunk;              /* Chunk size configured by FCNTL_CHUNK_SIZE */
-
  char *zFullPathCp;        /* Full path name of this file */
-
  os2ShmLink *pShmLink;     /* Instance of shared memory on this file */
-
};
-

-
#define LOCK_TIMEOUT 10L /* the default locking timeout */
-

-
/*
-
** Missing from some versions of the OS/2 toolkit -
-
** used to allocate from high memory if possible
-
*/
-
#ifndef OBJ_ANY
-
# define OBJ_ANY 0x00000400
-
#endif
-

-
/*****************************************************************************
-
** The next group of routines implement the I/O methods specified
-
** by the sqlite3_io_methods object.
-
******************************************************************************/
-

-
/*
-
** Close a file.
-
*/
-
static int os2Close( sqlite3_file *id ){
-
  APIRET rc;
-
  os2File *pFile = (os2File*)id;
-

-
  assert( id!=0 );
-
  OSTRACE(( "CLOSE %d (%s)\n", pFile->h, pFile->zFullPathCp ));
-

-
  rc = DosClose( pFile->h );
-

-
  if( pFile->flags & SQLITE_OPEN_DELETEONCLOSE )
-
    DosForceDelete( (PSZ)pFile->zFullPathCp );
-

-
  free( pFile->zFullPathCp );
-
  pFile->zFullPathCp = NULL;
-
  pFile->locktype = NO_LOCK;
-
  pFile->h = (HFILE)-1;
-
  pFile->flags = 0;
-

-
  OpenCounter( -1 );
-
  return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
-
}
-

-
/*
-
** 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 os2Read(
-
  sqlite3_file *id,               /* File to read from */
-
  void *pBuf,                     /* Write content into this buffer */
-
  int amt,                        /* Number of bytes to read */
-
  sqlite3_int64 offset            /* Begin reading at this offset */
-
){
-
  ULONG fileLocation = 0L;
-
  ULONG got;
-
  os2File *pFile = (os2File*)id;
-
  assert( id!=0 );
-
  SimulateIOError( return SQLITE_IOERR_READ );
-
  OSTRACE(( "READ %d lock=%d\n", pFile->h, pFile->locktype ));
-
  if( DosSetFilePtr(pFile->h, offset, FILE_BEGIN, &fileLocation) != NO_ERROR ){
-
    return SQLITE_IOERR;
-
  }
-
  if( DosRead( pFile->h, pBuf, amt, &got ) != NO_ERROR ){
-
    return SQLITE_IOERR_READ;
-
  }
-
  if( got == (ULONG)amt )
-
    return SQLITE_OK;
-
  else {
-
    /* Unread portions of the input buffer must be zero-filled */
-
    memset(&((char*)pBuf)[got], 0, amt-got);
-
    return SQLITE_IOERR_SHORT_READ;
-
  }
-
}
-

-
/*
-
** Write data from a buffer into a file.  Return SQLITE_OK on success
-
** or some other error code on failure.
-
*/
-
static int os2Write(
-
  sqlite3_file *id,               /* File to write into */
-
  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 */
-
){
-
  ULONG fileLocation = 0L;
-
  APIRET rc = NO_ERROR;
-
  ULONG wrote;
-
  os2File *pFile = (os2File*)id;
-
  assert( id!=0 );
-
  SimulateIOError( return SQLITE_IOERR_WRITE );
-
  SimulateDiskfullError( return SQLITE_FULL );
-
  OSTRACE(( "WRITE %d lock=%d\n", pFile->h, pFile->locktype ));
-
  if( DosSetFilePtr(pFile->h, offset, FILE_BEGIN, &fileLocation) != NO_ERROR ){
-
    return SQLITE_IOERR;
-
  }
-
  assert( amt>0 );
-
  while( amt > 0 &&
-
         ( rc = DosWrite( pFile->h, (PVOID)pBuf, amt, &wrote ) ) == NO_ERROR &&
-
         wrote > 0
-
  ){
-
    amt -= wrote;
-
    pBuf = &((char*)pBuf)[wrote];
-
  }
-

-
  return ( rc != NO_ERROR || amt > (int)wrote ) ? SQLITE_FULL : SQLITE_OK;
-
}
-

-
/*
-
** Truncate an open file to a specified size
-
*/
-
static int os2Truncate( sqlite3_file *id, i64 nByte ){
-
  APIRET rc;
-
  os2File *pFile = (os2File*)id;
-
  assert( id!=0 );
-
  OSTRACE(( "TRUNCATE %d %lld\n", pFile->h, nByte ));
-
  SimulateIOError( return SQLITE_IOERR_TRUNCATE );
-

-
  /* If the user has configured a chunk-size for this file, truncate the
-
  ** file so that it consists of an integer number of chunks (i.e. the
-
  ** actual file size after the operation may be larger than the requested
-
  ** size).
-
  */
-
  if( pFile->szChunk ){
-
    nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
-
  }
-
  
-
  rc = DosSetFileSize( pFile->h, nByte );
-
  return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR_TRUNCATE;
-
}
-

-
#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
-

-
/*
-
** Make sure all writes to a particular file are committed to disk.
-
*/
-
static int os2Sync( sqlite3_file *id, int flags ){
-
  os2File *pFile = (os2File*)id;
-
  OSTRACE(( "SYNC %d lock=%d\n", pFile->h, pFile->locktype ));
-
#ifdef SQLITE_TEST
-
  if( flags & SQLITE_SYNC_FULL){
-
    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
-
  UNUSED_PARAMETER(pFile);
-
  return SQLITE_OK;
-
#else
-
  return DosResetBuffer( pFile->h ) == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
-
#endif
-
}
-

-
/*
-
** Determine the current size of a file in bytes
-
*/
-
static int os2FileSize( sqlite3_file *id, sqlite3_int64 *pSize ){
-
  APIRET rc = NO_ERROR;
-
  FILESTATUS3 fsts3FileInfo;
-
  memset(&fsts3FileInfo, 0, sizeof(fsts3FileInfo));
-
  assert( id!=0 );
-
  SimulateIOError( return SQLITE_IOERR_FSTAT );
-
  rc = DosQueryFileInfo( ((os2File*)id)->h, FIL_STANDARD, &fsts3FileInfo, sizeof(FILESTATUS3) );
-
  if( rc == NO_ERROR ){
-
    *pSize = fsts3FileInfo.cbFile;
-
    return SQLITE_OK;
-
  }else{
-
    return SQLITE_IOERR_FSTAT;
-
  }
-
}
-

-
/*
-
** Acquire a reader lock.
-
*/
-
static int getReadLock( os2File *pFile ){
-
  FILELOCK  LockArea,
-
            UnlockArea;
-
  APIRET res;
-
  memset(&LockArea, 0, sizeof(LockArea));
-
  memset(&UnlockArea, 0, sizeof(UnlockArea));
-
  LockArea.lOffset = SHARED_FIRST;
-
  LockArea.lRange = SHARED_SIZE;
-
  UnlockArea.lOffset = 0L;
-
  UnlockArea.lRange = 0L;
-
  res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 1L );
-
  OSTRACE(( "GETREADLOCK %d res=%d\n", pFile->h, res ));
-
  return res;
-
}
-

-
/*
-
** Undo a readlock
-
*/
-
static int unlockReadLock( os2File *id ){
-
  FILELOCK  LockArea,
-
            UnlockArea;
-
  APIRET res;
-
  memset(&LockArea, 0, sizeof(LockArea));
-
  memset(&UnlockArea, 0, sizeof(UnlockArea));
-
  LockArea.lOffset = 0L;
-
  LockArea.lRange = 0L;
-
  UnlockArea.lOffset = SHARED_FIRST;
-
  UnlockArea.lRange = SHARED_SIZE;
-
  res = DosSetFileLocks( id->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 1L );
-
  OSTRACE(( "UNLOCK-READLOCK file handle=%d res=%d?\n", id->h, res ));
-
  return res;
-
}
-

-
/*
-
** 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.  The os2Unlock() routine
-
** erases all locks at once and returns us immediately to locking level 0.
-
** It is not possible to lower the locking level one step at a time.  You
-
** must go straight to locking level 0.
-
*/
-
static int os2Lock( sqlite3_file *id, int locktype ){
-
  int rc = SQLITE_OK;       /* Return code from subroutines */
-
  APIRET res = NO_ERROR;    /* Result of an OS/2 lock call */
-
  int newLocktype;       /* Set pFile->locktype to this value before exiting */
-
  int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
-
  FILELOCK  LockArea,
-
            UnlockArea;
-
  os2File *pFile = (os2File*)id;
-
  memset(&LockArea, 0, sizeof(LockArea));
-
  memset(&UnlockArea, 0, sizeof(UnlockArea));
-
  assert( pFile!=0 );
-
  OSTRACE(( "LOCK %d %d was %d\n", pFile->h, locktype, pFile->locktype ));
-

-
  /* If there is already a lock of this type or more restrictive on the
-
  ** os2File, do nothing. Don't use the end_lock: exit path, as
-
  ** sqlite3_mutex_enter() hasn't been called yet.
-
  */
-
  if( pFile->locktype>=locktype ){
-
    OSTRACE(( "LOCK %d %d ok (already held)\n", pFile->h, 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 );
-

-
  /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
-
  ** a SHARED lock.  If we are acquiring a SHARED lock, the acquisition of
-
  ** the PENDING_LOCK byte is temporary.
-
  */
-
  newLocktype = pFile->locktype;
-
  if( pFile->locktype==NO_LOCK
-
      || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK)
-
  ){
-
    LockArea.lOffset = PENDING_BYTE;
-
    LockArea.lRange = 1L;
-
    UnlockArea.lOffset = 0L;
-
    UnlockArea.lRange = 0L;
-

-
    /* wait longer than LOCK_TIMEOUT here not to have to try multiple times */
-
    res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 100L, 0L );
-
    if( res == NO_ERROR ){
-
      gotPendingLock = 1;
-
      OSTRACE(( "LOCK %d pending lock boolean set.  res=%d\n", pFile->h, res ));
-
    }
-
  }
-

-
  /* Acquire a shared lock
-
  */
-
  if( locktype==SHARED_LOCK && res == NO_ERROR ){
-
    assert( pFile->locktype==NO_LOCK );
-
    res = getReadLock(pFile);
-
    if( res == NO_ERROR ){
-
      newLocktype = SHARED_LOCK;
-
    }
-
    OSTRACE(( "LOCK %d acquire shared lock. res=%d\n", pFile->h, res ));
-
  }
-

-
  /* Acquire a RESERVED lock
-
  */
-
  if( locktype==RESERVED_LOCK && res == NO_ERROR ){
-
    assert( pFile->locktype==SHARED_LOCK );
-
    LockArea.lOffset = RESERVED_BYTE;
-
    LockArea.lRange = 1L;
-
    UnlockArea.lOffset = 0L;
-
    UnlockArea.lRange = 0L;
-
    res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
-
    if( res == NO_ERROR ){
-
      newLocktype = RESERVED_LOCK;
-
    }
-
    OSTRACE(( "LOCK %d acquire reserved lock. res=%d\n", pFile->h, res ));
-
  }
-

-
  /* Acquire a PENDING lock
-
  */
-
  if( locktype==EXCLUSIVE_LOCK && res == NO_ERROR ){
-
    newLocktype = PENDING_LOCK;
-
    gotPendingLock = 0;
-
    OSTRACE(( "LOCK %d acquire pending lock. pending lock boolean unset.\n",
-
               pFile->h ));
-
  }
-

-
  /* Acquire an EXCLUSIVE lock
-
  */
-
  if( locktype==EXCLUSIVE_LOCK && res == NO_ERROR ){
-
    assert( pFile->locktype>=SHARED_LOCK );
-
    res = unlockReadLock(pFile);
-
    OSTRACE(( "unreadlock = %d\n", res ));
-
    LockArea.lOffset = SHARED_FIRST;
-
    LockArea.lRange = SHARED_SIZE;
-
    UnlockArea.lOffset = 0L;
-
    UnlockArea.lRange = 0L;
-
    res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
-
    if( res == NO_ERROR ){
-
      newLocktype = EXCLUSIVE_LOCK;
-
    }else{
-
      OSTRACE(( "OS/2 error-code = %d\n", res ));
-
      getReadLock(pFile);
-
    }
-
    OSTRACE(( "LOCK %d acquire exclusive lock.  res=%d\n", pFile->h, res ));
-
  }
-

-
  /* If we are holding a PENDING lock that ought to be released, then
-
  ** release it now.
-
  */
-
  if( gotPendingLock && locktype==SHARED_LOCK ){
-
    int r;
-
    LockArea.lOffset = 0L;
-
    LockArea.lRange = 0L;
-
    UnlockArea.lOffset = PENDING_BYTE;
-
    UnlockArea.lRange = 1L;
-
    r = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
-
    OSTRACE(( "LOCK %d unlocking pending/is shared. r=%d\n", pFile->h, r ));
-
  }
-

-
  /* Update the state of the lock has held in the file descriptor then
-
  ** return the appropriate result code.
-
  */
-
  if( res == NO_ERROR ){
-
    rc = SQLITE_OK;
-
  }else{
-
    OSTRACE(( "LOCK FAILED %d trying for %d but got %d\n", pFile->h,
-
              locktype, newLocktype ));
-
    rc = SQLITE_BUSY;
-
  }
-
  pFile->locktype = newLocktype;
-
  OSTRACE(( "LOCK %d now %d\n", pFile->h, pFile->locktype ));
-
  return rc;
-
}
-

-
/*
-
** 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, return
-
** non-zero, otherwise zero.
-
*/
-
static int os2CheckReservedLock( sqlite3_file *id, int *pOut ){
-
  int r = 0;
-
  os2File *pFile = (os2File*)id;
-
  assert( pFile!=0 );
-
  if( pFile->locktype>=RESERVED_LOCK ){
-
    r = 1;
-
    OSTRACE(( "TEST WR-LOCK %d %d (local)\n", pFile->h, r ));
-
  }else{
-
    FILELOCK  LockArea,
-
              UnlockArea;
-
    APIRET rc = NO_ERROR;
-
    memset(&LockArea, 0, sizeof(LockArea));
-
    memset(&UnlockArea, 0, sizeof(UnlockArea));
-
    LockArea.lOffset = RESERVED_BYTE;
-
    LockArea.lRange = 1L;
-
    UnlockArea.lOffset = 0L;
-
    UnlockArea.lRange = 0L;
-
    rc = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
-
    OSTRACE(( "TEST WR-LOCK %d lock reserved byte rc=%d\n", pFile->h, rc ));
-
    if( rc == NO_ERROR ){
-
      APIRET rcu = NO_ERROR; /* return code for unlocking */
-
      LockArea.lOffset = 0L;
-
      LockArea.lRange = 0L;
-
      UnlockArea.lOffset = RESERVED_BYTE;
-
      UnlockArea.lRange = 1L;
-
      rcu = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
-
      OSTRACE(( "TEST WR-LOCK %d unlock reserved byte r=%d\n", pFile->h, rcu ));
-
    }
-
    r = !(rc == NO_ERROR);
-
    OSTRACE(( "TEST WR-LOCK %d %d (remote)\n", pFile->h, r ));
-
  }
-
  *pOut = r;
-
  return SQLITE_OK;
-
}
-

-
/*
-
** Lower the locking level on file descriptor id 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.
-
**
-
** It is not possible for this routine to fail if the second argument
-
** is NO_LOCK.  If the second argument is SHARED_LOCK then this routine
-
** might return SQLITE_IOERR;
-
*/
-
static int os2Unlock( sqlite3_file *id, int locktype ){
-
  int type;
-
  os2File *pFile = (os2File*)id;
-
  APIRET rc = SQLITE_OK;
-
  APIRET res = NO_ERROR;
-
  FILELOCK  LockArea,
-
            UnlockArea;
-
  memset(&LockArea, 0, sizeof(LockArea));
-
  memset(&UnlockArea, 0, sizeof(UnlockArea));
-
  assert( pFile!=0 );
-
  assert( locktype<=SHARED_LOCK );
-
  OSTRACE(( "UNLOCK %d to %d was %d\n", pFile->h, locktype, pFile->locktype ));
-
  type = pFile->locktype;
-
  if( type>=EXCLUSIVE_LOCK ){
-
    LockArea.lOffset = 0L;
-
    LockArea.lRange = 0L;
-
    UnlockArea.lOffset = SHARED_FIRST;
-
    UnlockArea.lRange = SHARED_SIZE;
-
    res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
-
    OSTRACE(( "UNLOCK %d exclusive lock res=%d\n", pFile->h, res ));
-
    if( locktype==SHARED_LOCK && getReadLock(pFile) != NO_ERROR ){
-
      /* This should never happen.  We should always be able to
-
      ** reacquire the read lock */
-
      OSTRACE(( "UNLOCK %d to %d getReadLock() failed\n", pFile->h, locktype ));
-
      rc = SQLITE_IOERR_UNLOCK;
-
    }
-
  }
-
  if( type>=RESERVED_LOCK ){
-
    LockArea.lOffset = 0L;
-
    LockArea.lRange = 0L;
-
    UnlockArea.lOffset = RESERVED_BYTE;
-
    UnlockArea.lRange = 1L;
-
    res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
-
    OSTRACE(( "UNLOCK %d reserved res=%d\n", pFile->h, res ));
-
  }
-
  if( locktype==NO_LOCK && type>=SHARED_LOCK ){
-
    res = unlockReadLock(pFile);
-
    OSTRACE(( "UNLOCK %d is %d want %d res=%d\n",
-
              pFile->h, type, locktype, res ));
-
  }
-
  if( type>=PENDING_LOCK ){
-
    LockArea.lOffset = 0L;
-
    LockArea.lRange = 0L;
-
    UnlockArea.lOffset = PENDING_BYTE;
-
    UnlockArea.lRange = 1L;
-
    res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
-
    OSTRACE(( "UNLOCK %d pending res=%d\n", pFile->h, res ));
-
  }
-
  pFile->locktype = locktype;
-
  OSTRACE(( "UNLOCK %d now %d\n", pFile->h, pFile->locktype ));
-
  return rc;
-
}
-

-
/*
-
** Control and query of the open file handle.
-
*/
-
static int os2FileControl(sqlite3_file *id, int op, void *pArg){
-
  switch( op ){
-
    case SQLITE_FCNTL_LOCKSTATE: {
-
      *(int*)pArg = ((os2File*)id)->locktype;
-
      OSTRACE(( "FCNTL_LOCKSTATE %d lock=%d\n",
-
                ((os2File*)id)->h, ((os2File*)id)->locktype ));
-
      return SQLITE_OK;
-
    }
-
    case SQLITE_FCNTL_CHUNK_SIZE: {
-
      ((os2File*)id)->szChunk = *(int*)pArg;
-
      return SQLITE_OK;
-
    }
-
    case SQLITE_FCNTL_SIZE_HINT: {
-
      sqlite3_int64 sz = *(sqlite3_int64*)pArg;
-
      SimulateIOErrorBenign(1);
-
      os2Truncate(id, sz);
-
      SimulateIOErrorBenign(0);
-
      return SQLITE_OK;
-
    }
-
    case SQLITE_FCNTL_SYNC_OMITTED: {
-
      return SQLITE_OK;
-
    }
-
  }
-
  return SQLITE_NOTFOUND;
-
}
-

-
/*
-
** Return the sector size in bytes of the underlying block device for
-
** the specified file. This is almost always 512 bytes, but may be
-
** larger for some devices.
-
**
-
** SQLite code assumes this function cannot fail. It also assumes that
-
** if two files are created in the same file-system directory (i.e.
-
** a database and its journal file) that the sector size will be the
-
** same for both.
-
*/
-
static int os2SectorSize(sqlite3_file *id){
-
  UNUSED_PARAMETER(id);
-
  return SQLITE_DEFAULT_SECTOR_SIZE;
-
}
-

-
/*
-
** Return a vector of device characteristics.
-
*/
-
static int os2DeviceCharacteristics(sqlite3_file *id){
-
  UNUSED_PARAMETER(id);
-
  return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN;
-
}
-

-

-
/*
-
** Character set conversion objects used by conversion routines.
-
*/
-
static UconvObject ucUtf8 = NULL; /* convert between UTF-8 and UCS-2 */
-
static UconvObject uclCp = NULL;  /* convert between local codepage and UCS-2 */
-

-
/*
-
** Helper function to initialize the conversion objects from and to UTF-8.
-
*/
-
static void initUconvObjects( void ){
-
  if( UniCreateUconvObject( UTF_8, &ucUtf8 ) != ULS_SUCCESS )
-
    ucUtf8 = NULL;
-
  if ( UniCreateUconvObject( (UniChar *)L"@path=yes", &uclCp ) != ULS_SUCCESS )
-
    uclCp = NULL;
-
}
-

-
/*
-
** Helper function to free the conversion objects from and to UTF-8.
-
*/
-
static void freeUconvObjects( void ){
-
  if ( ucUtf8 )
-
    UniFreeUconvObject( ucUtf8 );
-
  if ( uclCp )
-
    UniFreeUconvObject( uclCp );
-
  ucUtf8 = NULL;
-
  uclCp = NULL;
-
}
-

-
/*
-
** Helper function to convert UTF-8 filenames to local OS/2 codepage.
-
** The two-step process: first convert the incoming UTF-8 string
-
** into UCS-2 and then from UCS-2 to the current codepage.
-
** The returned char pointer has to be freed.
-
*/
-
static char *convertUtf8PathToCp( const char *in ){
-
  UniChar tempPath[CCHMAXPATH];
-
  char *out = (char *)calloc( CCHMAXPATH, 1 );
-

-
  if( !out )
-
    return NULL;
-

-
  if( !ucUtf8 || !uclCp )
-
    initUconvObjects();
-

-
  /* determine string for the conversion of UTF-8 which is CP1208 */
-
  if( UniStrToUcs( ucUtf8, tempPath, (char *)in, CCHMAXPATH ) != ULS_SUCCESS )
-
    return out; /* if conversion fails, return the empty string */
-

-
  /* conversion for current codepage which can be used for paths */
-
  UniStrFromUcs( uclCp, out, tempPath, CCHMAXPATH );
-

-
  return out;
-
}
-

-
/*
-
** Helper function to convert filenames from local codepage to UTF-8.
-
** The two-step process: first convert the incoming codepage-specific
-
** string into UCS-2 and then from UCS-2 to the codepage of UTF-8.
-
** The returned char pointer has to be freed.
-
**
-
** This function is non-static to be able to use this in shell.c and
-
** similar applications that take command line arguments.
-
*/
-
char *convertCpPathToUtf8( const char *in ){
-
  UniChar tempPath[CCHMAXPATH];
-
  char *out = (char *)calloc( CCHMAXPATH, 1 );
-

-
  if( !out )
-
    return NULL;
-

-
  if( !ucUtf8 || !uclCp )
-
    initUconvObjects();
-

-
  /* conversion for current codepage which can be used for paths */
-
  if( UniStrToUcs( uclCp, tempPath, (char *)in, CCHMAXPATH ) != ULS_SUCCESS )
-
    return out; /* if conversion fails, return the empty string */
-

-
  /* determine string for the conversion of UTF-8 which is CP1208 */
-
  UniStrFromUcs( ucUtf8, out, tempPath, CCHMAXPATH );
-

-
  return out;
-
}
-

-

-
#ifndef SQLITE_OMIT_WAL
-

-
/*
-
** Use main database file for interprocess locking. If un-defined
-
** a separate file is created for this purpose. The file will be
-
** used only to set file locks. There will be no data written to it.
-
*/
-
#define SQLITE_OS2_NO_WAL_LOCK_FILE     
-

-
#if 0
-
static void _ERR_TRACE( const char *fmt, ... ) {
-
  va_list  ap;
-
  va_start(ap, fmt);
-
  vfprintf(stderr, fmt, ap);
-
  fflush(stderr);
-
}
-
#define ERR_TRACE(rc, msg)        \
-
        if( (rc) != SQLITE_OK ) _ERR_TRACE msg;
-
#else
-
#define ERR_TRACE(rc, msg)
-
#endif
-

-
/*
-
** Helper functions to obtain and relinquish the global mutex. The
-
** global mutex is used to protect os2ShmNodeList.
-
**
-
** Function os2ShmMutexHeld() is used to assert() that the global mutex 
-
** is held when required. This function is only used as part of assert() 
-
** statements. e.g.
-
**
-
**   os2ShmEnterMutex()
-
**     assert( os2ShmMutexHeld() );
-
**   os2ShmLeaveMutex()
-
*/
-
static void os2ShmEnterMutex(void){
-
  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-
}
-
static void os2ShmLeaveMutex(void){
-
  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-
}
-
#ifdef SQLITE_DEBUG
-
static int os2ShmMutexHeld(void) {
-
  return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-
}
-
int GetCurrentProcessId(void) {
-
  PPIB pib;
-
  DosGetInfoBlocks(NULL, &pib);
-
  return (int)pib->pib_ulpid;
-
}
-
#endif
-

-
/*
-
** Object used to represent a the shared memory area for a single log file.
-
** When multiple threads all reference the same log-summary, each thread has
-
** its own os2File object, but they all point to a single instance of this 
-
** object.  In other words, each log-summary is opened only once per process.
-
**
-
** os2ShmMutexHeld() must be true when creating or destroying
-
** this object or while reading or writing the following fields:
-
**
-
**      nRef
-
**      pNext 
-
**
-
** The following fields are read-only after the object is created:
-
** 
-
**      szRegion
-
**      hLockFile
-
**      shmBaseName
-
**
-
** Either os2ShmNode.mutex must be held or os2ShmNode.nRef==0 and
-
** os2ShmMutexHeld() is true when reading or writing any other field
-
** in this structure.
-
**
-
*/
-
struct os2ShmNode {
-
  sqlite3_mutex *mutex;      /* Mutex to access this object */
-
  os2ShmNode *pNext;         /* Next in list of all os2ShmNode objects */
-

-
  int szRegion;              /* Size of shared-memory regions */
-

-
  int nRegion;               /* Size of array apRegion */
-
  void **apRegion;           /* Array of pointers to shared-memory regions */
-

-
  int nRef;                  /* Number of os2ShmLink objects pointing to this */
-
  os2ShmLink *pFirst;        /* First os2ShmLink object pointing to this */
-

-
  HFILE hLockFile;           /* File used for inter-process memory locking */
-
  char shmBaseName[1];       /* Name of the memory object !!! must last !!! */
-
};
-

-

-
/*
-
** Structure used internally by this VFS to record the state of an
-
** open shared memory connection.
-
**
-
** The following fields are initialized when this object is created and
-
** are read-only thereafter:
-
**
-
**    os2Shm.pShmNode
-
**    os2Shm.id
-
**
-
** All other fields are read/write.  The os2Shm.pShmNode->mutex must be held
-
** while accessing any read/write fields.
-
*/
-
struct os2ShmLink {
-
  os2ShmNode *pShmNode;      /* The underlying os2ShmNode object */
-
  os2ShmLink *pNext;         /* Next os2Shm with the same os2ShmNode */
-
  u32 sharedMask;            /* Mask of shared locks held */
-
  u32 exclMask;              /* Mask of exclusive locks held */
-
#ifdef SQLITE_DEBUG
-
  u8 id;                     /* Id of this connection with its os2ShmNode */
-
#endif
-
};
-

-

-
/*
-
** A global list of all os2ShmNode objects.
-
**
-
** The os2ShmMutexHeld() must be true while reading or writing this list.
-
*/
-
static os2ShmNode *os2ShmNodeList = NULL;
-

-
/*
-
** Constants used for locking
-
*/
-
#ifdef  SQLITE_OS2_NO_WAL_LOCK_FILE
-
#define OS2_SHM_BASE   (PENDING_BYTE + 0x10000)         /* first lock byte */
-
#else
-
#define OS2_SHM_BASE   ((22+SQLITE_SHM_NLOCK)*4)        /* first lock byte */
-
#endif
-

-
#define OS2_SHM_DMS    (OS2_SHM_BASE+SQLITE_SHM_NLOCK)  /* deadman switch */
-

-
/*
-
** Apply advisory locks for all n bytes beginning at ofst.
-
*/
-
#define _SHM_UNLCK  1   /* no lock */
-
#define _SHM_RDLCK  2   /* shared lock, no wait */
-
#define _SHM_WRLCK  3   /* exlusive lock, no wait */
-
#define _SHM_WRLCK_WAIT 4 /* exclusive lock, wait */
-
static int os2ShmSystemLock(
-
  os2ShmNode *pNode,    /* Apply locks to this open shared-memory segment */
-
  int lockType,         /* _SHM_UNLCK, _SHM_RDLCK, _SHM_WRLCK or _SHM_WRLCK_WAIT */
-
  int ofst,             /* Offset to first byte to be locked/unlocked */
-
  int nByte             /* Number of bytes to lock or unlock */
-
){
-
  APIRET rc;
-
  FILELOCK area;
-
  ULONG mode, timeout;
-

-
  /* Access to the os2ShmNode object is serialized by the caller */
-
  assert( sqlite3_mutex_held(pNode->mutex) || pNode->nRef==0 );
-

-
  mode = 1;     /* shared lock */
-
  timeout = 0;  /* no wait */
-
  area.lOffset = ofst;
-
  area.lRange = nByte;
-

-
  switch( lockType ) {
-
    case _SHM_WRLCK_WAIT:
-
      timeout = (ULONG)-1;      /* wait forever */
-
    case _SHM_WRLCK:
-
      mode = 0;                 /* exclusive lock */
-
    case _SHM_RDLCK:
-
      rc = DosSetFileLocks(pNode->hLockFile, 
-
                           NULL, &area, timeout, mode);
-
      break;
-
    /* case _SHM_UNLCK: */
-
    default:
-
      rc = DosSetFileLocks(pNode->hLockFile, 
-
                           &area, NULL, 0, 0);
-
      break;
-
  }
-
                          
-
  OSTRACE(("SHM-LOCK %d %s %s 0x%08lx\n", 
-
           pNode->hLockFile,
-
           rc==SQLITE_OK ? "ok" : "failed",
-
           lockType==_SHM_UNLCK ? "Unlock" : "Lock",
-
           rc));
-

-
  ERR_TRACE(rc, ("os2ShmSystemLock: %d %s\n", rc, pNode->shmBaseName))
-

-
  return ( rc == 0 ) ?  SQLITE_OK : SQLITE_BUSY;
-
}
-

-
/*
-
** Find an os2ShmNode in global list or allocate a new one, if not found.
-
**
-
** This is not a VFS shared-memory method; it is a utility function called
-
** by VFS shared-memory methods.
-
*/
-
static int os2OpenSharedMemory( os2File *fd, int szRegion ) {
-
  os2ShmLink *pLink;
-
  os2ShmNode *pNode;
-
  int cbShmName, rc = SQLITE_OK;
-
  char shmName[CCHMAXPATH + 30];
-
#ifndef SQLITE_OS2_NO_WAL_LOCK_FILE
-
  ULONG action;
-
#endif
-
  
-
  /* We need some additional space at the end to append the region number */
-
  cbShmName = sprintf(shmName, "\\SHAREMEM\\%s", fd->zFullPathCp );
-
  if( cbShmName >= CCHMAXPATH-8 )
-
    return SQLITE_IOERR_SHMOPEN; 
-

-
  /* Replace colon in file name to form a valid shared memory name */
-
  shmName[10+1] = '!';
-

-
  /* Allocate link object (we free it later in case of failure) */
-
  pLink = sqlite3_malloc( sizeof(*pLink) );
-
  if( !pLink )
-
    return SQLITE_NOMEM;
-

-
  /* Access node list */
-
  os2ShmEnterMutex();
-

-
  /* Find node by it's shared memory base name */
-
  for( pNode = os2ShmNodeList; 
-
       pNode && stricmp(shmName, pNode->shmBaseName) != 0; 
-
       pNode = pNode->pNext )   ;
-

-
  /* Not found: allocate a new node */
-
  if( !pNode ) {
-
    pNode = sqlite3_malloc( sizeof(*pNode) + cbShmName );
-
    if( pNode ) {
-
      memset(pNode, 0, sizeof(*pNode) );
-
      pNode->szRegion = szRegion;
-
      pNode->hLockFile = (HFILE)-1;      
-
      strcpy(pNode->shmBaseName, shmName);
-

-
#ifdef SQLITE_OS2_NO_WAL_LOCK_FILE
-
      if( DosDupHandle(fd->h, &pNode->hLockFile) != 0 ) {
-
#else
-
      sprintf(shmName, "%s-lck", fd->zFullPathCp);
-
      if( DosOpen((PSZ)shmName, &pNode->hLockFile, &action, 0, FILE_NORMAL, 
-
                  OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW,
-
                  OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE | 
-
                  OPEN_FLAGS_NOINHERIT | OPEN_FLAGS_FAIL_ON_ERROR,
-
                  NULL) != 0 ) {
-
#endif
-
        sqlite3_free(pNode);  
-
        rc = SQLITE_IOERR;
-
      } else {
-
        pNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
-
        if( !pNode->mutex ) {
-
          sqlite3_free(pNode);  
-
          rc = SQLITE_NOMEM;
-
        }
-
      }   
-
    } else {
-
      rc = SQLITE_NOMEM;
-
    }
-
    
-
    if( rc == SQLITE_OK ) {
-
      pNode->pNext = os2ShmNodeList;
-
      os2ShmNodeList = pNode;
-
    } else {
-
      pNode = NULL;
-
    }
-
  } else if( pNode->szRegion != szRegion ) {
-
    rc = SQLITE_IOERR_SHMSIZE;
-
    pNode = NULL;
-
  }
-

-
  if( pNode ) {
-
    sqlite3_mutex_enter(pNode->mutex);
-

-
    memset(pLink, 0, sizeof(*pLink));
-

-
    pLink->pShmNode = pNode;
-
    pLink->pNext = pNode->pFirst;
-
    pNode->pFirst = pLink;
-
    pNode->nRef++;
-

-
    fd->pShmLink = pLink;
-

-
    sqlite3_mutex_leave(pNode->mutex);
-
    
-
  } else {
-
    /* Error occured. Free our link object. */
-
    sqlite3_free(pLink);  
-
  }
-

-
  os2ShmLeaveMutex();
-

-
  ERR_TRACE(rc, ("os2OpenSharedMemory: %d  %s\n", rc, fd->zFullPathCp))  
-
  
-
  return rc;
-
}
-

-
/*
-
** Purge the os2ShmNodeList list of all entries with nRef==0.
-
**
-
** This is not a VFS shared-memory method; it is a utility function called
-
** by VFS shared-memory methods.
-
*/
-
static void os2PurgeShmNodes( int deleteFlag ) {
-
  os2ShmNode *pNode;
-
  os2ShmNode **ppNode;
-

-
  os2ShmEnterMutex();
-
  
-
  ppNode = &os2ShmNodeList;
-

-
  while( *ppNode ) {
-
    pNode = *ppNode;
-

-
    if( pNode->nRef == 0 ) {
-
      *ppNode = pNode->pNext;   
-
     
-
      if( pNode->apRegion ) {
-
        /* Prevent other processes from resizing the shared memory */
-
        os2ShmSystemLock(pNode, _SHM_WRLCK_WAIT, OS2_SHM_DMS, 1);
-

-
        while( pNode->nRegion-- ) {
-
#ifdef SQLITE_DEBUG
-
          int rc = 
-
#endif          
-
          DosFreeMem(pNode->apRegion[pNode->nRegion]);
-

-
          OSTRACE(("SHM-PURGE pid-%d unmap region=%d %s\n",
-
                  (int)GetCurrentProcessId(), pNode->nRegion,
-
                  rc == 0 ? "ok" : "failed"));
-
        }
-

-
        /* Allow other processes to resize the shared memory */
-
        os2ShmSystemLock(pNode, _SHM_UNLCK, OS2_SHM_DMS, 1);
-

-
        sqlite3_free(pNode->apRegion);
-
      }  
-

-
      DosClose(pNode->hLockFile);
-
      
-
#ifndef SQLITE_OS2_NO_WAL_LOCK_FILE
-
      if( deleteFlag ) {
-
         char fileName[CCHMAXPATH];
-
         /* Skip "\\SHAREMEM\\" */
-
         sprintf(fileName, "%s-lck", pNode->shmBaseName + 10);
-
         /* restore colon */
-
         fileName[1] = ':';
-
         
-
         DosForceDelete(fileName); 
-
      }
-
#endif
-

-
      sqlite3_mutex_free(pNode->mutex);
-

-
      sqlite3_free(pNode);
-
      
-
    } else {
-
      ppNode = &pNode->pNext;
-
    }
-
  } 
-

-
  os2ShmLeaveMutex();
-
}
-

-
/*
-
** This function is called to obtain a pointer to region iRegion of the
-
** shared-memory associated with the database file id. Shared-memory regions
-
** are numbered starting from zero. Each shared-memory region is szRegion
-
** bytes in size.
-
**
-
** If an error occurs, an error code is returned and *pp is set to NULL.
-
**
-
** Otherwise, if the bExtend parameter is 0 and the requested shared-memory
-
** region has not been allocated (by any client, including one running in a
-
** separate process), then *pp is set to NULL and SQLITE_OK returned. If
-
** bExtend is non-zero and the requested shared-memory region has not yet
-
** been allocated, it is allocated by this function.
-
**
-
** If the shared-memory region has already been allocated or is allocated by
-
** this call as described above, then it is mapped into this processes
-
** address space (if it is not already), *pp is set to point to the mapped
-
** memory and SQLITE_OK returned.
-
*/
-
static int os2ShmMap(
-
  sqlite3_file *id,               /* Handle open on database file */
-
  int iRegion,                    /* Region to retrieve */
-
  int szRegion,                   /* Size of regions */
-
  int bExtend,                    /* True to extend block if necessary */
-
  void volatile **pp              /* OUT: Mapped memory */
-
){
-
  PVOID pvTemp;
-
  void **apRegion;
-
  os2ShmNode *pNode;
-
  int n, rc = SQLITE_OK;
-
  char shmName[CCHMAXPATH];
-
  os2File *pFile = (os2File*)id;
-
  
-
  *pp = NULL;
-

-
  if( !pFile->pShmLink )
-
    rc = os2OpenSharedMemory( pFile, szRegion );
-
  
-
  if( rc == SQLITE_OK ) {
-
    pNode = pFile->pShmLink->pShmNode ;
-
    
-
    sqlite3_mutex_enter(pNode->mutex);
-
    
-
    assert( szRegion==pNode->szRegion );
-

-
    /* Unmapped region ? */
-
    if( iRegion >= pNode->nRegion ) {
-
      /* Prevent other processes from resizing the shared memory */
-
      os2ShmSystemLock(pNode, _SHM_WRLCK_WAIT, OS2_SHM_DMS, 1);
-

-
      apRegion = sqlite3_realloc(
-
        pNode->apRegion, (iRegion + 1) * sizeof(apRegion[0]));
-

-
      if( apRegion ) {
-
        pNode->apRegion = apRegion;
-

-
        while( pNode->nRegion <= iRegion ) {
-
          sprintf(shmName, "%s-%u", 
-
                  pNode->shmBaseName, pNode->nRegion);
-

-
          if( DosGetNamedSharedMem(&pvTemp, (PSZ)shmName, 
-
                PAG_READ | PAG_WRITE) != NO_ERROR ) {
-
            if( !bExtend )
-
              break;
-

-
            if( DosAllocSharedMem(&pvTemp, (PSZ)shmName, szRegion,
-
                  PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_ANY) != NO_ERROR && 
-
                DosAllocSharedMem(&pvTemp, (PSZ)shmName, szRegion,
-
                  PAG_READ | PAG_WRITE | PAG_COMMIT) != NO_ERROR ) { 
-
              rc = SQLITE_NOMEM;
-
              break;
-
            }
-
          }
-

-
          apRegion[pNode->nRegion++] = pvTemp;
-
        }
-

-
        /* zero out remaining entries */ 
-
        for( n = pNode->nRegion; n <= iRegion; n++ )
-
          pNode->apRegion[n] = NULL;
-

-
        /* Return this region (maybe zero) */
-
        *pp = pNode->apRegion[iRegion];
-
      } else {
-
        rc = SQLITE_NOMEM;
-
      }
-

-
      /* Allow other processes to resize the shared memory */
-
      os2ShmSystemLock(pNode, _SHM_UNLCK, OS2_SHM_DMS, 1);
-
      
-
    } else {
-
      /* Region has been mapped previously */
-
      *pp = pNode->apRegion[iRegion];
-
    }
-

-
    sqlite3_mutex_leave(pNode->mutex);
-
  } 
-

-
  ERR_TRACE(rc, ("os2ShmMap: %s iRgn = %d, szRgn = %d, bExt = %d : %d\n", 
-
                 pFile->zFullPathCp, iRegion, szRegion, bExtend, rc))
-
          
-
  return rc;
-
}
-

-
/*
-
** Close a connection to shared-memory.  Delete the underlying
-
** storage if deleteFlag is true.
-
**
-
** If there is no shared memory associated with the connection then this
-
** routine is a harmless no-op.
-
*/
-
static int os2ShmUnmap(
-
  sqlite3_file *id,               /* The underlying database file */
-
  int deleteFlag                  /* Delete shared-memory if true */
-
){
-
  os2File *pFile = (os2File*)id;
-
  os2ShmLink *pLink = pFile->pShmLink;
-
  
-
  if( pLink ) {
-
    int nRef = -1;
-
    os2ShmLink **ppLink;
-
    os2ShmNode *pNode = pLink->pShmNode;
-

-
    sqlite3_mutex_enter(pNode->mutex);
-
    
-
    for( ppLink = &pNode->pFirst;
-
         *ppLink && *ppLink != pLink;
-
         ppLink = &(*ppLink)->pNext )   ;
-
         
-
    assert(*ppLink);
-

-
    if( *ppLink ) {
-
      *ppLink = pLink->pNext;
-
      nRef = --pNode->nRef;
-
    } else {
-
      ERR_TRACE(1, ("os2ShmUnmap: link not found ! %s\n", 
-
                    pNode->shmBaseName))
-
    }
-
    
-
    pFile->pShmLink = NULL;
-
    sqlite3_free(pLink);
-

-
    sqlite3_mutex_leave(pNode->mutex);
-
    
-
    if( nRef == 0 )
-
      os2PurgeShmNodes( deleteFlag );
-
  }
-

-
  return SQLITE_OK;
-
}
-

-
/*
-
** Change the lock state for a shared-memory segment.
-
**
-
** Note that the relationship between SHAREd and EXCLUSIVE locks is a little
-
** different here than in posix.  In xShmLock(), one can go from unlocked
-
** to shared and back or from unlocked to exclusive and back.  But one may
-
** not go from shared to exclusive or from exclusive to shared.
-
*/
-
static int os2ShmLock(
-
  sqlite3_file *id,          /* Database file holding the shared memory */
-
  int ofst,                  /* First lock to acquire or release */
-
  int n,                     /* Number of locks to acquire or release */
-
  int flags                  /* What to do with the lock */
-
){
-
  u32 mask;                             /* Mask of locks to take or release */
-
  int rc = SQLITE_OK;                   /* Result code */
-
  os2File *pFile = (os2File*)id;
-
  os2ShmLink *p = pFile->pShmLink;      /* The shared memory being locked */
-
  os2ShmLink *pX;                       /* For looping over all siblings */
-
  os2ShmNode *pShmNode = p->pShmNode;   /* Our node */
-
  
-
  assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
-
  assert( n>=1 );
-
  assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
-
       || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
-
       || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
-
       || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
-
  assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
-

-
  mask = (u32)((1U<<(ofst+n)) - (1U<<ofst));
-
  assert( n>1 || mask==(1<<ofst) );
-

-

-
  sqlite3_mutex_enter(pShmNode->mutex);
-

-
  if( flags & SQLITE_SHM_UNLOCK ){
-
    u32 allMask = 0; /* Mask of locks held by siblings */
-

-
    /* See if any siblings hold this same lock */
-
    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
-
      if( pX==p ) continue;
-
      assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 );
-
      allMask |= pX->sharedMask;
-
    }
-

-
    /* Unlock the system-level locks */
-
    if( (mask & allMask)==0 ){
-
      rc = os2ShmSystemLock(pShmNode, _SHM_UNLCK, ofst+OS2_SHM_BASE, n);
-
    }else{
-
      rc = SQLITE_OK;
-
    }
-

-
    /* Undo the local locks */
-
    if( rc==SQLITE_OK ){
-
      p->exclMask &= ~mask;
-
      p->sharedMask &= ~mask;
-
    } 
-
  }else if( flags & SQLITE_SHM_SHARED ){
-
    u32 allShared = 0;  /* Union of locks held by connections other than "p" */
-

-
    /* Find out which shared locks are already held by sibling connections.
-
    ** If any sibling already holds an exclusive lock, go ahead and return
-
    ** SQLITE_BUSY.
-
    */
-
    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
-
      if( (pX->exclMask & mask)!=0 ){
-
        rc = SQLITE_BUSY;
-
        break;
-
      }
-
      allShared |= pX->sharedMask;
-
    }
-

-
    /* Get shared locks at the system level, if necessary */
-
    if( rc==SQLITE_OK ){
-
      if( (allShared & mask)==0 ){
-
        rc = os2ShmSystemLock(pShmNode, _SHM_RDLCK, ofst+OS2_SHM_BASE, n);
-
      }else{
-
        rc = SQLITE_OK;
-
      }
-
    }
-

-
    /* Get the local shared locks */
-
    if( rc==SQLITE_OK ){
-
      p->sharedMask |= mask;
-
    }
-
  }else{
-
    /* Make sure no sibling connections hold locks that will block this
-
    ** lock.  If any do, return SQLITE_BUSY right away.
-
    */
-
    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
-
      if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){
-
        rc = SQLITE_BUSY;
-
        break;
-
      }
-
    }
-
  
-
    /* Get the exclusive locks at the system level.  Then if successful
-
    ** also mark the local connection as being locked.
-
    */
-
    if( rc==SQLITE_OK ){
-
      rc = os2ShmSystemLock(pShmNode, _SHM_WRLCK, ofst+OS2_SHM_BASE, n);
-
      if( rc==SQLITE_OK ){
-
        assert( (p->sharedMask & mask)==0 );
-
        p->exclMask |= mask;
-
      }
-
    }
-
  }
-

-
  sqlite3_mutex_leave(pShmNode->mutex);
-
  
-
  OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x %s\n",
-
           p->id, (int)GetCurrentProcessId(), p->sharedMask, p->exclMask,
-
           rc ? "failed" : "ok"));
-

-
  ERR_TRACE(rc, ("os2ShmLock: ofst = %d, n = %d, flags = 0x%x -> %d \n", 
-
                 ofst, n, flags, rc))
-
                  
-
  return rc; 
-
}
-

-
/*
-
** Implement a memory barrier or memory fence on shared memory.
-
**
-
** All loads and stores begun before the barrier must complete before
-
** any load or store begun after the barrier.
-
*/
-
static void os2ShmBarrier(
-
  sqlite3_file *id                /* Database file holding the shared memory */
-
){
-
  UNUSED_PARAMETER(id);
-
  os2ShmEnterMutex();
-
  os2ShmLeaveMutex();
-
}
-

-
#else
-
# define os2ShmMap     0
-
# define os2ShmLock    0
-
# define os2ShmBarrier 0
-
# define os2ShmUnmap   0
-
#endif /* #ifndef SQLITE_OMIT_WAL */
-

-

-
/*
-
** This vector defines all the methods that can operate on an
-
** sqlite3_file for os2.
-
*/
-
static const sqlite3_io_methods os2IoMethod = {
-
  2,                              /* iVersion */
-
  os2Close,                       /* xClose */
-
  os2Read,                        /* xRead */
-
  os2Write,                       /* xWrite */
-
  os2Truncate,                    /* xTruncate */
-
  os2Sync,                        /* xSync */
-
  os2FileSize,                    /* xFileSize */
-
  os2Lock,                        /* xLock */
-
  os2Unlock,                      /* xUnlock */
-
  os2CheckReservedLock,           /* xCheckReservedLock */
-
  os2FileControl,                 /* xFileControl */
-
  os2SectorSize,                  /* xSectorSize */
-
  os2DeviceCharacteristics,       /* xDeviceCharacteristics */
-
  os2ShmMap,                      /* xShmMap */
-
  os2ShmLock,                     /* xShmLock */
-
  os2ShmBarrier,                  /* xShmBarrier */
-
  os2ShmUnmap                     /* xShmUnmap */
-
};
-

-

-
/***************************************************************************
-
** Here ends the I/O methods that form the sqlite3_io_methods object.
-
**
-
** The next block of code implements the VFS methods.
-
****************************************************************************/
-

-
/*
-
** Create a temporary file name in zBuf.  zBuf must be big enough to
-
** hold at pVfs->mxPathname characters.
-
*/
-
static int getTempname(int nBuf, char *zBuf ){
-
  static const char zChars[] =
-
    "abcdefghijklmnopqrstuvwxyz"
-
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-
    "0123456789";
-
  int i, j;
-
  PSZ zTempPathCp;      
-
  char zTempPath[CCHMAXPATH];
-
  ULONG ulDriveNum, ulDriveMap;
-
  
-
  /* 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. 
-
  */
-
  SimulateIOError( return SQLITE_IOERR );
-

-
  if( sqlite3_temp_directory ) {
-
    sqlite3_snprintf(CCHMAXPATH-30, zTempPath, "%s", sqlite3_temp_directory);
-
  } else if( DosScanEnv( (PSZ)"TEMP",   &zTempPathCp ) == NO_ERROR ||
-
             DosScanEnv( (PSZ)"TMP",    &zTempPathCp ) == NO_ERROR ||
-
             DosScanEnv( (PSZ)"TMPDIR", &zTempPathCp ) == NO_ERROR ) {
-
    char *zTempPathUTF = convertCpPathToUtf8( (char *)zTempPathCp );
-
    sqlite3_snprintf(CCHMAXPATH-30, zTempPath, "%s", zTempPathUTF);
-
    free( zTempPathUTF );
-
  } else if( DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap ) == NO_ERROR ) {
-
    zTempPath[0] = (char)('A' + ulDriveNum - 1);
-
    zTempPath[1] = ':'; 
-
    zTempPath[2] = '\0'; 
-
  } else {
-
    zTempPath[0] = '\0'; 
-
  }
-
  
-
  /* 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 = sqlite3Strlen30(zTempPath);
-
  while( j > 0 && ( zTempPath[j-1] == '\\' || zTempPath[j-1] == '/' || 
-
                    zTempPath[j-1] == ' ' ) ){
-
    j--;
-
  }
-
  zTempPath[j] = '\0';
-
  
-
  /* We use 20 bytes to randomize the name */
-
  sqlite3_snprintf(nBuf-22, zBuf,
-
                   "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath);
-
  j = sqlite3Strlen30(zBuf);
-
  sqlite3_randomness( 20, &zBuf[j] );
-
  for( i = 0; i < 20; i++, j++ ){
-
    zBuf[j] = zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
-
  }
-
  zBuf[j] = 0;
-

-
  OSTRACE(( "TEMP FILENAME: %s\n", zBuf ));
-
  return SQLITE_OK;
-
}
-

-

-
/*
-
** Turn a relative pathname into a full pathname.  Write the full
-
** pathname into zFull[].  zFull[] will be at least pVfs->mxPathname
-
** bytes in size.
-
*/
-
static int os2FullPathname(
-
  sqlite3_vfs *pVfs,          /* Pointer to vfs object */
-
  const char *zRelative,      /* Possibly relative input path */
-
  int nFull,                  /* Size of output buffer in bytes */
-
  char *zFull                 /* Output buffer */
-
){
-
  char *zRelativeCp = convertUtf8PathToCp( zRelative );
-
  char zFullCp[CCHMAXPATH] = "\0";
-
  char *zFullUTF;
-
  APIRET rc = DosQueryPathInfo( (PSZ)zRelativeCp, FIL_QUERYFULLNAME, 
-
                                zFullCp, CCHMAXPATH );
-
  free( zRelativeCp );
-
  zFullUTF = convertCpPathToUtf8( zFullCp );
-
  sqlite3_snprintf( nFull, zFull, zFullUTF );
-
  free( zFullUTF );
-
  return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
-
}
-

-

-
/*
-
** Open a file.
-
*/
-
static int os2Open(
-
  sqlite3_vfs *pVfs,            /* Not used */
-
  const char *zName,            /* Name of the file (UTF-8) */
-
  sqlite3_file *id,             /* Write the SQLite file handle here */
-
  int flags,                    /* Open mode flags */
-
  int *pOutFlags                /* Status return flags */
-
){
-
  HFILE h;
-
  ULONG ulOpenFlags = 0;
-
  ULONG ulOpenMode = 0;
-
  ULONG ulAction = 0;
-
  ULONG rc;
-
  os2File *pFile = (os2File*)id;
-
  const char *zUtf8Name = zName;
-
  char *zNameCp;
-
  char  zTmpname[CCHMAXPATH];
-

-
  int isExclusive  = (flags & SQLITE_OPEN_EXCLUSIVE);
-
  int isCreate     = (flags & SQLITE_OPEN_CREATE);
-
  int isReadWrite  = (flags & SQLITE_OPEN_READWRITE);
-
#ifndef NDEBUG
-
  int isDelete     = (flags & SQLITE_OPEN_DELETEONCLOSE);
-
  int isReadonly   = (flags & SQLITE_OPEN_READONLY);
-
  int eType        = (flags & 0xFFFFFF00);
-
  int isOpenJournal = (isCreate && (
-
        eType==SQLITE_OPEN_MASTER_JOURNAL 
-
     || eType==SQLITE_OPEN_MAIN_JOURNAL 
-
     || eType==SQLITE_OPEN_WAL
-
  ));
-
#endif
-

-
  UNUSED_PARAMETER(pVfs);
-
  assert( id!=0 );
-

-
  /* Check the following statements are true: 
-
  **
-
  **   (a) Exactly one of the READWRITE and READONLY flags must be set, and 
-
  **   (b) if CREATE is set, then READWRITE must also be set, and
-
  **   (c) if EXCLUSIVE is set, then CREATE must also be set.
-
  **   (d) if DELETEONCLOSE is set, then CREATE must also be set.
-
  */
-
  assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly));
-
  assert(isCreate==0 || isReadWrite);
-
  assert(isExclusive==0 || isCreate);
-
  assert(isDelete==0 || isCreate);
-

-
  /* The main DB, main journal, WAL file and master journal are never 
-
  ** automatically deleted. Nor are they ever temporary files.  */
-
  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB );
-
  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL );
-
  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL );
-
  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL );
-

-
  /* Assert that the upper layer has set one of the "file-type" flags. */
-
  assert( eType==SQLITE_OPEN_MAIN_DB      || eType==SQLITE_OPEN_TEMP_DB 
-
       || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL 
-
       || eType==SQLITE_OPEN_SUBJOURNAL   || eType==SQLITE_OPEN_MASTER_JOURNAL 
-
       || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
-
  );
-

-
  memset( pFile, 0, sizeof(*pFile) );
-
  pFile->h = (HFILE)-1;
-

-
  /* If the second argument to this function is NULL, generate a 
-
  ** temporary file name to use 
-
  */
-
  if( !zUtf8Name ){
-
    assert(isDelete && !isOpenJournal);
-
    rc = getTempname(CCHMAXPATH, zTmpname);
-
    if( rc!=SQLITE_OK ){
-
      return rc;
-
    }
-
    zUtf8Name = zTmpname;
-
  }
-

-
  if( isReadWrite ){
-
    ulOpenMode |= OPEN_ACCESS_READWRITE;
-
  }else{
-
    ulOpenMode |= OPEN_ACCESS_READONLY;
-
  }
-

-
  /* Open in random access mode for possibly better speed.  Allow full
-
  ** sharing because file locks will provide exclusive access when needed.
-
  ** The handle should not be inherited by child processes and we don't 
-
  ** want popups from the critical error handler.
-
  */
-
  ulOpenMode |= OPEN_FLAGS_RANDOM | OPEN_SHARE_DENYNONE | 
-
                OPEN_FLAGS_NOINHERIT | OPEN_FLAGS_FAIL_ON_ERROR;
-

-
  /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is 
-
  ** created. SQLite doesn't use it to indicate "exclusive access" 
-
  ** as it is usually understood.
-
  */
-
  if( isExclusive ){
-
    /* Creates a new file, only if it does not already exist. */
-
    /* If the file exists, it fails. */
-
    ulOpenFlags |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_FAIL_IF_EXISTS;
-
  }else if( isCreate ){
-
    /* Open existing file, or create if it doesn't exist */
-
    ulOpenFlags |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
-
  }else{
-
    /* Opens a file, only if it exists. */
-
    ulOpenFlags |= OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
-
  }
-

-
  zNameCp = convertUtf8PathToCp( zUtf8Name );
-
  rc = DosOpen( (PSZ)zNameCp,
-
                &h,
-
                &ulAction,
-
                0L,
-
                FILE_NORMAL,
-
                ulOpenFlags,
-
                ulOpenMode,
-
                (PEAOP2)NULL );
-
  free( zNameCp );
-

-
  if( rc != NO_ERROR ){
-
    OSTRACE(( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulFlags=%#lx, ulMode=%#lx\n",
-
              rc, zUtf8Name, ulAction, ulOpenFlags, ulOpenMode ));
-

-
    if( isReadWrite ){
-
      return os2Open( pVfs, zName, id,
-
                      ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)),
-
                      pOutFlags );
-
    }else{
-
      return SQLITE_CANTOPEN;
-
    }
-
  }
-

-
  if( pOutFlags ){
-
    *pOutFlags = isReadWrite ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY;
-
  }
-

-
  os2FullPathname( pVfs, zUtf8Name, sizeof( zTmpname ), zTmpname );
-
  pFile->zFullPathCp = convertUtf8PathToCp( zTmpname );
-
  pFile->pMethod = &os2IoMethod;
-
  pFile->flags = flags;
-
  pFile->h = h;
-

-
  OpenCounter(+1);
-
  OSTRACE(( "OPEN %d pOutFlags=%d\n", pFile->h, pOutFlags ));
-
  return SQLITE_OK;
-
}
-

-
/*
-
** Delete the named file.
-
*/
-
static int os2Delete(
-
  sqlite3_vfs *pVfs,                     /* Not used on os2 */
-
  const char *zFilename,                 /* Name of file to delete */
-
  int syncDir                            /* Not used on os2 */
-
){
-
  APIRET rc;
-
  char *zFilenameCp;
-
  SimulateIOError( return SQLITE_IOERR_DELETE );
-
  zFilenameCp = convertUtf8PathToCp( zFilename );
-
  rc = DosDelete( (PSZ)zFilenameCp );
-
  free( zFilenameCp );
-
  OSTRACE(( "DELETE \"%s\"\n", zFilename ));
-
  return (rc == NO_ERROR ||
-
          rc == ERROR_FILE_NOT_FOUND ||
-
          rc == ERROR_PATH_NOT_FOUND ) ? SQLITE_OK : SQLITE_IOERR_DELETE;
-
}
-

-
/*
-
** Check the existance and status of a file.
-
*/
-
static int os2Access(
-
  sqlite3_vfs *pVfs,        /* Not used on os2 */
-
  const char *zFilename,    /* Name of file to check */
-
  int flags,                /* Type of test to make on this file */
-
  int *pOut                 /* Write results here */
-
){
-
  APIRET rc;
-
  FILESTATUS3 fsts3ConfigInfo;
-
  char *zFilenameCp;
-

-
  UNUSED_PARAMETER(pVfs);
-
  SimulateIOError( return SQLITE_IOERR_ACCESS; );
-
  
-
  zFilenameCp = convertUtf8PathToCp( zFilename );
-
  rc = DosQueryPathInfo( (PSZ)zFilenameCp, FIL_STANDARD,
-
                         &fsts3ConfigInfo, sizeof(FILESTATUS3) );
-
  free( zFilenameCp );
-
  OSTRACE(( "ACCESS fsts3ConfigInfo.attrFile=%d flags=%d rc=%d\n",
-
            fsts3ConfigInfo.attrFile, flags, rc ));
-

-
  switch( flags ){
-
    case SQLITE_ACCESS_EXISTS:
-
      /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file
-
      ** as if it does not exist.
-
      */
-
      if( fsts3ConfigInfo.cbFile == 0 ) 
-
        rc = ERROR_FILE_NOT_FOUND;
-
      break;
-
    case SQLITE_ACCESS_READ:
-
      break;
-
    case SQLITE_ACCESS_READWRITE:
-
      if( fsts3ConfigInfo.attrFile & FILE_READONLY )
-
        rc = ERROR_ACCESS_DENIED;
-
      break;
-
    default:
-
      rc = ERROR_FILE_NOT_FOUND;
-
      assert( !"Invalid flags argument" );
-
  }
-

-
  *pOut = (rc == NO_ERROR);
-
  OSTRACE(( "ACCESS %s flags %d: rc=%d\n", zFilename, flags, *pOut ));
-

-
  return SQLITE_OK;
-
}
-

-

-
#ifndef SQLITE_OMIT_LOAD_EXTENSION
-
/*
-
** Interfaces for opening a shared library, finding entry points
-
** within the shared library, and closing the shared library.
-
*/
-
/*
-
** Interfaces for opening a shared library, finding entry points
-
** within the shared library, and closing the shared library.
-
*/
-
static void *os2DlOpen(sqlite3_vfs *pVfs, const char *zFilename){
-
  HMODULE hmod;
-
  APIRET rc;
-
  char *zFilenameCp = convertUtf8PathToCp(zFilename);
-
  rc = DosLoadModule(NULL, 0, (PSZ)zFilenameCp, &hmod);
-
  free(zFilenameCp);
-
  return rc != NO_ERROR ? 0 : (void*)hmod;
-
}
-
/*
-
** A no-op since the error code is returned on the DosLoadModule call.
-
** os2Dlopen returns zero if DosLoadModule is not successful.
-
*/
-
static void os2DlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
-
/* no-op */
-
}
-
static void (*os2DlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
-
  PFN pfn;
-
  APIRET rc;
-
  rc = DosQueryProcAddr((HMODULE)pHandle, 0L, (PSZ)zSymbol, &pfn);
-
  if( rc != NO_ERROR ){
-
    /* if the symbol itself was not found, search again for the same
-
     * symbol with an extra underscore, that might be needed depending
-
     * on the calling convention */
-
    char _zSymbol[256] = "_";
-
    strncat(_zSymbol, zSymbol, 254);
-
    rc = DosQueryProcAddr((HMODULE)pHandle, 0L, (PSZ)_zSymbol, &pfn);
-
  }
-
  return rc != NO_ERROR ? 0 : (void(*)(void))pfn;
-
}
-
static void os2DlClose(sqlite3_vfs *pVfs, void *pHandle){
-
  DosFreeModule((HMODULE)pHandle);
-
}
-
#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
-
  #define os2DlOpen 0
-
  #define os2DlError 0
-
  #define os2DlSym 0
-
  #define os2DlClose 0
-
#endif
-

-

-
/*
-
** Write up to nBuf bytes of randomness into zBuf.
-
*/
-
static int os2Randomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf ){
-
  int n = 0;
-
#if defined(SQLITE_TEST)
-
  n = nBuf;
-
  memset(zBuf, 0, nBuf);
-
#else
-
  int i;                           
-
  PPIB ppib;
-
  PTIB ptib;
-
  DATETIME dt; 
-
  static unsigned c = 0;
-
  /* Ordered by variation probability */
-
  static ULONG svIdx[6] = { QSV_MS_COUNT, QSV_TIME_LOW,
-
                            QSV_MAXPRMEM, QSV_MAXSHMEM,
-
                            QSV_TOTAVAILMEM, QSV_TOTRESMEM };
-

-
  /* 8 bytes; timezone and weekday don't increase the randomness much */
-
  if( (int)sizeof(dt)-3 <= nBuf - n ){
-
    c += 0x0100;
-
    DosGetDateTime(&dt);
-
    dt.year = (USHORT)((dt.year - 1900) | c);
-
    memcpy(&zBuf[n], &dt, sizeof(dt)-3);
-
    n += sizeof(dt)-3;
-
  }
-

-
  /* 4 bytes; PIDs and TIDs are 16 bit internally, so combine them */
-
  if( (int)sizeof(ULONG) <= nBuf - n ){
-
    DosGetInfoBlocks(&ptib, &ppib);
-
    *(PULONG)&zBuf[n] = MAKELONG(ppib->pib_ulpid,
-
                                 ptib->tib_ptib2->tib2_ultid);
-
    n += sizeof(ULONG);
-
  }
-

-
  /* Up to 6 * 4 bytes; variables depend on the system state */
-
  for( i = 0; i < 6 && (int)sizeof(ULONG) <= nBuf - n; i++ ){
-
    DosQuerySysInfo(svIdx[i], svIdx[i], 
-
                    (PULONG)&zBuf[n], sizeof(ULONG));
-
    n += sizeof(ULONG);
-
  } 
-
#endif
-

-
  return n;
-
}
-

-
/*
-
** Sleep for a little while.  Return the amount of time slept.
-
** The argument is the number of microseconds we want to sleep.
-
** The return value is the number of microseconds of sleep actually
-
** requested from the underlying operating system, a number which
-
** might be greater than or equal to the argument, but not less
-
** than the argument.
-
*/
-
static int os2Sleep( sqlite3_vfs *pVfs, int microsec ){
-
  DosSleep( (microsec/1000) );
-
  return microsec;
-
}
-

-
/*
-
** 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;
-
#endif
-

-
/*
-
** Find the current time (in Universal Coordinated Time).  Write into *piNow
-
** the current time and date as a Julian Day number times 86_400_000.  In
-
** other words, write into *piNow the number of milliseconds since the Julian
-
** epoch of noon in Greenwich on November 24, 4714 B.C according to the
-
** proleptic Gregorian calendar.
-
**
-
** On success, return 0.  Return 1 if the time and date cannot be found.
-
*/
-
static int os2CurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
-
#ifdef SQLITE_TEST
-
  static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
-
#endif
-
  int year, month, datepart, timepart;
-
 
-
  DATETIME dt;
-
  DosGetDateTime( &dt );
-

-
  year = dt.year;
-
  month = dt.month;
-

-
  /* Calculations from http://www.astro.keele.ac.uk/~rno/Astronomy/hjd.html
-
  ** http://www.astro.keele.ac.uk/~rno/Astronomy/hjd-0.1.c
-
  ** Calculate the Julian days
-
  */
-
  datepart = (int)dt.day - 32076 +
-
    1461*(year + 4800 + (month - 14)/12)/4 +
-
    367*(month - 2 - (month - 14)/12*12)/12 -
-
    3*((year + 4900 + (month - 14)/12)/100)/4;
-

-
  /* Time in milliseconds, hours to noon added */
-
  timepart = 12*3600*1000 + dt.hundredths*10 + dt.seconds*1000 +
-
    ((int)dt.minutes + dt.timezone)*60*1000 + dt.hours*3600*1000;
-

-
  *piNow = (sqlite3_int64)datepart*86400*1000 + timepart;
-
   
-
#ifdef SQLITE_TEST
-
  if( sqlite3_current_time ){
-
    *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
-
  }
-
#endif
-

-
  UNUSED_PARAMETER(pVfs);
-
  return 0;
-
}
-

-
/*
-
** Find the current time (in Universal Coordinated Time).  Write the
-
** current time and date as a Julian Day number into *prNow and
-
** return 0.  Return 1 if the time and date cannot be found.
-
*/
-
static int os2CurrentTime( sqlite3_vfs *pVfs, double *prNow ){
-
  int rc;
-
  sqlite3_int64 i;
-
  rc = os2CurrentTimeInt64(pVfs, &i);
-
  if( !rc ){
-
    *prNow = i/86400000.0;
-
  }
-
  return rc;
-
}
-

-
/*
-
** The idea is that this function works like a combination of
-
** GetLastError() and FormatMessage() on windows (or errno and
-
** strerror_r() on unix). After an error is returned by an OS
-
** function, SQLite calls this function with zBuf pointing to
-
** a buffer of nBuf bytes. The OS layer should populate the
-
** buffer with a nul-terminated UTF-8 encoded error message
-
** describing the last IO error to have occurred within the calling
-
** thread.
-
**
-
** If the error message is too large for the supplied buffer,
-
** it should be truncated. The return value of xGetLastError
-
** is zero if the error message fits in the buffer, or non-zero
-
** otherwise (if the message was truncated). If non-zero is returned,
-
** then it is not necessary to include the nul-terminator character
-
** in the output buffer.
-
**
-
** Not supplying an error message will have no adverse effect
-
** on SQLite. It is fine to have an implementation that never
-
** returns an error message:
-
**
-
**   int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
-
**     assert(zBuf[0]=='\0');
-
**     return 0;
-
**   }
-
**
-
** However if an error message is supplied, it will be incorporated
-
** by sqlite into the error message available to the user using
-
** sqlite3_errmsg(), possibly making IO errors easier to debug.
-
*/
-
static int os2GetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
-
  assert(zBuf[0]=='\0');
-
  return 0;
-
}
-

-
/*
-
** Initialize and deinitialize the operating system interface.
-
*/
-
SQLITE_API int sqlite3_os_init(void){
-
  static sqlite3_vfs os2Vfs = {
-
    3,                 /* iVersion */
-
    sizeof(os2File),   /* szOsFile */
-
    CCHMAXPATH,        /* mxPathname */
-
    0,                 /* pNext */
-
    "os2",             /* zName */
-
    0,                 /* pAppData */
-

-
    os2Open,           /* xOpen */
-
    os2Delete,         /* xDelete */
-
    os2Access,         /* xAccess */
-
    os2FullPathname,   /* xFullPathname */
-
    os2DlOpen,         /* xDlOpen */
-
    os2DlError,        /* xDlError */
-
    os2DlSym,          /* xDlSym */
-
    os2DlClose,        /* xDlClose */
-
    os2Randomness,     /* xRandomness */
-
    os2Sleep,          /* xSleep */
-
    os2CurrentTime,    /* xCurrentTime */
-
    os2GetLastError,   /* xGetLastError */
-
    os2CurrentTimeInt64, /* xCurrentTimeInt64 */
-
    0,                 /* xSetSystemCall */
-
    0,                 /* xGetSystemCall */
-
    0                  /* xNextSystemCall */
-
  };
-
  sqlite3_vfs_register(&os2Vfs, 1);
-
  initUconvObjects();
-
/*  sqlite3OSTrace = 1; */
-
  return SQLITE_OK;
-
}
-
SQLITE_API int sqlite3_os_end(void){
-
  freeUconvObjects();
-
  return SQLITE_OK;
-
}
-

-
#endif /* SQLITE_OS_OS2 */
-

-
/************** End of os_os2.c **********************************************/
-
/************** Begin file os_unix.c *****************************************/
-
/*
-
** 2004 May 22
-
**
-
** The author disclaims copyright to this source code.  In place of
-
** a legal notice, here is a blessing:
-
**
-
**    May you do good and not evil.
-
**    May you find forgiveness for yourself and forgive others.
-
**    May you share freely, never taking more than you give.
-
**
-
******************************************************************************
-
**
-
** This file contains 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().
-
*/
-
#if SQLITE_OS_UNIX              /* This file is used on unix only */
-

-
/*
-
** 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(__APPLE__)
-
#    define SQLITE_ENABLE_LOCKING_STYLE 1
-
#  else
-
#    define SQLITE_ENABLE_LOCKING_STYLE 0
-
#  endif
-
#endif
-

-
/*
-
** Define the OS_VXWORKS pre-processor macro to 1 if building on 
-
** vxworks, or 0 otherwise.
-
*/
-
#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
-
** underlying operating system supports it.  If the OS lacks
-
** large file support, these should be no-ops.
-
**
-
** 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
-
** 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
-
#   define _FILE_OFFSET_BITS 64
-
# endif
-
# define _LARGEFILE_SOURCE 1
-
#endif
-

-
/*
-
** standard include files.
-
*/
-
#include <sys/types.h>
-
#include <sys/stat.h>
-
#include <fcntl.h>
-
#include <unistd.h>
-
/* #include <time.h> */
-
#include <sys/time.h>
-
#include <errno.h>
-
#ifndef SQLITE_OMIT_WAL
-
#include <sys/mman.h>
-
#endif
-

-

-
#if SQLITE_ENABLE_LOCKING_STYLE
-
# include <sys/ioctl.h>
-
# if OS_VXWORKS
-
#  include <semaphore.h>
-
#  include <limits.h>
-
# else
-
#  include <sys/file.h>
-
#  include <sys/param.h>
-
# endif
-
#endif /* SQLITE_ENABLE_LOCKING_STYLE */
-

-
#if defined(__APPLE__) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS)
-
# include <sys/mount.h>
-
#endif
-

-
#ifdef HAVE_UTIME
-
# include <utime.h>
-
#endif
-

-
/*
-
** Allowed values of unixFile.fsFlags
-
*/
-
#define SQLITE_FSFLAGS_IS_MSDOS     0x1
-

-
/*
-
** If we are to be thread-safe, include the pthreads header and define
-
** the SQLITE_UNIX_THREADS macro.
-
*/
-
#if SQLITE_THREADSAFE
-
/* # include <pthread.h> */
-
# define SQLITE_UNIX_THREADS 1
-
#endif
-

-
/*
-
** Default permissions when creating a new file
-
*/
-
#ifndef SQLITE_DEFAULT_FILE_PERMISSIONS
-
# 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
-

-
/*
-
** 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))
-

-
/* Forward references */
-
typedef struct unixShm unixShm;               /* Connection shared memory */
-
typedef struct unixShmNode unixShmNode;       /* Shared memory instance */
-
typedef struct unixInodeInfo unixInodeInfo;   /* An i-node */
-
typedef struct UnixUnusedFd UnixUnusedFd;     /* An unused file descriptor */
-

-
/*
-
** Sometimes, after a file handle is closed by SQLite, the file descriptor
-
** cannot be closed immediately. In these cases, instances of the following
-
** structure are used to store the file descriptor while waiting for an
-
** opportunity to either close or reuse it.
-
*/
-
struct UnixUnusedFd {
-
  int fd;                   /* File descriptor to close */
-
  int flags;                /* Flags this file descriptor was opened with */
-
  UnixUnusedFd *pNext;      /* Next unused file descriptor on same file */
-
};
-

-
/*
-
** 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 */
-
  sqlite3_vfs *pVfs;                  /* The VFS that created this unixFile */
-
  unixInodeInfo *pInode;              /* Info about locks on this inode */
-
  int h;                              /* The file descriptor */
-
  unsigned char eFileLock;            /* The type of lock held on this fd */
-
  unsigned short int ctrlFlags;       /* Behavioral bits.  UNIXFILE_* flags */
-
  int lastErrno;                      /* The unix errno from last I/O error */
-
  void *lockingContext;               /* Locking style specific state */
-
  UnixUnusedFd *pUnused;              /* Pre-allocated UnixUnusedFd */
-
  const char *zPath;                  /* Name of the file */
-
  unixShm *pShm;                      /* Shared memory segment information */
-
  int szChunk;                        /* Configured by FCNTL_CHUNK_SIZE */
-
#if SQLITE_ENABLE_LOCKING_STYLE
-
  int openFlags;                      /* The flags specified at open() */
-
#endif
-
#if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__)
-
  unsigned fsFlags;                   /* cached details from statfs() */
-
#endif
-
#if OS_VXWORKS
-
  struct vxworksFileId *pId;          /* Unique file ID */
-
#endif
-
#ifdef SQLITE_DEBUG
-
  /* The next group of variables are used to track whether or not the
-
  ** transaction counter in bytes 24-27 of database files are updated
-
  ** whenever any part of the database changes.  An assertion fault will
-
  ** occur if a file is updated without also updating the transaction
-
  ** counter.  This test is made to avoid new problems similar to the
-
  ** one described by ticket #3584. 
-
  */
-
  unsigned char transCntrChng;   /* True if the transaction counter changed */
-
  unsigned char dbUpdate;        /* True if any part of database file changed */
-
  unsigned char inNormalWrite;   /* True if in a normal write operation */
-
#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
-
};
-

-
/*
-
** Allowed values for the unixFile.ctrlFlags bitmask:
-
*/
-
#define UNIXFILE_EXCL        0x01     /* Connections from one process only */
-
#define UNIXFILE_RDONLY      0x02     /* Connection is read only */
-
#define UNIXFILE_PERSIST_WAL 0x04     /* Persistent WAL mode */
-
#ifndef SQLITE_DISABLE_DIRSYNC
-
# define UNIXFILE_DIRSYNC    0x08     /* Directory sync needed */
-
#else
-
# define UNIXFILE_DIRSYNC    0x00
-
#endif
-
#define UNIXFILE_PSOW        0x10     /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
-
#define UNIXFILE_DELETE      0x20     /* Delete on close */
-
#define UNIXFILE_URI         0x40     /* Filename might have query parameters */
-
#define UNIXFILE_NOLOCK      0x80     /* Do no file locking */
-

-
/*
-
** Include code that is common to all os_*.c files
-
*/
-
/************** Include os_common.h in the middle of os_unix.c ***************/
+
/************** Include os_common.h in the middle of os_unix.c ***************/
/************** Begin file os_common.h ***************************************/
/*
** 2004 May 22
@@ -25843,9 +23480,9 @@ static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) {
  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) ){
+
        (sqliteIOErr == SQLITE_IOERR_UNLOCK) || 
+
        (sqliteIOErr == SQLITE_IOERR_RDLOCK) ||
+
        (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ){
      return SQLITE_BUSY;
    }
    /* else fall through */
@@ -26180,7 +23817,7 @@ static unixInodeInfo *inodeList = 0;
** The first argument passed to the macro should be the error code that
** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN). 
** The two subsequent arguments should be the name of the OS function that
-
** failed (e.g. "unlink", "open") and the the associated file-system path,
+
** failed (e.g. "unlink", "open") and the associated file-system path,
** if any.
*/
#define unixLogError(a,b,c)     unixLogErrorAtLine(a,b,c,__LINE__)
@@ -26203,7 +23840,7 @@ static int unixLogErrorAtLine(
  zErr = aErr;

  /* If STRERROR_R_CHAR_P (set by autoconf scripts) or __USE_GNU is defined,
-
  ** assume that the system provides the the GNU version of strerror_r() that 
+
  ** assume that the system provides the GNU version of strerror_r() that
  ** returns a pointer to a buffer containing the error message. That pointer 
  ** may point to aErr[], or it may point to some static storage somewhere. 
  ** Otherwise, assume that the system provides the POSIX version of 
@@ -26892,7 +24529,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
        pInode->eFileLock = NO_LOCK;
      }else{
        rc = SQLITE_IOERR_UNLOCK;
-
	pFile->lastErrno = errno;
+
        pFile->lastErrno = errno;
        pInode->eFileLock = NO_LOCK;
        pFile->eFileLock = NO_LOCK;
      }
@@ -26908,7 +24545,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
      closePendingFds(pFile);
    }
  }
-
	
+

end_unlock:
  unixLeaveMutex();
  if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock;
@@ -27175,7 +24812,7 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) {

  assert( pFile );
  OSTRACE(("UNLOCK  %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock,
-
	   pFile->eFileLock, getpid()));
+
           pFile->eFileLock, getpid()));
  assert( eFileLock<=SHARED_LOCK );
  
  /* no-op if possible */
@@ -27562,7 +25199,7 @@ static int semUnlock(sqlite3_file *id, int eFileLock) {
  assert( pFile );
  assert( pSem );
  OSTRACE(("UNLOCK  %d %d was %d pid=%d (sem)\n", pFile->h, eFileLock,
-
	   pFile->eFileLock, getpid()));
+
           pFile->eFileLock, getpid()));
  assert( eFileLock<=SHARED_LOCK );
  
  /* no-op if possible */
@@ -28152,7 +25789,7 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
      if( newOffset == -1 ){
        ((unixFile*)id)->lastErrno = errno;
      }else{
-
        ((unixFile*)id)->lastErrno = 0;			
+
        ((unixFile*)id)->lastErrno = 0;
      }
      return -1;
    }
@@ -28240,7 +25877,7 @@ static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){
      if( newOffset == -1 ){
        ((unixFile*)id)->lastErrno = errno;
      }else{
-
        ((unixFile*)id)->lastErrno = 0;			
+
        ((unixFile*)id)->lastErrno = 0;
      }
      return -1;
    }
@@ -30754,7 +28391,7 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
** address in the shared range is taken for a SHARED lock, the entire
** shared range is taken for an EXCLUSIVE lock):
**
-
**      PENDING_BYTE        0x40000000		   	
+
**      PENDING_BYTE        0x40000000
**      RESERVED_BYTE       0x40000001
**      SHARED_RANGE        0x40000002 -> 0x40000200
**
@@ -32274,9 +29911,11 @@ SQLITE_API int sqlite3_open_file_count = 0;
# define FILE_ATTRIBUTE_MASK     (0x0003FFF7)
#endif

+
#ifndef SQLITE_OMIT_WAL
/* Forward references */
typedef struct winShm winShm;           /* A connection to shared-memory */
typedef struct winShmNode winShmNode;   /* A region of shared-memory */
+
#endif

/*
** WinCE lacks native support for file locking so we have to fake it
@@ -32304,7 +29943,9 @@ struct winFile {
  short sharedLockByte;   /* Randomly chosen byte used as a shared lock */
  u8 ctrlFlags;           /* Flags.  See WINFILE_* below */
  DWORD lastErrno;        /* The Windows errno from the last I/O error */
+
#ifndef SQLITE_OMIT_WAL
  winShm *pShm;           /* Instance of shared memory on this file */
+
#endif
  const char *zPath;      /* Full pathname of this file */
  int szChunk;            /* Chunk size configured by FCNTL_CHUNK_SIZE */
#if SQLITE_OS_WINCE
@@ -32330,6 +29971,22 @@ struct winFile {
#endif

/*
+
 * The value used with sqlite3_win32_set_directory() to specify that
+
 * the data directory should be changed.
+
 */
+
#ifndef SQLITE_WIN32_DATA_DIRECTORY_TYPE
+
#  define SQLITE_WIN32_DATA_DIRECTORY_TYPE (1)
+
#endif
+

+
/*
+
 * The value used with sqlite3_win32_set_directory() to specify that
+
 * the temporary directory should be changed.
+
 */
+
#ifndef SQLITE_WIN32_TEMP_DIRECTORY_TYPE
+
#  define SQLITE_WIN32_TEMP_DIRECTORY_TYPE (2)
+
#endif
+

+
/*
 * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the
 * various Win32 API heap functions instead of our own.
 */
@@ -32516,7 +30173,8 @@ static struct win_syscall {
#define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \
        LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent)

-
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
+
#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
+
        !defined(SQLITE_OMIT_WAL))
  { "CreateFileMappingW",      (SYSCALL)CreateFileMappingW,      0 },
#else
  { "CreateFileMappingW",      (SYSCALL)0,                       0 },
@@ -32828,7 +30486,7 @@ static struct win_syscall {
        LPOVERLAPPED))aSyscall[45].pCurrent)
#endif

-
#if !SQLITE_OS_WINRT
+
#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL))
  { "MapViewOfFile",           (SYSCALL)MapViewOfFile,           0 },
#else
  { "MapViewOfFile",           (SYSCALL)0,                       0 },
@@ -32898,7 +30556,11 @@ static struct win_syscall {
#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
        LPOVERLAPPED))aSyscall[55].pCurrent)

+
#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL)
  { "UnmapViewOfFile",         (SYSCALL)UnmapViewOfFile,         0 },
+
#else
+
  { "UnmapViewOfFile",         (SYSCALL)0,                       0 },
+
#endif

#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[56].pCurrent)

@@ -32930,7 +30592,7 @@ static struct win_syscall {
#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
        DWORD))aSyscall[60].pCurrent)

-
#if !SQLITE_OS_WINCE
+
#if SQLITE_OS_WINRT
  { "WaitForSingleObjectEx",   (SYSCALL)WaitForSingleObjectEx,   0 },
#else
  { "WaitForSingleObjectEx",   (SYSCALL)0,                       0 },
@@ -32939,7 +30601,7 @@ static struct win_syscall {
#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
        BOOL))aSyscall[61].pCurrent)

-
#if !SQLITE_OS_WINCE
+
#if SQLITE_OS_WINRT
  { "SetFilePointerEx",        (SYSCALL)SetFilePointerEx,        0 },
#else
  { "SetFilePointerEx",        (SYSCALL)0,                       0 },
@@ -32957,7 +30619,7 @@ static struct win_syscall {
#define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
        FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[63].pCurrent)

-
#if SQLITE_OS_WINRT
+
#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
  { "MapViewOfFileFromApp",    (SYSCALL)MapViewOfFileFromApp,    0 },
#else
  { "MapViewOfFileFromApp",    (SYSCALL)0,                       0 },
@@ -33021,7 +30683,7 @@ static struct win_syscall {

#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[71].pCurrent)

-
#if SQLITE_OS_WINRT
+
#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
  { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
#else
  { "CreateFileMappingFromApp", (SYSCALL)0,                      0 },
@@ -33537,6 +31199,42 @@ SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){
  return zFilenameMbcs;
}

+
/*
+
** This function sets the data directory or the temporary directory based on
+
** the provided arguments.  The type argument must be 1 in order to set the
+
** data directory or 2 in order to set the temporary directory.  The zValue
+
** argument is the name of the directory to use.  The return value will be
+
** SQLITE_OK if successful.
+
*/
+
SQLITE_API int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
+
  char **ppDirectory = 0;
+
#ifndef SQLITE_OMIT_AUTOINIT
+
  int rc = sqlite3_initialize();
+
  if( rc ) return rc;
+
#endif
+
  if( type==SQLITE_WIN32_DATA_DIRECTORY_TYPE ){
+
    ppDirectory = &sqlite3_data_directory;
+
  }else if( type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE ){
+
    ppDirectory = &sqlite3_temp_directory;
+
  }
+
  assert( !ppDirectory || type==SQLITE_WIN32_DATA_DIRECTORY_TYPE
+
          || type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE
+
  );
+
  assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) );
+
  if( ppDirectory ){
+
    char *zValueUtf8 = 0;
+
    if( zValue && zValue[0] ){
+
      zValueUtf8 = unicodeToUtf8(zValue);
+
      if ( zValueUtf8==0 ){
+
        return SQLITE_NOMEM;
+
      }
+
    }
+
    sqlite3_free(*ppDirectory);
+
    *ppDirectory = zValueUtf8;
+
    return SQLITE_OK;
+
  }
+
  return SQLITE_ERROR;
+
}

/*
** The return value of getLastErrorMsg
@@ -33631,7 +31329,7 @@ static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
** The first argument passed to the macro should be the error code that
** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN). 
** The two subsequent arguments should be the name of the OS function that
-
** failed and the the associated file-system path, if any.
+
** failed and the associated file-system path, if any.
*/
#define winLogError(a,b,c,d)   winLogErrorAtLine(a,b,c,d,__LINE__)
static int winLogErrorAtLine(
@@ -34153,7 +31851,9 @@ static int winClose(sqlite3_file *id){
  winFile *pFile = (winFile*)id;

  assert( id!=0 );
+
#ifndef SQLITE_OMIT_WAL
  assert( pFile->pShm==0 );
+
#endif
  OSTRACE(("CLOSE %d\n", pFile->h));
  do{
    rc = osCloseHandle(pFile->h);
@@ -35755,6 +33455,13 @@ static int winOpen(
  assert( id!=0 );
  UNUSED_PARAMETER(pVfs);

+
#if SQLITE_OS_WINRT
+
  if( !sqlite3_temp_directory ){
+
    sqlite3_log(SQLITE_ERROR,
+
        "sqlite3_temp_directory variable should be set for WinRT");
+
  }
+
#endif
+

  pFile->h = INVALID_HANDLE_VALUE;

  /* If the second argument to this function is NULL, generate a 
@@ -35903,7 +33610,9 @@ static int winOpen(
  pFile->h = h;
  pFile->lastErrno = NO_ERROR;
  pFile->pVfs = pVfs;
+
#ifndef SQLITE_OMIT_WAL
  pFile->pShm = 0;
+
#endif
  pFile->zPath = zName;
  if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
    pFile->ctrlFlags |= WINFILE_PSOW;
@@ -36066,7 +33775,7 @@ static int winAccess(
      }
    }else{
      logIoerr(cnt);
-
      if( lastErrno!=ERROR_FILE_NOT_FOUND ){
+
      if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){
        winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename);
        sqlite3_free(zConverted);
        return SQLITE_IOERR_ACCESS;
@@ -36879,10 +34588,9 @@ SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){
  /* Allocate the Bitvec to be tested and a linear array of
  ** bits to act as the reference */
  pBitvec = sqlite3BitvecCreate( sz );
-
  pV = sqlite3_malloc( (sz+7)/8 + 1 );
+
  pV = sqlite3MallocZero( (sz+7)/8 + 1 );
  pTmpSpace = sqlite3_malloc(BITVEC_SZ);
  if( pBitvec==0 || pV==0 || pTmpSpace==0  ) goto bitvec_end;
-
  memset(pV, 0, (sz+7)/8 + 1);

  /* NULL pBitvec tests */
  sqlite3BitvecSet(0, 1);
@@ -37966,11 +35674,10 @@ static int pcache1ResizeHash(PCache1 *p){

  pcache1LeaveMutex(p->pGroup);
  if( p->nHash ){ sqlite3BeginBenignMalloc(); }
-
  apNew = (PgHdr1 **)sqlite3_malloc(sizeof(PgHdr1 *)*nNew);
+
  apNew = (PgHdr1 **)sqlite3MallocZero(sizeof(PgHdr1 *)*nNew);
  if( p->nHash ){ sqlite3EndBenignMalloc(); }
  pcache1EnterMutex(p->pGroup);
  if( apNew ){
-
    memset(apNew, 0, sizeof(PgHdr1 *)*nNew);
    for(i=0; i<p->nHash; i++){
      PgHdr1 *pPage;
      PgHdr1 *pNext = p->apHash[i];
@@ -38154,9 +35861,8 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
  assert( szExtra < 300 );

  sz = sizeof(PCache1) + sizeof(PGroup)*separateCache;
-
  pCache = (PCache1 *)sqlite3_malloc(sz);
+
  pCache = (PCache1 *)sqlite3MallocZero(sz);
  if( pCache ){
-
    memset(pCache, 0, sz);
    if( separateCache ){
      pGroup = (PGroup*)&pCache[1];
      pGroup->mxPinned = 10;
@@ -39034,7 +36740,7 @@ SQLITE_PRIVATE int sqlite3RowSetNext(RowSet *p, i64 *pRowid){
}

/*
-
** Check to see if element iRowid was inserted into the the rowset as
+
** Check to see if element iRowid was inserted into the rowset as
** part of any insert batch prior to iBatch.  Return 1 or 0.
**
** If this is the first test of a new batch and if there exist entires
@@ -39318,7 +37024,7 @@ SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal);
** 
** Definition: Two databases (or the same database at two points it time)
** are said to be "logically equivalent" if they give the same answer to
-
** all queries.  Note in particular the the content of freelist leaf
+
** all queries.  Note in particular the content of freelist leaf
** pages can be changed arbitarily without effecting the logical equivalence
** of the database.
** 
@@ -43092,7 +40798,7 @@ SQLITE_PRIVATE void sqlite3PagerRef(DbPage *pPg){
**
** If the Pager.noSync flag is set, then this function is a no-op.
** Otherwise, the actions required depend on the journal-mode and the 
-
** device characteristics of the the file-system, as follows:
+
** device characteristics of the file-system, as follows:
**
**   * If the journal file is an in-memory journal file, no action need
**     be taken.
@@ -46323,14 +44029,15 @@ SQLITE_PRIVATE void *sqlite3PagerCodec(PgHdr *pPg){
** byte order of the host computer.
**
** The purpose of the wal-index is to answer this question quickly:  Given
-
** a page number P, return the index of the last frame for page P in the WAL,
-
** or return NULL if there are no frames for page P in the WAL.
+
** a page number P and a maximum frame index M, return the index of the 
+
** last frame in the wal before frame M for page P in the WAL, or return
+
** NULL if there are no frames for page P in the WAL prior to M.
**
** The wal-index consists of a header region, followed by an one or
** more index blocks.  
**
** The wal-index header contains the total number of frames within the WAL
-
** in the the mxFrame field.  
+
** in the mxFrame field.
**
** Each index block except for the first contains information on 
** HASHTABLE_NPAGE frames. The first index block contains information on
@@ -47378,6 +45085,7 @@ finished:
    pInfo->nBackfill = 0;
    pInfo->aReadMark[0] = 0;
    for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
+
    if( pWal->hdr.mxFrame ) pInfo->aReadMark[1] = pWal->hdr.mxFrame;

    /* If more than one frame was recovered from the log file, report an
    ** event via sqlite3_log(). This is to help with identifying performance
@@ -47878,7 +45586,7 @@ static int walCheckpoint(
      assert( y<=pWal->hdr.mxFrame );
      rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1);
      if( rc==SQLITE_OK ){
-
        pInfo->aReadMark[i] = READMARK_NOT_USED;
+
        pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
        walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
      }else if( rc==SQLITE_BUSY ){
        mxSafeFrame = y;
@@ -48791,7 +46499,8 @@ static int walRestartLog(Wal *pWal){
        aSalt[1] = salt1;
        walIndexWriteHdr(pWal);
        pInfo->nBackfill = 0;
-
        for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
+
        pInfo->aReadMark[1] = 0;
+
        for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
        assert( pInfo->aReadMark[0]==0 );
        walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
      }else if( rc!=SQLITE_BUSY ){
@@ -49794,6 +47503,7 @@ struct BtCursor {
#ifndef SQLITE_OMIT_INCRBLOB
  u8 isIncrblobHandle;      /* True if this cursor is an incr. io handle */
#endif
+
  u8 hints;                             /* As configured by CursorSetHints() */
  i16 iPage;                            /* Index of current page in apPage */
  u16 aiIdx[BTCURSOR_MAX_DEPTH];        /* Current index in apPage[i] */
  MemPage *apPage[BTCURSOR_MAX_DEPTH];  /* Pages from root to current page */
@@ -51678,7 +49388,7 @@ static int btreeInitPage(MemPage *pPage){
      size = get2byte(&data[pc+2]);
      if( (next>0 && next<=pc+size+3) || pc+size>usableSize ){
        /* Free blocks must be in ascending order. And the last byte of
-
	** the free-block must lie on the database page.  */
+
        ** the free-block must lie on the database page.  */
        return SQLITE_CORRUPT_BKPT; 
      }
      nFree = nFree + size;
@@ -52852,7 +50562,7 @@ SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
      pBt->nTransaction++;
#ifndef SQLITE_OMIT_SHARED_CACHE
      if( p->sharable ){
-
	assert( p->lock.pBtree==p && p->lock.iTable==1 );
+
        assert( p->lock.pBtree==p && p->lock.iTable==1 );
        p->lock.eLock = READ_LOCK;
        p->lock.pNext = pBt->pLock;
        pBt->pLock = &p->lock;
@@ -56143,7 +53853,8 @@ static int balance_nonroot(
  MemPage *pParent,               /* Parent page of siblings being balanced */
  int iParentIdx,                 /* Index of "the page" in pParent */
  u8 *aOvflSpace,                 /* page-size bytes of space for parent ovfl */
-
  int isRoot                      /* True if pParent is a root-page */
+
  int isRoot,                     /* True if pParent is a root-page */
+
  int bBulk                       /* True if this call is part of a bulk load */
){
  BtShared *pBt;               /* The whole database */
  int nCell = 0;               /* Number of cells in apCell[] */
@@ -56207,18 +53918,19 @@ static int balance_nonroot(
  i = pParent->nOverflow + pParent->nCell;
  if( i<2 ){
    nxDiv = 0;
-
    nOld = i+1;
  }else{
-
    nOld = 3;
+
    assert( bBulk==0 || bBulk==1 );
    if( iParentIdx==0 ){                 
      nxDiv = 0;
    }else if( iParentIdx==i ){
-
      nxDiv = i-2;
+
      nxDiv = i-2+bBulk;
    }else{
+
      assert( bBulk==0 );
      nxDiv = iParentIdx-1;
    }
-
    i = 2;
+
    i = 2-bBulk;
  }
+
  nOld = i+1;
  if( (i+nxDiv-pParent->nOverflow)==pParent->nCell ){
    pRight = &pParent->aData[pParent->hdrOffset+8];
  }else{
@@ -56298,7 +54010,7 @@ static int balance_nonroot(
  /*
  ** Load pointers to all cells on sibling pages and the divider cells
  ** into the local apCell[] array.  Make copies of the divider cells
-
  ** into space obtained from aSpace1[] and remove the the divider Cells
+
  ** into space obtained from aSpace1[] and remove the divider cells
  ** from pParent.
  **
  ** If the siblings are on leaf pages, then the child pointers of the
@@ -56427,7 +54139,9 @@ static int balance_nonroot(
    d = r + 1 - leafData;
    assert( d<nMaxCells );
    assert( r<nMaxCells );
-
    while( szRight==0 || szRight+szCell[d]+2<=szLeft-(szCell[r]+2) ){
+
    while( szRight==0 
+
       || (!bBulk && szRight+szCell[d]+2<=szLeft-(szCell[r]+2)) 
+
    ){
      szRight += szCell[d] + 2;
      szLeft -= szCell[r] + 2;
      cntNew[i-1]--;
@@ -56474,7 +54188,7 @@ static int balance_nonroot(
      if( rc ) goto balance_cleanup;
    }else{
      assert( i>0 );
-
      rc = allocateBtreePage(pBt, &pNew, &pgno, pgno, 0);
+
      rc = allocateBtreePage(pBt, &pNew, &pgno, (bBulk ? 1 : pgno), 0);
      if( rc ) goto balance_cleanup;
      apNew[i] = pNew;
      nNew++;
@@ -56686,6 +54400,7 @@ static int balance_nonroot(
        ** sibling page j. If the siblings are not leaf pages of an
        ** intkey b-tree, then cell i was a divider cell. */
        assert( j+1 < ArraySize(apCopy) );
+
        assert( j+1 < nOld );
        pOld = apCopy[++j];
        iNextOld = i + !leafData + pOld->nCell + pOld->nOverflow;
        if( pOld->nOverflow ){
@@ -56924,7 +54639,7 @@ static int balance(BtCursor *pCur){
          ** pSpace buffer passed to the latter call to balance_nonroot().
          */
          u8 *pSpace = sqlite3PageMalloc(pCur->pBt->pageSize);
-
          rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1);
+
          rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1, pCur->hints);
          if( pFree ){
            /* If pFree is not NULL, it points to the pSpace buffer used 
            ** by a previous call to balance_nonroot(). Its contents are
@@ -58512,6 +56227,15 @@ SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){
  return rc;
}

+
/*
+
** set the mask of hint flags for cursor pCsr. Currently the only valid
+
** values are 0 and BTREE_BULKLOAD.
+
*/
+
SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *pCsr, unsigned int mask){
+
  assert( mask==BTREE_BULKLOAD || mask==0 );
+
  pCsr->hints = mask;
+
}
+

/************** End of btree.c ***********************************************/
/************** Begin file backup.c ******************************************/
/*
@@ -58678,7 +56402,7 @@ SQLITE_API sqlite3_backup *sqlite3_backup_init(
    ** EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a
    ** call to sqlite3_backup_init() and is destroyed by a call to
    ** sqlite3_backup_finish(). */
-
    p = (sqlite3_backup *)sqlite3_malloc(sizeof(sqlite3_backup));
+
    p = (sqlite3_backup *)sqlite3MallocZero(sizeof(sqlite3_backup));
    if( !p ){
      sqlite3Error(pDestDb, SQLITE_NOMEM, 0);
    }
@@ -58686,7 +56410,6 @@ SQLITE_API sqlite3_backup *sqlite3_backup_init(

  /* If the allocation succeeded, populate the new object. */
  if( p ){
-
    memset(p, 0, sizeof(sqlite3_backup));
    p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb);
    p->pDest = findBtree(pDestDb, pDestDb, zDestDb);
    p->pDestDb = pDestDb;
@@ -59057,14 +56780,14 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
*/
SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
  sqlite3_backup **pp;                 /* Ptr to head of pagers backup list */
-
  MUTEX_LOGIC( sqlite3_mutex *mutex; ) /* Mutex to protect source database */
+
  sqlite3 *pSrcDb;                     /* Source database connection */
  int rc;                              /* Value to return */

  /* Enter the mutexes */
  if( p==0 ) return SQLITE_OK;
-
  sqlite3_mutex_enter(p->pSrcDb->mutex);
+
  pSrcDb = p->pSrcDb;
+
  sqlite3_mutex_enter(pSrcDb->mutex);
  sqlite3BtreeEnter(p->pSrc);
-
  MUTEX_LOGIC( mutex = p->pSrcDb->mutex; )
  if( p->pDestDb ){
    sqlite3_mutex_enter(p->pDestDb->mutex);
  }
@@ -59090,7 +56813,7 @@ SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){

  /* Exit the mutexes and free the backup context structure. */
  if( p->pDestDb ){
-
    sqlite3_mutex_leave(p->pDestDb->mutex);
+
    sqlite3LeaveMutexAndCloseZombie(p->pDestDb);
  }
  sqlite3BtreeLeave(p->pSrc);
  if( p->pDestDb ){
@@ -59099,7 +56822,7 @@ SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
    ** sqlite3_backup_finish(). */
    sqlite3_free(p);
  }
-
  sqlite3_mutex_leave(mutex);
+
  sqlite3LeaveMutexAndCloseZombie(pSrcDb);
  return rc;
}

@@ -61168,7 +58891,7 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int

#ifndef NDEBUG
/*
-
** Change the comment on the the most recently coded instruction.  Or
+
** Change the comment on the most recently coded instruction.  Or
** insert a No-op and add the comment to that new instruction.  This
** makes the code easier to read during debugging.  None of this happens
** in a production build.
@@ -62863,6 +60586,7 @@ SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){

  if( NEVER(p==0) ) return;
  db = p->db;
+
  assert( sqlite3_mutex_held(db->mutex) );
  if( p->pPrev ){
    p->pPrev->pNext = p->pNext;
  }else{
@@ -63702,17 +61426,11 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt){
  }else{
    Vdbe *v = (Vdbe*)pStmt;
    sqlite3 *db = v->db;
-
#if SQLITE_THREADSAFE
-
    sqlite3_mutex *mutex;
-
#endif
    if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT;
-
#if SQLITE_THREADSAFE
-
    mutex = v->db->mutex;
-
#endif
-
    sqlite3_mutex_enter(mutex);
+
    sqlite3_mutex_enter(db->mutex);
    rc = sqlite3VdbeFinalize(v);
    rc = sqlite3ApiExit(db, rc);
-
    sqlite3_mutex_leave(mutex);
+
    sqlite3LeaveMutexAndCloseZombie(db);
  }
  return rc;
}
@@ -65115,9 +62833,8 @@ SQLITE_PRIVATE void sqlite3ExplainBegin(Vdbe *pVdbe){
  if( pVdbe ){
    Explain *p;
    sqlite3BeginBenignMalloc();
-
    p = sqlite3_malloc( sizeof(Explain) );
+
    p = (Explain *)sqlite3MallocZero( sizeof(Explain) );
    if( p ){
-
      memset(p, 0, sizeof(*p));
      p->pVdbe = pVdbe;
      sqlite3_free(pVdbe->pExplain);
      pVdbe->pExplain = p;
@@ -66386,7 +64103,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
    }
#endif

-
    /* On any opcode with the "out2-prerelase" tag, free any
+
    /* On any opcode with the "out2-prerelease" tag, free any
    ** external allocations out of mem[p2] and set mem[p2] to be
    ** an undefined integer.  Opcodes will either fill in the integer
    ** value or convert mem[p2] to a different type.
@@ -68898,6 +66615,9 @@ case OP_OpenWrite: {
  Db *pDb;
#endif /* local variables moved into u.ax */

+
  assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 );
+
  assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 );
+

  if( p->expired ){
    rc = SQLITE_ABORT;
    break;
@@ -68921,7 +66641,7 @@ case OP_OpenWrite: {
  }else{
    u.ax.wrFlag = 0;
  }
-
  if( pOp->p5 ){
+
  if( pOp->p5 & OPFLAG_P2ISREG ){
    assert( u.ax.p2>0 );
    assert( u.ax.p2<=p->nMem );
    pIn2 = &aMem[u.ax.p2];
@@ -68952,6 +66672,8 @@ case OP_OpenWrite: {
  u.ax.pCur->isOrdered = 1;
  rc = sqlite3BtreeCursor(u.ax.pX, u.ax.p2, u.ax.wrFlag, u.ax.pKeyInfo, u.ax.pCur->pCursor);
  u.ax.pCur->pKeyInfo = u.ax.pKeyInfo;
+
  assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
+
  sqlite3BtreeCursorHints(u.ax.pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR));

  /* Since it performs no memory allocation or IO, the only value that
  ** sqlite3BtreeCursor() may return is SQLITE_OK. */
@@ -72571,6 +70293,7 @@ SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){

typedef struct VdbeSorterIter VdbeSorterIter;
typedef struct SorterRecord SorterRecord;
+
typedef struct FileWriter FileWriter;

/*
** NOTES ON DATA STRUCTURE USED FOR N-WAY MERGES:
@@ -72668,6 +70391,24 @@ struct VdbeSorterIter {
  sqlite3_file *pFile;            /* File iterator is reading from */
  u8 *aAlloc;                     /* Allocated space */
  u8 *aKey;                       /* Pointer to current key */
+
  u8 *aBuffer;                    /* Current read buffer */
+
  int nBuffer;                    /* Size of read buffer in bytes */
+
};
+

+
/*
+
** An instance of this structure is used to organize the stream of records
+
** being written to files by the merge-sort code into aligned, page-sized
+
** blocks.  Doing all I/O in aligned page-sized blocks helps I/O to go
+
** faster on many operating systems.
+
*/
+
struct FileWriter {
+
  int eFWErr;                     /* Non-zero if in an error state */
+
  u8 *aBuffer;                    /* Pointer to write buffer */
+
  int nBuffer;                    /* Size of write buffer in bytes */
+
  int iBufStart;                  /* First byte of buffer to write */
+
  int iBufEnd;                    /* Last byte of buffer to write */
+
  i64 iWriteOff;                  /* Offset of start of buffer in file */
+
  sqlite3_file *pFile;            /* File to write to */
};

/*
@@ -72693,108 +70434,144 @@ struct SorterRecord {
*/
static void vdbeSorterIterZero(sqlite3 *db, VdbeSorterIter *pIter){
  sqlite3DbFree(db, pIter->aAlloc);
+
  sqlite3DbFree(db, pIter->aBuffer);
  memset(pIter, 0, sizeof(VdbeSorterIter));
}

/*
-
** Advance iterator pIter to the next key in its PMA. Return SQLITE_OK if
-
** no error occurs, or an SQLite error code if one does.
-
*/
-
static int vdbeSorterIterNext(
-
  sqlite3 *db,                    /* Database handle (for sqlite3DbMalloc() ) */
-
  VdbeSorterIter *pIter           /* Iterator to advance */
-
){
-
  int rc;                         /* Return Code */
-
  int nRead;                      /* Number of bytes read */
-
  int nRec = 0;                   /* Size of record in bytes */
-
  int iOff = 0;                   /* Size of serialized size varint in bytes */
-

-
  assert( pIter->iEof>=pIter->iReadOff );
-
  if( pIter->iEof-pIter->iReadOff>5 ){
-
    nRead = 5;
-
  }else{
-
    nRead = (int)(pIter->iEof - pIter->iReadOff);
-
  }
-
  if( nRead<=0 ){
-
    /* This is an EOF condition */
-
    vdbeSorterIterZero(db, pIter);
-
    return SQLITE_OK;
+
** Read nByte bytes of data from the stream of data iterated by object p.
+
** If successful, set *ppOut to point to a buffer containing the data
+
** and return SQLITE_OK. Otherwise, if an error occurs, return an SQLite
+
** error code.
+
**
+
** The buffer indicated by *ppOut may only be considered valid until the
+
** next call to this function.
+
*/
+
static int vdbeSorterIterRead(
+
  sqlite3 *db,                    /* Database handle (for malloc) */
+
  VdbeSorterIter *p,              /* Iterator */
+
  int nByte,                      /* Bytes of data to read */
+
  u8 **ppOut                      /* OUT: Pointer to buffer containing data */
+
){
+
  int iBuf;                       /* Offset within buffer to read from */
+
  int nAvail;                     /* Bytes of data available in buffer */
+
  assert( p->aBuffer );
+

+
  /* If there is no more data to be read from the buffer, read the next 
+
  ** p->nBuffer bytes of data from the file into it. Or, if there are less
+
  ** than p->nBuffer bytes remaining in the PMA, read all remaining data.  */
+
  iBuf = p->iReadOff % p->nBuffer;
+
  if( iBuf==0 ){
+
    int nRead;                    /* Bytes to read from disk */
+
    int rc;                       /* sqlite3OsRead() return code */
+

+
    /* Determine how many bytes of data to read. */
+
    nRead = (int)(p->iEof - p->iReadOff);
+
    if( nRead>p->nBuffer ) nRead = p->nBuffer;
+
    assert( nRead>0 );
+

+
    /* Read data from the file. Return early if an error occurs. */
+
    rc = sqlite3OsRead(p->pFile, p->aBuffer, nRead, p->iReadOff);
+
    assert( rc!=SQLITE_IOERR_SHORT_READ );
+
    if( rc!=SQLITE_OK ) return rc;
  }
+
  nAvail = p->nBuffer - iBuf; 
+

+
  if( nByte<=nAvail ){
+
    /* The requested data is available in the in-memory buffer. In this
+
    ** case there is no need to make a copy of the data, just return a 
+
    ** pointer into the buffer to the caller.  */
+
    *ppOut = &p->aBuffer[iBuf];
+
    p->iReadOff += nByte;
+
  }else{
+
    /* The requested data is not all available in the in-memory buffer.
+
    ** In this case, allocate space at p->aAlloc[] to copy the requested
+
    ** range into. Then return a copy of pointer p->aAlloc to the caller.  */
+
    int nRem;                     /* Bytes remaining to copy */
+

+
    /* Extend the p->aAlloc[] allocation if required. */
+
    if( p->nAlloc<nByte ){
+
      int nNew = p->nAlloc*2;
+
      while( nByte>nNew ) nNew = nNew*2;
+
      p->aAlloc = sqlite3DbReallocOrFree(db, p->aAlloc, nNew);
+
      if( !p->aAlloc ) return SQLITE_NOMEM;
+
      p->nAlloc = nNew;
+
    }
+

+
    /* Copy as much data as is available in the buffer into the start of
+
    ** p->aAlloc[].  */
+
    memcpy(p->aAlloc, &p->aBuffer[iBuf], nAvail);
+
    p->iReadOff += nAvail;
+
    nRem = nByte - nAvail;
+

+
    /* The following loop copies up to p->nBuffer bytes per iteration into
+
    ** the p->aAlloc[] buffer.  */
+
    while( nRem>0 ){
+
      int rc;                     /* vdbeSorterIterRead() return code */
+
      int nCopy;                  /* Number of bytes to copy */
+
      u8 *aNext;                  /* Pointer to buffer to copy data from */

-
  rc = sqlite3OsRead(pIter->pFile, pIter->aAlloc, nRead, pIter->iReadOff);
-
  if( rc==SQLITE_OK ){
-
    iOff = getVarint32(pIter->aAlloc, nRec);
-
    if( (iOff+nRec)>nRead ){
-
      int nRead2;                   /* Number of extra bytes to read */
-
      if( (iOff+nRec)>pIter->nAlloc ){
-
        int nNew = pIter->nAlloc*2;
-
        while( (iOff+nRec)>nNew ) nNew = nNew*2;
-
        pIter->aAlloc = sqlite3DbReallocOrFree(db, pIter->aAlloc, nNew);
-
        if( !pIter->aAlloc ) return SQLITE_NOMEM;
-
        pIter->nAlloc = nNew;
-
      }
-
  
-
      nRead2 = iOff + nRec - nRead;
-
      rc = sqlite3OsRead(
-
          pIter->pFile, &pIter->aAlloc[nRead], nRead2, pIter->iReadOff+nRead
-
      );
+
      nCopy = nRem;
+
      if( nRem>p->nBuffer ) nCopy = p->nBuffer;
+
      rc = vdbeSorterIterRead(db, p, nCopy, &aNext);
+
      if( rc!=SQLITE_OK ) return rc;
+
      assert( aNext!=p->aAlloc );
+
      memcpy(&p->aAlloc[nByte - nRem], aNext, nCopy);
+
      nRem -= nCopy;
    }
+

+
    *ppOut = p->aAlloc;
  }

-
  assert( rc!=SQLITE_OK || nRec>0 );
-
  pIter->iReadOff += iOff+nRec;
-
  pIter->nKey = nRec;
-
  pIter->aKey = &pIter->aAlloc[iOff];
-
  return rc;
+
  return SQLITE_OK;
}

/*
-
** Write a single varint, value iVal, to file-descriptor pFile. Return
-
** SQLITE_OK if successful, or an SQLite error code if some error occurs.
-
**
-
** The value of *piOffset when this function is called is used as the byte
-
** offset in file pFile to write to. Before returning, *piOffset is 
-
** incremented by the number of bytes written.
+
** Read a varint from the stream of data accessed by p. Set *pnOut to
+
** the value read.
*/
-
static int vdbeSorterWriteVarint(
-
  sqlite3_file *pFile,            /* File to write to */
-
  i64 iVal,                       /* Value to write as a varint */
-
  i64 *piOffset                   /* IN/OUT: Write offset in file pFile */
-
){
-
  u8 aVarint[9];                  /* Buffer large enough for a varint */
-
  int nVarint;                    /* Number of used bytes in varint */
-
  int rc;                         /* Result of write() call */
+
static int vdbeSorterIterVarint(sqlite3 *db, VdbeSorterIter *p, u64 *pnOut){
+
  int iBuf;

-
  nVarint = sqlite3PutVarint(aVarint, iVal);
-
  rc = sqlite3OsWrite(pFile, aVarint, nVarint, *piOffset);
-
  *piOffset += nVarint;
+
  iBuf = p->iReadOff % p->nBuffer;
+
  if( iBuf && (p->nBuffer-iBuf)>=9 ){
+
    p->iReadOff += sqlite3GetVarint(&p->aBuffer[iBuf], pnOut);
+
  }else{
+
    u8 aVarint[16], *a;
+
    int i = 0, rc;
+
    do{
+
      rc = vdbeSorterIterRead(db, p, 1, &a);
+
      if( rc ) return rc;
+
      aVarint[(i++)&0xf] = a[0];
+
    }while( (a[0]&0x80)!=0 );
+
    sqlite3GetVarint(aVarint, pnOut);
+
  }

-
  return rc;
+
  return SQLITE_OK;
}

+

/*
-
** Read a single varint from file-descriptor pFile. Return SQLITE_OK if
-
** successful, or an SQLite error code if some error occurs.
-
**
-
** The value of *piOffset when this function is called is used as the
-
** byte offset in file pFile from whence to read the varint. If successful
-
** (i.e. if no IO error occurs), then *piOffset is set to the offset of
-
** the first byte past the end of the varint before returning. *piVal is
-
** set to the integer value read. If an error occurs, the final values of
-
** both *piOffset and *piVal are undefined.
+
** Advance iterator pIter to the next key in its PMA. Return SQLITE_OK if
+
** no error occurs, or an SQLite error code if one does.
*/
-
static int vdbeSorterReadVarint(
-
  sqlite3_file *pFile,            /* File to read from */
-
  i64 *piOffset,                  /* IN/OUT: Read offset in pFile */
-
  i64 *piVal                      /* OUT: Value read from file */
+
static int vdbeSorterIterNext(
+
  sqlite3 *db,                    /* Database handle (for sqlite3DbMalloc() ) */
+
  VdbeSorterIter *pIter           /* Iterator to advance */
){
-
  u8 aVarint[9];                  /* Buffer large enough for a varint */
-
  i64 iOff = *piOffset;           /* Offset in file to read from */
-
  int rc;                         /* Return code */
+
  int rc;                         /* Return Code */
+
  u64 nRec = 0;                   /* Size of record in bytes */

-
  rc = sqlite3OsRead(pFile, aVarint, 9, iOff);
+
  if( pIter->iReadOff>=pIter->iEof ){
+
    /* This is an EOF condition */
+
    vdbeSorterIterZero(db, pIter);
+
    return SQLITE_OK;
+
  }
+

+
  rc = vdbeSorterIterVarint(db, pIter, &nRec);
  if( rc==SQLITE_OK ){
-
    *piOffset += getVarint(aVarint, (u64 *)piVal);
+
    pIter->nKey = (int)nRec;
+
    rc = vdbeSorterIterRead(db, pIter, (int)nRec, &pIter->aKey);
  }

  return rc;
@@ -72808,27 +70585,52 @@ static int vdbeSorterReadVarint(
*/
static int vdbeSorterIterInit(
  sqlite3 *db,                    /* Database handle */
-
  VdbeSorter *pSorter,            /* Sorter object */
+
  const VdbeSorter *pSorter,      /* Sorter object */
  i64 iStart,                     /* Start offset in pFile */
  VdbeSorterIter *pIter,          /* Iterator to populate */
  i64 *pnByte                     /* IN/OUT: Increment this value by PMA size */
){
-
  int rc;
+
  int rc = SQLITE_OK;
+
  int nBuf;
+

+
  nBuf = sqlite3BtreeGetPageSize(db->aDb[0].pBt);

  assert( pSorter->iWriteOff>iStart );
  assert( pIter->aAlloc==0 );
+
  assert( pIter->aBuffer==0 );
  pIter->pFile = pSorter->pTemp1;
  pIter->iReadOff = iStart;
  pIter->nAlloc = 128;
  pIter->aAlloc = (u8 *)sqlite3DbMallocRaw(db, pIter->nAlloc);
-
  if( !pIter->aAlloc ){
+
  pIter->nBuffer = nBuf;
+
  pIter->aBuffer = (u8 *)sqlite3DbMallocRaw(db, nBuf);
+

+
  if( !pIter->aBuffer ){
    rc = SQLITE_NOMEM;
  }else{
-
    i64 nByte;                         /* Total size of PMA in bytes */
-
    rc = vdbeSorterReadVarint(pSorter->pTemp1, &pIter->iReadOff, &nByte);
-
    *pnByte += nByte;
-
    pIter->iEof = pIter->iReadOff + nByte;
+
    int iBuf;
+

+
    iBuf = iStart % nBuf;
+
    if( iBuf ){
+
      int nRead = nBuf - iBuf;
+
      if( (iStart + nRead) > pSorter->iWriteOff ){
+
        nRead = (int)(pSorter->iWriteOff - iStart);
+
      }
+
      rc = sqlite3OsRead(
+
          pSorter->pTemp1, &pIter->aBuffer[iBuf], nRead, iStart
+
      );
+
      assert( rc!=SQLITE_IOERR_SHORT_READ );
+
    }
+

+
    if( rc==SQLITE_OK ){
+
      u64 nByte;                       /* Size of PMA in bytes */
+
      pIter->iEof = pSorter->iWriteOff;
+
      rc = vdbeSorterIterVarint(db, pIter, &nByte);
+
      pIter->iEof = pIter->iReadOff + nByte;
+
      *pnByte += nByte;
+
    }
  }
+

  if( rc==SQLITE_OK ){
    rc = vdbeSorterIterNext(db, pIter);
  }
@@ -72852,10 +70654,10 @@ static int vdbeSorterIterInit(
** has been allocated and contains an unpacked record that is used as key2.
*/
static void vdbeSorterCompare(
-
  VdbeCursor *pCsr,               /* Cursor object (for pKeyInfo) */
+
  const VdbeCursor *pCsr,         /* Cursor object (for pKeyInfo) */
  int bOmitRowid,                 /* Ignore rowid field at end of keys */
-
  void *pKey1, int nKey1,         /* Left side of comparison */
-
  void *pKey2, int nKey2,         /* Right side of comparison */
+
  const void *pKey1, int nKey1,   /* Left side of comparison */
+
  const void *pKey2, int nKey2,   /* Right side of comparison */
  int *pRes                       /* OUT: Result of comparison */
){
  KeyInfo *pKeyInfo = pCsr->pKeyInfo;
@@ -72887,7 +70689,7 @@ static void vdbeSorterCompare(
** multiple b-tree segments. Parameter iOut is the index of the aTree[] 
** value to recalculate.
*/
-
static int vdbeSorterDoCompare(VdbeCursor *pCsr, int iOut){
+
static int vdbeSorterDoCompare(const VdbeCursor *pCsr, int iOut){
  VdbeSorter *pSorter = pCsr->pSorter;
  int i1;
  int i2;
@@ -73013,7 +70815,7 @@ static int vdbeSorterOpenTempFile(sqlite3 *db, sqlite3_file **ppFile){
** Set *ppOut to the head of the new list.
*/
static void vdbeSorterMerge(
-
  VdbeCursor *pCsr,               /* For pKeyInfo */
+
  const VdbeCursor *pCsr,         /* For pKeyInfo */
  SorterRecord *p1,               /* First list to merge */
  SorterRecord *p2,               /* Second list to merge */
  SorterRecord **ppOut            /* OUT: Head of merged list */
@@ -73047,7 +70849,7 @@ static void vdbeSorterMerge(
** if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if an error
** occurs.
*/
-
static int vdbeSorterSort(VdbeCursor *pCsr){
+
static int vdbeSorterSort(const VdbeCursor *pCsr){
  int i;
  SorterRecord **aSlot;
  SorterRecord *p;
@@ -73080,6 +70882,91 @@ static int vdbeSorterSort(VdbeCursor *pCsr){
  return SQLITE_OK;
}

+
/*
+
** Initialize a file-writer object.
+
*/
+
static void fileWriterInit(
+
  sqlite3 *db,                    /* Database (for malloc) */
+
  sqlite3_file *pFile,            /* File to write to */
+
  FileWriter *p,                  /* Object to populate */
+
  i64 iStart                      /* Offset of pFile to begin writing at */
+
){
+
  int nBuf = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
+

+
  memset(p, 0, sizeof(FileWriter));
+
  p->aBuffer = (u8 *)sqlite3DbMallocRaw(db, nBuf);
+
  if( !p->aBuffer ){
+
    p->eFWErr = SQLITE_NOMEM;
+
  }else{
+
    p->iBufEnd = p->iBufStart = (iStart % nBuf);
+
    p->iWriteOff = iStart - p->iBufStart;
+
    p->nBuffer = nBuf;
+
    p->pFile = pFile;
+
  }
+
}
+

+
/*
+
** Write nData bytes of data to the file-write object. Return SQLITE_OK
+
** if successful, or an SQLite error code if an error occurs.
+
*/
+
static void fileWriterWrite(FileWriter *p, u8 *pData, int nData){
+
  int nRem = nData;
+
  while( nRem>0 && p->eFWErr==0 ){
+
    int nCopy = nRem;
+
    if( nCopy>(p->nBuffer - p->iBufEnd) ){
+
      nCopy = p->nBuffer - p->iBufEnd;
+
    }
+

+
    memcpy(&p->aBuffer[p->iBufEnd], &pData[nData-nRem], nCopy);
+
    p->iBufEnd += nCopy;
+
    if( p->iBufEnd==p->nBuffer ){
+
      p->eFWErr = sqlite3OsWrite(p->pFile, 
+
          &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, 
+
          p->iWriteOff + p->iBufStart
+
      );
+
      p->iBufStart = p->iBufEnd = 0;
+
      p->iWriteOff += p->nBuffer;
+
    }
+
    assert( p->iBufEnd<p->nBuffer );
+

+
    nRem -= nCopy;
+
  }
+
}
+

+
/*
+
** Flush any buffered data to disk and clean up the file-writer object.
+
** The results of using the file-writer after this call are undefined.
+
** Return SQLITE_OK if flushing the buffered data succeeds or is not 
+
** required. Otherwise, return an SQLite error code.
+
**
+
** Before returning, set *piEof to the offset immediately following the
+
** last byte written to the file.
+
*/
+
static int fileWriterFinish(sqlite3 *db, FileWriter *p, i64 *piEof){
+
  int rc;
+
  if( p->eFWErr==0 && ALWAYS(p->aBuffer) && p->iBufEnd>p->iBufStart ){
+
    p->eFWErr = sqlite3OsWrite(p->pFile, 
+
        &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, 
+
        p->iWriteOff + p->iBufStart
+
    );
+
  }
+
  *piEof = (p->iWriteOff + p->iBufEnd);
+
  sqlite3DbFree(db, p->aBuffer);
+
  rc = p->eFWErr;
+
  memset(p, 0, sizeof(FileWriter));
+
  return rc;
+
}
+

+
/*
+
** Write value iVal encoded as a varint to the file-write object. Return 
+
** SQLITE_OK if successful, or an SQLite error code if an error occurs.
+
*/
+
static void fileWriterWriteVarint(FileWriter *p, u64 iVal){
+
  int nByte; 
+
  u8 aByte[10];
+
  nByte = sqlite3PutVarint(aByte, iVal);
+
  fileWriterWrite(p, aByte, nByte);
+
}

/*
** Write the current contents of the in-memory linked-list to a PMA. Return
@@ -73094,9 +70981,12 @@ static int vdbeSorterSort(VdbeCursor *pCsr){
**       Each record consists of a varint followed by a blob of data (the 
**       key). The varint is the number of bytes in the blob of data.
*/
-
static int vdbeSorterListToPMA(sqlite3 *db, VdbeCursor *pCsr){
+
static int vdbeSorterListToPMA(sqlite3 *db, const VdbeCursor *pCsr){
  int rc = SQLITE_OK;             /* Return code */
  VdbeSorter *pSorter = pCsr->pSorter;
+
  FileWriter writer;
+

+
  memset(&writer, 0, sizeof(FileWriter));

  if( pSorter->nInMemory==0 ){
    assert( pSorter->pRecord==0 );
@@ -73114,39 +71004,20 @@ static int vdbeSorterListToPMA(sqlite3 *db, VdbeCursor *pCsr){
  }

  if( rc==SQLITE_OK ){
-
    i64 iOff = pSorter->iWriteOff;
    SorterRecord *p;
    SorterRecord *pNext = 0;
-
    static const char eightZeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };

+
    fileWriterInit(db, pSorter->pTemp1, &writer, pSorter->iWriteOff);
    pSorter->nPMA++;
-
    rc = vdbeSorterWriteVarint(pSorter->pTemp1, pSorter->nInMemory, &iOff);
-
    for(p=pSorter->pRecord; rc==SQLITE_OK && p; p=pNext){
+
    fileWriterWriteVarint(&writer, pSorter->nInMemory);
+
    for(p=pSorter->pRecord; p; p=pNext){
      pNext = p->pNext;
-
      rc = vdbeSorterWriteVarint(pSorter->pTemp1, p->nVal, &iOff);
-

-
      if( rc==SQLITE_OK ){
-
        rc = sqlite3OsWrite(pSorter->pTemp1, p->pVal, p->nVal, iOff);
-
        iOff += p->nVal;
-
      }
-

+
      fileWriterWriteVarint(&writer, p->nVal);
+
      fileWriterWrite(&writer, p->pVal, p->nVal);
      sqlite3DbFree(db, p);
    }
-

-
    /* This assert verifies that unless an error has occurred, the size of 
-
    ** the PMA on disk is the same as the expected size stored in
-
    ** pSorter->nInMemory. */ 
-
    assert( rc!=SQLITE_OK || pSorter->nInMemory==(
-
          iOff-pSorter->iWriteOff-sqlite3VarintLen(pSorter->nInMemory)
-
    ));
-

-
    pSorter->iWriteOff = iOff;
-
    if( rc==SQLITE_OK ){
-
      /* Terminate each file with 8 extra bytes so that from any offset
-
      ** in the file we can always read 9 bytes without a SHORT_READ error */
-
      rc = sqlite3OsWrite(pSorter->pTemp1, eightZeros, 8, iOff);
-
    }
    pSorter->pRecord = p;
+
    rc = fileWriterFinish(db, &writer, &pSorter->iWriteOff);
  }

  return rc;
@@ -73157,7 +71028,7 @@ static int vdbeSorterListToPMA(sqlite3 *db, VdbeCursor *pCsr){
*/
SQLITE_PRIVATE int sqlite3VdbeSorterWrite(
  sqlite3 *db,                    /* Database handle */
-
  VdbeCursor *pCsr,               /* Sorter cursor */
+
  const VdbeCursor *pCsr,               /* Sorter cursor */
  Mem *pVal                       /* Memory cell containing record */
){
  VdbeSorter *pSorter = pCsr->pSorter;
@@ -73191,8 +71062,14 @@ SQLITE_PRIVATE int sqlite3VdbeSorterWrite(
        (pSorter->nInMemory>pSorter->mxPmaSize)
     || (pSorter->nInMemory>pSorter->mnPmaSize && sqlite3HeapNearlyFull())
  )){
+
#ifdef SQLITE_DEBUG
+
    i64 nExpect = pSorter->iWriteOff
+
                + sqlite3VarintLen(pSorter->nInMemory)
+
                + pSorter->nInMemory;
+
#endif
    rc = vdbeSorterListToPMA(db, pCsr);
    pSorter->nInMemory = 0;
+
    assert( rc!=SQLITE_OK || (nExpect==pSorter->iWriteOff) );
  }

  return rc;
@@ -73203,7 +71080,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterWrite(
*/
static int vdbeSorterInitMerge(
  sqlite3 *db,                    /* Database handle */
-
  VdbeCursor *pCsr,               /* Cursor handle for this sorter */
+
  const VdbeCursor *pCsr,         /* Cursor handle for this sorter */
  i64 *pnByte                     /* Sum of bytes in all opened PMAs */
){
  VdbeSorter *pSorter = pCsr->pSorter;
@@ -73233,7 +71110,7 @@ static int vdbeSorterInitMerge(
** Once the sorter has been populated, this function is called to prepare
** for iterating through its contents in sorted order.
*/
-
SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){
+
SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){
  VdbeSorter *pSorter = pCsr->pSorter;
  int rc;                         /* Return code */
  sqlite3_file *pTemp2 = 0;       /* Second temp file to use */
@@ -73253,7 +71130,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, VdbeCursor *pCsr, int *p
    return vdbeSorterSort(pCsr);
  }

-
  /* Write the current b-tree to a PMA. Close the b-tree cursor. */
+
  /* Write the current in-memory list to a PMA. */
  rc = vdbeSorterListToPMA(db, pCsr);
  if( rc!=SQLITE_OK ) return rc;

@@ -73275,8 +71152,12 @@ SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, VdbeCursor *pCsr, int *p
        rc==SQLITE_OK && iNew*SORTER_MAX_MERGE_COUNT<pSorter->nPMA; 
        iNew++
    ){
+
      int rc2;                    /* Return code from fileWriterFinish() */
+
      FileWriter writer;          /* Object used to write to disk */
      i64 nWrite;                 /* Number of bytes in new PMA */

+
      memset(&writer, 0, sizeof(FileWriter));
+

      /* If there are SORTER_MAX_MERGE_COUNT or less PMAs in file pTemp1,
      ** initialize an iterator for each of them and break out of the loop.
      ** These iterators will be incrementally merged as the VDBE layer calls
@@ -73299,22 +71180,19 @@ SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, VdbeCursor *pCsr, int *p
      }

      if( rc==SQLITE_OK ){
-
        rc = vdbeSorterWriteVarint(pTemp2, nWrite, &iWrite2);
-
      }
-

-
      if( rc==SQLITE_OK ){
        int bEof = 0;
+
        fileWriterInit(db, pTemp2, &writer, iWrite2);
+
        fileWriterWriteVarint(&writer, nWrite);
        while( rc==SQLITE_OK && bEof==0 ){
-
          int nToWrite;
          VdbeSorterIter *pIter = &pSorter->aIter[ pSorter->aTree[1] ];
          assert( pIter->pFile );
-
          nToWrite = pIter->nKey + sqlite3VarintLen(pIter->nKey);
-
          rc = sqlite3OsWrite(pTemp2, pIter->aAlloc, nToWrite, iWrite2);
-
          iWrite2 += nToWrite;
-
          if( rc==SQLITE_OK ){
-
            rc = sqlite3VdbeSorterNext(db, pCsr, &bEof);
-
          }
+

+
          fileWriterWriteVarint(&writer, pIter->nKey);
+
          fileWriterWrite(&writer, pIter->aKey, pIter->nKey);
+
          rc = sqlite3VdbeSorterNext(db, pCsr, &bEof);
        }
+
        rc2 = fileWriterFinish(db, &writer, &iWrite2);
+
        if( rc==SQLITE_OK ) rc = rc2;
      }
    }

@@ -73341,7 +71219,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, VdbeCursor *pCsr, int *p
/*
** Advance to the next element in the sorter.
*/
-
SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){
+
SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){
  VdbeSorter *pSorter = pCsr->pSorter;
  int rc;                         /* Return code */

@@ -73371,7 +71249,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, VdbeCursor *pCsr, int *pbE
** current key.
*/
static void *vdbeSorterRowkey(
-
  VdbeSorter *pSorter,            /* Sorter object */
+
  const VdbeSorter *pSorter,      /* Sorter object */
  int *pnKey                      /* OUT: Size of current key in bytes */
){
  void *pKey;
@@ -73390,7 +71268,7 @@ static void *vdbeSorterRowkey(
/*
** Copy the current sorter key into the memory cell pOut.
*/
-
SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(VdbeCursor *pCsr, Mem *pOut){
+
SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){
  VdbeSorter *pSorter = pCsr->pSorter;
  void *pKey; int nKey;           /* Sorter key to copy into pOut */

@@ -73416,7 +71294,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(VdbeCursor *pCsr, Mem *pOut){
** key.
*/
SQLITE_PRIVATE int sqlite3VdbeSorterCompare(
-
  VdbeCursor *pCsr,               /* Sorter cursor */
+
  const VdbeCursor *pCsr,         /* Sorter cursor */
  Mem *pVal,                      /* Value to compare to current sorter key */
  int *pRes                       /* OUT: Result of comparison */
){
@@ -74059,13 +71937,19 @@ SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){
  int rc;
  if( p==0 || pWalker->xSelectCallback==0 ) return WRC_Continue;
  rc = WRC_Continue;
-
  while( p  ){
+
  pWalker->walkerDepth++;
+
  while( p ){
    rc = pWalker->xSelectCallback(pWalker, p);
    if( rc ) break;
-
    if( sqlite3WalkSelectExpr(pWalker, p) ) return WRC_Abort;
-
    if( sqlite3WalkSelectFrom(pWalker, p) ) return WRC_Abort;
+
    if( sqlite3WalkSelectExpr(pWalker, p)
+
     || sqlite3WalkSelectFrom(pWalker, p)
+
    ){
+
      pWalker->walkerDepth--;
+
      return WRC_Abort;
+
    }
    p = p->pPrior;
  }
+
  pWalker->walkerDepth--;
  return rc & WRC_Abort;
}

@@ -74091,6 +71975,29 @@ SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){
/* #include <string.h> */

/*
+
** Walk the expression tree pExpr and increase the aggregate function
+
** depth (the Expr.op2 field) by N on every TK_AGG_FUNCTION node.
+
** This needs to occur when copying a TK_AGG_FUNCTION node from an
+
** outer query into an inner subquery.
+
**
+
** incrAggFunctionDepth(pExpr,n) is the main routine.  incrAggDepth(..)
+
** is a helper function - a callback for the tree walker.
+
*/
+
static int incrAggDepth(Walker *pWalker, Expr *pExpr){
+
  if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.i;
+
  return WRC_Continue;
+
}
+
static void incrAggFunctionDepth(Expr *pExpr, int N){
+
  if( N>0 ){
+
    Walker w;
+
    memset(&w, 0, sizeof(w));
+
    w.xExprCallback = incrAggDepth;
+
    w.u.i = N;
+
    sqlite3WalkExpr(&w, pExpr);
+
  }
+
}
+

+
/*
** Turn the pExpr expression into an alias for the iCol-th column of the
** result set in pEList.
**
@@ -74116,13 +72023,20 @@ SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){
** The result of random()%5 in the GROUP BY clause is probably different
** from the result in the result-set.  We might fix this someday.  Or
** then again, we might not...
+
**
+
** The nSubquery parameter specifies how many levels of subquery the
+
** alias is removed from the original expression.  The usually value is
+
** zero but it might be more if the alias is contained within a subquery
+
** of the original expression.  The Expr.op2 field of TK_AGG_FUNCTION
+
** structures must be increased by the nSubquery amount.
*/
static void resolveAlias(
  Parse *pParse,         /* Parsing context */
  ExprList *pEList,      /* A result set */
  int iCol,              /* A column in the result set.  0..pEList->nExpr-1 */
  Expr *pExpr,           /* Transform this into an alias to the result set */
-
  const char *zType      /* "GROUP" or "ORDER" or "" */
+
  const char *zType,     /* "GROUP" or "ORDER" or "" */
+
  int nSubquery          /* Number of subqueries that the label is moving */
){
  Expr *pOrig;           /* The iCol-th column of the result set */
  Expr *pDup;            /* Copy of pOrig */
@@ -74135,6 +72049,7 @@ static void resolveAlias(
  db = pParse->db;
  if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){
    pDup = sqlite3ExprDup(db, pOrig, 0);
+
    incrAggFunctionDepth(pDup, nSubquery);
    pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0);
    if( pDup==0 ) return;
    if( pEList->a[iCol].iAlias==0 ){
@@ -74223,9 +72138,10 @@ static int lookupName(
  NameContext *pNC,    /* The name context used to resolve the name */
  Expr *pExpr          /* Make this EXPR node point to the selected column */
){
-
  int i, j;            /* Loop counters */
+
  int i, j;                         /* Loop counters */
  int cnt = 0;                      /* Number of matching column names */
  int cntTab = 0;                   /* Number of matching table names */
+
  int nSubquery = 0;                /* How many levels of subquery */
  sqlite3 *db = pParse->db;         /* The database connection */
  struct SrcList_item *pItem;       /* Use for looping over pSrcList items */
  struct SrcList_item *pMatch = 0;  /* The matching pSrcList item */
@@ -74387,7 +72303,7 @@ static int lookupName(
            sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
            return WRC_Abort;
          }
-
          resolveAlias(pParse, pEList, j, pExpr, "");
+
          resolveAlias(pParse, pEList, j, pExpr, "", nSubquery);
          cnt = 1;
          pMatch = 0;
          assert( zTab==0 && zDb==0 );
@@ -74401,6 +72317,7 @@ static int lookupName(
    */
    if( cnt==0 ){
      pNC = pNC->pNext;
+
      nSubquery++;
    }
  }

@@ -74640,13 +72557,19 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
             nId, zId);
        pNC->nErr++;
      }
+
      if( is_agg ) pNC->ncFlags &= ~NC_AllowAgg;
+
      sqlite3WalkExprList(pWalker, pList);
      if( is_agg ){
+
        NameContext *pNC2 = pNC;
        pExpr->op = TK_AGG_FUNCTION;
-
        pNC->ncFlags |= NC_HasAgg;
+
        pExpr->op2 = 0;
+
        while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){
+
          pExpr->op2++;
+
          pNC2 = pNC2->pNext;
+
        }
+
        if( pNC2 ) pNC2->ncFlags |= NC_HasAgg;
+
        pNC->ncFlags |= NC_AllowAgg;
      }
-
      if( is_agg ) pNC->ncFlags &= ~NC_AllowAgg;
-
      sqlite3WalkExprList(pWalker, pList);
-
      if( is_agg ) pNC->ncFlags |= NC_AllowAgg;
      /* FIX ME:  Compute pExpr->affinity based on the expected return
      ** type of the function 
      */
@@ -74925,7 +72848,7 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(
        resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr);
        return 1;
      }
-
      resolveAlias(pParse, pEList, pItem->iOrderByCol-1, pItem->pExpr, zType);
+
      resolveAlias(pParse, pEList, pItem->iOrderByCol-1, pItem->pExpr, zType,0);
    }
  }
  return 0;
@@ -77003,7 +74926,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(

        assert( !isRowid );
        sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
-
        dest.affinity = (u8)affinity;
+
        dest.affSdst = (u8)affinity;
        assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
        pExpr->x.pSelect->iLimit = 0;
        if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){
@@ -77096,11 +75019,11 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
      sqlite3SelectDestInit(&dest, 0, ++pParse->nMem);
      if( pExpr->op==TK_SELECT ){
        dest.eDest = SRT_Mem;
-
        sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iParm);
+
        sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iSDParm);
        VdbeComment((v, "Init subquery result"));
      }else{
        dest.eDest = SRT_Exists;
-
        sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iParm);
+
        sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
        VdbeComment((v, "Init EXISTS result"));
      }
      sqlite3ExprDelete(pParse->db, pSel->pLimit);
@@ -77110,7 +75033,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
      if( sqlite3Select(pParse, pSel, &dest) ){
        return 0;
      }
-
      rReg = dest.iParm;
+
      rReg = dest.iSDParm;
      ExprSetIrreducible(pExpr);
      break;
    }
@@ -78425,9 +76348,12 @@ SQLITE_PRIVATE void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){
      }else{
        pFarg = pExpr->x.pList;
      }
-
      sqlite3ExplainPrintf(pOut, "%sFUNCTION:%s(",
-
                           op==TK_AGG_FUNCTION ? "AGG_" : "",
-
                           pExpr->u.zToken);
+
      if( op==TK_AGG_FUNCTION ){
+
        sqlite3ExplainPrintf(pOut, "AGG_FUNCTION%d:%s(",
+
                             pExpr->op2, pExpr->u.zToken);
+
      }else{
+
        sqlite3ExplainPrintf(pOut, "FUNCTION:%s(", pExpr->u.zToken);
+
      }
      if( pFarg ){
        sqlite3ExplainExprList(pOut, pFarg);
      }
@@ -79118,38 +77044,60 @@ SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB){
}

/*
-
** This is the expression callback for sqlite3FunctionUsesOtherSrc().
-
**
-
** Determine if an expression references any table other than one of the
-
** tables in pWalker->u.pSrcList and abort if it does.
+
** An instance of the following structure is used by the tree walker
+
** to count references to table columns in the arguments of an 
+
** aggregate function, in order to implement the
+
** sqlite3FunctionThisSrc() routine.
*/
-
static int exprUsesOtherSrc(Walker *pWalker, Expr *pExpr){
-
  if( pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN ){
+
struct SrcCount {
+
  SrcList *pSrc;   /* One particular FROM clause in a nested query */
+
  int nThis;       /* Number of references to columns in pSrcList */
+
  int nOther;      /* Number of references to columns in other FROM clauses */
+
};
+

+
/*
+
** Count the number of references to columns.
+
*/
+
static int exprSrcCount(Walker *pWalker, Expr *pExpr){
+
  /* The NEVER() on the second term is because sqlite3FunctionUsesThisSrc()
+
  ** is always called before sqlite3ExprAnalyzeAggregates() and so the
+
  ** TK_COLUMNs have not yet been converted into TK_AGG_COLUMN.  If
+
  ** sqlite3FunctionUsesThisSrc() is used differently in the future, the
+
  ** NEVER() will need to be removed. */
+
  if( pExpr->op==TK_COLUMN || NEVER(pExpr->op==TK_AGG_COLUMN) ){
    int i;
-
    SrcList *pSrc = pWalker->u.pSrcList;
+
    struct SrcCount *p = pWalker->u.pSrcCount;
+
    SrcList *pSrc = p->pSrc;
    for(i=0; i<pSrc->nSrc; i++){
-
      if( pExpr->iTable==pSrc->a[i].iCursor ) return WRC_Continue;
+
      if( pExpr->iTable==pSrc->a[i].iCursor ) break;
+
    }
+
    if( i<pSrc->nSrc ){
+
      p->nThis++;
+
    }else{
+
      p->nOther++;
    }
-
    return WRC_Abort;
-
  }else{
-
    return WRC_Continue;
  }
+
  return WRC_Continue;
}

/*
-
** Determine if any of the arguments to the pExpr Function references
-
** any SrcList other than pSrcList.  Return true if they do.  Return
-
** false if pExpr has no argument or has only constant arguments or
-
** only references tables named in pSrcList.
+
** Determine if any of the arguments to the pExpr Function reference
+
** pSrcList.  Return true if they do.  Also return true if the function
+
** has no arguments or has only constant arguments.  Return false if pExpr
+
** references columns but not columns of tables found in pSrcList.
*/
-
static int sqlite3FunctionUsesOtherSrc(Expr *pExpr, SrcList *pSrcList){
+
SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){
  Walker w;
+
  struct SrcCount cnt;
  assert( pExpr->op==TK_AGG_FUNCTION );
  memset(&w, 0, sizeof(w));
-
  w.xExprCallback = exprUsesOtherSrc;
-
  w.u.pSrcList = pSrcList;
-
  if( sqlite3WalkExprList(&w, pExpr->x.pList)!=WRC_Continue ) return 1;
-
  return 0;
+
  w.xExprCallback = exprSrcCount;
+
  w.u.pSrcCount = &cnt;
+
  cnt.pSrc = pSrcList;
+
  cnt.nThis = 0;
+
  cnt.nOther = 0;
+
  sqlite3WalkExprList(&w, pExpr->x.pList);
+
  return cnt.nThis>0 || cnt.nOther==0;
}

/*
@@ -79268,7 +77216,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
    }
    case TK_AGG_FUNCTION: {
      if( (pNC->ncFlags & NC_InAggFunc)==0
-
       && !sqlite3FunctionUsesOtherSrc(pExpr, pSrcList)
+
       && pWalker->walkerDepth==pExpr->op2
      ){
        /* Check to see if pExpr is a duplicate of another aggregate 
        ** function that is already in the pAggInfo structure
@@ -80424,7 +78372,7 @@ static void openStatTable(
          "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols
      );
      aRoot[i] = pParse->regRoot;
-
      aCreateTbl[i] = 1;
+
      aCreateTbl[i] = OPFLAG_P2ISREG;
    }else{
      /* The table already exists. If zWhere is not NULL, delete all entries 
      ** associated with the table zWhere. If zWhere is NULL, delete the
@@ -80504,12 +78452,11 @@ static void stat3Init(
  nRow = (tRowcnt)sqlite3_value_int64(argv[0]);
  mxSample = sqlite3_value_int(argv[1]);
  n = sizeof(*p) + sizeof(p->a[0])*mxSample;
-
  p = sqlite3_malloc( n );
+
  p = sqlite3MallocZero( n );
  if( p==0 ){
    sqlite3_result_error_nomem(context);
    return;
  }
-
  memset(p, 0, n);
  p->a = (struct Stat3Sample*)&p[1];
  p->nRow = nRow;
  p->mxSample = mxSample;
@@ -82719,7 +80666,7 @@ SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
    if( !db || db->pnBytesFreed==0 ){
      char *zName = pIndex->zName; 
      TESTONLY ( Index *pOld = ) sqlite3HashInsert(
-
	  &pIndex->pSchema->idxHash, zName, sqlite3Strlen30(zName), 0
+
         &pIndex->pSchema->idxHash, zName, sqlite3Strlen30(zName), 0
      );
      assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
      assert( pOld==pIndex || pOld==0 );
@@ -83766,7 +81713,7 @@ SQLITE_PRIVATE void sqlite3EndTable(

      assert(pParse->nTab==1);
      sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb);
-
      sqlite3VdbeChangeP5(v, 1);
+
      sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG);
      pParse->nTab = 2;
      sqlite3SelectDestInit(&dest, SRT_Table, 1);
      sqlite3Select(pParse, pSelect, &dest);
@@ -84582,9 +82529,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
  pKey = sqlite3IndexKeyinfo(pParse, pIndex);
  sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, 
                    (char *)pKey, P4_KEYINFO_HANDOFF);
-
  if( memRootPage>=0 ){
-
    sqlite3VdbeChangeP5(v, 1);
-
  }
+
  sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));

#ifndef SQLITE_OMIT_MERGE_SORT
  /* Open the sorter cursor if we are to use one. */
@@ -84723,7 +82668,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
    assert( pName && pName->z );

#ifndef SQLITE_OMIT_TEMPDB
-
    /* If the index name was unqualified, check if the the table
+
    /* If the index name was unqualified, check if the table
    ** is a temp table. If so, set the database to 1. Do not do this
    ** if initialising a database schema.
    */
@@ -86877,7 +84822,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
    */
    sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet);
    pWInfo = sqlite3WhereBegin(
-
        pParse, pTabList, pWhere, 0, 0, WHERE_DUPLICATES_OK
+
        pParse, pTabList, pWhere, 0, 0, WHERE_DUPLICATES_OK, 0
    );
    if( pWInfo==0 ) goto delete_from_cleanup;
    regRowid = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, iRowid, 0);
@@ -88021,8 +85966,19 @@ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  assert( argc==1 );
  UNUSED_PARAMETER(argc);
  switch( sqlite3_value_type(argv[0]) ){
-
    case SQLITE_INTEGER:
    case SQLITE_FLOAT: {
+
      double r1, r2;
+
      char zBuf[50];
+
      r1 = sqlite3_value_double(argv[0]);
+
      sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.15g", r1);
+
      sqlite3AtoF(zBuf, &r2, 20, SQLITE_UTF8);
+
      if( r1!=r2 ){
+
        sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.20e", r1);
+
      }
+
      sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
+
      break;
+
    }
+
    case SQLITE_INTEGER: {
      sqlite3_result_value(context, argv[0]);
      break;
    }
@@ -89334,7 +87290,7 @@ static void fkScanChildren(
  ** clause. If the constraint is not deferred, throw an exception for
  ** each row found. Otherwise, for deferred constraints, increment the
  ** deferred constraint counter by nIncr for each row selected.  */
-
  pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0);
+
  pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0);
  if( nIncr>0 && pFKey->isDeferred==0 ){
    sqlite3ParseToplevel(pParse)->mayAbort = 1;
  }
@@ -90592,7 +88548,7 @@ SQLITE_PRIVATE void sqlite3Insert(
    VdbeComment((v, "SELECT eof flag"));
    sqlite3SelectDestInit(&dest, SRT_Coroutine, ++pParse->nMem);
    addrSelect = sqlite3VdbeCurrentAddr(v)+2;
-
    sqlite3VdbeAddOp2(v, OP_Integer, addrSelect-1, dest.iParm);
+
    sqlite3VdbeAddOp2(v, OP_Integer, addrSelect-1, dest.iSDParm);
    j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
    VdbeComment((v, "Jump over SELECT coroutine"));

@@ -90603,15 +88559,15 @@ SQLITE_PRIVATE void sqlite3Insert(
      goto insert_cleanup;
    }
    sqlite3VdbeAddOp2(v, OP_Integer, 1, regEof);         /* EOF <- 1 */
-
    sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm);   /* yield X */
+
    sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);   /* yield X */
    sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_INTERNAL, OE_Abort);
    VdbeComment((v, "End of SELECT coroutine"));
    sqlite3VdbeJumpHere(v, j1);                          /* label B: */

-
    regFromSelect = dest.iMem;
+
    regFromSelect = dest.iSdst;
    assert( pSelect->pEList );
    nColumn = pSelect->pEList->nExpr;
-
    assert( dest.nMem==nColumn );
+
    assert( dest.nSdst==nColumn );

    /* Set useTempTable to TRUE if the result of the SELECT statement
    ** should be written into a temporary table (template 4).  Set to
@@ -90647,7 +88603,7 @@ SQLITE_PRIVATE void sqlite3Insert(
      regRec = sqlite3GetTempReg(pParse);
      regTempRowid = sqlite3GetTempReg(pParse);
      sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn);
-
      addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm);
+
      addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
      addrIf = sqlite3VdbeAddOp1(v, OP_If, regEof);
      sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec);
      sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid);
@@ -90784,7 +88740,7 @@ SQLITE_PRIVATE void sqlite3Insert(
    **         goto C
    **      D: ...
    */
-
    addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm);
+
    addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
    addrInsTop = sqlite3VdbeAddOp1(v, OP_If, regEof);
  }

@@ -91266,7 +89222,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
      case OE_Replace: {
        /* If there are DELETE triggers on this table and the
        ** recursive-triggers flag is set, call GenerateRowDelete() to
-
        ** remove the conflicting row from the the table. This will fire
+
        ** remove the conflicting row from the table. This will fire
        ** the triggers and remove both the table and index b-tree entries.
        **
        ** Otherwise, if there are no triggers or the recursive-triggers
@@ -94267,6 +92223,19 @@ SQLITE_PRIVATE void sqlite3Pragma(

    int isQuick = (sqlite3Tolower(zLeft[0])=='q');

+
    /* If the PRAGMA command was of the form "PRAGMA <db>.integrity_check",
+
    ** then iDb is set to the index of the database identified by <db>.
+
    ** In this case, the integrity of database iDb only is verified by
+
    ** the VDBE created below.
+
    **
+
    ** Otherwise, if the command was simply "PRAGMA integrity_check" (or
+
    ** "PRAGMA quick_check"), then iDb is set to 0. In this case, set iDb
+
    ** to -1 here, to indicate that the VDBE should verify the integrity
+
    ** of all attached databases.  */
+
    assert( iDb>=0 );
+
    assert( iDb==0 || pId2->z );
+
    if( pId2->z==0 ) iDb = -1;
+

    /* Initialize the VDBE program */
    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
    pParse->nMem = 6;
@@ -94290,6 +92259,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
      int cnt = 0;

      if( OMIT_TEMPDB && i==1 ) continue;
+
      if( iDb>=0 && i!=iDb ) continue;

      sqlite3CodeVerifySchema(pParse, i);
      addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */
@@ -94301,7 +92271,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
      ** Begin by filling registers 2, 3, ... with the root pages numbers
      ** for all tables and indices in the database.
      */
-
      assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+
      assert( sqlite3SchemaMutexHeld(db, i, 0) );
      pTbls = &db->aDb[i].pSchema->tblHash;
      for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
        Table *pTab = sqliteHashData(x);
@@ -95625,10 +93595,10 @@ static void clearSelect(sqlite3 *db, Select *p){
*/
SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){
  pDest->eDest = (u8)eDest;
-
  pDest->iParm = iParm;
-
  pDest->affinity = 0;
-
  pDest->iMem = 0;
-
  pDest->nMem = 0;
+
  pDest->iSDParm = iParm;
+
  pDest->affSdst = 0;
+
  pDest->iSdst = 0;
+
  pDest->nSdst = 0;
}


@@ -96140,7 +94110,7 @@ static void selectInnerLoop(
  int hasDistinct;        /* True if the DISTINCT keyword is present */
  int regResult;              /* Start of memory holding result set */
  int eDest = pDest->eDest;   /* How to dispose of results */
-
  int iParm = pDest->iParm;   /* First argument to disposal method */
+
  int iParm = pDest->iSDParm; /* First argument to disposal method */
  int nResultCol;             /* Number of result columns */

  assert( v );
@@ -96158,14 +94128,14 @@ static void selectInnerLoop(
  }else{
    nResultCol = pEList->nExpr;
  }
-
  if( pDest->iMem==0 ){
-
    pDest->iMem = pParse->nMem+1;
-
    pDest->nMem = nResultCol;
+
  if( pDest->iSdst==0 ){
+
    pDest->iSdst = pParse->nMem+1;
+
    pDest->nSdst = nResultCol;
    pParse->nMem += nResultCol;
  }else{ 
-
    assert( pDest->nMem==nResultCol );
+
    assert( pDest->nSdst==nResultCol );
  }
-
  regResult = pDest->iMem;
+
  regResult = pDest->iSdst;
  if( nColumn>0 ){
    for(i=0; i<nColumn; i++){
      sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i);
@@ -96244,7 +94214,7 @@ static void selectInnerLoop(
    */
    case SRT_Set: {
      assert( nColumn==1 );
-
      p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affinity);
+
      p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst);
      if( pOrderBy ){
        /* At first glance you would think we could optimize out the
        ** ORDER BY in this case since the order of entries in the set
@@ -96299,7 +94269,7 @@ static void selectInnerLoop(
        pushOntoSorter(pParse, pOrderBy, p, r1);
        sqlite3ReleaseTempReg(pParse, r1);
      }else if( eDest==SRT_Coroutine ){
-
        sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm);
+
        sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
      }else{
        sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nColumn);
        sqlite3ExprCacheAffinityChange(pParse, regResult, nColumn);
@@ -96479,7 +94449,7 @@ static void generateSortTail(
  ExprList *pOrderBy = p->pOrderBy;

  int eDest = pDest->eDest;
-
  int iParm = pDest->iParm;
+
  int iParm = pDest->iSDParm;

  int regRow;
  int regRowid;
@@ -96538,17 +94508,17 @@ static void generateSortTail(
      testcase( eDest==SRT_Output );
      testcase( eDest==SRT_Coroutine );
      for(i=0; i<nColumn; i++){
-
        assert( regRow!=pDest->iMem+i );
-
        sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iMem+i);
+
        assert( regRow!=pDest->iSdst+i );
+
        sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iSdst+i);
        if( i==0 ){
          sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
        }
      }
      if( eDest==SRT_Output ){
-
        sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iMem, nColumn);
-
        sqlite3ExprCacheAffinityChange(pParse, pDest->iMem, nColumn);
+
        sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iSdst, nColumn);
+
        sqlite3ExprCacheAffinityChange(pParse, pDest->iSdst, nColumn);
      }else{
-
        sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm);
+
        sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
      }
      break;
    }
@@ -97199,7 +95169,7 @@ static int multiSelect(
  */
  if( dest.eDest==SRT_EphemTab ){
    assert( p->pEList );
-
    sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iParm, p->pEList->nExpr);
+
    sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iSDParm, p->pEList->nExpr);
    sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
    dest.eDest = SRT_Table;
  }
@@ -97285,7 +95255,7 @@ static int multiSelect(
                                     ** of a 3-way or more compound */
        assert( p->pLimit==0 );      /* Not allowed on leftward elements */
        assert( p->pOffset==0 );     /* Not allowed on leftward elements */
-
        unionTab = dest.iParm;
+
        unionTab = dest.iSDParm;
      }else{
        /* We will need to create our own temporary table to hold the
        ** intermediate results.
@@ -97342,7 +95312,7 @@ static int multiSelect(
      /* Convert the data in the temporary table into whatever form
      ** it is that we currently need.
      */
-
      assert( unionTab==dest.iParm || dest.eDest!=priorOp );
+
      assert( unionTab==dest.iSDParm || dest.eDest!=priorOp );
      if( dest.eDest!=priorOp ){
        int iCont, iBreak, iStart;
        assert( p->pEList );
@@ -97406,7 +95376,7 @@ static int multiSelect(
      p->pLimit = 0;
      pOffset = p->pOffset;
      p->pOffset = 0;
-
      intersectdest.iParm = tab2;
+
      intersectdest.iSDParm = tab2;
      explainSetInteger(iSub2, pParse->iNextSelectId);
      rc = sqlite3Select(pParse, p, &intersectdest);
      testcase( rc!=SQLITE_OK );
@@ -97500,8 +95470,8 @@ static int multiSelect(
  }

multi_select_end:
-
  pDest->iMem = dest.iMem;
-
  pDest->nMem = dest.nMem;
+
  pDest->iSdst = dest.iSdst;
+
  pDest->nSdst = dest.nSdst;
  sqlite3SelectDelete(db, pDelete);
  return rc;
}
@@ -97511,8 +95481,8 @@ multi_select_end:
** Code an output subroutine for a coroutine implementation of a
** SELECT statment.
**
-
** The data to be output is contained in pIn->iMem.  There are
-
** pIn->nMem columns to be output.  pDest is where the output should
+
** The data to be output is contained in pIn->iSdst.  There are
+
** pIn->nSdst columns to be output.  pDest is where the output should
** be sent.
**
** regReturn is the number of the register holding the subroutine
@@ -97550,16 +95520,16 @@ static int generateOutputSubroutine(
  if( regPrev ){
    int j1, j2;
    j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev);
-
    j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iMem, regPrev+1, pIn->nMem,
+
    j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst,
                              (char*)pKeyInfo, p4type);
    sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2);
    sqlite3VdbeJumpHere(v, j1);
-
    sqlite3ExprCodeCopy(pParse, pIn->iMem, regPrev+1, pIn->nMem);
+
    sqlite3ExprCodeCopy(pParse, pIn->iSdst, regPrev+1, pIn->nSdst);
    sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev);
  }
  if( pParse->db->mallocFailed ) return 0;

-
  /* Suppress the the first OFFSET entries if there is an OFFSET clause
+
  /* Suppress the first OFFSET entries if there is an OFFSET clause
  */
  codeOffset(v, p, iContinue);

@@ -97572,9 +95542,9 @@ static int generateOutputSubroutine(
      int r2 = sqlite3GetTempReg(pParse);
      testcase( pDest->eDest==SRT_Table );
      testcase( pDest->eDest==SRT_EphemTab );
-
      sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iMem, pIn->nMem, r1);
-
      sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iParm, r2);
-
      sqlite3VdbeAddOp3(v, OP_Insert, pDest->iParm, r1, r2);
+
      sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1);
+
      sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iSDParm, r2);
+
      sqlite3VdbeAddOp3(v, OP_Insert, pDest->iSDParm, r1, r2);
      sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
      sqlite3ReleaseTempReg(pParse, r2);
      sqlite3ReleaseTempReg(pParse, r1);
@@ -97588,13 +95558,13 @@ static int generateOutputSubroutine(
    */
    case SRT_Set: {
      int r1;
-
      assert( pIn->nMem==1 );
+
      assert( pIn->nSdst==1 );
      p->affinity = 
-
         sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affinity);
+
         sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affSdst);
      r1 = sqlite3GetTempReg(pParse);
-
      sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iMem, 1, r1, &p->affinity, 1);
-
      sqlite3ExprCacheAffinityChange(pParse, pIn->iMem, 1);
-
      sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iParm, r1);
+
      sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, 1, r1, &p->affinity, 1);
+
      sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, 1);
+
      sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iSDParm, r1);
      sqlite3ReleaseTempReg(pParse, r1);
      break;
    }
@@ -97603,7 +95573,7 @@ static int generateOutputSubroutine(
    /* If any row exist in the result set, record that fact and abort.
    */
    case SRT_Exists: {
-
      sqlite3VdbeAddOp2(v, OP_Integer, 1, pDest->iParm);
+
      sqlite3VdbeAddOp2(v, OP_Integer, 1, pDest->iSDParm);
      /* The LIMIT clause will terminate the loop for us */
      break;
    }
@@ -97614,23 +95584,23 @@ static int generateOutputSubroutine(
    ** of the scan loop.
    */
    case SRT_Mem: {
-
      assert( pIn->nMem==1 );
-
      sqlite3ExprCodeMove(pParse, pIn->iMem, pDest->iParm, 1);
+
      assert( pIn->nSdst==1 );
+
      sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, 1);
      /* The LIMIT clause will jump out of the loop for us */
      break;
    }
#endif /* #ifndef SQLITE_OMIT_SUBQUERY */

    /* The results are stored in a sequence of registers
-
    ** starting at pDest->iMem.  Then the co-routine yields.
+
    ** starting at pDest->iSdst.  Then the co-routine yields.
    */
    case SRT_Coroutine: {
-
      if( pDest->iMem==0 ){
-
        pDest->iMem = sqlite3GetTempRange(pParse, pIn->nMem);
-
        pDest->nMem = pIn->nMem;
+
      if( pDest->iSdst==0 ){
+
        pDest->iSdst = sqlite3GetTempRange(pParse, pIn->nSdst);
+
        pDest->nSdst = pIn->nSdst;
      }
-
      sqlite3ExprCodeMove(pParse, pIn->iMem, pDest->iMem, pDest->nMem);
-
      sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm);
+
      sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pDest->nSdst);
+
      sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
      break;
    }

@@ -97644,8 +95614,8 @@ static int generateOutputSubroutine(
    */
    default: {
      assert( pDest->eDest==SRT_Output );
-
      sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iMem, pIn->nMem);
-
      sqlite3ExprCacheAffinityChange(pParse, pIn->iMem, pIn->nMem);
+
      sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iSdst, pIn->nSdst);
+
      sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst);
      break;
    }
  }
@@ -98064,7 +96034,7 @@ static int multiSelectOrderBy(
  */
  sqlite3VdbeResolveLabel(v, labelCmpr);
  sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY);
-
  sqlite3VdbeAddOp4(v, OP_Compare, destA.iMem, destB.iMem, nOrderBy,
+
  sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy,
                         (char*)pKeyMerge, P4_KEYINFO_HANDOFF);
  sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);

@@ -98278,6 +96248,12 @@ static void substSelect(
**        operators have an implied DISTINCT which is disallowed by
**        restriction (4).
**
+
**        Also, each component of the sub-query must return the same number
+
**        of result columns. This is actually a requirement for any compound
+
**        SELECT statement, but all the code here does is make sure that no
+
**        such (illegal) sub-query is flattened. The caller will detect the
+
**        syntax error and return a detailed message.
+
**
**  (18)  If the sub-query is a compound select, then all terms of the
**        ORDER by clause of the parent must be simple references to 
**        columns of the sub-query.
@@ -98421,6 +96397,7 @@ static int flattenSubquery(
      if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0
       || (pSub1->pPrior && pSub1->op!=TK_ALL) 
       || pSub1->pSrc->nSrc<1
+
       || pSub->pEList->nExpr!=pSub1->pEList->nExpr
      ){
        return 0;
      }
@@ -98738,7 +96715,7 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){

  if( IsVirtual(pTab) ) return 0;
  if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
-
  if( pAggInfo->nFunc==0 ) return 0;
+
  if( NEVER(pAggInfo->nFunc==0) ) return 0;
  if( (pAggInfo->aFunc[0].pFunc->flags&SQLITE_FUNC_COUNT)==0 ) return 0;
  if( pExpr->flags&EP_Distinct ) return 0;

@@ -99110,7 +97087,7 @@ static void sqlite3SelectAddTypeInfo(Parse *pParse, Select *pSelect){


/*
-
** This routine sets of a SELECT statement for processing.  The
+
** This routine sets up a SELECT statement for processing.  The
** following is accomplished:
**
**     *  VDBE Cursor numbers are assigned to all FROM-clause terms.
@@ -99142,7 +97119,8 @@ SQLITE_PRIVATE void sqlite3SelectPrep(
**
** The aggregate accumulator is a set of memory cells that hold
** intermediate results while calculating an aggregate.  This
-
** routine simply stores NULLs in all of those memory cells.
+
** routine generates code that stores NULLs in all of those memory
+
** cells.
*/
static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
  Vdbe *v = pParse->pVdbe;
@@ -99310,23 +97288,24 @@ static void explainSimpleCount(
**
**     SRT_Mem         Only valid if the result is a single column.
**                     Store the first column of the first result row
-
**                     in register pDest->iParm then abandon the rest
+
**                     in register pDest->iSDParm then abandon the rest
**                     of the query.  This destination implies "LIMIT 1".
**
**     SRT_Set         The result must be a single column.  Store each
-
**                     row of result as the key in table pDest->iParm. 
-
**                     Apply the affinity pDest->affinity before storing
+
**                     row of result as the key in table pDest->iSDParm. 
+
**                     Apply the affinity pDest->affSdst before storing
**                     results.  Used to implement "IN (SELECT ...)".
**
-
**     SRT_Union       Store results as a key in a temporary table pDest->iParm.
+
**     SRT_Union       Store results as a key in a temporary table 
+
**                     identified by pDest->iSDParm.
**
-
**     SRT_Except      Remove results from the temporary table pDest->iParm.
+
**     SRT_Except      Remove results from the temporary table pDest->iSDParm.
**
-
**     SRT_Table       Store results in temporary table pDest->iParm.
+
**     SRT_Table       Store results in temporary table pDest->iSDParm.
**                     This is like SRT_EphemTab except that the table
**                     is assumed to already be open.
**
-
**     SRT_EphemTab    Create an temporary table pDest->iParm and store
+
**     SRT_EphemTab    Create an temporary table pDest->iSDParm and store
**                     the result there. The cursor is left open after
**                     returning.  This is like SRT_Table except that
**                     this destination uses OP_OpenEphemeral to create
@@ -99334,9 +97313,9 @@ static void explainSimpleCount(
**
**     SRT_Coroutine   Generate a co-routine that returns a new row of
**                     results each time it is invoked.  The entry point
-
**                     of the co-routine is stored in register pDest->iParm.
+
**                     of the co-routine is stored in register pDest->iSDParm.
**
-
**     SRT_Exists      Store a 1 in memory cell pDest->iParm if the result
+
**     SRT_Exists      Store a 1 in memory cell pDest->iSDParm if the result
**                     set is not empty.
**
**     SRT_Discard     Throw the results away.  This is used by SELECT
@@ -99580,7 +97559,7 @@ SQLITE_PRIVATE int sqlite3Select(
  /* If the output is destined for a temporary table, open that table.
  */
  if( pDest->eDest==SRT_EphemTab ){
-
    sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iParm, pEList->nExpr);
+
    sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr);
  }

  /* Set the limiter.
@@ -99611,7 +97590,7 @@ SQLITE_PRIVATE int sqlite3Select(
    ExprList *pDist = (isDistinct ? p->pEList : 0);

    /* Begin the database scan. */
-
    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pOrderBy, pDist, 0);
+
    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pOrderBy, pDist, 0,0);
    if( pWInfo==0 ) goto select_end;
    if( pWInfo->nRowOut < p->nSelectRow ) p->nSelectRow = pWInfo->nRowOut;

@@ -99784,7 +97763,7 @@ SQLITE_PRIVATE int sqlite3Select(
      ** in the right order to begin with.
      */
      sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
-
      pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy, 0, 0);
+
      pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy, 0, 0, 0);
      if( pWInfo==0 ) goto select_end;
      if( pGroupBy==0 ){
        /* The optimizer is able to deliver rows in group by order so
@@ -100053,7 +98032,7 @@ SQLITE_PRIVATE int sqlite3Select(
        ** of output.
        */
        resetAccumulator(pParse, &sAggInfo);
-
        pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pMinMax, 0, flag);
+
        pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pMinMax,0,flag,0);
        if( pWInfo==0 ){
          sqlite3ExprListDelete(db, pDel);
          goto select_end;
@@ -100525,7 +98504,7 @@ SQLITE_PRIVATE void sqlite3BeginTrigger(
    iDb = 1;
    pName = pName1;
  }else{
-
    /* Figure out the db that the the trigger will be created in */
+
    /* Figure out the db that the trigger will be created in */
    iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
    if( iDb<0 ){
      goto trigger_cleanup;
@@ -101853,7 +99832,7 @@ SQLITE_PRIVATE void sqlite3Update(
  */
  sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid);
  pWInfo = sqlite3WhereBegin(
-
      pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED
+
      pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED, 0
  );
  if( pWInfo==0 ) goto update_cleanup;
  okOnePass = pWInfo->okOnePass;
@@ -102694,7 +100673,7 @@ SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *pVTab){

  assert( db );
  assert( pVTab->nRef>0 );
-
  assert( sqlite3SafetyCheckOk(db) );
+
  assert( db->magic==SQLITE_MAGIC_OPEN || db->magic==SQLITE_MAGIC_ZOMBIE );

  pVTab->nRef--;
  if( pVTab->nRef==0 ){
@@ -107282,7 +105261,7 @@ static int codeAllEqualityTerms(
    int r1;
    int k = pIdx->aiColumn[j];
    pTerm = findTerm(pWC, iCur, k, notReady, pLevel->plan.wsFlags, pIdx);
-
    if( NEVER(pTerm==0) ) break;
+
    if( pTerm==0 ) break;
    /* The following true for indices with redundant columns. 
    ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */
    testcase( (pTerm->wtFlags & TERM_CODED)!=0 );
@@ -107957,6 +105936,8 @@ static Bitmask codeOneLoopStart(
    */
    WhereClause *pOrWc;    /* The OR-clause broken out into subterms */
    SrcList *pOrTab;       /* Shortened table list or OR-clause generation */
+
    Index *pCov = 0;             /* Potential covering index (or NULL) */
+
    int iCovCur = pParse->nTab++;  /* Cursor used for index scans (if any) */

    int regReturn = ++pParse->nMem;           /* Register used with OP_Gosub */
    int regRowset = 0;                        /* Register for RowSet object */
@@ -107975,7 +105956,7 @@ static Bitmask codeOneLoopStart(
    pLevel->op = OP_Return;
    pLevel->p1 = regReturn;

-
    /* Set up a new SrcList ni pOrTab containing the table being scanned
+
    /* Set up a new SrcList in pOrTab containing the table being scanned
    ** by this loop in the a[0] slot and all notReady tables in a[1..] slots.
    ** This becomes the SrcList in the recursive call to sqlite3WhereBegin().
    */
@@ -108052,8 +106033,10 @@ static Bitmask codeOneLoopStart(
        /* Loop through table entries that match term pOrTerm. */
        pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
                        WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY |
-
                        WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY);
+
                        WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY, iCovCur);
+
        assert( pSubWInfo || pParse->nErr || pParse->db->mallocFailed );
        if( pSubWInfo ){
+
          WhereLevel *pLvl;
          explainOneScan(
              pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
          );
@@ -108074,11 +106057,36 @@ static Bitmask codeOneLoopStart(
          */
          if( pSubWInfo->untestedTerms ) untestedTerms = 1;

+
          /* If all of the OR-connected terms are optimized using the same
+
          ** index, and the index is opened using the same cursor number
+
          ** by each call to sqlite3WhereBegin() made by this loop, it may
+
          ** be possible to use that index as a covering index.
+
          **
+
          ** If the call to sqlite3WhereBegin() above resulted in a scan that
+
          ** uses an index, and this is either the first OR-connected term
+
          ** processed or the index is the same as that used by all previous
+
          ** terms, set pCov to the candidate covering index. Otherwise, set 
+
          ** pCov to NULL to indicate that no candidate covering index will 
+
          ** be available.
+
          */
+
          pLvl = &pSubWInfo->a[0];
+
          if( (pLvl->plan.wsFlags & WHERE_INDEXED)!=0
+
           && (pLvl->plan.wsFlags & WHERE_TEMP_INDEX)==0
+
           && (ii==0 || pLvl->plan.u.pIdx==pCov)
+
          ){
+
            assert( pLvl->iIdxCur==iCovCur );
+
            pCov = pLvl->plan.u.pIdx;
+
          }else{
+
            pCov = 0;
+
          }
+

          /* Finish the loop through table entries that match term pOrTerm. */
          sqlite3WhereEnd(pSubWInfo);
        }
      }
    }
+
    pLevel->u.pCovidx = pCov;
+
    pLevel->iIdxCur = iCovCur;
    if( pAndExpr ){
      pAndExpr->pLeft = 0;
      sqlite3ExprDelete(pParse->db, pAndExpr);
@@ -108296,7 +106304,8 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
  Expr *pWhere,         /* The WHERE clause */
  ExprList **ppOrderBy, /* An ORDER BY clause, or NULL */
  ExprList *pDistinct,  /* The select-list for DISTINCT queries - or NULL */
-
  u16 wctrlFlags        /* One of the WHERE_* flags defined in sqliteInt.h */
+
  u16 wctrlFlags,       /* One of the WHERE_* flags defined in sqliteInt.h */
+
  int iIdxCur           /* If WHERE_ONETABLE_ONLY is set, index cursor number */
){
  int i;                     /* Loop counter */
  int nByteWInfo;            /* Num. bytes allocated for WhereInfo struct */
@@ -108616,7 +106625,13 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
    testcase( bestPlan.plan.wsFlags & WHERE_INDEXED );
    testcase( bestPlan.plan.wsFlags & WHERE_TEMP_INDEX );
    if( bestPlan.plan.wsFlags & (WHERE_INDEXED|WHERE_TEMP_INDEX) ){
-
      pLevel->iIdxCur = pParse->nTab++;
+
      if( (wctrlFlags & WHERE_ONETABLE_ONLY) 
+
       && (bestPlan.plan.wsFlags & WHERE_TEMP_INDEX)==0 
+
      ){
+
        pLevel->iIdxCur = iIdxCur;
+
      }else{
+
        pLevel->iIdxCur = pParse->nTab++;
+
      }
    }else{
      pLevel->iIdxCur = -1;
    }
@@ -108717,10 +106732,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
    if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){
      Index *pIx = pLevel->plan.u.pIdx;
      KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx);
-
      int iIdxCur = pLevel->iIdxCur;
+
      int iIndexCur = pLevel->iIdxCur;
      assert( pIx->pSchema==pTab->pSchema );
-
      assert( iIdxCur>=0 );
-
      sqlite3VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIx->tnum, iDb,
+
      assert( iIndexCur>=0 );
+
      sqlite3VdbeAddOp4(v, OP_OpenRead, iIndexCur, pIx->tnum, iDb,
                        (char*)pKey, P4_KEYINFO_HANDOFF);
      VdbeComment((v, "%s", pIx->zName));
    }
@@ -108868,6 +106883,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
  */
  assert( pWInfo->nLevel==1 || pWInfo->nLevel==pTabList->nSrc );
  for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){
+
    Index *pIdx = 0;
    struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom];
    Table *pTab = pTabItem->pTab;
    assert( pTab!=0 );
@@ -108897,12 +106913,15 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
    ** that reference the table and converts them into opcodes that
    ** reference the index.
    */
-
    if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 && !db->mallocFailed){
+
    if( pLevel->plan.wsFlags & WHERE_INDEXED ){
+
      pIdx = pLevel->plan.u.pIdx;
+
    }else if( pLevel->plan.wsFlags & WHERE_MULTI_OR ){
+
      pIdx = pLevel->u.pCovidx;
+
    }
+
    if( pIdx && !db->mallocFailed){
      int k, j, last;
      VdbeOp *pOp;
-
      Index *pIdx = pLevel->plan.u.pIdx;

-
      assert( pIdx!=0 );
      pOp = sqlite3VdbeGetOp(v, pWInfo->iTop);
      last = sqlite3VdbeCurrentAddr(v);
      for(k=pWInfo->iTop; k<last; k++, pOp++){
@@ -114351,12 +112370,24 @@ static void disconnectAllVtab(sqlite3 *db){
}

/*
-
** Close an existing SQLite database
+
** Return TRUE if database connection db has unfinalized prepared
+
** statements or unfinished sqlite3_backup objects.  
*/
-
SQLITE_API int sqlite3_close(sqlite3 *db){
-
  HashElem *i;                    /* Hash table iterator */
+
static int connectionIsBusy(sqlite3 *db){
  int j;
+
  assert( sqlite3_mutex_held(db->mutex) );
+
  if( db->pVdbe ) return 1;
+
  for(j=0; j<db->nDb; j++){
+
    Btree *pBt = db->aDb[j].pBt;
+
    if( pBt && sqlite3BtreeIsInBackup(pBt) ) return 1;
+
  }
+
  return 0;
+
}

+
/*
+
** Close an existing SQLite database
+
*/
+
static int sqlite3Close(sqlite3 *db, int forceZombie){
  if( !db ){
    return SQLITE_OK;
  }
@@ -114377,25 +112408,63 @@ SQLITE_API int sqlite3_close(sqlite3 *db){
  */
  sqlite3VtabRollback(db);

-
  /* If there are any outstanding VMs, return SQLITE_BUSY. */
-
  if( db->pVdbe ){
-
    sqlite3Error(db, SQLITE_BUSY, 
-
        "unable to close due to unfinalised statements");
+
  /* Legacy behavior (sqlite3_close() behavior) is to return
+
  ** SQLITE_BUSY if the connection can not be closed immediately.
+
  */
+
  if( !forceZombie && connectionIsBusy(db) ){
+
    sqlite3Error(db, SQLITE_BUSY, "unable to close due to unfinalized "
+
       "statements or unfinished backups");
    sqlite3_mutex_leave(db->mutex);
    return SQLITE_BUSY;
  }
-
  assert( sqlite3SafetyCheckSickOrOk(db) );

-
  for(j=0; j<db->nDb; j++){
-
    Btree *pBt = db->aDb[j].pBt;
-
    if( pBt && sqlite3BtreeIsInBackup(pBt) ){
-
      sqlite3Error(db, SQLITE_BUSY, 
-
          "unable to close due to unfinished backup operation");
-
      sqlite3_mutex_leave(db->mutex);
-
      return SQLITE_BUSY;
-
    }
+
  /* Convert the connection into a zombie and then close it.
+
  */
+
  db->magic = SQLITE_MAGIC_ZOMBIE;
+
  sqlite3LeaveMutexAndCloseZombie(db);
+
  return SQLITE_OK;
+
}
+

+
/*
+
** Two variations on the public interface for closing a database
+
** connection. The sqlite3_close() version returns SQLITE_BUSY and
+
** leaves the connection option if there are unfinalized prepared
+
** statements or unfinished sqlite3_backups.  The sqlite3_close_v2()
+
** version forces the connection to become a zombie if there are
+
** unclosed resources, and arranges for deallocation when the last
+
** prepare statement or sqlite3_backup closes.
+
*/
+
SQLITE_API int sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); }
+
SQLITE_API int sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); }
+

+

+
/*
+
** Close the mutex on database connection db.
+
**
+
** Furthermore, if database connection db is a zombie (meaning that there
+
** has been a prior call to sqlite3_close(db) or sqlite3_close_v2(db)) and
+
** every sqlite3_stmt has now been finalized and every sqlite3_backup has
+
** finished, then free all resources.
+
*/
+
SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
+
  HashElem *i;                    /* Hash table iterator */
+
  int j;
+

+
  /* If there are outstanding sqlite3_stmt or sqlite3_backup objects
+
  ** or if the connection has not yet been closed by sqlite3_close_v2(),
+
  ** then just leave the mutex and return.
+
  */
+
  if( db->magic!=SQLITE_MAGIC_ZOMBIE || connectionIsBusy(db) ){
+
    sqlite3_mutex_leave(db->mutex);
+
    return;
  }

+
  /* If we reach this point, it means that the database connection has
+
  ** closed all sqlite3_stmt and sqlite3_backup objects and has been
+
  ** pased to sqlite3_close (meaning that it is a zombie).  Therefore,
+
  ** go ahead and free all resources.
+
  */
+

  /* Free any outstanding Savepoint structures. */
  sqlite3CloseSavepoints(db);

@@ -114483,7 +112552,6 @@ SQLITE_API int sqlite3_close(sqlite3 *db){
    sqlite3_free(db->lookaside.pStart);
  }
  sqlite3_free(db);
-
  return SQLITE_OK;
}

/*
@@ -118027,10 +116095,20 @@ SQLITE_PRIVATE int sqlite3Fts3ReadBlock(Fts3Table*, sqlite3_int64, char **, int*
SQLITE_PRIVATE int sqlite3Fts3SelectDoctotal(Fts3Table *, sqlite3_stmt **);
SQLITE_PRIVATE int sqlite3Fts3SelectDocsize(Fts3Table *, sqlite3_int64, sqlite3_stmt **);

+
#ifndef SQLITE_DISABLE_FTS4_DEFERRED
SQLITE_PRIVATE void sqlite3Fts3FreeDeferredTokens(Fts3Cursor *);
SQLITE_PRIVATE int sqlite3Fts3DeferToken(Fts3Cursor *, Fts3PhraseToken *, int);
SQLITE_PRIVATE int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *);
SQLITE_PRIVATE void sqlite3Fts3FreeDeferredDoclists(Fts3Cursor *);
+
SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *);
+
#else
+
# define sqlite3Fts3FreeDeferredTokens(x)
+
# define sqlite3Fts3DeferToken(x,y,z) SQLITE_OK
+
# define sqlite3Fts3CacheDeferredDoclists(x) SQLITE_OK
+
# define sqlite3Fts3FreeDeferredDoclists(x)
+
# define sqlite3Fts3DeferredTokenList(x,y,z) SQLITE_OK
+
#endif
+

SQLITE_PRIVATE void sqlite3Fts3SegmentsClose(Fts3Table *);
SQLITE_PRIVATE int sqlite3Fts3MaxLevel(Fts3Table *, int *);

@@ -118139,8 +116217,6 @@ SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iC
SQLITE_PRIVATE int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *);
SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr);

-
SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *);
-

/* fts3_unicode2.c (functions generated by parsing unicode text files) */
#ifdef SQLITE_ENABLE_FTS4_UNICODE61
SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int, int);
@@ -122298,6 +120374,7 @@ static int fts3EvalStart(Fts3Cursor *pCsr){
  fts3EvalAllocateReaders(pCsr, pCsr->pExpr, &nToken, &nOr, &rc);

  /* Determine which, if any, tokens in the expression should be deferred. */
+
#ifndef SQLITE_DISABLE_FTS4_DEFERRED
  if( rc==SQLITE_OK && nToken>1 && pTab->bFts4 ){
    Fts3TokenAndCost *aTC;
    Fts3Expr **apOr;
@@ -122328,6 +120405,7 @@ static int fts3EvalStart(Fts3Cursor *pCsr){
      sqlite3_free(aTC);
    }
  }
+
#endif

  fts3EvalStartReaders(pCsr, pCsr->pExpr, 1, &rc);
  return rc;
@@ -122711,6 +120789,7 @@ static int fts3EvalTestExpr(
        break;

      default: {
+
#ifndef SQLITE_DISABLE_FTS4_DEFERRED
        if( pCsr->pDeferred 
         && (pExpr->iDocid==pCsr->iPrevId || pExpr->bDeferred)
        ){
@@ -122722,7 +120801,9 @@ static int fts3EvalTestExpr(
          *pRc = fts3EvalDeferredPhrase(pCsr, pPhrase);
          bHit = (pPhrase->doclist.pList!=0);
          pExpr->iDocid = pCsr->iPrevId;
-
        }else{
+
        }else
+
#endif
+
        {
          bHit = (pExpr->bEof==0 && pExpr->iDocid==pCsr->iPrevId);
        }
        break;
@@ -129421,7 +127502,7 @@ static int fts3SegmentMerge(

  if( iLevel==FTS3_SEGCURSOR_ALL ){
    /* This call is to merge all segments in the database to a single
-
    ** segment. The level of the new segment is equal to the the numerically 
+
    ** segment. The level of the new segment is equal to the numerically
    ** greatest segment level currently present in the database for this
    ** index. The idx of the new segment is always 0.  */
    if( csr.nSegment==1 ){
@@ -130051,7 +128132,7 @@ static int fts3IncrmergePush(
        pNode->key.n = nTerm;
      }
    }else{
-
      /* Otherwise, flush the the current node of layer iLayer to disk.
+
      /* Otherwise, flush the current node of layer iLayer to disk.
      ** Then allocate a new, empty sibling node. The key will be written
      ** into the parent of this node. */
      rc = fts3WriteSegment(p, pNode->iBlock, pNode->block.a, pNode->block.n);
@@ -131498,6 +129579,7 @@ static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){
  return rc;
}

+
#ifndef SQLITE_DISABLE_FTS4_DEFERRED
/*
** Delete all cached deferred doclists. Deferred doclists are cached
** (allocated) by the sqlite3Fts3CacheDeferredDoclists() function.
@@ -131635,6 +129717,7 @@ SQLITE_PRIVATE int sqlite3Fts3DeferToken(

  return SQLITE_OK;
}
+
#endif

/*
** SQLite value pRowid contains the rowid of a row that may or may not be
@@ -133899,7 +131982,7 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int c){
    }
    assert( aEntry[0]<key );
    assert( key>=aEntry[iRes] );
-
    return (c >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF)));
+
    return (((unsigned int)c) >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF)));
  }
  return 1;
}
@@ -138179,7 +136262,7 @@ static int icuNext(

    while( iStart<iEnd ){
      int iWhite = iStart;
-
      U8_NEXT(pCsr->aChar, iWhite, pCsr->nChar, c);
+
      U16_NEXT(pCsr->aChar, iWhite, pCsr->nChar, c);
      if( u_isspace(c) ){
        iStart = iWhite;
      }else{
modified external/sqlite/sqlite3.h
@@ -107,9 +107,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-
#define SQLITE_VERSION        "3.7.13"
-
#define SQLITE_VERSION_NUMBER 3007013
-
#define SQLITE_SOURCE_ID      "2012-06-11 02:05:22 f5b5a13f7394dc143aa136f1d4faba6839eaa6dc"
+
#define SQLITE_VERSION        "3.7.14"
+
#define SQLITE_VERSION_NUMBER 3007014
+
#define SQLITE_SOURCE_ID      "2012-09-03 15:42:36 c0d89d4a9752922f9e367362366efde4f1b06f2a"

/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -219,7 +219,8 @@ SQLITE_API int sqlite3_threadsafe(void);
** the opaque structure named "sqlite3".  It is useful to think of an sqlite3
** pointer as an object.  The [sqlite3_open()], [sqlite3_open16()], and
** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()]
-
** is its destructor.  There are many other interfaces (such as
+
** and [sqlite3_close_v2()] are its destructors.  There are many other
+
** interfaces (such as
** [sqlite3_prepare_v2()], [sqlite3_create_function()], and
** [sqlite3_busy_timeout()] to name but three) that are methods on an
** sqlite3 object.
@@ -266,28 +267,46 @@ typedef sqlite_uint64 sqlite3_uint64;
/*
** CAPI3REF: Closing A Database Connection
**
-
** ^The sqlite3_close() routine is the destructor for the [sqlite3] object.
-
** ^Calls to sqlite3_close() return SQLITE_OK if the [sqlite3] object is
-
** successfully destroyed and all associated resources are deallocated.
-
**
-
** Applications must [sqlite3_finalize | finalize] all [prepared statements]
-
** and [sqlite3_blob_close | close] all [BLOB handles] associated with
-
** the [sqlite3] object prior to attempting to close the object.  ^If
+
** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors
+
** for the [sqlite3] object.
+
** ^Calls to sqlite3_close() and sqlite3_close_v2() return SQLITE_OK if
+
** the [sqlite3] object is successfully destroyed and all associated
+
** resources are deallocated.
+
**
+
** ^If the database connection is associated with unfinalized prepared
+
** statements or unfinished sqlite3_backup objects then sqlite3_close()
+
** will leave the database connection open and return [SQLITE_BUSY].
+
** ^If sqlite3_close_v2() is called with unfinalized prepared statements
+
** and unfinished sqlite3_backups, then the database connection becomes
+
** an unusable "zombie" which will automatically be deallocated when the
+
** last prepared statement is finalized or the last sqlite3_backup is
+
** finished.  The sqlite3_close_v2() interface is intended for use with
+
** host languages that are garbage collected, and where the order in which
+
** destructors are called is arbitrary.
+
**
+
** Applications should [sqlite3_finalize | finalize] all [prepared statements],
+
** [sqlite3_blob_close | close] all [BLOB handles], and 
+
** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
+
** with the [sqlite3] object prior to attempting to close the object.  ^If
** sqlite3_close() is called on a [database connection] that still has
-
** outstanding [prepared statements] or [BLOB handles], then it returns
-
** SQLITE_BUSY.
+
** outstanding [prepared statements], [BLOB handles], and/or
+
** [sqlite3_backup] objects then it returns SQLITE_OK but the deallocation
+
** of resources is deferred until all [prepared statements], [BLOB handles],
+
** and [sqlite3_backup] objects are also destroyed.
**
-
** ^If [sqlite3_close()] is invoked while a transaction is open,
+
** ^If an [sqlite3] object is destroyed while a transaction is open,
** the transaction is automatically rolled back.
**
-
** The C parameter to [sqlite3_close(C)] must be either a NULL
+
** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)]
+
** must be either a NULL
** pointer or an [sqlite3] object pointer obtained
** from [sqlite3_open()], [sqlite3_open16()], or
** [sqlite3_open_v2()], and not previously closed.
-
** ^Calling sqlite3_close() with a NULL pointer argument is a 
-
** harmless no-op.
+
** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer
+
** argument is a harmless no-op.
*/
-
SQLITE_API int sqlite3_close(sqlite3 *);
+
SQLITE_API int sqlite3_close(sqlite3*);
+
SQLITE_API int sqlite3_close_v2(sqlite3*);

/*
** The type for a callback function.
@@ -498,7 +517,7 @@ SQLITE_API int sqlite3_exec(
** CAPI3REF: Device Characteristics
**
** The xDeviceCharacteristics method of the [sqlite3_io_methods]
-
** object returns an integer which is a vector of the these
+
** object returns an integer which is a vector of these
** bit values expressing I/O characteristics of the mass storage
** device that holds the file that the [sqlite3_io_methods]
** refers to.
@@ -2648,6 +2667,12 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** codepage is currently defined.  Filenames containing international
** characters must be converted to UTF-8 prior to passing them into
** sqlite3_open() or sqlite3_open_v2().
+
**
+
** <b>Note to Windows Runtime users:</b>  The temporary directory must be set
+
** prior to calling sqlite3_open() or sqlite3_open_v2().  Otherwise, various
+
** features that require the use of temporary files may fail.
+
**
+
** See also: [sqlite3_temp_directory]
*/
SQLITE_API int sqlite3_open(
  const char *filename,   /* Database filename (UTF-8) */
@@ -3140,8 +3165,11 @@ typedef struct sqlite3_context sqlite3_context;
** ^(In those routines that have a fourth argument, its value is the
** number of bytes in the parameter.  To be clear: the value is the
** number of <u>bytes</u> in the value, not the number of characters.)^
-
** ^If the fourth parameter is negative, the length of the string is
+
** ^If the fourth parameter to sqlite3_bind_text() or sqlite3_bind_text16()
+
** is negative, then the length of the string is
** the number of bytes up to the first zero terminator.
+
** If the fourth parameter to sqlite3_bind_blob() is negative, then
+
** the behavior is undefined.
** If a non-negative fourth parameter is provided to sqlite3_bind_text()
** or sqlite3_bind_text16() then that parameter must be the byte offset
** where the NUL terminator would occur assuming the string were NUL
@@ -4138,11 +4166,11 @@ typedef void (*sqlite3_destructor_type)(void*);
** the error code is SQLITE_ERROR.  ^A subsequent call to sqlite3_result_error()
** or sqlite3_result_error16() resets the error code to SQLITE_ERROR.
**
-
** ^The sqlite3_result_toobig() interface causes SQLite to throw an error
-
** indicating that a string or BLOB is too long to represent.
+
** ^The sqlite3_result_error_toobig() interface causes SQLite to throw an
+
** error indicating that a string or BLOB is too long to represent.
**
-
** ^The sqlite3_result_nomem() interface causes SQLite to throw an error
-
** indicating that a memory allocation failed.
+
** ^The sqlite3_result_error_nomem() interface causes SQLite to throw an
+
** error indicating that a memory allocation failed.
**
** ^The sqlite3_result_int() interface sets the return value
** of the application-defined function to be the 32-bit signed integer
@@ -4449,6 +4477,21 @@ SQLITE_API int sqlite3_sleep(int);
** Hence, if this variable is modified directly, either it should be
** made NULL or made to point to memory obtained from [sqlite3_malloc]
** or else the use of the [temp_store_directory pragma] should be avoided.
+
**
+
** <b>Note to Windows Runtime users:</b>  The temporary directory must be set
+
** prior to calling [sqlite3_open] or [sqlite3_open_v2].  Otherwise, various
+
** features that require the use of temporary files may fail.  Here is an
+
** example of how to do this using C++ with the Windows Runtime:
+
**
+
** <blockquote><pre>
+
** LPCWSTR zPath = Windows::Storage::ApplicationData::Current->
+
** &nbsp;     TemporaryFolder->Path->Data();
+
** char zPathBuf&#91;MAX_PATH + 1&#93;;
+
** memset(zPathBuf, 0, sizeof(zPathBuf));
+
** WideCharToMultiByte(CP_UTF8, 0, zPath, -1, zPathBuf, sizeof(zPathBuf),
+
** &nbsp;     NULL, NULL);
+
** sqlite3_temp_directory = sqlite3_mprintf("%s", zPathBuf);
+
** </pre></blockquote>
*/
SQLITE_API SQLITE_EXTERN char *sqlite3_temp_directory;

@@ -5494,7 +5537,6 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
** implementations are available in the SQLite core:
**
** <ul>
-
** <li>   SQLITE_MUTEX_OS2
** <li>   SQLITE_MUTEX_PTHREADS
** <li>   SQLITE_MUTEX_W32
** <li>   SQLITE_MUTEX_NOOP
@@ -5502,9 +5544,9 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
**
** ^The SQLITE_MUTEX_NOOP implementation is a set of routines
** that does no real locking and is appropriate for use in
-
** a single-threaded application.  ^The SQLITE_MUTEX_OS2,
-
** SQLITE_MUTEX_PTHREADS, and SQLITE_MUTEX_W32 implementations
-
** are appropriate for use on OS/2, Unix, and Windows.
+
** a single-threaded application.  ^The SQLITE_MUTEX_PTHREADS and
+
** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix
+
** and Windows.
**
** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex